pax_global_header 0000666 0000000 0000000 00000000064 11676375214 0014526 g ustar 00root root 0000000 0000000 52 comment=379712559a34d9b638762310d07a03eb956f3953
a/ 0000775 0000000 0000000 00000000000 11676375214 0011312 5 ustar 00root root 0000000 0000000 a/Example.cs 0000664 0000000 0000000 00000004171 11676375214 0013237 0 ustar 00root root 0000000 0000000 using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace BasicDrawingSample
{
class EllipseDrawer
{
public Image Draw(int width, int height, int
strokeWidth, Color strokeColor, Color fillColor)
{
// create the bitmap we will draw to
Image image = new Bitmap(width + strokeWidth,
height + strokeWidth);
// calculate the half of the stroke
width for use later
float halfStrokeWidth = strokeWidth / 2F;
// create a rectangle that bounds the
ellipse we want to draw
RectangleF ellipseBound = new RectangleF(
halfStrokeWidth, halfStrokeWidth,
width, height);
// create a Graphics object from the bitmap
using(Graphics graphics =
Graphics.FromImage(image))
{
// create a solid color brush
using(Brush fillBrush = new
SolidBrush(fillColor))
{
// fill the ellipse
specified by the rectangle calculated above
graphics.FillEllipse(fillBrush, ellipseBound);
}
// create a pen
using(Pen pen = new
Pen(strokeColor, strokeWidth))
{
// draw the stroke of
the ellipse specified by the rectangle calculated above
graphics.DrawEllipse(pen, ellipseBound);
}
}
return image;
}
[STAThread]
static void Main(string[] args)
{
if(args.Length != 5)
{
Console.WriteLine("Usage:
ellipseDrawer width height stroke-width stroke-color fill-color");
}
else
{
// get values from the command
line arguments
int width = Int32.Parse(args[0]);
int height = Int32.Parse(args[1]);
int strokeWidth = Int32.Parse(args[2]);
Color strokeColor =
ColorTranslator.FromHtml(args[3]);
Color fillColor =
ColorTranslator.FromHtml(args[4]);
// create and instance of the
EllipseDrawer
EllipseDrawer ellipseDrawer =
new EllipseDrawer();
// draw our ellipse
Image image =
ellipseDrawer.Draw(width, height, strokeWidth, strokeColor,
fillColor);
// save to a file
image.Save("ellipse.png",
ImageFormat.Png);
// clean up the image resources
image.Dispose();
}
}
}
}
a/pom.xml 0000664 0000000 0000000 00000002554 11676375214 0012635 0 ustar 00root root 0000000 0000000
* Company: ATLANTEC Enterprise Solutions GmbH
*
* @author Carsten Zerbst carsten.zerbst@atlantec-es.com
* @version $Id$
*/
import java.io.File;
/**
* A simple interpreter displaying an EMF file read in by the EMFInputStream in
* a JPanel
*/
public class EMFDisplay {
public static void main(String[] args) {
try {
EMFViewer emfViewer = new EMFViewer();
if (args[0] != null) {
emfViewer.show(new File(args[0]));
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
// EMFDisplay
a/src/main/java/org/freehep/graphicsio/emf/EMFExportFileType.java 0000664 0000000 0000000 00000003765 11676375214 0025203 0 ustar 00root root 0000000 0000000 // Copyright 2000-2007, FreeHEP
package org.freehep.graphicsio.emf;
import java.awt.Component;
import java.awt.Dimension;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphicsio.AbstractVectorGraphicsIO;
import org.freehep.graphicsio.exportchooser.AbstractExportFileType;
import org.freehep.graphicsio.exportchooser.BackgroundPanel;
import org.freehep.graphicsio.exportchooser.FontPanel;
import org.freehep.graphicsio.exportchooser.OptionPanel;
import org.freehep.swing.layout.TableLayout;
import org.freehep.util.UserProperties;
/**
* // FIXME, check all options
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFExportFileType extends AbstractExportFileType {
public String getDescription() {
return "Windows Enhanced Metafile";
}
public String[] getExtensions() {
return new String[] { "emf" };
}
public String[] getMIMETypes() {
return new String[] { "image/x-emf" };
}
public boolean hasOptionPanel() {
return true;
}
public JPanel createOptionPanel(Properties user) {
UserProperties options = new UserProperties(user, EMFGraphics2D
.getDefaultProperties());
String rootKey = EMFGraphics2D.class.getName();
String abstractRootKey = AbstractVectorGraphicsIO.class.getName();
// Make the full panel.
OptionPanel optionsPanel = new OptionPanel();
optionsPanel.add("0 0 [5 5 5 5] wt", new BackgroundPanel(options,
rootKey, true));
optionsPanel.add("0 1 [5 5 5 5] wt", new FontPanel(options, null,
abstractRootKey));
optionsPanel.add(TableLayout.COLUMN_FILL, new JLabel());
return optionsPanel;
}
public VectorGraphics getGraphics(OutputStream os, Component target)
throws IOException {
return new EMFGraphics2D(os, target);
}
public VectorGraphics getGraphics(OutputStream os, Dimension dimension)
throws IOException {
return new EMFGraphics2D(os, dimension);
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFGraphics2D.java 0000664 0000000 0000000 00000064462 11676375214 0024207 0 ustar 00root root 0000000 0000000 // Copyright 2000-2007 FreeHEP
package org.freehep.graphicsio.emf;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.freehep.graphics2d.PrintColor;
import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphics2d.font.FontEncoder;
import org.freehep.graphics2d.font.FontUtilities;
import org.freehep.graphicsio.AbstractVectorGraphicsIO;
import org.freehep.graphicsio.PageConstants;
import org.freehep.graphicsio.emf.gdi.AlphaBlend;
import org.freehep.graphicsio.emf.gdi.BeginPath;
import org.freehep.graphicsio.emf.gdi.CreateBrushIndirect;
import org.freehep.graphicsio.emf.gdi.DeleteObject;
import org.freehep.graphicsio.emf.gdi.EOF;
import org.freehep.graphicsio.emf.gdi.EndPath;
import org.freehep.graphicsio.emf.gdi.ExtCreateFontIndirectW;
import org.freehep.graphicsio.emf.gdi.ExtCreatePen;
import org.freehep.graphicsio.emf.gdi.ExtLogFontW;
import org.freehep.graphicsio.emf.gdi.ExtLogPen;
import org.freehep.graphicsio.emf.gdi.ExtTextOutW;
import org.freehep.graphicsio.emf.gdi.FillPath;
import org.freehep.graphicsio.emf.gdi.LogBrush32;
import org.freehep.graphicsio.emf.gdi.ModifyWorldTransform;
import org.freehep.graphicsio.emf.gdi.RestoreDC;
import org.freehep.graphicsio.emf.gdi.SaveDC;
import org.freehep.graphicsio.emf.gdi.SelectClipPath;
import org.freehep.graphicsio.emf.gdi.SelectObject;
import org.freehep.graphicsio.emf.gdi.SetBkMode;
import org.freehep.graphicsio.emf.gdi.SetMapMode;
import org.freehep.graphicsio.emf.gdi.SetMiterLimit;
import org.freehep.graphicsio.emf.gdi.SetPolyFillMode;
import org.freehep.graphicsio.emf.gdi.SetTextAlign;
import org.freehep.graphicsio.emf.gdi.SetTextColor;
import org.freehep.graphicsio.emf.gdi.SetViewportExtEx;
import org.freehep.graphicsio.emf.gdi.SetViewportOrgEx;
import org.freehep.graphicsio.emf.gdi.SetWindowExtEx;
import org.freehep.graphicsio.emf.gdi.SetWindowOrgEx;
import org.freehep.graphicsio.emf.gdi.SetWorldTransform;
import org.freehep.graphicsio.emf.gdi.StrokeAndFillPath;
import org.freehep.graphicsio.emf.gdi.StrokePath;
import org.freehep.graphicsio.emf.gdi.TextW;
import org.freehep.graphicsio.font.FontTable;
import org.freehep.util.UserProperties;
import org.freehep.util.images.ImageUtilities;
/**
* Enhanced Metafile Format Graphics 2D driver.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFGraphics2D extends AbstractVectorGraphicsIO implements
EMFConstants {
public static final String version = "$Revision$";
private EMFHandleManager handleManager;
private int penHandle;
private int brushHandle;
private Rectangle imageBounds;
private OutputStream ros;
private EMFOutputStream os;
private Color textColor = null;
private Color penColor = null;
private Color brushColor = null;
private Map fontTable; // java fonts
private Map unitFontTable; // windows fonts
private EMFPathConstructor pathConstructor;
private boolean evenOdd;
private static final Rectangle dummy = new Rectangle(0, 0, 0, 0);
/*
* ================================================================================
* Table of Contents: ------------------ 1. Constructors & Factory Methods
* 2. Document Settings 3. Header, Trailer, Multipage & Comments 3.1 Header &
* Trailer 3.2 MultipageDocument methods 4. Create & Dispose 5. Drawing
* Methods 5.1. shapes (draw/fill) 5.1.1. lines, rectangles, round
* rectangles 5.1.2. polylines, polygons 5.1.3. ovals, arcs 5.1.4. shapes
* 5.2. Images 5.3. Strings 6. Transformations 7. Clipping 8. Graphics State /
* Settings 8.1. stroke/linewidth 8.2. paint/color 8.3. font 8.4. rendering
* hints 9. Auxiliary 10. Private/Utility Methos
* ================================================================================
*/
private static final String rootKey = EMFGraphics2D.class.getName();
public static final String TRANSPARENT = rootKey + "."
+ PageConstants.TRANSPARENT;
public static final String BACKGROUND = rootKey + "."
+ PageConstants.BACKGROUND;
public static final String BACKGROUND_COLOR = rootKey + "."
+ PageConstants.BACKGROUND_COLOR;
private static final UserProperties defaultProperties = new UserProperties();
static {
defaultProperties.setProperty(TRANSPARENT, true);
defaultProperties.setProperty(BACKGROUND, false);
defaultProperties.setProperty(BACKGROUND_COLOR, Color.GRAY);
defaultProperties.setProperty(CLIP, true);
// NOTE: using TEXT_AS_SHAPES makes the text shapes quite unreadable.
defaultProperties.setProperty(TEXT_AS_SHAPES, false);
}
public static Properties getDefaultProperties() {
return defaultProperties;
}
public static void setDefaultProperties(Properties newProperties) {
defaultProperties.setProperties(newProperties);
}
/*
* ================================================================================
* 1. Constructors & Factory Methods
* ================================================================================
*/
public EMFGraphics2D(File file, Dimension size)
throws FileNotFoundException {
this(new FileOutputStream(file), size);
}
public EMFGraphics2D(File file, Component component)
throws FileNotFoundException {
this(new FileOutputStream(file), component);
}
public EMFGraphics2D(OutputStream os, Dimension size) {
super(size, false);
this.imageBounds = new Rectangle(0, 0, size.width, size.height);
init(os);
}
public EMFGraphics2D(OutputStream os, Component component) {
super(component, false);
this.imageBounds = new Rectangle(0, 0, getSize().width,
getSize().height);
init(os);
}
private void init(OutputStream os) {
fontTable = new HashMap();
unitFontTable = new HashMap();
evenOdd = false;
handleManager = new EMFHandleManager();
ros = os;
initProperties(defaultProperties);
}
protected EMFGraphics2D(EMFGraphics2D graphics, boolean doRestoreOnDispose) {
super(graphics, doRestoreOnDispose);
// Create a graphics context from a given graphics context.
// This constructor is used by the system to clone a given graphics
// context.
// doRestoreOnDispose is used to call writeGraphicsRestore(),
// when the graphics context is being disposed off.
os = graphics.os;
imageBounds = graphics.imageBounds;
handleManager = graphics.handleManager;
fontTable = graphics.fontTable;
unitFontTable = graphics.unitFontTable;
pathConstructor = graphics.pathConstructor;
evenOdd = graphics.evenOdd;
textColor = graphics.textColor;
penColor = graphics.penColor;
brushColor = graphics.brushColor;
}
/*
* ================================================================================ |
* 2. Document Settings
* ================================================================================
*/
/*
* ================================================================================ |
* 3. Header, Trailer, Multipage & Comments
* ================================================================================
*/
/* 3.1 Header & Trailer */
public void writeHeader() throws IOException {
ros = new BufferedOutputStream(ros);
Dimension device = isDeviceIndependent() ? new Dimension(1024, 768)
: Toolkit.getDefaultToolkit().getScreenSize();
String producer = getClass().getName();
if (!isDeviceIndependent()) {
producer += " " + version.substring(1, version.length() - 1);
}
os = new EMFOutputStream(ros, imageBounds, handleManager, getCreator(),
producer, device);
pathConstructor = new EMFPathConstructor(os, imageBounds);
Point orig = new Point(imageBounds.x, imageBounds.y);
Dimension size = new Dimension(imageBounds.width, imageBounds.height);
os.writeTag(new SetMapMode(MM_ANISOTROPIC));
os.writeTag(new SetWindowOrgEx(orig));
os.writeTag(new SetWindowExtEx(size));
os.writeTag(new SetViewportOrgEx(orig));
os.writeTag(new SetViewportExtEx(size));
os.writeTag(new SetTextAlign(TA_BASELINE));
os.writeTag(new SetTextColor(getColor()));
os.writeTag(new SetPolyFillMode(EMFConstants.WINDING));
}
public void writeGraphicsState() throws IOException {
super.writeGraphicsState();
// write a special matrix here to scale all written coordinates by a
// factor of TWIPS
AffineTransform n = AffineTransform.getScaleInstance(1.0 / TWIPS,
1.0 / TWIPS);
os.writeTag(new SetWorldTransform(n));
}
public void writeBackground() throws IOException {
if (isProperty(TRANSPARENT)) {
setBackground(null);
os.writeTag(new SetBkMode(BKG_TRANSPARENT));
} else if (isProperty(BACKGROUND)) {
os.writeTag(new SetBkMode(BKG_OPAQUE));
setBackground(getPropertyColor(BACKGROUND_COLOR));
clearRect(0.0, 0.0, getSize().width, getSize().height);
} else {
os.writeTag(new SetBkMode(BKG_OPAQUE));
setBackground(getComponent() != null ? getComponent()
.getBackground() : Color.WHITE);
clearRect(0.0, 0.0, getSize().width, getSize().height);
}
}
public void writeTrailer() throws IOException {
// delete any remaining objects
for (;;) {
int handle = handleManager.highestHandleInUse();
if (handle < 0)
break;
os.writeTag(new DeleteObject(handle));
handleManager.freeHandle(handle);
}
os.writeTag(new EOF());
}
public void closeStream() throws IOException {
os.close();
}
/* 3.2 MultipageDocument methods */
/*
* ================================================================================
* 4. Create & Dispose
* ================================================================================
*/
public Graphics create() {
// Create a new graphics context from the current one.
try {
// Save the current context for restore later.
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
// The correct graphics context should be created.
return new EMFGraphics2D(this, true);
}
public Graphics create(double x, double y, double width, double height) {
// Create a new graphics context from the current one.
try {
// Save the current context for restore later.
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
// The correct graphics context should be created.
VectorGraphics graphics = new EMFGraphics2D(this, true);
graphics.translate(x, y);
graphics.clipRect(0, 0, width, height);
return graphics;
}
protected void writeGraphicsSave() throws IOException {
os.writeTag(new SaveDC());
}
protected void writeGraphicsRestore() throws IOException {
if (penHandle != 0)
os.writeTag(new DeleteObject(handleManager.freeHandle(penHandle)));
if (brushHandle != 0)
os
.writeTag(new DeleteObject(handleManager
.freeHandle(brushHandle)));
os.writeTag(new RestoreDC());
}
/*
* ================================================================================ |
* 5. Drawing Methods
* ================================================================================
*/
/* 5.1.4. shapes */
public void draw(Shape shape) {
try {
if (getStroke() instanceof BasicStroke) {
writePen((BasicStroke) getStroke(), getColor());
writePath(shape);
os.writeTag(new StrokePath(imageBounds));
} else {
writeBrush(getColor());
writePath(getStroke().createStrokedShape(shape));
os.writeTag(new FillPath(imageBounds));
}
} catch (IOException e) {
handleException(e);
}
}
public void fill(Shape shape) {
try {
if (getPaint() instanceof Color) {
writeBrush(getColor());
writePath(shape);
os.writeTag(new FillPath(imageBounds));
} else {
// draw paint as image
fill(shape, getPaint());
}
} catch (IOException e) {
handleException(e);
}
}
public void fillAndDraw(Shape shape, Color fillColor) {
try {
if (getPaint() instanceof Color) {
writePen((BasicStroke) getStroke(), getColor());
writeBrush(fillColor);
writePath(shape);
os.writeTag(new StrokeAndFillPath(imageBounds));
} else {
// draw paint as image
fill(shape, getPaint());
// draw shape
draw(shape);
}
} catch (IOException e) {
handleException(e);
}
}
/* 5.2. Images */
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
writeWarning(getClass()
+ ": copyArea(int, int, int, int, int, int) not implemented.");
// Mostly unimplemented.
}
// NOTE: does not use writeGraphicsSave and writeGraphicsRestore since these
// delete pen and brush
protected void writeImage(RenderedImage image, AffineTransform xform,
Color bkg) throws IOException {
os.writeTag(new SaveDC());
AffineTransform imageTransform = new AffineTransform(
1.0, 0.0, 0.0, -1.0, 0.0, image.getHeight());
imageTransform.preConcatenate(xform);
writeTransform(imageTransform);
BufferedImage bufferedImage = ImageUtilities.createBufferedImage(
image, null, null);
AlphaBlend alphaBlend = new AlphaBlend(
imageBounds,
toUnit(0),
toUnit(0),
toUnit(image.getWidth()),
toUnit(image.getHeight()),
new AffineTransform(),
bufferedImage,
bkg);
os.writeTag(alphaBlend);
os.writeTag(new RestoreDC());
}
/* 5.3. Strings */
public void writeString(String string, double x, double y)
throws IOException {
Color color;
Paint paint = getPaint();
if (paint instanceof Color) {
color = (Color) paint;
} else if (paint instanceof GradientPaint) {
GradientPaint gp = (GradientPaint) paint;
color = PrintColor.mixColor(gp.getColor1(), gp.getColor2());
} else {
Color bkg = getBackground();
if (bkg == null) {
color = Color.BLACK;
} else {
color = PrintColor.invert(bkg);
}
}
if (!color.equals(textColor)) {
textColor = color;
os.writeTag(new SetTextColor(textColor));
}
// dialog.bold -> Dialog with TextAttribute.WEIGHT_BOLD
Map attributes = FontUtilities.getAttributes(getFont());
FontTable.normalize(attributes);
Font font = new Font(attributes);
Font unitFont = (Font) unitFontTable.get(font);
Integer fontIndex = (Integer) fontTable.get(font);
if (fontIndex == null) {
// for special fonts (Symbol, ZapfDingbats) we choose a standard
// font and
// encode using unicode.
String fontName = font.getName();
string = FontEncoder.getEncodedString(string, fontName);
String windowsFontName = FontUtilities
.getWindowsFontName(fontName);
unitFont = new Font(windowsFontName, font.getStyle(), font
.getSize());
unitFont = unitFont.deriveFont(font.getSize2D()
* UNITS_PER_PIXEL * TWIPS);
unitFontTable.put(font, unitFont);
ExtLogFontW logFontW = new ExtLogFontW(unitFont);
int handle = handleManager.getHandle();
os.writeTag(new ExtCreateFontIndirectW(handle, logFontW));
fontIndex = new Integer(handle);
fontTable.put(font, fontIndex);
}
os.writeTag(new SelectObject(fontIndex.intValue()));
int[] widths = new int[string.length()];
for (int i = 0; i < widths.length; i++) {
double w = unitFont.getStringBounds(string, i, i + 1,
getFontRenderContext()).getWidth();
widths[i] = (int) w;
}
// font transformation sould _not_ transform string position
translate(x, y);
// apply font transformation
AffineTransform t = font.getTransform();
if (!t.isIdentity()) {
writeGraphicsSave();
writeTransform(t);
}
TextW text = new TextW(new Point(0, 0), string, 0, dummy, widths);
os.writeTag(new ExtTextOutW(imageBounds, EMFConstants.GM_ADVANCED, 1, 1, text));
// revert font transformation
if (!t.isIdentity()) {
writeGraphicsRestore();
}
// translation for string position.
translate(-x, -y);
}
/*
* ================================================================================ |
* 6. Transformations
* ================================================================================
*/
protected void writeTransform(AffineTransform t) throws IOException {
AffineTransform n = new AffineTransform(t.getScaleX(), t.getShearY(), t
.getShearX(), t.getScaleY(), t.getTranslateX()
* UNITS_PER_PIXEL * TWIPS, t.getTranslateY() * UNITS_PER_PIXEL
* TWIPS);
os.writeTag(new ModifyWorldTransform(n, EMFConstants.MWT_LEFTMULTIPLY));
}
protected void writeSetTransform(AffineTransform t) throws IOException {
// write a special matrix here to scale all written coordinates by a factor of TWIPS
AffineTransform n = AffineTransform.getScaleInstance(1.0/TWIPS, 1.0/TWIPS);
os.writeTag(new SetWorldTransform(n));
// apply transform
writeTransform(t);
}
/*
* ================================================================================ |
* 7. Clipping
* ================================================================================
*/
protected void writeSetClip(Shape s) throws IOException {
if (!isProperty(CLIP)) {
return;
}
// if s == null the clip is reset to the imageBounds
if (s == null && imageBounds != null) {
s = new Rectangle(imageBounds);
AffineTransform at = getTransform();
if (at != null) {
s = at.createTransformedShape(s);
}
}
writePath(s);
os.writeTag(new SelectClipPath(EMFConstants.RGN_COPY));
}
protected void writeClip(Shape s) throws IOException {
if (s == null || !isProperty(CLIP)) {
return;
}
writePath(s);
os.writeTag(new SelectClipPath(EMFConstants.RGN_AND));
}
/*
* ================================================================================ |
* 8. Graphics State
* ================================================================================
*/
public void writeStroke(Stroke stroke) throws IOException {
if (stroke instanceof BasicStroke) {
writePen((BasicStroke) stroke, getColor());
}
}
/* 8.2. paint/color */
public void setPaintMode() {
writeWarning(getClass() + ": setPaintMode() not implemented.");
// Mostly unimplemented.
}
public void setXORMode(Color c1) {
writeWarning(getClass() + ": setXORMode(Color) not implemented.");
// Mostly unimplemented.
}
protected void writePaint(Color p) throws IOException {
// all color setting delayed
}
protected void writePaint(GradientPaint p) throws IOException {
// all paint setting delayed
}
protected void writePaint(TexturePaint p) throws IOException {
// all paint setting delayed
}
protected void writePaint(Paint p) throws IOException {
// all paint setting delayed
}
/* 8.3. font */
protected void writeFont(Font font) throws IOException {
// written when needed
}
/* 8.4. rendering hints */
/*
* ================================================================================ |
* 9. Auxiliary
* ================================================================================
*/
public GraphicsConfiguration getDeviceConfiguration() {
writeWarning(getClass() + ": getDeviceConfiguration() not implemented.");
// Mostly unimplemented
return null;
}
public void writeComment(String comment) throws IOException {
writeWarning(getClass() + ": writeComment(String) not implemented.");
// Write out the comment.
}
public String toString() {
return "EMFGraphics2D";
}
/**
* Implementation of createShape makes sure that the points are different by
* at least one Unit.
*/
protected Shape createShape(double[] xPoints, double[] yPoints,
int nPoints, boolean close) {
GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
if (nPoints > 0) {
path.moveTo((float) xPoints[0], (float) yPoints[0]);
double lastX = xPoints[0];
double lastY = yPoints[0];
if (close && (Math.abs(xPoints[nPoints - 1] - lastX) < 1)
&& (Math.abs(yPoints[nPoints - 1] - lastY) < 1)) {
nPoints--;
}
for (int i = 1; i < nPoints; i++) {
if ((Math.abs(xPoints[i] - lastX) > 1)
|| (Math.abs(yPoints[i] - lastY) > 1)) {
path.lineTo((float) xPoints[i], (float) yPoints[i]);
lastX = xPoints[i];
lastY = yPoints[i];
}
}
if (close)
path.closePath();
}
return path;
}
/*
* Private methods
*/
private boolean writePath(Shape shape) throws IOException {
boolean eo = EMFPathConstructor.isEvenOdd(shape);
if (eo != evenOdd) {
evenOdd = eo;
os.writeTag(new SetPolyFillMode((evenOdd) ? EMFConstants.ALTERNATE
: EMFConstants.WINDING));
}
os.writeTag(new BeginPath());
pathConstructor.addPath(shape);
os.writeTag(new EndPath());
return evenOdd;
}
private void writePen(BasicStroke stroke, Color color) throws IOException {
if (color.equals(penColor) && stroke.equals(getStroke()))
return;
penColor = color;
int style = EMFConstants.PS_GEOMETRIC;
switch (stroke.getEndCap()) {
case BasicStroke.CAP_BUTT:
style |= EMFConstants.PS_ENDCAP_FLAT;
break;
case BasicStroke.CAP_ROUND:
style |= EMFConstants.PS_ENDCAP_ROUND;
break;
case BasicStroke.CAP_SQUARE:
style |= EMFConstants.PS_ENDCAP_SQUARE;
break;
}
switch (stroke.getLineJoin()) {
case BasicStroke.JOIN_MITER:
style |= EMFConstants.PS_JOIN_MITER;
break;
case BasicStroke.JOIN_ROUND:
style |= EMFConstants.PS_JOIN_ROUND;
break;
case BasicStroke.JOIN_BEVEL:
style |= EMFConstants.PS_JOIN_BEVEL;
break;
}
// FIXME int conversion
// FIXME phase ignored
float[] dashArray = stroke.getDashArray();
int[] dash = new int[(dashArray != null) ? dashArray.length : 0];
style |= (dash.length == 0) ? EMFConstants.PS_SOLID
: EMFConstants.PS_USERSTYLE;
for (int i = 0; i < dash.length; i++) {
dash[i] = toUnit(dashArray[i]);
}
int brushStyle = (color.getAlpha() == 0) ? EMFConstants.BS_NULL
: EMFConstants.BS_SOLID;
ExtLogPen pen = new ExtLogPen(style, toUnit(stroke.getLineWidth()),
brushStyle, getPrintColor(color), 0, dash);
if (penHandle != 0) {
os.writeTag(new DeleteObject(penHandle));
} else {
penHandle = handleManager.getHandle();
}
os.writeTag(new ExtCreatePen(penHandle, pen));
os.writeTag(new SelectObject(penHandle));
if (!(getStroke() instanceof BasicStroke)
|| (((BasicStroke) getStroke()).getMiterLimit() != stroke
.getMiterLimit())) {
os.writeTag(new SetMiterLimit(toUnit(stroke.getMiterLimit())));
}
}
private void writeBrush(Color color) throws IOException {
if (color.equals(brushColor))
return;
brushColor = color;
int brushStyle = (color.getAlpha() == 0) ? EMFConstants.BS_NULL
: EMFConstants.BS_SOLID;
LogBrush32 brush = new LogBrush32(brushStyle, getPrintColor(color), 0);
if (brushHandle != 0) {
os.writeTag(new DeleteObject(brushHandle));
} else {
brushHandle = handleManager.getHandle();
}
os.writeTag(new CreateBrushIndirect(brushHandle, brush));
os.writeTag(new SelectObject(brushHandle));
}
private int toUnit(double d) {
return (int) Math.floor(d * UNITS_PER_PIXEL * TWIPS);
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFHandleManager.java 0000664 0000000 0000000 00000001574 11676375214 0024742 0 ustar 00root root 0000000 0000000 package org.freehep.graphicsio.emf;
import java.util.BitSet;
/**
* Allocates and frees handles for EMF files
*
* @author Tony Johnson
* @version $Id$
*/
public class EMFHandleManager {
private BitSet handles = new BitSet();
private int maxHandle;
public int getHandle() {
int handle = nextClearBit();
handles.set(handle);
if (handle > maxHandle)
maxHandle = handle;
return handle;
}
public int freeHandle(int handle) {
handles.clear(handle);
return handle;
}
private int nextClearBit() {
// return handles.nextClearBit(1); // JDK 1.4
for (int i = 1;; i++)
if (!handles.get(i))
return i;
}
public int highestHandleInUse() {
return handles.length() - 1;
}
public int maxHandlesUsed() {
return maxHandle + 1;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFHeader.java 0000664 0000000 0000000 00000022664 11676375214 0023447 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.IOException;
/**
* EMF File Header.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFHeader implements EMFConstants {
private static final Dimension screenMM = new Dimension(320, 240);
public final static int TYPE_INVALID = 0; // Invalid metafile
public final static int TYPE_WMF = 1; // Standard WMF
public final static int TYPE_WMF_PLACEABLE = 2; // Placeable WMF
public final static int TYPE_EMF = 3; // EMF (not EMF+)
public final static int TYPE_EMF_PLUS_ONLY = 4; // EMF+ without dual, down-level records
public final static int TYPE_EMF_PLUS_DUAL = 5; // EMF+ with dual, down-level records
private int type;
private Rectangle bounds;
private Rectangle frame;
private String signature;
private int versionMajor;
private int versionMinor;
private int bytes;
private int records;
private int handles;
private String description;
private int palEntries;
private Dimension device;
private Dimension millimeters;
private Dimension micrometers;
private boolean openGL;
/**
* @deprecated
*/
public EMFHeader(Rectangle bounds, int versionMajor, int versionMinor,
int bytes, int records, int handles, String application,
String name, Dimension device) {
// Was WMF in 2.0 should be EMF from now on
this(TYPE_EMF, bounds, versionMajor, versionMinor, bytes, records, handles, application, name, device);
}
public EMFHeader(int type, Rectangle bounds, int versionMajor, int versionMinor,
int bytes, int records, int handles, String application,
String name, Dimension device) {
this.type = type;
this.bounds = bounds;
// this assumes you use MM_ANISOTROPIC or MM_ISOTROPIC as MapMode
double pixelWidth = (double) screenMM.width / device.width;
double pixelHeight = (double) screenMM.height / device.height;
this.frame = new Rectangle((int) (bounds.x * 100 * pixelWidth),
(int) (bounds.y * 100 * pixelHeight),
(int) (bounds.width * 100 * pixelWidth),
(int) (bounds.height * 100 * pixelHeight));
this.signature = " EMF";
this.versionMajor = versionMajor >= 0x4000 ? versionMajor - 0x4000 : versionMajor;
this.versionMinor = versionMinor;
this.bytes = bytes;
this.records = records;
this.handles = handles;
this.description = application.trim() + "\0" + name.trim() + "\0\0";
this.palEntries = 0;
this.device = device;
this.millimeters = screenMM;
this.openGL = false;
this.micrometers = new Dimension(screenMM.width * 1000,
screenMM.height * 1000);
}
EMFHeader(EMFInputStream emf) throws IOException {
// FIXME: incomplete
type = emf.readDWORD(); // 4
int length = emf.readDWORD(); // 8
bounds = emf.readRECTL(); // 24
frame = emf.readRECTL(); // 40
signature = new String(emf.readBYTE(4)); // 44
int version = emf.readDWORD(); // 48
versionMajor = version >> 16;
versionMinor = version & 0xFFFF;
bytes = emf.readDWORD(); // 52
records = emf.readDWORD(); // 56
handles = emf.readWORD(); // 58
emf.readWORD(); // 60
int dLen = emf.readDWORD(); // 64
int dOffset = emf.readDWORD(); // 68
palEntries = emf.readDWORD(); // 72
device = emf.readSIZEL(); // 80
millimeters = emf.readSIZEL(); // 88
int bytesRead = 88;
if (dOffset > 88) {
emf.readDWORD(); // 92
emf.readDWORD(); // 96
openGL = (emf.readDWORD() != 0) ? true : false; // 100
bytesRead += 12;
if (dOffset > 100) {
micrometers = emf.readSIZEL(); // 108
bytesRead += 8;
}
}
// Discard any bytes leading up to the description (usually zero, but safer not to assume.)
if (bytesRead < dOffset) {
emf.skipBytes(dOffset - bytesRead);
bytesRead = dOffset;
}
description = emf.readWCHAR(dLen);
bytesRead += dLen * 2;
// Discard bytes after the description up to the end of the header.
if (bytesRead < length) {
emf.skipBytes(length - bytesRead);
}
}
public void write(EMFOutputStream emf) throws IOException {
int align = emf.getTagAlignment();
int padding = (align - (size() % align)) % align;
int alignedSize = size() + padding;
emf.writeDWORD(type); // Header Type
emf.writeDWORD(alignedSize); // length of header
emf.writeRECTL(bounds); // inclusive bounds
emf.writeRECTL(frame); // inclusive picture
emf.writeBYTE(signature.getBytes()); // signature ID EMF
emf.writeDWORD((versionMajor << 16) | versionMinor); // version
emf.writeDWORD(alignedSize + bytes); // file size
emf.writeDWORD(records); // # of records
emf.writeWORD(handles); // # of handles, 1 minimum
emf.writeWORD(0); // reserved
emf.writeDWORD(type == TYPE_EMF_PLUS_ONLY ? 0 : description.length()); // size of descriptor in WORDS
emf.writeDWORD(type == TYPE_EMF_PLUS_ONLY ? 0 : 0x6C); // offset to descriptor
emf.writeDWORD(palEntries); // # of palette entries
emf.writeSIZEL(device); // size of ref device
emf.writeSIZEL(millimeters); // size of ref device in MM
if (type != TYPE_EMF_PLUS_ONLY) {
emf.writeDWORD(0); // cbPixelFormat
emf.writeDWORD(0); // offPixelFormat
emf.writeDWORD(openGL); // bOpenGL
emf.writeSIZEL(micrometers); // size of ref device in microns
// optional description
emf.writeWCHAR(description);
}
// padding
for (int i = 0; i < padding; i++) {
emf.write(0);
}
}
/**
* @return size of emf file in bytes ?
*/
public int size() {
return 108 + (2 * description.length());
}
public String toString() {
StringBuffer s = new StringBuffer("EMF Header\n");
s.append(" bounds: ").append(bounds).append("\n");
s.append(" frame: ").append(frame).append("\n");
s.append(" signature: ").append(signature).append("\n");
s.append(" versionMajor: ").append(versionMajor).append("\n");
s.append(" versionMinor: ").append(versionMinor).append("\n");
s.append(" #bytes: ").append(bytes).append("\n");
s.append(" #records: ").append(records).append("\n");
s.append(" #handles: ").append(handles).append("\n");
s.append(" description: ").append(description).append("\n");
s.append(" #palEntries: ").append(palEntries).append("\n");
s.append(" device: ").append(device).append("\n");
s.append(" millimeters: ").append(millimeters).append("\n");
s.append(" openGL: ").append(openGL).append("\n");
s.append(" micrometers: ").append(micrometers);
return s.toString();
}
/**
* Specifies the dimensions, in device units, of the smallest rectangle that
* can be drawn around the picture stored in the metafile. This rectangle is
* supplied by graphics device interface (GDI). Its dimensions include the
* right and bottom edges.
* @return bounds of device
*/
public Rectangle getBounds() {
return bounds;
}
/**
* Specifies the dimensions, in .01 millimeter units, of a rectangle that
* surrounds the picture stored in the metafile. This rectangle must be
* supplied by the application that creates the metafile. Its dimensions
* include the right and bottom edges.
* @return bounds of frame
*/
public Rectangle getFrame() {
return frame;
}
/**
* Specifies a double word signature. This member must specify the value
* assigned to the ENHMETA_SIGNATURE constant.
* @return signature
*/
public String getSignature() {
return signature;
}
/**
* @return the description of the enhanced metafile's contents
*/
public String getDescription() {
return description;
}
/**
* Specifies the resolution of the reference device, in pixels.
* @return resolution of the reference device, in pixels
*/
public Dimension getDevice() {
return device;
}
/**
* Specifies the resolution of the reference device, in millimeters.
* @return size in millimeters
*/
public Dimension getMillimeters() {
return millimeters;
}
/**
* Windows 98/Me, Windows 2000/XP: Size of the reference device in
* micrometers.
* @return size in micrometers
*/
public Dimension getMicrometers() {
return micrometers;
}
/**
* Windows 95/98/Me, Windows NT 4.0 and later: Specifies whether any OpenGL
* records are present in a metafile. bOpenGL is a simple Boolean flag that
* you can use to determine whether an enhanced metafile requires OpenGL
* handling. When a metafile contains OpenGL records, bOpenGL is TRUE;
* otherwise it is FALSE.
*
* @return false is default
*/
public boolean isOpenGL() {
return openGL;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFImageLoader.java 0000664 0000000 0000000 00000043523 11676375214 0024425 0 ustar 00root root 0000000 0000000 package org.freehep.graphicsio.emf;
import org.freehep.graphicsio.emf.gdi.BitmapInfoHeader;
import org.freehep.graphicsio.emf.gdi.BlendFunction;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.io.IOException;
import java.util.Arrays;
/**
* this class creates a BufferedImage from EMF imaga data stored in
* a byte[].
*
* @author Steffen Greiffenberg
* @version $Id$
*/
public class EMFImageLoader {
/**
* creates a BufferedImage from an EMFInputStream using
* BitmapInfoHeader data
*
* @param bmi BitmapInfoHeader storing Bitmap informations
* @param width expected image width
* @param height expected image height
* @param emf EMF stream
* @param len length of image data
* @param blendFunction contains values for transparency
* @return BufferedImage or null
* @throws java.io.IOException thrown by EMFInputStream
*/
public static BufferedImage readImage(
BitmapInfoHeader bmi,
int width,
int height,
EMFInputStream emf,
int len,
BlendFunction blendFunction) throws IOException {
// 0 Windows 98/Me, Windows 2000/XP: The number of bits-per-pixel
// is specified or is implied by the JPEG or PNG format.
if (bmi.getBitCount() == 1) {
// 1 The bitmap is monochrome, and the bmiColors
// member of BITMAPINFO contains two entries. Each
// bit in the bitmap array represents a pixel. If
// the bit is clear, the pixel is displayed with
// the color of the first entry in the bmiColors
// table; if the bit is set, the pixel has the color
// of the second entry in the table.
// byte[] bytes = emf.readByte(len);
int blue = emf.readUnsignedByte();
int green = emf.readUnsignedByte();
int red = emf.readUnsignedByte();
/*int unused =*/ emf.readUnsignedByte();
int color1 = new Color(red, green, blue).getRGB();
blue = emf.readUnsignedByte();
green = emf.readUnsignedByte();
red = emf.readUnsignedByte();
/*unused = */ emf.readUnsignedByte();
int color2 = new Color(red, green, blue).getRGB();
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] data = emf.readUnsignedByte(len - 8);
// TODO: this is highly experimental and does
// not work for the tested examples
int strangeOffset = width % 8;
if (strangeOffset != 0) {
strangeOffset = 8 - strangeOffset;
}
// iterator for pixel data
int pixel = 0;
// mask for getting the bits from a pixel data byte
int[] mask = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
// image data are swapped compared to java standard
for (int y = height - 1; y > -1; y--) {
for (int x = 0; x < width; x++) {
int pixelDataGroup = data[pixel / 8];
int pixelData = pixelDataGroup & mask[pixel % 8];
pixel ++;
if (pixelData > 0) {
result.setRGB(x, y, color2);
} else {
result.setRGB(x, y, color1);
}
}
// add the extra width
pixel = pixel + strangeOffset;
}
/* for debugging: shows every loaded image
javax.swing.JFrame f = new javax.swing.JFrame("test");
f.getContentPane().setBackground(Color.green);
f.getContentPane().setLayout(
new java.awt.BorderLayout(0, 0));
f.getContentPane().add(
java.awt.BorderLayout.CENTER,
new javax.swing.JLabel(
new javax.swing.ImageIcon(result)));
f.setSize(new java.awt.Dimension(width + 20, height + 20));
f.setVisible(true);*/
return result;
} else if ((bmi.getBitCount() == 8) &&
(bmi.getCompression() == EMFConstants.BI_RGB)) {
// 8 The bitmap has a maximum of 256 colors, and the bmiColors member
// of BITMAPINFO contains up to 256 entries. In this case, each byte in
// the array represents a single pixel.
// TODO has to be done in BitMapInfoHeader?
// read the color table
int colorsUsed = bmi.getClrUsed();
// typedef struct tagRGBQUAD {
// BYTE rgbBlue;
// BYTE rgbGreen;
// BYTE rgbRed;
// BYTE rgbReserved;
// } RGBQUAD;
int[] colors = emf.readUnsignedByte(colorsUsed * 4);
// data a indexes to a certain color in the colortable.
// Each byte represents a pixel
int[] data = emf.readUnsignedByte(len - (colorsUsed * 4));
// convert it to a color table
int[] colorTable = new int[256];
// iterator for color data
int color = 0;
for (int i = 0; i < colorsUsed; i++, color = i * 4) {
colorTable[i] = new Color(
colors[color + 2],
colors[color + 1],
colors[color]).getRGB();
}
// fill with black to avoid ArrayIndexOutOfBoundExceptions;
// somme images seem to use more colors than stored in ClrUsed
if (colorsUsed < 256) {
Arrays.fill(colorTable, colorsUsed, 256, 0);
}
// don't know why, but the width has to be adjusted ...
// it took more than an hour to determine the strangeOffset
int strangeOffset = width % 4;
if (strangeOffset != 0) {
strangeOffset = 4 - strangeOffset;
}
// create the image
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// iterator for pixel data
int pixel = 0;
// image data are swapped compared to java standard
for (int y = height - 1; y > -1; y--) {
for (int x = 0; x < width; x++) {
result.setRGB(x, y, colorTable[data[pixel++]]);
}
// add the extra width
pixel = pixel + strangeOffset;
}
return result;
}
// The bitmap has a maximum of 2^16 colors. If the biCompression member
// of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is
// NULL.
else if ((bmi.getBitCount() == 16) &&
(bmi.getCompression() == EMFConstants.BI_RGB)) {
// Each WORD in the bitmap array represents a single pixel. The
// relative intensities of red, green, and blue are represented with
// five bits for each color component. The value for blue is in the least
// significant five bits, followed by five bits each for green and red.
// The most significant bit is not used. The bmiColors color table is used
// for optimizing colors used on palette-based devices, and must contain
// the number of entries specified by the biClrUsed member of the
// BITMAPINFOHEADER.
int[] data = emf.readDWORD(len / 4);
// don't know why, by the width has to be the half ...
// maybe that has something to do with sie HALFTONE rendering setting.
width = (width + (width % 2)) / 2;
// to avoid ArrayIndexOutOfBoundExcesptions
height = data.length / width / 2;
// create a non transparent image
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// found no sample and color model to mak this work
// tag.image.setRGB(0, 0, tag.widthSrc, tag.heightSrc, data, 0, 0);
// used in the loop
int off = 0;
int pixel, neighbor;
// image data are swapped compared to java standard
for (int y = height - 1; y > -1; y--, off = off + width) {
for (int x = 0; x < width; x++) {
neighbor = data[off + width];
pixel = data[off++];
// compute the average of the pixel and it's neighbor
// and set the reulting color values
result.setRGB(x, y, new Color(
// 0xF800 = 2 * 0x7C00
(float)((pixel & 0x7C00) + (neighbor & 0x7C00)) / 0xF800,
(float)((pixel & 0x3E0) + (neighbor & 0x3E0)) / 0x7C0,
(float)((pixel & 0x1F) + (neighbor & 0x1F)) / 0x3E).getRGB());
}
}
/* for debugging: shows every loaded image
javax.swing.JFrame f = new javax.swing.JFrame("test");
f.getContentPane().setBackground(Color.green);
f.getContentPane().setLayout(
new java.awt.BorderLayout(0, 0));
f.getContentPane().add(
java.awt.BorderLayout.CENTER,
new javax.swing.JLabel(
new javax.swing.ImageIcon(result)));
f.pack();
f.setVisible(true);*/
return result;
}
// The bitmap has a maximum of 2^32 colors. If the biCompression member of the
// BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is NULL.
else if ((bmi.getBitCount() == 32) &&
(bmi.getCompression() == EMFConstants.BI_RGB)) {
// Each DWORD in the bitmap array represents the relative intensities of blue,
// green, and red, respectively, for a pixel. The high byte in each DWORD is not
// used. The bmiColors color table is used for optimizing colors used on
// palette-based devices, and must contain the number of entries specified
// by the biClrUsed member of the BITMAPINFOHEADER.
width = (width + (width % 20)) / 20;
height = (height + (height % 20)) / 20;
// create a transparent image
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// read the image data
int[] data = emf.readDWORD(len / 4);
// used to iterate the pixels later
int off = 0;
int pixel;
int alpha;
// The SourceConstantaAlpha member of BLENDFUNCTION specifies an alpha transparency
// value to be used on the entire source bitmap. The SourceConstantAlpha value is
// combined with any per-pixel alpha values. If SourceConstantAlpha is 0, it is
// assumed that the image is transparent. Set the SourceConstantAlpha value to 255
// (which indicates that the image is opaque) when you only want to use per-pixel
// alpha values.
int sourceConstantAlpha = blendFunction.getSourceConstantAlpha();
if (blendFunction.getAlphaFormat() != EMFConstants.AC_SRC_ALPHA) {
// If the source bitmap has no per-pixel alpha value (that is, AC_SRC_ALPHA is not
// set), the SourceConstantAlpha value determines the blend of the source and
// destination bitmaps, as shown in the following table. Note that SCA is used
// for SourceConstantAlpha here. Also, SCA is divided by 255 because it has a
// value that ranges from 0 to 255.
// Dst.Red = Src.Red * (SCA/255.0) + Dst.Red * (1.0 - (SCA/255.0))
// Dst.Green = Src.Green * (SCA/255.0) + Dst.Green * (1.0 - (SCA/255.0))
// Dst.Blue = Src.Blue * (SCA/255.0) + Dst.Blue * (1.0 - (SCA/255.0))
// If the destination bitmap has an alpha channel, then the blend is as follows.
// Dst.Alpha = Src.Alpha * (SCA/255.0) + Dst.Alpha * (1.0 - (SCA/255.0))
for (int y = height - 1; y > -1 && off < data.length; y--) {
for (int x = 0; x < width && off < data.length; x++) {
pixel = data[off++];
result.setRGB(x, y, new Color(
(pixel & 0xFF0000) >> 16,
(pixel & 0xFF00) >> 8,
(pixel & 0xFF),
// TODO not tested
sourceConstantAlpha
).getRGB());
}
}
}
// When the BlendOp parameter is AC_SRC_OVER , the source bitmap is placed over
// the destination bitmap based on the alpha values of the source pixels.
else {
// If the source bitmap does not use SourceConstantAlpha (that is, it equals
// 0xFF), the per-pixel alpha determines the blend of the source and destination
// bitmaps, as shown in the following table.
if (sourceConstantAlpha == 0xFF) {
// Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
// Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green
// Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
// If the destination bitmap has an alpha channel, then the blend is as follows.
// Dest.alpha = Src.Alpha + (1 - SrcAlpha) * Dst.Alpha
// image data are swapped compared to java standard
for (int y = height - 1; y > -1 && off < data.length; y--) {
for (int x = 0; x < width && off < data.length; x++) {
pixel = data[off++];
alpha = (pixel & 0xFF000000) >> 24;
if (alpha == -1) {
alpha = 0xFF;
}
result.setRGB(x, y, new Color(
(pixel & 0xFF0000) >> 16,
(pixel & 0xFF00) >> 8,
(pixel & 0xFF),
alpha
).getRGB());
}
}
}
// If the source has both the SourceConstantAlpha (that is, it is not 0xFF)
// and per-pixel alpha, the source is pre-multiplied by the SourceConstantAlpha
// and then the blend is based on the per-pixel alpha. The following tables show
// this. Note that SourceConstantAlpha is divided by 255 because it has a value
// that ranges from 0 to 255.
else {
// Src.Red = Src.Red * SourceConstantAlpha / 255.0;
// Src.Green = Src.Green * SourceConstantAlpha / 255.0;
// Src.Blue = Src.Blue * SourceConstantAlpha / 255.0;
// Src.Alpha = Src.Alpha * SourceConstantAlpha / 255.0;
// Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
// Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green
// Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
// Dst.Alpha = Src.Alpha + (1 - Src.Alpha) * Dst.Alpha
for (int y = height - 1; y > -1 && off < data.length; y--) {
for (int x = 0; x < width && off < data.length; x++) {
pixel = data[off++];
alpha = (pixel & 0xFF000000) >> 24;
if (alpha == -1) {
alpha = 0xFF;
}
// TODO not tested
alpha = alpha * sourceConstantAlpha / 0xFF;
result.setRGB(x, y, new Color(
(pixel & 0xFF0000) >> 16,
(pixel & 0xFF00) >> 8,
(pixel & 0xFF),
alpha
).getRGB());
}
}
}
}
/* for debugging: shows every loaded image
javax.swing.JFrame f = new javax.swing.JFrame("test");
f.getContentPane().setBackground(Color.green);
f.getContentPane().setLayout(
new java.awt.BorderLayout(0, 0));
f.getContentPane().add(
java.awt.BorderLayout.CENTER,
new javax.swing.JLabel(
new javax.swing.ImageIcon(result)));
f.setSize(new java.awt.Dimension(width + 20, height + 20));
f.setVisible(true);*/
return result;
}
// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS,
// the bmiColors member contains three DWORD color masks that specify the
// red, green, and blue components, respectively, of each pixel. Each DWORD
// in the bitmap array represents a single pixel.
// Windows NT/ 2000: When the biCompression member is BI_BITFIELDS, bits set in
// each DWORD mask must be contiguous and should not overlap the bits of
// another mask. All the bits in the pixel do not need to be used.
// Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system
// supports only the following 32-bpp color mask: The blue mask is 0x000000FF,
// the green mask is 0x0000FF00, and the red mask is 0x00FF0000.
else if ((bmi.getBitCount() == 32) &&
(bmi.getCompression() == EMFConstants.BI_BITFIELDS)) {
/* byte[] bytes =*/ emf.readByte(len);
return null;
} else {
/* byte[] bytes =*/ emf.readByte(len);
return null;
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFInputStream.java 0000664 0000000 0000000 00000012475 11676375214 0024531 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.InputStream;
import org.freehep.util.io.ActionHeader;
import org.freehep.util.io.TagHeader;
import org.freehep.util.io.TaggedInputStream;
/**
* This class extends the TaggedInputStream with several methods to read EMF
* primitives from the stream and to read TagHeaders.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFInputStream extends TaggedInputStream implements EMFConstants {
public static int DEFAULT_VERSION = 1;
public EMFInputStream(InputStream is) {
this(is, DEFAULT_VERSION);
}
public EMFInputStream(InputStream is, int version) {
this(is, new EMFTagSet(version));
}
public EMFInputStream(InputStream is, EMFTagSet tagSet) {
// EMF is little-endian
super(is, tagSet, null, true);
}
public int readDWORD() throws IOException {
long i = readUnsignedInt();
return (int) i;
}
public int[] readDWORD(int size) throws IOException {
int[] x = new int[size];
for (int i = 0; i < x.length; i++) {
x[i] = readDWORD();
}
return x;
}
public int readWORD() throws IOException {
return readUnsignedShort();
}
public int readLONG() throws IOException {
return readInt();
}
public int[] readLONG(int size) throws IOException {
int[] x = new int[size];
for (int i = 0; i < x.length; i++) {
x[i] = readLONG();
}
return x;
}
public float readFLOAT() throws IOException {
return readFloat();
}
public int readUINT() throws IOException {
return (int) readUnsignedInt();
}
public int readULONG() throws IOException {
return (int) readUnsignedInt();
}
public Color readCOLORREF() throws IOException {
Color c = new Color(readUnsignedByte(), readUnsignedByte(),
readUnsignedByte());
readByte();
return c;
}
public Color readCOLOR16() throws IOException {
return new Color(readShort() >> 8, readShort() >> 8, readShort() >> 8,
readShort() >> 8);
}
public Color readCOLOR() throws IOException {
int b = readUnsignedByte();
int g = readUnsignedByte();
int r = readUnsignedByte();
int a = readUnsignedByte();
Color c = new Color(r, g, b, a);
return c;
}
public AffineTransform readXFORM() throws IOException {
return new AffineTransform(readFLOAT(), readFLOAT(), readFLOAT(),
readFLOAT(), readFLOAT(), readFLOAT());
}
public Rectangle readRECTL() throws IOException {
int x = readLONG();
int y = readLONG();
int w = readLONG() - x;
int h = readLONG() - y;
return new Rectangle(x, y, w, h);
}
public Point readPOINTL() throws IOException {
int x = readLONG();
int y = readLONG();
return new Point(x, y);
}
public Point[] readPOINTL(int size) throws IOException {
Point[] p = new Point[size];
for (int i = 0; i < p.length; i++) {
p[i] = readPOINTL();
}
return p;
}
public Point readPOINTS() throws IOException {
int x = readShort();
int y = readShort();
return new Point(x, y);
}
public Point[] readPOINTS(int size) throws IOException {
Point[] p = new Point[size];
for (int i = 0; i < p.length; i++) {
p[i] = readPOINTS();
}
return p;
}
public Dimension readSIZEL() throws IOException {
return new Dimension(readLONG(), readLONG());
}
public int readBYTE() throws IOException {
return readByte();
}
public byte[] readBYTE(int size) throws IOException {
byte[] x = new byte[size];
for (int i = 0; i < x.length; i++) {
x[i] = (byte) readBYTE();
}
return x;
}
public boolean readBOOLEAN() throws IOException {
return (readBYTE() != 0);
}
public String readWCHAR(int size) throws IOException {
byte[] bytes = readByte(2 * size);
int length = 2 * size;
for (int i = 0; i < 2 * size; i += 2) {
if (bytes[i] == 0 && bytes[i + 1] == 0) {
length = i;
break;
}
}
return new String(bytes, 0, length, "UTF-16LE");
}
protected TagHeader readTagHeader() throws IOException {
// Read the tag.
// byteAlign();
int tagID = read();
// End of stream
if (tagID == -1)
return null;
tagID |= readUnsignedByte() << 8;
int flags = readUnsignedByte();
flags |= readUnsignedByte() << 8;
long length = readDWORD();
return new EMFTagHeader(tagID, length - 8, flags);
}
protected ActionHeader readActionHeader() throws IOException {
return null;
}
private EMFHeader header;
public EMFHeader readHeader() throws IOException {
if (header == null) {
header = new EMFHeader(this);
}
return header;
}
public int getVersion() {
return DEFAULT_VERSION;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFOutputStream.java 0000664 0000000 0000000 00000016146 11676375214 0024731 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.OutputStream;
import org.freehep.graphicsio.emf.gdi.GDIComment;
import org.freehep.graphicsio.emf.gdiplus.EMFPlusTag;
import org.freehep.util.io.ActionHeader;
import org.freehep.util.io.Tag;
import org.freehep.util.io.TagHeader;
import org.freehep.util.io.TaggedOutputStream;
/**
* EMF Binary Output Stream. Tags written with this OutputStream will produce a
* binary EMF file.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFOutputStream extends TaggedOutputStream {
private String application;
private String name;
private int recordCount;
private Rectangle imageBounds;
private int version;
private EMFHandleManager handles;
private Dimension device;
public EMFOutputStream(OutputStream os, Rectangle imageBounds,
EMFHandleManager handles, String application, String name,
Dimension device, int version) throws IOException {
// EMF is little-endian
super(os, new EMFTagSet(version), null, true);
this.recordCount = 0;
this.version = version;
this.imageBounds = imageBounds;
this.handles = handles;
this.application = application;
this.name = name;
this.device = device;
// will be popped by close()
pushBuffer();
}
public EMFOutputStream(OutputStream os, Rectangle imageBounds,
EMFHandleManager handles, String application, String name,
Dimension device) throws IOException {
this(os, imageBounds, handles, application, name, device, 1);
}
public void close() throws IOException {
int len = popBuffer();
recordCount++;
// FIXME check this
EMFHeader header = new EMFHeader(EMFHeader.TYPE_WMF, imageBounds, getVersion(), 0, len,
recordCount, handles.maxHandlesUsed(), application, name,
device);
writeHeader(header);
append();
super.close();
}
// DWORD
public void writeDWORD(int i) throws IOException {
writeUnsignedInt(i);
}
// DWORD []
public void writeDWORD(int[] w) throws IOException {
for (int i = 0; i < w.length; i++) {
writeDWORD(w[i]);
}
}
// WORD
public void writeWORD(int s) throws IOException {
writeUnsignedShort(s);
}
public void writeFLOAT(float f) throws IOException {
writeFloat(f);
}
public void writeCOLORREF(Color c) throws IOException {
writeByte(c.getRed());
writeByte(c.getGreen());
writeByte(c.getBlue());
// NOTE: if not 0x00 EMF does not display correctly in full screen mode.
writeByte(0x00);
}
// COLOR16
public void writeCOLOR16(Color c) throws IOException {
writeShort(c.getRed() << 8);
writeShort(c.getGreen() << 8);
writeShort(c.getBlue() << 8);
writeShort(c.getAlpha() << 8);
}
public void writeCOLOR(Color c) throws IOException {
writeByte(c.getBlue());
writeByte(c.getGreen());
writeByte(c.getRed());
writeByte(c.getAlpha());
}
public void writeXFORM(AffineTransform t) throws IOException {
writeFLOAT((float) t.getScaleX());
writeFLOAT((float) t.getShearY());
writeFLOAT((float) t.getShearX());
writeFLOAT((float) t.getScaleY());
writeFLOAT((float) t.getTranslateX());
writeFLOAT((float) t.getTranslateY());
}
// POINTS []
public void writePOINTS(Point[] p) throws IOException {
writePOINTS(p.length, p);
}
public void writePOINTS(int n, Point[] p) throws IOException {
for (int i = 0; i < n; i++) {
writePOINTS(p[i]);
}
}
public void writePOINTS(Point p) throws IOException {
writeSHORT((short) p.x);
writeSHORT((short) p.y);
}
// POINTL []
public void writePOINTL(Point[] p) throws IOException {
writePOINTL(p.length, p);
}
public void writePOINTL(int n, Point[] p) throws IOException {
for (int i = 0; i < n; i++) {
writePOINTL(p[i]);
}
}
// POINTL
public void writePOINTL(Point p) throws IOException {
writeLONG(p.x);
writeLONG(p.y);
}
// RECTL
public void writeRECTL(Rectangle r) throws IOException {
writeLONG(r.x);
writeLONG(r.y);
writeLONG(r.x + r.width);
writeLONG(r.y + r.height);
}
// SIZEL
public void writeSIZEL(Dimension d) throws IOException {
writeLONG(d.width);
writeLONG(d.height);
}
// UINT
public void writeUINT(int i) throws IOException {
writeUnsignedInt(i);
}
// ULONG
public void writeULONG(int i) throws IOException {
writeUnsignedInt(i);
}
// LONG
public void writeLONG(int i) throws IOException {
writeInt(i);
}
public void writeSHORT(short i) throws IOException {
writeShort(i);
}
// BYTE []
public void writeBYTE(byte[] b) throws IOException {
writeByte(b);
}
// BYTE
public void writeBYTE(byte b) throws IOException {
writeByte(b);
}
// BYTE
public void writeBYTE(int b) throws IOException {
writeByte(b);
}
public void writeBYTE(boolean b) throws IOException {
writeBYTE((b) ? 1 : 0);
}
public void writeWORD(boolean b) throws IOException {
writeWORD((b) ? 1 : 0);
}
public void writeDWORD(boolean b) throws IOException {
writeDWORD((b) ? 1 : 0);
}
public void writeWCHAR(String s) throws IOException {
writeByte(s.getBytes("UTF-16LE"));
}
public void writeWCHAR(String s, int size) throws IOException {
writeWCHAR(s);
for (int i = size - s.length(); i > 0; i--) {
writeWORD(0);
}
}
protected int getTagAlignment() {
return 4;
}
protected TagHeader createTagHeader(Tag tag, long len) {
EMFTag emfTag = (EMFTag)tag;
return new EMFTagHeader(tag.getTag(), len, emfTag.getFlags());
}
protected void writeTagHeader(TagHeader header) throws IOException {
EMFTagHeader tagHeader = (EMFTagHeader)header;
writeUnsignedInt(tagHeader.getTag() | (tagHeader.getFlags() << 16));
writeUnsignedInt(tagHeader.getLength() + 8);
}
public void writeTag(Tag tag) throws IOException {
// nest EMFPlusTags in GDIComments
if (tag instanceof EMFPlusTag) {
tag = new GDIComment((EMFPlusTag)tag);
}
writeTag(tag, true);
}
public void writeTag(Tag tag, boolean doNotEmbed) throws IOException {
recordCount++;
super.writeTag(tag);
}
protected void writeActionHeader(ActionHeader header) throws IOException {
// empty
}
public void writeHeader(EMFHeader header) throws IOException {
header.write(this);
}
public int getVersion() {
return version;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFPanel.java 0000664 0000000 0000000 00000004446 11676375214 0023314 0 ustar 00root root 0000000 0000000 // Copyright 2007 FreeHEP
package org.freehep.graphicsio.emf;
import javax.swing.JComponent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
/**
* simple panel which displays an EMF image using the {@link EMFRenderer}
*
* @author Steffen Greiffenberg
* @version $id$
*/
public class EMFPanel extends JComponent {
/**
* factor used for zoom in an out
*/
private static double SCALE_FACTOR = 2;
/**
* renders an EMF image to a Graphics2D instance
*/
private EMFRenderer renderer;
/**
* used for zooming
*/
private double scale = 1;
/**
* defines a white background
*/
public EMFPanel() {
setBackground(Color.white);
}
/**
* sets the renderer an resets size
* @param renderer EMFRenderer to display
*/
public void setRenderer(EMFRenderer renderer) {
this.renderer = renderer;
scale = 1;
setSize(getPreferredSize());
}
/**
* @return {@link EMFRenderer#getSize()} for the renderer
*/
public Dimension getPreferredSize() {
if (renderer == null) {
return new Dimension(0, 0);
}
Dimension bounds = renderer.getSize();
return new Dimension(
(int)Math.ceil(bounds.width * scale),
(int)Math.ceil(bounds.height * scale));
}
/**
* paints using the renderer
* @param g Context of the component
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = ((Graphics2D)g);
super.paintComponent(g2);
if (renderer == null) {
return;
}
// to restore AffineTransform
AffineTransform at = g2.getTransform();
// apply the scale factor
g2.scale(scale, scale);
// render the emf
renderer.paint(g2);
// rest the AffineTransform
g2.setTransform(at);
}
/**
* scale = scale * 2
*/
public void zoomIn() {
scale = scale * SCALE_FACTOR;
setSize(getPreferredSize());
repaint();
}
/**
* scale = scale / 2;
*/
public void zoomOut() {
scale = scale / SCALE_FACTOR;
setSize(getPreferredSize());
repaint();
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFPathConstructor.java 0000664 0000000 0000000 00000006745 11676375214 0025423 0 ustar 00root root 0000000 0000000 // Copyright 2001 FreeHEP.
package org.freehep.graphicsio.emf;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import org.freehep.graphicsio.QuadToCubicPathConstructor;
import org.freehep.graphicsio.emf.gdi.CloseFigure;
import org.freehep.graphicsio.emf.gdi.LineTo;
import org.freehep.graphicsio.emf.gdi.MoveToEx;
import org.freehep.graphicsio.emf.gdi.PolyBezierTo;
import org.freehep.graphicsio.emf.gdi.PolyBezierTo16;
import org.freehep.graphicsio.emf.gdi.PolylineTo;
import org.freehep.graphicsio.emf.gdi.PolylineTo16;
/**
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFPathConstructor extends QuadToCubicPathConstructor implements
EMFConstants {
private EMFOutputStream os;
private Rectangle imageBounds;
private boolean curved;
private int pointIndex = 0;
private boolean wide = false;
private Point[] points = new Point[4];
public EMFPathConstructor(EMFOutputStream os, Rectangle imageBounds) {
super();
this.os = os;
this.imageBounds = imageBounds;
this.curved = false;
}
public void move(double x, double y) throws IOException {
flush();
os.writeTag(new MoveToEx(new Point(toUnit(x), toUnit(y))));
super.move(x, y);
}
private void addPoint(int n, double x, double y) {
if (n >= points.length) {
Point[] buf = new Point[n << 1];
System.arraycopy(points, 0, buf, 0, points.length);
points = buf;
}
int ix = toUnit(x);
int iy = toUnit(y);
if (wide || (ix < Short.MIN_VALUE) || (ix > Short.MAX_VALUE)
|| (iy < Short.MIN_VALUE) || (iy > Short.MAX_VALUE)) {
wide = true;
}
if (points[n] == null) {
points[n] = new Point(ix, iy);
} else {
points[n].x = ix;
points[n].y = iy;
}
}
public void line(double x, double y) throws IOException {
if (curved && (pointIndex > 0))
flush();
curved = false;
addPoint(pointIndex++, x, y);
super.line(x, y);
}
public void cubic(double x1, double y1, double x2, double y2, double x3,
double y3) throws IOException {
if (!curved && (pointIndex > 0))
flush();
curved = true;
addPoint(pointIndex++, x1, y1);
addPoint(pointIndex++, x2, y2);
addPoint(pointIndex++, x3, y3);
super.cubic(x1, y1, x2, y2, x3, y3);
}
public void closePath(double x0, double y0) throws IOException {
flush();
os.writeTag(new CloseFigure());
super.closePath(x0, y0);
}
public void flush() throws IOException {
if (curved) {
if (wide) {
os.writeTag(new PolyBezierTo(imageBounds, pointIndex, points));
} else {
os
.writeTag(new PolyBezierTo16(imageBounds, pointIndex,
points));
}
} else if (pointIndex == 1) {
os.writeTag(new LineTo(points[0]));
} else if (pointIndex > 1) {
if (wide) {
os.writeTag(new PolylineTo(imageBounds, pointIndex, points));
} else {
os.writeTag(new PolylineTo16(imageBounds, pointIndex, points));
}
}
pointIndex = 0;
wide = false;
super.flush();
}
protected int toUnit(double d) {
return (int) (d * UNITS_PER_PIXEL * TWIPS);
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFPlusExportFileType.java 0000664 0000000 0000000 00000004125 11676375214 0026036 0 ustar 00root root 0000000 0000000 // Copyright 2006 FreeHEP
package org.freehep.graphicsio.emf;
import java.awt.Component;
import java.awt.Dimension;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphicsio.exportchooser.AbstractExportFileType;
import org.freehep.graphicsio.exportchooser.BackgroundPanel;
import org.freehep.graphicsio.exportchooser.OptionPanel;
import org.freehep.swing.layout.TableLayout;
import org.freehep.util.UserProperties;
/**
*
* @author Mark Donszelmann
* @version $Id: EMFExportFileType.java 10100 2006-11-30 18:44:02Z duns $
*/
public class EMFPlusExportFileType extends AbstractExportFileType {
public String getDescription() {
return "Windows Enhanced Metafile Plus";
}
public String[] getExtensions() {
// NOTE: the extension emf+ is strictly not correct, but ExportFileType will not select it otherwise.
return new String[] { "emf", "emf+" };
}
public String[] getMIMETypes() {
return new String[] { "image/x-emf" };
}
public boolean hasOptionPanel() {
return true;
}
public JPanel createOptionPanel(Properties user) {
UserProperties options = new UserProperties(user, EMFGraphics2D
.getDefaultProperties());
String rootKey = EMFPlusGraphics2D.class.getName();
// Make the full panel.
OptionPanel optionsPanel = new OptionPanel();
optionsPanel.add("0 0 [5 5 5 5] wt", new BackgroundPanel(options,
rootKey, true));
optionsPanel.add(TableLayout.COLUMN_FILL, new JLabel());
return optionsPanel;
}
public VectorGraphics getGraphics(OutputStream os, Component target)
throws IOException {
return new EMFPlusGraphics2D(os, target);
}
public VectorGraphics getGraphics(OutputStream os, Dimension size)
throws IOException {
return new EMFPlusGraphics2D(os, size);
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFPlusGraphics2D.java 0000664 0000000 0000000 00000033025 11676375214 0025042 0 ustar 00root root 0000000 0000000 // Copyright 2006, FreeHEP
package org.freehep.graphicsio.emf;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.RenderedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphicsio.AbstractVectorGraphicsIO;
import org.freehep.graphicsio.PageConstants;
import org.freehep.graphicsio.emf.gdi.EOF;
import org.freehep.graphicsio.emf.gdiplus.Clear;
import org.freehep.graphicsio.emf.gdiplus.DrawImage;
import org.freehep.graphicsio.emf.gdiplus.DrawPath;
import org.freehep.graphicsio.emf.gdiplus.EndOfFile;
import org.freehep.graphicsio.emf.gdiplus.FillPath;
import org.freehep.graphicsio.emf.gdiplus.GDIPlusObject;
import org.freehep.graphicsio.emf.gdiplus.Header;
import org.freehep.graphicsio.emf.gdiplus.MultiplyWorldTransform;
import org.freehep.graphicsio.emf.gdiplus.ResetClip;
import org.freehep.graphicsio.emf.gdiplus.Restore;
import org.freehep.graphicsio.emf.gdiplus.Save;
import org.freehep.graphicsio.emf.gdiplus.SetAntiAliasMode;
import org.freehep.graphicsio.emf.gdiplus.SetClipPath;
import org.freehep.graphicsio.emf.gdiplus.SetWorldTransform;
import org.freehep.util.UserProperties;
import org.freehep.util.Value;
/**
* Converts calls to Graphics2D to EMF+ Format.
*
* @author Mark Donszelmann
* @version $Id: DummyGraphics2D.java 8584 2006-08-10 23:06:37Z duns $
*/
public class EMFPlusGraphics2D extends AbstractVectorGraphicsIO {
public static final String version = "$Revision: 10140 $";
private OutputStream ros;
private EMFOutputStream os;
private Rectangle imageBounds;
// FIXME do we need this?
private EMFHandleManager handleManager;
private Value containerIndex;
private Paint restorePaint;
private static final String rootKey = EMFPlusGraphics2D.class.getName();
public static final String TRANSPARENT = rootKey + "."
+ PageConstants.TRANSPARENT;
public static final String BACKGROUND = rootKey + "."
+ PageConstants.BACKGROUND;
public static final String BACKGROUND_COLOR = rootKey + "."
+ PageConstants.BACKGROUND_COLOR;
private static final UserProperties defaultProperties = new UserProperties();
static {
defaultProperties.setProperty(TRANSPARENT, true);
defaultProperties.setProperty(BACKGROUND, false);
defaultProperties.setProperty(BACKGROUND_COLOR, Color.GRAY);
defaultProperties.setProperty(CLIP, true);
defaultProperties.setProperty(TEXT_AS_SHAPES, true);
}
public static Properties getDefaultProperties() {
return defaultProperties;
}
// FIXME
public FontRenderContext getFontRenderContext() {
// NOTE: not sure?
return new FontRenderContext(new AffineTransform(-1, 0, 0, 1, 0, 0),
true, true);
}
public static void setDefaultProperties(Properties newProperties) {
defaultProperties.setProperties(newProperties);
}
public EMFPlusGraphics2D(File file, Dimension size)
throws FileNotFoundException {
this(new FileOutputStream(file), size);
}
public EMFPlusGraphics2D(File file, Component component)
throws FileNotFoundException {
this(new FileOutputStream(file), component);
}
public EMFPlusGraphics2D(OutputStream os, Dimension size) {
super(size, false);
this.imageBounds = new Rectangle(0, 0, size.width, size.height);
init(os);
}
public EMFPlusGraphics2D(OutputStream os, Component component) {
super(component, false);
this.imageBounds = new Rectangle(0, 0, getSize().width, getSize().height);
init(os);
}
private void init(OutputStream os) {
handleManager = new EMFHandleManager();
ros = os;
containerIndex = new Value();
containerIndex.set(0);
initProperties(defaultProperties);
}
protected EMFPlusGraphics2D(EMFPlusGraphics2D graphics,
boolean doRestoreOnDispose) {
super(graphics, doRestoreOnDispose);
// Create a graphics context from a given graphics context.
// This constructor is used by the system to clone a given graphics
// context.
// doRestoreOnDispose is used to call writeGraphicsRestore(),
// when the graphics context is being disposed off.
os = graphics.os;
imageBounds = graphics.imageBounds;
handleManager = graphics.handleManager;
containerIndex = graphics.containerIndex;
restorePaint = graphics.getPaint();
}
public void writeHeader() throws IOException {
ros = new BufferedOutputStream(ros);
Dimension device = isDeviceIndependent() ? new Dimension(1024, 768)
: Toolkit.getDefaultToolkit().getScreenSize();
String producer = getClass().getName();
if (!isDeviceIndependent()) {
producer += " " + version.substring(1, version.length() - 1);
}
os = new EMFOutputStream(ros, imageBounds, handleManager, getCreator(),
producer, device, 0x4001);
os.writeTag(new Header());
// leave this on since we do text as shapes.
os.writeTag(new SetAntiAliasMode(true));
//Point orig = new Point(imageBounds.x, imageBounds.y);
//Dimension size = new Dimension(imageBounds.width, imageBounds.height);
// FIXME check what to write
// os.writeTag(new SetMapMode(MM_ANISOTROPIC));
// os.writeTag(new SetWindowOrgEx(orig));
// os.writeTag(new SetWindowExtEx(size));
// os.writeTag(new SetViewportOrgEx(orig));
// os.writeTag(new SetViewportExtEx(size));
// os.writeTag(new SetTextAlign(TA_BASELINE));
// os.writeTag(new SetTextColor(getColor()));
// os.writeTag(new SetPolyFillMode(EMFConstants.WINDING));
}
public void writeBackground() throws IOException {
if (isProperty(TRANSPARENT)) {
setBackground(null);
// FIXME
// os.writeTag(new Clear(new Color(0xFF, 0xFF, 0xFF, 0x00)));
} else if (isProperty(BACKGROUND)) {
setBackground(getPropertyColor(BACKGROUND_COLOR));
os.writeTag(new Clear(getBackground()));
} else {
setBackground(getComponent() != null ? getComponent()
.getBackground() : Color.WHITE);
os.writeTag(new Clear(getBackground()));
}
}
public void writeTrailer() throws IOException {
// delete any remaining objects
for (;;) {
int handle = handleManager.highestHandleInUse();
if (handle < 0)
break;
// os.writeTag(new DeleteObject(handle));
handleManager.freeHandle(handle);
}
os.writeTag(new EndOfFile());
os.writeTag(new EOF());
}
public void closeStream() throws IOException {
os.close();
}
public Graphics create() {
// Create a new graphics context from the current one.
try {
// Save the current context for restore later.
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
// The correct graphics context should be created.
return new EMFPlusGraphics2D(this, true);
}
public Graphics create(double x, double y, double width, double height) {
// Create a new graphics context from the current one.
try {
// Save the current context for restore later.
writeGraphicsSave();
} catch (IOException e) {
handleException(e);
}
// The correct graphics context should be created.
VectorGraphics graphics = new EMFPlusGraphics2D(this, true);
graphics.translate(x, y);
graphics.clipRect(0, 0, width, height);
return graphics;
}
protected void writeGraphicsSave() throws IOException {
os.writeTag(new Save(containerIndex.getInt()));
containerIndex.set(containerIndex.getInt()+1);
}
protected void writeGraphicsRestore() throws IOException {
containerIndex.set(containerIndex.getInt()-1);
os.writeTag(new Restore(containerIndex.getInt()));
if (restorePaint != null) writePaint(restorePaint);
}
public void draw(Shape shape) {
try {
Stroke stroke = getStroke();
if ((stroke instanceof BasicStroke) && (((BasicStroke)stroke).getLineWidth() == 0)) {
os.writeTag(new GDIPlusObject(1, shape, false));
os.writeTag(new GDIPlusObject(2, new BasicStroke(0), getPaint()));
os.writeTag(new DrawPath(1, 2));
} else {
Shape strokedShape = getStroke().createStrokedShape(shape);
fill(new Area(strokedShape));
}
} catch (IOException e) {
handleException(e);
}
}
public void fill(Shape shape) {
try {
os.writeTag(new GDIPlusObject(1, shape, false));
os.writeTag(new FillPath(1, 0));
} catch (IOException e) {
handleException(e);
}
}
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
writeWarning(getClass()
+ ": copyArea(int, int, int, int, int, int) not implemented.");
// Mostly unimplemented.
}
protected void writeImage(RenderedImage image, AffineTransform xform,
Color bkg) throws IOException {
// FIXME use BKG and xform
writeGraphicsSave();
os.writeTag(new GDIPlusObject(5, image));
os.writeTag(new MultiplyWorldTransform(xform, true));
os.writeTag(new DrawImage(5, image));
writeGraphicsRestore();
}
protected void writeString(String string, double x, double y)
throws IOException {
// text is drawn as shapes
}
protected void writeTransform(AffineTransform t) throws IOException {
os.writeTag(new MultiplyWorldTransform(t, true));
}
protected void writeSetTransform(AffineTransform t) throws IOException {
os.writeTag(new SetWorldTransform(t));
}
protected void writeClip(Shape s) throws IOException {
os.writeTag(new GDIPlusObject(4, s, false));
os.writeTag(new SetClipPath(4, SetClipPath.INTERSECT));
}
protected void writeSetClip(Shape s) throws IOException {
if (s != null) {
os.writeTag(new GDIPlusObject(4, s, false));
os.writeTag(new SetClipPath(4, SetClipPath.REPLACE));
} else {
os.writeTag(new ResetClip());
}
}
protected void writeWidth(float width) throws IOException {
// settings convert to shape
}
protected void writeCap(int cap) throws IOException {
// settings convert to shape
}
protected void writeJoin(int join) throws IOException {
// settings convert to shape
}
protected void writeMiterLimit(float limit) throws IOException {
// settings convert to shape
}
protected void writeDash(float[] dash, float phase) throws IOException {
// settings convert to shape
}
public void setPaintMode() {
writeWarning(getClass() + ": setPaintMode() not implemented.");
// Mostly unimplemented.
}
public void setXORMode(Color c1) {
writeWarning(getClass() + ": setXORMode(Color) not implemented.");
// Mostly unimplemented.
}
protected void writePaint(Color p) throws IOException {
os.writeTag(new GDIPlusObject(0, p));
}
protected void writePaint(GradientPaint p) throws IOException {
os.writeTag(new GDIPlusObject(0, p));
}
protected void writePaint(TexturePaint p) throws IOException {
os.writeTag(new GDIPlusObject(0, p));
}
protected void writePaint(Paint p) throws IOException {
os.writeTag(new GDIPlusObject(0, p));
}
protected void writeFont(Font font) throws IOException {
// text converts to shapes
}
public GraphicsConfiguration getDeviceConfiguration() {
writeWarning(getClass() + ": getDeviceConfiguration() not implemented.");
// Mostly unimplemented
return null;
}
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
writeWarning(getClass()
+ ": hit(Rectangle, Shape, boolean) not implemented.");
// Mostly unimplemented
return false;
}
public void writeComment(String comment) throws IOException {
writeWarning(getClass() + ": writeComment(String) not implemented.");
// Write out the comment.
}
protected void writeWarning(String string) {
System.err.println(string);
}
public String toString() {
return "EMFPlusGraphics2D";
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFRenderer.java 0000664 0000000 0000000 00000063573 11676375214 0024031 0 ustar 00root root 0000000 0000000 package org.freehep.graphicsio.emf;
import java.io.IOException;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.BasicStroke;
import java.awt.Stroke;
import java.awt.Paint;
import java.awt.Color;
import java.awt.Shape;
import java.awt.AlphaComposite;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.util.logging.Logger;
import java.util.Stack;
import java.util.Vector;
import java.util.Map;
import org.freehep.util.io.Tag;
import org.freehep.graphicsio.emf.gdi.GDIObject;
/**
* Standalone EMF renderer.
*
* @author Daniel Noll (daniel@nuix.com)
* @version $Id$
*/
public class EMFRenderer {
private static final Logger logger = Logger.getLogger("org.freehep.graphicsio.emf");
/**
* Header read from the EMFInputStream
*/
private EMFHeader header;
/**
* Each logical unit is mapped to one twentieth of a
* printer's point (1/1440 inch, also called a twip).
*/
public static double TWIP_SCALE = 1d / 1440 * 254;
/**
* affect by all XXXTo methods, e.g. LinTo. ExtMoveTo creates the
* starting point. CloseFigure closes the figure.
*/
private GeneralPath figure = null;
/**
* AffineTransform which is the base for all rendering
* operations.
*/
private AffineTransform initialTransform;
/**
* origin of the emf window, set by SetWindowOrgEx
*/
private Point windowOrigin = null;
/**
* origin of the emf viewport, set By SetViewportOrgEx
*/
private Point viewportOrigin = null;
/**
* size of the emf window, set by SetWindowExtEx
*/
private Dimension windowSize = null;
/**
* size of the emf viewport, set by SetViewportExtEx
*/
private Dimension viewportSize = null;
/**
* The MM_ISOTROPIC mode ensures a 1:1 aspect ratio.
* The MM_ANISOTROPIC mode allows the x-coordinates
* and y-coordinates to be adjusted independently.
*/
private boolean mapModeIsotropic = false;
/**
* AffineTransform defined by SetMapMode. Used for
* resizing the emf to propper device bounds.
*/
private AffineTransform mapModeTransform =
AffineTransform.getScaleInstance(TWIP_SCALE, TWIP_SCALE);
/**
* clipping area which is the base for all rendering
* operations.
*/
private Shape initialClip;
/**
* current Graphics2D to paint on. It is set during
* {@link #paint(java.awt.Graphics2D)}
*/
private Graphics2D g2;
/**
* objects used by {@link org.freehep.graphicsio.emf.gdi.SelectObject}.
* The array is filled by CreateXXX functions, e.g.
* {@link org.freehep.graphicsio.emf.gdi.CreatePen}
*/
private GDIObject[] gdiObjects = new GDIObject[256]; // TODO: Make this more flexible.
// Rendering state.
private Paint brushPaint = new Color(0, 0, 0, 0);
private Paint penPaint = Color.BLACK;
private Stroke penStroke = new BasicStroke();
private int textAlignMode = 0;
/**
* color for simple text rendering
*/
private Color textColor = Color.BLACK;
/**
* written by {@link org.freehep.graphicsio.emf.gdi.SetPolyFillMode} used by
* e.g. {@link org.freehep.graphicsio.emf.gdi.PolyPolygon16}
*/
private int windingRule = GeneralPath.WIND_EVEN_ODD;
/**
* Defined by SetBkModes, either {@link EMFConstants#BKG_OPAQUE} or
* {@link EMFConstants#BKG_TRANSPARENT}. Used in
* {@link #fillAndDrawOrAppend(java.awt.Graphics2D, java.awt.Shape)}
*/
private int bkMode = EMFConstants.BKG_OPAQUE;
/**
* The SetBkMode function affects the line styles for lines drawn using a
* pen created by the CreatePen function. SetBkMode does not affect lines
* drawn using a pen created by the ExtCreatePen function.
*/
private boolean useCreatePen = true;
/**
* The miter length is defined as the distance from the intersection
* of the line walls on the inside of the join to the intersection of
* the line walls on the outside of the join. The miter limit is the
* maximum allowed ratio of the miter length to the line width.
*/
private int meterLimit = 10;
/**
* The SetROP2 function sets the current foreground mix mode.
* Default is to use the pen.
*/
private int rop2 = EMFConstants.R2_COPYPEN;
/**
* e.g. {@link Image#SCALE_SMOOTH} for rendering images
*/
private int scaleMode = Image.SCALE_SMOOTH;
/**
* The brush origin is a pair of coordinates specifying the location of one
* pixel in the bitmap. The default brush origin coordinates are (0,0). For
* horizontal coordinates, the value 0 corresponds to the leftmost column
* of pixels; the width corresponds to the rightmost column. For vertical
* coordinates, the value 0 corresponds to the uppermost row of pixels;
* the height corresponds to the lowermost row.
*/
private Point brushOrigin = new Point(0, 0);
/**
* stores the parsed tags. Filled by the constructor. Read by
* {@link #paint(java.awt.Graphics2D)}
*/
private Vector tags = new Vector(0);
/**
* Created by BeginPath and closed by EndPath.
*/
private GeneralPath path = null;
/**
* The transformations set by ModifyWorldTransform are redirected to
* that AffineTransform. They do not affect the current paint context,
* after BeginPath is called. Only the figures appended to path
* are transformed by this AffineTransform.
* BeginPath clears the transformation, ModifyWorldTransform changes ist.
*/
private AffineTransform pathTransform = new AffineTransform();
/**
* {@link org.freehep.graphicsio.emf.gdi.SaveDC} stores
* an Instance of DC if saveDC is read. RestoreDC pops an object.
*/
private Stack dcStack = new Stack();
/**
* default direction is counterclockwise
*/
private int arcDirection = EMFConstants.AD_COUNTERCLOCKWISE;
/**
* Class the encapsulate the state of a Graphics2D object.
* Instances are store in dcStack by
* {@link org.freehep.graphicsio.emf.EMFRenderer#paint(java.awt.Graphics2D)}
*/
private class DC {
private Paint paint;
private Stroke stroke;
private AffineTransform transform;
private Shape clip;
public GeneralPath path;
public int bkMode;
public int windingRule;
public int meterLimit;
public boolean useCreatePen;
public int scaleMode;
public AffineTransform pathTransform;
}
/**
* Constructs the renderer.
*
* @param is the input stream to read the EMF records from.
* @throws IOException if an error occurs reading the header.
*/
public EMFRenderer(EMFInputStream is) throws IOException {
this.header = is.readHeader();
// read all tags
Tag tag;
while ((tag = is.readTag()) != null) {
tags.add(tag);
}
is.close();
}
/**
* Gets the size of a canvas which would be required to render the EMF.
*
* @return the size.
*/
public Dimension getSize() {
return header.getBounds().getSize();
// TODO see the mapModePart of resetTransformation()
// if uncommented size is too small
/* Dimension bounds = header.getBounds().getSize();
return new Dimension(
(int)Math.ceil(bounds.width * TWIP_SCALE),
(int)Math.ceil(bounds.height * TWIP_SCALE));*/
}
/**
* Paints the EMF onto the provided graphics context.
*
* @param g2 the graphics context to paint onto.
*/
public void paint(Graphics2D g2) {
this.g2 = g2;
// store at leat clip and transformation
Shape clip = g2.getClip();
AffineTransform at = g2.getTransform();
Map hints = g2.getRenderingHints();
// some quality settings
g2.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(
RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// used by SetWorldTransform to reset transformation
initialTransform = g2.getTransform();
// set the initial value, defaults for EMF
path = null;
figure = null;
meterLimit = 10;
windingRule = GeneralPath.WIND_EVEN_ODD;
bkMode = EMFConstants.BKG_OPAQUE;
useCreatePen = true;
scaleMode = Image.SCALE_SMOOTH;
windowOrigin = null;
viewportOrigin = null;
windowSize = null;
viewportSize = null;
mapModeIsotropic = false;
mapModeTransform = AffineTransform.getScaleInstance(
TWIP_SCALE, TWIP_SCALE);
// apply all default settings
resetTransformation(g2);
// determin initial clip after all basic transformations
initialClip = g2.getClip();
// iterate and render all tags
Tag tag;
for (int i = 0; i < tags.size(); i++) {
tag = (Tag) tags.get(i);
if (tag instanceof EMFTag) {
((EMFTag) tags.get(i)).render(this);
} else {
logger.warning("unknown tag: " + tag);
}
}
// reset Transform and clip
g2.setRenderingHints(hints);
g2.setTransform(at);
g2.setClip(clip);
}
// ---------------------------------------------------------------------
// complex drawing methods for EMFTags
// ---------------------------------------------------------------------
/**
* set the initial transform, the windowOrigin and viewportOrigin,
* scales by viewportSize and windowSize
* @param g2 Context to apply transformations
*/
private void resetTransformation(Graphics2D g2) {
// rest to device configuration
if (initialTransform != null) {
g2.setTransform(initialTransform);
} else {
g2.setTransform(new AffineTransform());
}
/* TODO mapModeTransform dows not work correctly
if (mapModeTransform != null) {
g2.transform(mapModeTransform);
}*/
// move to window origin
if (windowOrigin != null) {
g2.translate(
- windowOrigin.getX(),
- windowOrigin.getY());
}
// move to window origin
if (viewportOrigin != null) {
g2.translate(
- viewportOrigin.getX(),
- viewportOrigin.getY());
}
// TWIP_SCALE by window and viewport size
if (viewportSize != null && windowSize != null) {
double scaleX =
viewportSize.getWidth() /
windowSize.getWidth();
double scaleY =
viewportSize.getHeight() /
windowSize.getHeight();
g2.scale(scaleX, scaleY);
}
}
/**
* Stores the current state. Used by
* {@link org.freehep.graphicsio.emf.gdi.SaveDC}
*/
public void saveDC() {
// create a DC instance with current settings
DC dc = new DC();
dc.paint = g2.getPaint();
dc.stroke = g2.getStroke();
dc.transform = g2.getTransform();
dc.pathTransform = pathTransform;
dc.clip = g2.getClip();
dc.path = path;
dc.meterLimit = meterLimit;
dc.windingRule = windingRule;
dc.bkMode = bkMode;
dc.useCreatePen = useCreatePen;
dc.scaleMode = scaleMode;
// push it on top of the stack
dcStack.push(dc);
}
/**
* Retores a saved state. Used by
* {@link org.freehep.graphicsio.emf.gdi.RestoreDC}
*/
public void retoreDC() {
// is somethoing stored?
if (!dcStack.empty()) {
// read it
DC dc = (DC) dcStack.pop();
// use it
meterLimit = dc.meterLimit;
windingRule = dc.windingRule;
path = dc.path;
bkMode = dc.bkMode;
useCreatePen = dc.useCreatePen;
scaleMode = dc.scaleMode;
pathTransform = dc.pathTransform;
g2.setPaint(dc.paint);
g2.setStroke(dc.stroke);
g2.setTransform(dc.transform);
g2.setClip(dc.clip);
} else {
// set the default values
}
}
/**
* closes and appends the current open figure to the
* path
*/
public void closeFigure() {
if (figure == null) {
return;
}
try {
figure.closePath();
appendToPath(figure);
figure = null;
} catch (java.awt.geom.IllegalPathStateException e) {
logger.warning("no figure to close");
}
}
/**
* Logical units are mapped to arbitrary units with equally scaled axes;
* that is, one unit along the x-axis is equal to one unit along the y-axis.
* Use the SetWindowExtEx and SetViewportExtEx functions to specify the
* units and the orientation of the axes. Graphics device interface (GDI)
* makes adjustments as necessary to ensure the x and y units remain the
* same size (When the window extent is set, the viewport will be adjusted
* to keep the units isotropic).
*/
public void fixViewportSize() {
if (mapModeIsotropic && (windowSize != null && viewportSize != null)) {
viewportSize.setSize(
viewportSize.getWidth(),
viewportSize.getWidth() *
(windowSize.getHeight() / windowSize.getWidth())
);
}
}
/**
* fills a shape using the brushPaint, penPaint and penStroke
* @param g2 Painting context
* @param s Shape to fill with current brush
*/
private void fillAndDrawOrAppend(Graphics2D g2, Shape s) {
// don't draw, just append the shape if BeginPath
// has opened the path
if (!appendToPath(s)) {
// The SetBkMode function affects the line styles for lines drawn using a
// pen created by the CreatePen function. SetBkMode does not affect lines
// drawn using a pen created by the ExtCreatePen function.
if (useCreatePen) {
// OPAQUE Background is filled with the current background
// color before the text, hatched brush, or pen is drawn.
if (bkMode == EMFConstants.BKG_OPAQUE) {
fillShape(g2, s);
} else {
// TRANSPARENT Background remains untouched.
// TODO: if we really do nothing some drawings are incomplete
// this needs definitly a fix
fillShape(g2, s);
}
} else {
// always fill the background if ExtCreatePen is set
fillShape(g2, s);
}
drawShape(g2, s);
}
}
/**
* draws a shape using the penPaint and penStroke
* @param g2 Painting context
* @param s Shape to draw with current paen
*/
private void drawOrAppend(Graphics2D g2, Shape s) {
// don't draw, just append the shape if BeginPath
// opens a GeneralPath
if (!appendToPath(s)) {
drawShape(g2, s);
}
}
/**
* draws the text
*
* @param text Text
* @param x x-Position
* @param y y-Position
*/
public void drawOrAppendText(String text, double x, double y) {
// TODO: Use explicit widths to pixel-position each character, if present.
// TODO: Implement alignment properly. What we have already seems to work well enough.
// FontRenderContext frc = g2.getFontRenderContext();
// TextLayout layout = new TextLayout(str, g2.getFont(), frc);
// if ((textAlignMode & EMFConstants.TA_CENTER) != 0) {
// layout.draw(g2, x + (width - textWidth) / 2, y);
// } else if ((textAlignMode & EMFConstants.TA_RIGHT) != 0) {
// layout.draw(g2, x + width - textWidth, y);
// } else {
// layout.draw(g2, x, y);
// }
if (path != null) {
// do not use g2.drawString(str, x, y) to be aware of path
TextLayout tl = new TextLayout(
text,
g2.getFont(),
g2.getFontRenderContext());
path.append(tl.getOutline(null), false);
} else {
g2.setPaint(textColor);
g2.drawString(text, (int)x, (int)y);
}
}
/**
* Append the shape to the current path
*
* @param s Shape to fill with current brush
* @return true, if path was changed
*/
private boolean appendToPath(Shape s) {
// don't draw, just append the shape if BeginPath
// opens a GeneralPath
if (path != null) {
// aplly transformation if set
if (pathTransform != null) {
s = pathTransform.createTransformedShape(s);
}
// append the shape
path.append(s, false);
// current path set
return true;
}
// current path not set
return false;
}
/**
* closes the path opened by {@link org.freehep.graphicsio.emf.gdi.BeginPath}
*/
public void closePath() {
if (path != null) {
try {
path.closePath();
} catch (java.awt.geom.IllegalPathStateException e) {
logger.warning("no figure to close");
}
}
}
/**
* fills a shape using the brushPaint, penPaint and penStroke.
* This method should only be called for path painting. It doesn't check for a
* current path.
*
* @param g2 Painting context
* @param s Shape to fill with current brush
*/
private void fillShape(Graphics2D g2, Shape s) {
g2.setPaint(brushPaint);
g2.fill(s);
}
/**
* draws a shape using the penPaint and penStroke
* This method should only be called for path drawing. It doesn't check for a
* current path.
*
* @param g2 Painting context
* @param s Shape to draw with current pen
*/
private void drawShape(Graphics2D g2, Shape s) {
g2.setStroke(penStroke);
// R2_BLACK Pixel is always 0.
if (rop2 == EMFConstants.R2_BLACK) {
g2.setComposite(AlphaComposite.SrcOver);
g2.setPaint(Color.black);
}
// R2_COPYPEN Pixel is the pen color.
else if (rop2 == EMFConstants.R2_COPYPEN) {
g2.setComposite(AlphaComposite.SrcOver);
g2.setPaint(penPaint);
}
// R2_NOP Pixel remains unchanged.
else if (rop2 == EMFConstants.R2_NOP) {
g2.setComposite(AlphaComposite.SrcOver);
g2.setPaint(penPaint);
}
// R2_WHITE Pixel is always 1.
else if (rop2 == EMFConstants.R2_WHITE) {
g2.setComposite(AlphaComposite.SrcOver);
g2.setPaint(Color.white);
}
// R2_NOTCOPYPEN Pixel is the inverse of the pen color.
else if (rop2 == EMFConstants.R2_NOTCOPYPEN) {
g2.setComposite(AlphaComposite.SrcOver);
// TODO: set at least inverted color if paint is a color
}
// R2_XORPEN Pixel is a combination of the colors
// in the pen and in the screen, but not in both.
else if (rop2 == EMFConstants.R2_XORPEN) {
g2.setComposite(AlphaComposite.Xor);
} else {
logger.warning("got unsupported ROP" + rop2);
// TODO:
//R2_MASKNOTPEN Pixel is a combination of the colors common to both the screen and the inverse of the pen.
//R2_MASKPEN Pixel is a combination of the colors common to both the pen and the screen.
//R2_MASKPENNOT Pixel is a combination of the colors common to both the pen and the inverse of the screen.
//R2_MERGENOTPEN Pixel is a combination of the screen color and the inverse of the pen color.
//R2_MERGEPEN Pixel is a combination of the pen color and the screen color.
//R2_MERGEPENNOT Pixel is a combination of the pen color and the inverse of the screen color.
//R2_NOT Pixel is the inverse of the screen color.
//R2_NOTCOPYPEN Pixel is the inverse of the pen color.
//R2_NOTMASKPEN Pixel is the inverse of the R2_MASKPEN color.
//R2_NOTMERGEPEN Pixel is the inverse of the R2_MERGEPEN color.
//R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color.
}
g2.draw(s);
}
// ---------------------------------------------------------------------
// simple wrapping methods to the painting context
// ---------------------------------------------------------------------
public void setFont(Font font) {
g2.setFont(font);
}
public AffineTransform getTransform() {
return g2.getTransform();
}
public void transform(AffineTransform transform) {
g2.transform(transform);
}
public void resetTransformation() {
resetTransformation(g2);
}
public void setTransform(AffineTransform at) {
g2.setTransform(at);
}
public void setClip(Shape shape) {
g2.setClip(shape);
}
public void clip(Shape shape) {
g2.clip(shape);
}
public Shape getClip() {
return g2.getClip();
}
public void drawImage(BufferedImage image, AffineTransform transform) {
g2.drawImage(image, transform, null);
}
public void drawImage(BufferedImage image, int x, int y, int width, int height) {
g2.drawImage(image, x, y, width, height, null);
}
public void drawShape(Shape shape) {
drawShape(g2, shape);
}
public void fillShape(Shape shape) {
fillShape(g2, shape);
}
public void fillAndDrawOrAppend(Shape s) {
fillAndDrawOrAppend(g2, s);
}
public void drawOrAppend(Shape s) {
drawOrAppend(g2, s);
}
// ---------------------------------------------------------------------
// simple getter / setter methods
// ---------------------------------------------------------------------
public int getWindingRule() {
return windingRule;
}
public GeneralPath getFigure() {
return figure;
}
public void setFigure(GeneralPath figure) {
this.figure = figure;
}
public GeneralPath getPath() {
return path;
}
public void setPath(GeneralPath path) {
this.path = path;
}
public Shape getInitialClip() {
return initialClip;
}
public AffineTransform getPathTransform() {
return pathTransform;
}
public void setPathTransform(AffineTransform pathTransform) {
this.pathTransform = pathTransform;
}
public void setWindingRule(int windingRule) {
this.windingRule = windingRule;
}
public void setMapModeIsotropic(boolean mapModeIsotropic) {
this.mapModeIsotropic = mapModeIsotropic;
}
public AffineTransform getMapModeTransform() {
return mapModeTransform;
}
public void setMapModeTransform(AffineTransform mapModeTransform) {
this.mapModeTransform = mapModeTransform;
}
public void setWindowOrigin(Point windowOrigin) {
this.windowOrigin = windowOrigin;
}
public void setViewportOrigin(Point viewportOrigin) {
this.viewportOrigin = viewportOrigin;
}
public void setViewportSize(Dimension viewportSize) {
this.viewportSize = viewportSize;
fixViewportSize();
resetTransformation();
}
public void setWindowSize(Dimension windowSize) {
this.windowSize = windowSize;
fixViewportSize();
resetTransformation();
}
public GDIObject getGDIObject(int index) {
return gdiObjects[index];
}
public void storeGDIObject(int index, GDIObject tag) {
gdiObjects[index] = tag;
}
public void setUseCreatePen(boolean useCreatePen) {
this.useCreatePen = useCreatePen;
}
public void setPenPaint(Paint penPaint) {
this.penPaint = penPaint;
}
public Stroke getPenStroke() {
return penStroke;
}
public void setPenStroke(Stroke penStroke) {
this.penStroke = penStroke;
}
public void setBrushPaint(Paint brushPaint) {
this.brushPaint = brushPaint;
}
public float getMeterLimit() {
return meterLimit;
}
public void setMeterLimit(int meterLimit) {
this.meterLimit = meterLimit;
}
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
public void setRop2(int rop2) {
this.rop2 = rop2;
}
public void setBkMode(int bkMode) {
this.bkMode = bkMode;
}
public int getTextAlignMode() {
return textAlignMode;
}
public void setTextAlignMode(int textAlignMode) {
this.textAlignMode = textAlignMode;
}
public void setScaleMode(int scaleMode) {
this.scaleMode = scaleMode;
}
public Point getBrushOrigin() {
return brushOrigin;
}
public void setBrushOrigin(Point brushOrigin) {
this.brushOrigin = brushOrigin;
}
public void setArcDirection(int arcDirection) {
this.arcDirection = arcDirection;
}
public int getArcDirection() {
return arcDirection;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFTag.java 0000664 0000000 0000000 00000004650 11676375214 0022765 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf;
import java.io.IOException;
import java.util.logging.Logger;
import org.freehep.util.io.Tag;
import org.freehep.util.io.TaggedInputStream;
import org.freehep.util.io.TaggedOutputStream;
import org.freehep.graphicsio.emf.gdi.GDIObject;
/**
* EMF specific tag, from which all other EMF Tags inherit.
*
* @author Mark Donszelmann
* @version $Id$
*/
public abstract class EMFTag extends Tag implements GDIObject {
/**
* logger for all instances
*/
protected static final Logger logger = Logger.getLogger("org.freehep.graphicsio.emf");
protected int flags = 0;
/**
* Constructs a EMFTag.
*
* @param id id of the element
* @param version emf version in which this element was first supported
*/
protected EMFTag(int id, int version) {
super(id, version);
}
public Tag read(int tagID, TaggedInputStream input, int len)
throws IOException {
EMFInputStream emf = (EMFInputStream)input;
EMFTagHeader tagHeader = (EMFTagHeader)emf.getTagHeader();
flags = tagHeader.getFlags();
return read(tagID, emf, len);
}
public abstract EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException;
public void write(int tagID, TaggedOutputStream output) throws IOException {
write(tagID, (EMFOutputStream) output);
}
/**
* Writes the extra tag information to the outputstream in binary format.
* This implementation writes nothing, but concrete tags may override this
* method. This method is called just after the TagHeader is written.
*
* @param tagID id of the tag
* @param emf Binary EMF output stream
* @throws java.io.IOException thrown by EMFOutputStream
*/
public void write(int tagID, EMFOutputStream emf) throws IOException {
// empty
}
public int getFlags() {
return flags;
}
/**
* @return a description of the tagName and tagID
*/
public String toString() {
int id = getTag();
return "EMFTag " + getName() + " (" + id + ") (0x"+Integer.toHexString(id)+")";
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
logger.warning("EMF tag not supported: " + toString());
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFTagHeader.java 0000664 0000000 0000000 00000000731 11676375214 0024072 0 ustar 00root root 0000000 0000000 // Copyright 2006, FreeHEP.
package org.freehep.graphicsio.emf;
import org.freehep.util.io.TagHeader;
/**
* Special TagHeader for EMF to include flags.
*
* @author duns
* @version $Id$
*/
public class EMFTagHeader extends TagHeader {
private int flags;
public EMFTagHeader(int tagID, long len, int flags) {
super(tagID, len);
this.flags = flags;
}
public int getFlags() {
return flags;
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFTagSet.java 0000664 0000000 0000000 00000035326 11676375214 0023445 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf;
import org.freehep.util.io.TagSet;
/**
* EMF specific tagset.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFTagSet extends TagSet {
public EMFTagSet(int version) {
if ((version >= 1) /* && (version < 0x4000) FIXME check */) {
// Set for Windows 3
addTag(new org.freehep.graphicsio.emf.gdi.PolyBezier()); // 2 02
addTag(new org.freehep.graphicsio.emf.gdi.EMFPolygon()); // 3 03
addTag(new org.freehep.graphicsio.emf.gdi.Polyline()); // 4 04
addTag(new org.freehep.graphicsio.emf.gdi.PolyBezierTo()); // 5 05
addTag(new org.freehep.graphicsio.emf.gdi.PolylineTo()); // 6 06
addTag(new org.freehep.graphicsio.emf.gdi.PolyPolyline()); // 7 07
addTag(new org.freehep.graphicsio.emf.gdi.PolyPolygon()); // 8 08
addTag(new org.freehep.graphicsio.emf.gdi.SetWindowExtEx()); // 9 09
addTag(new org.freehep.graphicsio.emf.gdi.SetWindowOrgEx()); // 10 0a
addTag(new org.freehep.graphicsio.emf.gdi.SetViewportExtEx()); // 11 0b
addTag(new org.freehep.graphicsio.emf.gdi.SetViewportOrgEx()); // 12 0c
addTag(new org.freehep.graphicsio.emf.gdi.SetBrushOrgEx()); // 13 0d
addTag(new org.freehep.graphicsio.emf.gdi.EOF()); // 14 0e
addTag(new org.freehep.graphicsio.emf.gdi.SetPixelV()); // 15 0f
addTag(new org.freehep.graphicsio.emf.gdi.SetMapperFlags()); // 16 10
addTag(new org.freehep.graphicsio.emf.gdi.SetMapMode()); // 17 11
addTag(new org.freehep.graphicsio.emf.gdi.SetBkMode()); // 18 12
addTag(new org.freehep.graphicsio.emf.gdi.SetPolyFillMode()); // 19 13
addTag(new org.freehep.graphicsio.emf.gdi.SetROP2()); // 20 14
addTag(new org.freehep.graphicsio.emf.gdi.SetStretchBltMode()); // 21 15
addTag(new org.freehep.graphicsio.emf.gdi.SetTextAlign()); // 22 16
// addTag(new org.freehep.graphicsio.emf.gdi.SetColorAdjustment()); // 23 17
addTag(new org.freehep.graphicsio.emf.gdi.SetTextColor()); // 24 18
addTag(new org.freehep.graphicsio.emf.gdi.SetBkColor()); // 25 19
addTag(new org.freehep.graphicsio.emf.gdi.OffsetClipRgn()); // 26 1a
addTag(new org.freehep.graphicsio.emf.gdi.MoveToEx()); // 27 1b
addTag(new org.freehep.graphicsio.emf.gdi.SetMetaRgn()); // 28 1c
addTag(new org.freehep.graphicsio.emf.gdi.ExcludeClipRect()); // 29 1d
addTag(new org.freehep.graphicsio.emf.gdi.IntersectClipRect()); // 30 1e
addTag(new org.freehep.graphicsio.emf.gdi.ScaleViewportExtEx()); // 31 1f
addTag(new org.freehep.graphicsio.emf.gdi.ScaleWindowExtEx()); // 32 20
addTag(new org.freehep.graphicsio.emf.gdi.SaveDC()); // 33 21
addTag(new org.freehep.graphicsio.emf.gdi.RestoreDC()); // 34 22
addTag(new org.freehep.graphicsio.emf.gdi.SetWorldTransform()); // 35 23
addTag(new org.freehep.graphicsio.emf.gdi.ModifyWorldTransform()); // 36 24
addTag(new org.freehep.graphicsio.emf.gdi.SelectObject()); // 37 25
addTag(new org.freehep.graphicsio.emf.gdi.CreatePen()); // 38 26
addTag(new org.freehep.graphicsio.emf.gdi.CreateBrushIndirect()); // 39 27
addTag(new org.freehep.graphicsio.emf.gdi.DeleteObject()); // 40 28
addTag(new org.freehep.graphicsio.emf.gdi.AngleArc()); // 41 29
addTag(new org.freehep.graphicsio.emf.gdi.Ellipse()); // 42 2a
addTag(new org.freehep.graphicsio.emf.gdi.EMFRectangle()); // 43 2b
addTag(new org.freehep.graphicsio.emf.gdi.RoundRect()); // 44 2c
addTag(new org.freehep.graphicsio.emf.gdi.Arc()); // 45 2d
addTag(new org.freehep.graphicsio.emf.gdi.Chord()); // 46 2e
addTag(new org.freehep.graphicsio.emf.gdi.Pie()); // 47 2f
addTag(new org.freehep.graphicsio.emf.gdi.SelectPalette()); // 48 30
// addTag(new org.freehep.graphicsio.emf.gdi.CreatePalette()); // 49 31
// addTag(new org.freehep.graphicsio.emf.gdi.SetPaletteEntries()); // 50 32
addTag(new org.freehep.graphicsio.emf.gdi.ResizePalette()); // 51 33
addTag(new org.freehep.graphicsio.emf.gdi.RealizePalette()); // 52 34
addTag(new org.freehep.graphicsio.emf.gdi.ExtFloodFill()); // 53 35
addTag(new org.freehep.graphicsio.emf.gdi.LineTo()); // 54 36
addTag(new org.freehep.graphicsio.emf.gdi.ArcTo()); // 55 37
addTag(new org.freehep.graphicsio.emf.gdi.PolyDraw()); // 56 38
addTag(new org.freehep.graphicsio.emf.gdi.SetArcDirection()); // 57 39
addTag(new org.freehep.graphicsio.emf.gdi.SetMiterLimit()); // 58 3a
addTag(new org.freehep.graphicsio.emf.gdi.BeginPath()); // 59 3b
addTag(new org.freehep.graphicsio.emf.gdi.EndPath()); // 60 3c
addTag(new org.freehep.graphicsio.emf.gdi.CloseFigure()); // 61 3d
addTag(new org.freehep.graphicsio.emf.gdi.FillPath()); // 62 3e
addTag(new org.freehep.graphicsio.emf.gdi.StrokeAndFillPath()); // 63 3f
addTag(new org.freehep.graphicsio.emf.gdi.StrokePath()); // 64 40
addTag(new org.freehep.graphicsio.emf.gdi.FlattenPath()); // 65 41
addTag(new org.freehep.graphicsio.emf.gdi.WidenPath()); // 66 42
addTag(new org.freehep.graphicsio.emf.gdi.SelectClipPath()); // 67 43
addTag(new org.freehep.graphicsio.emf.gdi.AbortPath()); // 68 44
// this tag does not exist // 69 45
addTag(new org.freehep.graphicsio.emf.gdi.GDIComment()); // 70 46
// addTag(new org.freehep.graphicsio.emf.gdi.FillRgn()); // 71 47
// addTag(new org.freehep.graphicsio.emf.gdi.FrameRgn()); // 72 48
// addTag(new org.freehep.graphicsio.emf.gdi.InvertRgn()); // 73 49
// addTag(new org.freehep.graphicsio.emf.gdi.PaintRgn()); // 74 4a
addTag(new org.freehep.graphicsio.emf.gdi.ExtSelectClipRgn()); // 75 4b
addTag(new org.freehep.graphicsio.emf.gdi.BitBlt()); // 76 4c
// addTag(new org.freehep.graphicsio.emf.gdi.StretchBlt()); // 77 4d
// addTag(new org.freehep.graphicsio.emf.gdi.MaskBlt()); // 78 4e
// addTag(new org.freehep.graphicsio.emf.gdi.PlgBlt()); // 79 4f
// addTag(new org.freehep.graphicsio.emf.gdi.SetDIBitsToDevice()); // 80 50
addTag(new org.freehep.graphicsio.emf.gdi.StretchDIBits()); // 81 51
addTag(new org.freehep.graphicsio.emf.gdi.ExtCreateFontIndirectW()); // 82 52
addTag(new org.freehep.graphicsio.emf.gdi.ExtTextOutA()); // 83 53
addTag(new org.freehep.graphicsio.emf.gdi.ExtTextOutW()); // 84 54
addTag(new org.freehep.graphicsio.emf.gdi.PolyBezier16()); // 85 55
addTag(new org.freehep.graphicsio.emf.gdi.Polygon16()); // 86 56
addTag(new org.freehep.graphicsio.emf.gdi.Polyline16()); // 87 57
addTag(new org.freehep.graphicsio.emf.gdi.PolyBezierTo16()); // 88 58
addTag(new org.freehep.graphicsio.emf.gdi.PolylineTo16()); // 89 59
addTag(new org.freehep.graphicsio.emf.gdi.PolyPolyline16()); // 90 5a
addTag(new org.freehep.graphicsio.emf.gdi.PolyPolygon16()); // 91 5b
addTag(new org.freehep.graphicsio.emf.gdi.PolyDraw16()); // 92 5c
// addTag(new org.freehep.graphicsio.emf.gdi.CreateMonoBrush()); // 93 5d
// addTag(new org.freehep.graphicsio.emf.gdi.CreateDIBPatternBrushPt()); // 94 5e
addTag(new org.freehep.graphicsio.emf.gdi.ExtCreatePen()); // 95 5f
// addTag(new org.freehep.graphicsio.emf.gdi.PolyTextOutA()); // 96 60
// addTag(new org.freehep.graphicsio.emf.gdi.PolyTextOutW()); // 97 61
// Set for Windows 4 (NT)
addTag(new org.freehep.graphicsio.emf.gdi.SetICMMode()); // 98 62
// addTag(new org.freehep.graphicsio.emf.gdi.CreateColorSpace()); // 99 63
// addTag(new org.freehep.graphicsio.emf.gdi.SetColorSpace()); // 100 64
// addTag(new org.freehep.graphicsio.emf.gdi.DeleteColorSpace()); // 101 65
// addTag(new org.freehep.graphicsio.emf.gdi.GLSRecord()); // 102 66
// addTag(new org.freehep.graphicsio.emf.gdi.GLSBoundedRecord()); // 103 67
// addTag(new org.freehep.graphicsio.emf.gdi.PixelFormat()); // 104 68
// Set for Windows 5 (2000/XP)
// addTag(new org.freehep.graphicsio.emf.gdi.DrawEscape()); // 105 69
// addTag(new org.freehep.graphicsio.emf.gdi.ExtEscape()); // 106 6a
// addTag(new org.freehep.graphicsio.emf.gdi.StartDoc()); // 107 6b
// addTag(new org.freehep.graphicsio.emf.gdi.SmallTextOut()); // 108 6c
// addTag(new org.freehep.graphicsio.emf.gdi.ForceUFIMapping()); // 109 6d
// addTag(new org.freehep.graphicsio.emf.gdi.NamedEscape()); // 110 6e
// addTag(new org.freehep.graphicsio.emf.gdi.ColorCorrectPalette()); // 111 6f
// addTag(new org.freehep.graphicsio.emf.gdi.SetICMProfileA()); // 112 70
// addTag(new org.freehep.graphicsio.emf.gdi.SetICMProfileW()); // 113 71
addTag(new org.freehep.graphicsio.emf.gdi.AlphaBlend()); // 114 72
// addTag(new org.freehep.graphicsio.emf.gdi.AlphaDIBBlend()); // 115 73
// addTag(new org.freehep.graphicsio.emf.gdi.TransparentBlt()); // 116 74
// addTag(new org.freehep.graphicsio.emf.gdi.TransparentDIB()); // 117 75
addTag(new org.freehep.graphicsio.emf.gdi.GradientFill()); // 118 76
// addTag(new org.freehep.graphicsio.emf.gdi.SetLinkedUFIs()); // 119 77
// addTag(new org.freehep.graphicsio.emf.gdi.SetTextJustification()); // 120 78
}
if (version >= 0x4000) {
// From GdiPlusEnums.h of Microsoft Platform SDK 2003 R2
// base 0x0004000
addTag(new org.freehep.graphicsio.emf.gdiplus.Header()); // 1
addTag(new org.freehep.graphicsio.emf.gdiplus.EndOfFile()); // 2
//addTag(new org.freehep.graphicsio.emf.gdiplus.Comment()); // 3
//addTag(new org.freehep.graphicsio.emf.gdiplus.GetDC()); // 4
//addTag(new org.freehep.graphicsio.emf.gdiplus.MultiFormatStart()); // 5
//addTag(new org.freehep.graphicsio.emf.gdiplus.MultiFormatSection());// 6
//addTag(new org.freehep.graphicsio.emf.gdiplus.MultiFormatEnd()); // 7
// For all persistent objects
addTag(new org.freehep.graphicsio.emf.gdiplus.GDIPlusObject()); // 8
// Drawing Records
addTag(new org.freehep.graphicsio.emf.gdiplus.Clear()); // 9
//addTag(new org.freehep.graphicsio.emf.gdiplus.FillRects()); // 10
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawRects()); // 11
//addTag(new org.freehep.graphicsio.emf.gdiplus.FillPolygon()); // 12
addTag(new org.freehep.graphicsio.emf.gdiplus.DrawLines()); // 13
addTag(new org.freehep.graphicsio.emf.gdiplus.FillEllipse()); // 14
addTag(new org.freehep.graphicsio.emf.gdiplus.DrawEllipse()); // 15
//addTag(new org.freehep.graphicsio.emf.gdiplus.FillPie()); // 16
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawPie()); // 17
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawArc()); // 18
//addTag(new org.freehep.graphicsio.emf.gdiplus.FillRegion()); // 19
addTag(new org.freehep.graphicsio.emf.gdiplus.FillPath()); // 20
addTag(new org.freehep.graphicsio.emf.gdiplus.DrawPath()); // 21
//addTag(new org.freehep.graphicsio.emf.gdiplus.FillClosedCurve()); // 22
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawClosedCurve()); // 23
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawCurve()); // 24
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawBeziers()); // 25
addTag(new org.freehep.graphicsio.emf.gdiplus.DrawImage()); // 26
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawImagePoints()); // 27
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawString()); // 28
// Graphics State Records
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetRenderingOrigin());// 29
addTag(new org.freehep.graphicsio.emf.gdiplus.SetAntiAliasMode()); // 30
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetTextRenderingHint());//31
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetTextContrast()); // 32
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetInterpolationMode());//33
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetPixelOffsetMode());// 34
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetCompositingMode());// 35
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetCompositingQuality());//36
addTag(new org.freehep.graphicsio.emf.gdiplus.Save()); // 37
addTag(new org.freehep.graphicsio.emf.gdiplus.Restore()); // 38
//addTag(new org.freehep.graphicsio.emf.gdiplus.BeginContainer()); // 39
//addTag(new org.freehep.graphicsio.emf.gdiplus.BeginContainerNoParams());//40
//addTag(new org.freehep.graphicsio.emf.gdiplus.EndContainer()); // 41
addTag(new org.freehep.graphicsio.emf.gdiplus.SetWorldTransform()); // 42
//addTag(new org.freehep.graphicsio.emf.gdiplus.ResetWorldTransform());// 43
addTag(new org.freehep.graphicsio.emf.gdiplus.MultiplyWorldTransform());//44
//addTag(new org.freehep.graphicsio.emf.gdiplus.TranslateWorldTransform());//45
//addTag(new org.freehep.graphicsio.emf.gdiplus.ScaleWorldTransform());// 46
//addTag(new org.freehep.graphicsio.emf.gdiplus.RotateWorldTransform());//47
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetPageTransform()); // 48
addTag(new org.freehep.graphicsio.emf.gdiplus.ResetClip()); // 49
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetClipRect()); // 50
addTag(new org.freehep.graphicsio.emf.gdiplus.SetClipPath()); // 51
//addTag(new org.freehep.graphicsio.emf.gdiplus.SetClipRegion()); // 52
//addTag(new org.freehep.graphicsio.emf.gdiplus.OffsetClip()); // 53
//addTag(new org.freehep.graphicsio.emf.gdiplus.DrawDriverString()); // 54
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/EMFViewer.java 0000664 0000000 0000000 00000010320 11676375214 0023502 0 ustar 00root root 0000000 0000000 // Copyright 2007 FreeHEP
package org.freehep.graphicsio.emf;
import org.freehep.swing.ExtensionFileFilter;
import javax.swing.JFrame;
import javax.swing.JFileChooser;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
/**
* Simple frame to display EMF images.
*
* @author Steffen Greiffenberg
* @version $ID$
*/
public class EMFViewer extends JFrame {
/**
* Prefix for the TITLE
*/
private static String TITLE = "Freehep EMF Viewer";
/**
* Title for the Button
*/
private static String LOAD_BUTTON_TITLE = "Open EMF";
/**
* Title for the Button
*/
private static String ZOOMIN__BUTTON_TITLE = "Zoom in";
/**
* Title for the Button
*/
private static String ZOOMOUT_BUTTON_TITLE = "Zoom out";
/**
* simple panel for displaying an EMF
*/
private EMFPanel emfPanel = new EMFPanel();
/**
* used to open EMF-Files
*/
private JFileChooser fileChooser = new JFileChooser();
public EMFViewer() {
initGUI();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 300);
}
/**
* creates the content of tha frame
*/
private void initGUI() {
setTitle(TITLE);
// create a panel for the window content
getContentPane().setLayout(new BorderLayout(0, 0));
JPanel mainPanel = new JPanel();
getContentPane().add(mainPanel);
// layout the mainPanel
mainPanel.setLayout(new BorderLayout(3, 3));
mainPanel.add(
BorderLayout.CENTER,
new JScrollPane(emfPanel));
// prepare the filechooser
fileChooser.addChoosableFileFilter(
new ExtensionFileFilter("emf", "Encapsulated Metafile"));
// panel for buttons
JPanel buttonPanel = new JPanel(
new FlowLayout(FlowLayout.RIGHT, 3, 3));
mainPanel.add(
BorderLayout.SOUTH,
buttonPanel);
// button to zoom in
JButton zoomInButton = new JButton(ZOOMIN__BUTTON_TITLE);
zoomInButton.addActionListener(new ZoomInAction());
buttonPanel.add(zoomInButton);
// button to zoom out
JButton zoomOutButton = new JButton(ZOOMOUT_BUTTON_TITLE);
zoomOutButton.addActionListener(new ZoomOutAction());
buttonPanel.add(zoomOutButton);
// loadButton to open files
JButton loadButton = new JButton(LOAD_BUTTON_TITLE);
loadButton.addActionListener(new OpenFileAction());
buttonPanel.add(loadButton);
}
/**
* displays the file and
* @param emfFile File to show
*/
public void show(File emfFile) {
try {
FileInputStream fis = new FileInputStream(emfFile);
EMFInputStream emf = new EMFInputStream(new BufferedInputStream(fis));
EMFRenderer renderer = new EMFRenderer(emf);
emfPanel.setRenderer(renderer);
// set the window title
setTitle(TITLE + " - " + emfFile.getName());
} catch (Exception e) {
e.printStackTrace();
}
// show the frame
if (!isVisible()) {
setVisible(true);
}
}
/**
* Uses the fileChooser to open a file.
* Uses the emfPanel to display the file.
*/
private class OpenFileAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showOpenDialog(EMFViewer.this);
if (result == JFileChooser.APPROVE_OPTION) {
show(fileChooser.getSelectedFile());
}
}
}
/**
* zoom the panel in
*/
private class ZoomInAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
emfPanel.zoomIn();
}
}
/**
* zoom the panel out
*/
private class ZoomOutAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
emfPanel.zoomOut();
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ 0000775 0000000 0000000 00000000000 11676375214 0021615 5 ustar 00root root 0000000 0000000 a/src/main/java/org/freehep/graphicsio/emf/gdi/AbortPath.java 0000664 0000000 0000000 00000000744 11676375214 0024351 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* AbortPath TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class AbortPath extends EMFTag {
public AbortPath() {
super(68, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return this;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractArc.java 0000664 0000000 0000000 00000004327 11676375214 0024657 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFOutputStream;
import java.awt.geom.Arc2D;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Shape;
import java.io.IOException;
/**
* @author Steffen Greiffenberg
* @version $Id$
*/
public abstract class AbstractArc extends EMFTag {
private Rectangle bounds;
private Point start, end;
protected AbstractArc(int id, int version, Rectangle bounds, Point start, Point end) {
super(id, version);
this.bounds = bounds;
this.start = start;
this.end = end;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
emf.writePOINTL(start);
emf.writePOINTL(end);
}
public String toString() {
return super.toString() +
"\n bounds: " + bounds +
"\n start: " + start +
"\n end: " + end;
}
/**
* creates a shape based on bounds, start and end
*
* @param renderer EMFRenderer storing the drawing session data
* @param arcType type of arc, e.g. {@link Arc2D#OPEN}
* @return shape to render
*/
protected Shape getShape(EMFRenderer renderer, int arcType) {
// normalize start and end point to a circle
double nx0 = start.getX() / bounds.getWidth();
// double ny0 = arc.getStart().y / arc.getBounds().height;
double nx1 = end.getX() / bounds.getWidth();
// double ny1 = arc.getEnd().y / arc.getBounds().height;
// calculate angle of start point
double alpha0, alpha1;
if (renderer.getArcDirection() == EMFConstants.AD_CLOCKWISE) {
alpha0 = Math.acos(nx0);
alpha1 = Math.acos(nx1);
} else {
alpha0 = Math.acos(nx1);
alpha1 = Math.acos(nx0);
}
return new Arc2D.Double(
start.getX(),
start.getY(),
bounds.getWidth(),
bounds.getHeight(),
alpha0,
alpha1 - alpha0,
arcType);
}
} a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractClipPath.java 0000664 0000000 0000000 00000006740 11676375214 0025657 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.graphicsio.emf.EMFConstants;
import java.awt.geom.GeneralPath;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.Shape;
/**
* base class for all tags that change the
* clipping area of the {@link org.freehep.graphicsio.emf.EMFRenderer}
*
* @author Steffen Greiffenberg
* @version $Id$
*/
public abstract class AbstractClipPath extends EMFTag {
private int mode;
protected AbstractClipPath(int id, int version, int mode) {
super(id, version);
this.mode = mode;
}
public String toString() {
return super.toString() + "\n mode: " + mode;
}
public int getMode() {
return mode;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
* @param shape shape to use as clipping area
*/
public void render(EMFRenderer renderer, Shape shape) {
if (shape != null) {
// The new clipping region includes the intersection
// (overlapping areas) of the current clipping region and the current shape.
if (mode == EMFConstants.RGN_AND) {
renderer.clip(shape);
}
// The new clipping region is the current shape
else if (mode == EMFConstants.RGN_COPY) {
// rest the clip ...
AffineTransform at = renderer.getTransform();
// temporarly switch to the base transformation to
// aplly the base clipping area
renderer.resetTransformation();
// set the clip
renderer.setClip(renderer.getInitialClip());
renderer.setTransform(at);
renderer.clip(shape);
}
// The new clipping region includes the areas of the
// current clipping region with those of the current shape excluded.
else if (mode == EMFConstants.RGN_DIFF) {
Shape clip = renderer.getClip();
if (clip != null) {
Area a = new Area(shape);
a.subtract(new Area(clip));
renderer.setClip(a);
} else {
renderer.setClip(shape);
}
}
// The new clipping region includes the union (combined areas)
// of the current clipping region and the current shape.
else if(mode == EMFConstants.RGN_OR) {
GeneralPath path = new GeneralPath(shape);
Shape clip = renderer.getClip();
if (clip != null) {
path.append(clip, false);
}
renderer.setClip(path);
}
// The new clipping region includes the union of the current
// clipping region and the current shape but without the overlapping areas.
else if(mode == EMFConstants.RGN_XOR) {
Shape clip = renderer.getClip();
if (clip != null) {
Area a = new Area(shape);
a.exclusiveOr(new Area(clip));
renderer.setClip(a);
} else {
renderer.setClip(shape);
}
}
}
// delete the current shape
renderer.setPath(null);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractExtTextOut.java 0000664 0000000 0000000 00000004245 11676375214 0026246 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.graphicsio.emf.EMFOutputStream;
import java.awt.Rectangle;
import java.io.IOException;
/**
* Abstraction of commonality between the {@link ExtTextOutA} and {@link ExtTextOutW} tags.
*
* @author Daniel Noll (daniel@nuix.com)
* @version $Id: ExtTextOutW.java 10140 2006-12-07 07:50:41Z duns $
*/
public abstract class AbstractExtTextOut extends EMFTag implements EMFConstants {
private Rectangle bounds;
private int mode;
private float xScale, yScale;
/**
* Constructs the tag.
*
* @param id id of the element
* @param version emf version in which this element was first supported
* @param bounds text boundary
* @param mode text mode
* @param xScale horizontal scale factor
* @param yScale vertical scale factor
*/
protected AbstractExtTextOut(
int id,
int version,
Rectangle bounds,
int mode,
float xScale,
float yScale) {
super(id, version);
this.bounds = bounds;
this.mode = mode;
this.xScale = xScale;
this.yScale = yScale;
}
public abstract Text getText();
public String toString() {
return super.toString() +
"\n bounds: " + bounds +
"\n mode: " + mode +
"\n xScale: " + xScale +
"\n yScale: " + yScale +
"\n" + getText().toString();
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
emf.writeDWORD(mode);
emf.writeFLOAT(xScale);
emf.writeFLOAT(yScale);
getText().write(emf);
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
Text text = getText();
renderer.drawOrAppendText(
text.getString(),
text.getPos().getX(),
text.getPos().getY());
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractPen.java 0000664 0000000 0000000 00000014747 11676375214 0024703 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFRenderer;
import java.util.logging.Logger;
import java.awt.BasicStroke;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
/**
* @author Steffen Greiffenberg
* @version $Id$
*/
public abstract class AbstractPen implements EMFConstants, GDIObject {
/**
* Represents a stroke that draws inside the given shape.
* Used if EMFConstants.PS_INSIDEFRAME is used
*/
private class InsideFrameStroke implements Stroke {
private BasicStroke stroke;
public InsideFrameStroke (
float width,
int cap,
int join,
float miterlimit,
float dash[],
float dash_phase) {
stroke = new BasicStroke(width, cap, join, miterlimit, dash, dash_phase);
}
public Shape createStrokedShape(Shape shape) {
if (shape == null) {
return null;
}
Rectangle2D oldBounds = shape.getBounds2D();
float witdh = stroke.getLineWidth();
// calcute a transformation for inside drawing
// based on the stroke width
AffineTransform at = new AffineTransform();
if (oldBounds.getWidth() > 0) {
at.scale(
(oldBounds.getWidth() - witdh) /
oldBounds.getWidth(), 1);
}
if (oldBounds.getHeight() > 0) {
at.scale(1,
(oldBounds.getHeight() - witdh)
/ oldBounds.getHeight());
}
// recalculate shape and its oldBounds
shape = at.createTransformedShape(shape);
Rectangle2D newBounds = shape.getBounds2D();
// move the shape to the old origin + the line width offset
AffineTransform moveBackTransform = AffineTransform.getTranslateInstance(
oldBounds.getX() - newBounds.getX() + witdh / 2,
oldBounds.getY() - newBounds.getY() + witdh / 2);
shape = moveBackTransform.createTransformedShape(shape);
// outline the shape using the simple basic stroke
return stroke.createStrokedShape(shape);
}
}
/**
* logger for all instances
*/
private static final Logger logger = Logger.getLogger("org.freehep.graphicsio.emf");
/**
* returns a BasicStroke JOIN for an EMF pen style
* @param penStyle penstyle
* @return e.g. {@link java.awt.BasicStroke#JOIN_MITER}
*/
protected int getJoin(int penStyle) {
switch (penStyle & 0xF000) {
case EMFConstants.PS_JOIN_ROUND:
return BasicStroke.JOIN_ROUND;
case EMFConstants.PS_JOIN_BEVEL:
return BasicStroke.JOIN_BEVEL;
case EMFConstants.PS_JOIN_MITER:
return BasicStroke.JOIN_MITER;
default:
logger.warning("got unsupported pen style " + penStyle);
return BasicStroke.JOIN_ROUND;
}
}
/**
* returns a BasicStroke JOIN for an EMF pen style
* @param penStyle Style to convert
* @return asicStroke.CAP_ROUND, BasicStroke.CAP_SQUARE, BasicStroke.CAP_BUTT
*/
protected int getCap(int penStyle) {
switch (penStyle & 0xF00) {
case EMFConstants.PS_ENDCAP_ROUND:
return BasicStroke.CAP_ROUND;
case EMFConstants.PS_ENDCAP_SQUARE:
return BasicStroke.CAP_SQUARE;
case EMFConstants.PS_ENDCAP_FLAT:
return BasicStroke.CAP_BUTT;
default:
logger.warning("got unsupported pen style " + penStyle);
return BasicStroke.CAP_ROUND;
}
}
/**
* returns a Dash for an EMF pen style
* @param penStyle Style to convert
* @param style used if EMFConstants#PS_USERSTYLE is set
* @return float[] representing a dash
*/
protected float[] getDash(int penStyle, int[] style) {
switch (penStyle & 0xFF) {
case EMFConstants.PS_SOLID:
// do not use float[] { 1 }
// it's _slow_
return null;
case EMFConstants.PS_DASH:
return new float[] { 5, 5 };
case EMFConstants.PS_DOT:
return new float[] { 1, 2 };
case EMFConstants.PS_DASHDOT:
return new float[] { 5, 2, 1, 2 };
case EMFConstants.PS_DASHDOTDOT:
return new float[] { 5, 2, 1, 2, 1, 2 };
case EMFConstants.PS_INSIDEFRAME:
// Represents a pen style that consists of a solid
// pen that is drawn from within any given bounding rectangle
return null;
case EMFConstants.PS_NULL:
// do not use float[] { 1 }
// it's _slow_
return null;
case EMFConstants.PS_USERSTYLE:
if (style != null && style.length > 0) {
float[] result = new float[style.length];
for (int i = 0; i < style.length; i++) {
result[i] = style[i];
}
return result;
} else {
return null;
}
default:
logger.warning("got unsupported pen style " + penStyle);
// do not use float[] { 1 }
// it's _slow_
return null;
}
}
/**
* @param penStyle stored pen style
* @return true if PS_INSIDEFRAME is set
*/
private boolean isInsideFrameStroke(int penStyle) {
return (penStyle & 0xFF) == EMFConstants.PS_INSIDEFRAME;
}
protected Stroke createStroke(
EMFRenderer renderer,
int penStyle,
int[] style,
float width) {
if (isInsideFrameStroke(penStyle)) {
return new InsideFrameStroke(
width,
getCap(penStyle),
getJoin(penStyle),
renderer.getMeterLimit(),
getDash(penStyle, style),
0);
} else {
return new BasicStroke(
width,
getCap(penStyle),
getJoin(penStyle),
renderer.getMeterLimit(),
getDash(penStyle, style),
0);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractPolyPolygon.java 0000664 0000000 0000000 00000006121 11676375214 0026437 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
/**
* abstract parent for PolyPolygon drawing
*
* @author Steffen Greiffenberg
* @version $Id$
*/
public abstract class AbstractPolyPolygon extends EMFTag {
private Rectangle bounds;
private int[] numberOfPoints;
private Point[][] points;
/**
* Constructs a EMFTag.
*
* @param id id of the element
* @param version emf version in which this element was first supported
* @param bounds bounds of figure
* @param numberOfPoints number of points
* @param points points
*/
protected AbstractPolyPolygon(
int id, int version,
Rectangle bounds,
int[] numberOfPoints,
Point[][] points) {
super(id, version);
this.bounds = bounds;
this.numberOfPoints = numberOfPoints;
this.points = points;
}
public String toString() {
return super.toString() +
"\n bounds: " + bounds +
"\n #polys: " + numberOfPoints.length;
}
protected Rectangle getBounds() {
return bounds;
}
protected int[] getNumberOfPoints() {
return numberOfPoints;
}
protected Point[][] getPoints() {
return points;
}
/**
* displays the tag using the renderer. The default behavior
* is to close and fill the polgygons for rendering.
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
render(renderer, true);
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
* @param closePath if true the path is closed and filled
*/
protected void render(EMFRenderer renderer, boolean closePath) {
// create a GeneralPath containing GeneralPathes
GeneralPath path = new GeneralPath(
renderer.getWindingRule());
// iterate the polgons
Point p;
for (int polygon = 0; polygon < numberOfPoints.length; polygon++) {
// create a new member of path
GeneralPath gp = new GeneralPath(
renderer.getWindingRule());
for (int point = 0; point < numberOfPoints[polygon]; point ++) {
// add a point to gp
p = points[polygon][point];
if (point > 0) {
gp.lineTo((float) p.getX(), (float)p.getY());
} else {
gp.moveTo((float) p.getX(), (float)p.getY());
}
}
// close the member, add it to path
if (closePath) {
gp.closePath();
}
path.append(gp, false);
}
// draw the complete path
if (closePath) {
renderer.fillAndDrawOrAppend(path);
} else {
renderer.drawOrAppend(path);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractPolyPolyline.java 0000664 0000000 0000000 00000001627 11676375214 0026611 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFRenderer;
import java.awt.Point;
import java.awt.Rectangle;
/**
* Parent class for a group of PolyLines. Childs are
* rendered as not closed polygons.
*
* @author Steffen Greiffenberg
* @version $Id$§
*/
public abstract class AbstractPolyPolyline extends AbstractPolyPolygon {
protected AbstractPolyPolyline(
int id,
int version,
Rectangle bounds,
int[] numberOfPoints,
Point[][] points) {
super(id, version, bounds, numberOfPoints, points);
}
/**
* displays the tag using the renderer. The default behavior
* is not to close the polygons and not to fill them.
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
render(renderer, false);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AbstractPolygon.java 0000664 0000000 0000000 00000003251 11676375214 0025574 0 ustar 00root root 0000000 0000000 // Copyright 2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFOutputStream;
import java.awt.Rectangle;
import java.awt.Point;
import java.io.IOException;
/**
* @author Steffen Greiffenberg
* @version $Id$
*/
public abstract class AbstractPolygon extends EMFTag {
private Rectangle bounds;
private int numberOfPoints;
private Point[] points;
protected AbstractPolygon(int id, int version) {
super(id, version);
}
protected AbstractPolygon(int id, int version, Rectangle bounds, int numberOfPoints, Point[] points) {
super(id, version);
this.bounds = bounds;
this.numberOfPoints = numberOfPoints;
this.points = points;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
emf.writeDWORD(numberOfPoints);
emf.writePOINTL(numberOfPoints, points);
}
public String toString() {
String result = super.toString() +
"\n bounds: " + bounds +
"\n #points: " + numberOfPoints;
if (points != null) {
result += "\n points: ";
for (int i = 0; i < points.length; i++) {
result += "[" + points[i].x + "," + points[i].y + "]";
if (i < points.length - 1) {
result += ", ";
}
}
}
return result;
}
protected Rectangle getBounds() {
return bounds;
}
protected int getNumberOfPoints() {
return numberOfPoints;
}
protected Point[] getPoints() {
return points;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AlphaBlend.java 0000664 0000000 0000000 00000013060 11676375214 0024452 0 ustar 00root root 0000000 0000000 // Copyright 2002-2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.RenderedImage;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.freehep.graphicsio.ImageGraphics2D;
import org.freehep.graphicsio.ImageConstants;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFImageLoader;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.util.io.NoCloseOutputStream;
/**
* PNG and JPG seem not to work.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class AlphaBlend extends EMFTag implements EMFConstants {
private final static int size = 108;
private Rectangle bounds;
private int x, y, width, height;
private BlendFunction dwROP;
private int xSrc, ySrc;
private AffineTransform transform;
private Color bkg;
private int usage;
private BitmapInfo bmi;
private BufferedImage image;
public AlphaBlend() {
super(114, 1);
}
public AlphaBlend(
Rectangle bounds,
int x,
int y,
int width,
int height,
AffineTransform transform,
BufferedImage image,
Color bkg) {
this();
this.bounds = bounds;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.dwROP = new BlendFunction(AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA);
this.xSrc = 0;
this.ySrc = 0;
this.transform = transform;
this.bkg = (bkg == null) ? new Color(0, 0, 0, 0) : bkg;
this.usage = DIB_RGB_COLORS;
this.image = image;
this.bmi = null;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
AlphaBlend tag = new AlphaBlend();
tag.bounds = emf.readRECTL(); // 16
tag.x = emf.readLONG(); // 20
tag.y = emf.readLONG(); // 24
tag.width = emf.readLONG(); // 28
tag.height = emf.readLONG(); // 32
tag.dwROP = new BlendFunction(emf); // 36
tag.xSrc = emf.readLONG(); // 40
tag.ySrc = emf.readLONG(); // 44
tag.transform = emf.readXFORM(); // 68
tag.bkg = emf.readCOLORREF(); // 72
tag.usage = emf.readDWORD(); // 76
// ignored
/* int bmiOffset = */ emf.readDWORD(); // 80
int bmiSize = emf.readDWORD(); // 84
/* int bitmapOffset = */ emf.readDWORD(); // 88
int bitmapSize = emf.readDWORD(); // 92
/* int width = */ emf.readLONG(); // 96
/* int height = */ emf.readLONG(); // 100
// FIXME: this size can differ and can be placed somewhere else
tag.bmi = (bmiSize > 0) ? new BitmapInfo(emf) : null;
tag.image = EMFImageLoader.readImage(
tag.bmi.getHeader(),
tag.width,
tag.height,
emf,
bitmapSize,
tag.dwROP);
return tag;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
emf.writeLONG(x);
emf.writeLONG(y);
emf.writeLONG(width);
emf.writeLONG(height);
dwROP.write(emf);
emf.writeLONG(xSrc);
emf.writeLONG(ySrc);
emf.writeXFORM(transform);
emf.writeCOLORREF(bkg);
emf.writeDWORD(usage);
emf.writeDWORD(size); // bmi follows this record immediately
emf.writeDWORD(BitmapInfoHeader.size);
emf.writeDWORD(size + BitmapInfoHeader.size); // bitmap follows bmi
emf.pushBuffer();
int encode;
// plain
encode = BI_RGB;
ImageGraphics2D.writeImage(
(RenderedImage) image,
ImageConstants.RAW.toLowerCase(),
ImageGraphics2D.getRAWProperties(bkg, "*BGRA"),
new NoCloseOutputStream(emf));
// emf.writeImage(image, bkg, "*BGRA", 1);
// png
// encode = BI_PNG;
// ImageGraphics2D.writeImage(image, "png", new Properties(), new
// NoCloseOutputStream(emf));
// jpg
// encode = BI_JPEG;
// ImageGraphics2D.writeImage(image, "jpg", new Properties(), new
// NoCloseOutputStream(emf));
int length = emf.popBuffer();
emf.writeDWORD(length);
emf.writeLONG(image.getWidth());
emf.writeLONG(image.getHeight());
BitmapInfoHeader header = new BitmapInfoHeader(image.getWidth(), image
.getHeight(), 32, encode, length, 0, 0, 0, 0);
bmi = new BitmapInfo(header);
bmi.write(emf);
emf.append();
}
public String toString() {
return super.toString() +
"\n bounds: " + bounds +
"\n x, y, w, h: " + x + " " + y + " " + width + " " + height +
"\n dwROP: " + dwROP +
"\n xSrc, ySrc: " + xSrc + " " + ySrc +
"\n transform: " + transform +
"\n bkg: " + bkg +
"\n usage: " + usage +
"\n" + ((bmi != null) ? bmi.toString() : " bitmap: null");
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// This function displays bitmaps that have transparent or semitransparent pixels.
if (image != null) {
renderer.drawImage(image, x, y, width, height);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/AngleArc.java 0000664 0000000 0000000 00000002674 11676375214 0024145 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Point;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* AngleArc TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class AngleArc extends EMFTag {
private Point center;
private int radius;
private float startAngle, sweepAngle;
public AngleArc() {
super(41, 1);
}
public AngleArc(Point center, int radius, float startAngle, float sweepAngle) {
this();
this.center = center;
this.radius = radius;
this.startAngle = startAngle;
this.sweepAngle = sweepAngle;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new AngleArc(
emf.readPOINTL(),
emf.readDWORD(), emf.readFLOAT(),
emf.readFLOAT());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writePOINTL(center);
emf.writeDWORD(radius);
emf.writeFLOAT(startAngle);
emf.writeFLOAT(sweepAngle);
}
public String toString() {
return super.toString() +
"\n center: " + center +
"\n radius: " + radius +
"\n startAngle: " + startAngle +
"\n sweepAngle: " + sweepAngle;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/Arc.java 0000664 0000000 0000000 00000004676 11676375214 0023202 0 ustar 00root root 0000000 0000000 // Copyright 2002-2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Arc2D;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* Arc TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class Arc extends AbstractArc {
public Arc() {
super(45, 1, null, null, null);
}
public Arc(Rectangle bounds, Point start, Point end) {
super(45, 1, bounds, start, end);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new Arc(
emf.readRECTL(),
emf.readPOINTL(),
emf.readPOINTL());
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// The Arc function draws an elliptical arc.
//
// BOOL Arc(
// HDC hdc, // handle to device context
// int nLeftRect, // x-coord of rectangle's upper-left corner
// int nTopRect, // y-coord of rectangle's upper-left corner
// int nRightRect, // x-coord of rectangle's lower-right corner
// int nBottomRect, // y-coord of rectangle's lower-right corner
// int nXStartArc, // x-coord of first radial ending point
// int nYStartArc, // y-coord of first radial ending point
// int nXEndArc, // x-coord of second radial ending point
// int nYEndArc // y-coord of second radial ending point
// );
// The points (nLeftRect, nTopRect) and (nRightRect, nBottomRect)
// specify the bounding rectangle.
// An ellipse formed by the specified bounding rectangle defines the
// curve of the arc.
// The arc extends in the current drawing direction from the point
// where it intersects the
// radial from the center of the bounding rectangle to the
// (nXStartArc, nYStartArc) point.
// The arc ends where it intersects the radial from the center of
// the bounding rectangle to
// the (nXEndArc, nYEndArc) point. If the starting point and ending
// point are the same,
// a complete ellipse is drawn.
renderer.fillAndDrawOrAppend(
getShape(renderer, Arc2D.OPEN));
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ArcTo.java 0000664 0000000 0000000 00000005512 11676375214 0023473 0 ustar 00root root 0000000 0000000 // Copyright 2002-2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Arc2D;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* ArcTo TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ArcTo extends AbstractArc {
public ArcTo() {
super(55, 1, null, null, null);
}
public ArcTo(Rectangle bounds, Point start, Point end) {
super(55, 1, bounds, start, end);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ArcTo(
emf.readRECTL(),
emf.readPOINTL(),
emf.readPOINTL());
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// The ArcTo function draws an elliptical arc.
//
// BOOL ArcTo(
// HDC hdc, // handle to device context
// int nLeftRect, // x-coord of rectangle's upper-left corner
// int nTopRect, // y-coord of rectangle's upper-left corner
// int nRightRect, // x-coord of rectangle's lower-right corner
// int nBottomRect, // y-coord of rectangle's lower-right corner
// int nXRadial1, // x-coord of first radial ending point
// int nYRadial1, // y-coord of first radial ending point
// int nXRadial2, // x-coord of second radial ending point
// int nYRadial2 // y-coord of second radial ending point
// );
// ArcTo is similar to the Arc function, except that the current
// position is updated.
//
// The points (nLeftRect, nTopRect) and (nRightRect, nBottomRect)
// specify the bounding rectangle.
// An ellipse formed by the specified bounding rectangle defines the
// curve of the arc. The arc extends
// counterclockwise from the point where it intersects the radial
// line from the center of the bounding
// rectangle to the (nXRadial1, nYRadial1) point. The arc ends where
// it intersects the radial line from
// the center of the bounding rectangle to the (nXRadial2,
// nYRadial2) point. If the starting point and
// ending point are the same, a complete ellipse is drawn.
//
// A line is drawn from the current position to the starting point
// of the arc.
// If no error occurs, the current position is set to the ending
// point of the arc.
//
// The arc is drawn using the current pen; it is not filled.
renderer.getFigure().append(
getShape(renderer, Arc2D.OPEN), true);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/BeginPath.java 0000664 0000000 0000000 00000002012 11676375214 0024314 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import java.awt.geom.GeneralPath;
import java.awt.geom.AffineTransform;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* BeginPath TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class BeginPath extends EMFTag {
public BeginPath() {
super(59, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return this;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// The BeginPath function opens a path bracket in the specified
// device context.
renderer.setPath(new GeneralPath(
renderer.getWindingRule()));
renderer.setPathTransform(new AffineTransform());
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/BitBlt.java 0000664 0000000 0000000 00000012346 11676375214 0023646 0 ustar 00root root 0000000 0000000 // Copyright 2002-2003, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.RenderedImage;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.freehep.graphicsio.ImageGraphics2D;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFImageLoader;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.graphicsio.raw.RawImageWriteParam;
import org.freehep.util.UserProperties;
import org.freehep.util.io.NoCloseOutputStream;
/**
* BitBlt TAG. Encoded as plain RGB rather than the not-yet-working PNG format.
* The BI_code for BI_PNG and BI_JPG seems to be missing from the WINGDI.H file
* of visual C++.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class BitBlt extends EMFTag implements EMFConstants {
private final static int size = 100;
private Rectangle bounds;
private int x, y, width, height;
private int dwROP;
private int xSrc, ySrc;
private AffineTransform transform;
private Color bkg;
private int usage;
private BitmapInfo bmi;
private BufferedImage image;
public BitBlt() {
super(76, 1);
}
public BitBlt(Rectangle bounds, int x, int y, int width, int height,
AffineTransform transform, BufferedImage image, Color bkg) {
this();
this.bounds = bounds;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.dwROP = SRCCOPY;
this.xSrc = 0;
this.ySrc = 0;
this.transform = transform;
this.bkg = bkg;
this.usage = DIB_RGB_COLORS;
this.image = image;
this.bmi = null;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
BitBlt tag = new BitBlt();
tag.bounds = emf.readRECTL(); // 16
tag.x = emf.readLONG(); // 20
tag.y = emf.readLONG(); // 24
tag.width = emf.readLONG(); // 28
tag.height = emf.readLONG(); // 32
tag.dwROP = emf.readDWORD(); // 36
tag.xSrc = emf.readLONG(); // 40
tag.ySrc = emf.readLONG(); // 44
tag.transform = emf.readXFORM(); // 68
tag.bkg = emf.readCOLORREF(); // 72
tag.usage = emf.readDWORD(); // 76
// ignored
/* int bmiOffset = */ emf.readDWORD(); // 80
int bmiSize = emf.readDWORD(); // 84
/* int bitmapOffset = */ emf.readDWORD(); // 88
int bitmapSize = emf.readDWORD(); // 92
// read bmi
if (bmiSize > 0) {
tag.bmi = new BitmapInfo(emf);
} else {
tag.bmi = null;
}
if (bitmapSize > 0 && tag.bmi != null) {
tag.image = EMFImageLoader.readImage(
tag.bmi.getHeader(),
tag.width,
tag.height,
emf,
bitmapSize, null);
} else {
tag.image = null;
}
return tag;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
emf.writeLONG(x);
emf.writeLONG(y);
emf.writeLONG(width);
emf.writeLONG(height);
emf.writeDWORD(dwROP);
emf.writeLONG(xSrc);
emf.writeLONG(ySrc);
emf.writeXFORM(transform);
emf.writeCOLORREF(bkg);
emf.writeDWORD(usage);
emf.writeDWORD(size); // bmi follows this record immediately
emf.writeDWORD(BitmapInfoHeader.size);
emf.writeDWORD(size + BitmapInfoHeader.size); // bitmap follows bmi
emf.pushBuffer();
UserProperties properties = new UserProperties();
properties.setProperty(RawImageWriteParam.BACKGROUND, bkg);
properties.setProperty(RawImageWriteParam.CODE, "BGR");
properties.setProperty(RawImageWriteParam.PAD, 4);
ImageGraphics2D.writeImage((RenderedImage)image, "raw", properties,
new NoCloseOutputStream(emf));
// emf.writeImage(image, bkg, "BGR", 4);
int length = emf.popBuffer();
BitmapInfoHeader header = new BitmapInfoHeader(
image.getWidth(),
image.getHeight(), 24, BI_RGB, length, 0, 0, 0, 0);
bmi = new BitmapInfo(header);
bmi.write(emf);
emf.writeDWORD(length);
emf.append();
}
public String toString() {
return super.toString() +
"\n bounds: " + bounds +
"\n x, y, w, h: " + x + " " + y + " " + width + " " + height +
"\n dwROP: 0x" + Integer.toHexString(dwROP) +
"\n xSrc, ySrc: " + xSrc + " " + ySrc +
"\n transform: " + transform +
"\n bkg: " + bkg +
"\n usage: " + usage +
"\n" + ((bmi != null) ? bmi.toString() : " bitmap: null");
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
if (image != null) {
renderer.drawImage(image, transform);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/BitmapInfo.java 0000664 0000000 0000000 00000001620 11676375214 0024507 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
/**
* EMF BitmapInfo
*
* @author Mark Donszelmann
* @version $Id$
*/
public class BitmapInfo {
private BitmapInfoHeader header;
public BitmapInfo(BitmapInfoHeader header) {
this.header = header;
}
public BitmapInfo(EMFInputStream emf) throws IOException {
header = new BitmapInfoHeader(emf);
// colormap not necessary for true color image
}
public void write(EMFOutputStream emf) throws IOException {
header.write(emf);
// colormap not necessary for true color image
}
public String toString() {
return " BitmapInfo\n" + header.toString();
}
public BitmapInfoHeader getHeader() {
return header;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/BitmapInfoHeader.java 0000664 0000000 0000000 00000005744 11676375214 0025633 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
/**
* EMF BitmapInfoHeader
*
* @author Mark Donszelmann
* @version $Id$
*/
public class BitmapInfoHeader implements EMFConstants {
public static final int size = 40;
private int width;
private int height;
private int planes;
private int bitCount;
private int compression;
private int sizeImage;
private int xPelsPerMeter;
private int yPelsPerMeter;
private int clrUsed;
private int clrImportant;
public BitmapInfoHeader(int width, int height, int bitCount,
int compression, int sizeImage, int xPelsPerMeter,
int yPelsPerMeter, int clrUsed, int clrImportant) {
this.width = width;
this.height = height;
this.planes = 1;
this.bitCount = bitCount;
this.compression = compression;
this.sizeImage = sizeImage;
this.xPelsPerMeter = xPelsPerMeter;
this.yPelsPerMeter = yPelsPerMeter;
this.clrUsed = clrUsed;
this.clrImportant = clrImportant;
}
public BitmapInfoHeader(EMFInputStream emf) throws IOException {
/*int len = */ emf.readDWORD(); // seems fixed
width = emf.readLONG();
height = emf.readLONG();
planes = emf.readWORD();
bitCount = emf.readWORD();
compression = emf.readDWORD();
sizeImage = emf.readDWORD();
xPelsPerMeter = emf.readLONG();
yPelsPerMeter = emf.readLONG();
clrUsed = emf.readDWORD();
clrImportant = emf.readDWORD();
}
public void write(EMFOutputStream emf) throws IOException {
emf.writeDWORD(size);
emf.writeLONG(width);
emf.writeLONG(height);
emf.writeWORD(planes);
emf.writeWORD(bitCount);
emf.writeDWORD(compression);
emf.writeDWORD(sizeImage);
emf.writeLONG(xPelsPerMeter);
emf.writeLONG(yPelsPerMeter);
emf.writeDWORD(clrUsed);
emf.writeDWORD(clrImportant);
}
public String toString() {
return " size: " + size +
"\n width: " + width +
"\n height: " + height +
"\n planes: " + planes +
"\n bitCount: " + bitCount +
"\n compression: " + compression +
"\n sizeImage: " + sizeImage +
"\n xPelsPerMeter: " + xPelsPerMeter +
"\n yPelsPerMeter: " + yPelsPerMeter +
"\n clrUsed: " + clrUsed +
"\n clrImportant: " + clrImportant;
}
public int getBitCount() {
return bitCount;
}
public int getCompression() {
return compression;
}
public int getClrUsed() {
return clrUsed;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/BlendFunction.java 0000664 0000000 0000000 00000003000 11676375214 0025203 0 ustar 00root root 0000000 0000000 // Copyright 2002-2003, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
/**
* EMF BitmapInfoHeader
*
* @author Mark Donszelmann
* @version $Id$
*/
public class BlendFunction implements EMFConstants {
public static final int size = 4;
private int blendOp;
private int blendFlags;
private int sourceConstantAlpha;
private int alphaFormat;
public BlendFunction(int blendOp, int blendFlags, int sourceConstantAlpha,
int alphaFormat) {
this.blendOp = blendOp;
this.blendFlags = blendFlags;
this.sourceConstantAlpha = sourceConstantAlpha;
this.alphaFormat = alphaFormat;
}
public BlendFunction(EMFInputStream emf) throws IOException {
blendOp = emf.readUnsignedByte();
blendFlags = emf.readUnsignedByte();
sourceConstantAlpha = emf.readUnsignedByte();
alphaFormat = emf.readUnsignedByte();
}
public void write(EMFOutputStream emf) throws IOException {
emf.writeBYTE(blendOp);
emf.writeBYTE(blendFlags);
emf.writeBYTE(sourceConstantAlpha);
emf.writeBYTE(alphaFormat);
}
public String toString() {
return "BlendFunction";
}
public int getSourceConstantAlpha() {
return sourceConstantAlpha;
}
public int getAlphaFormat() {
return alphaFormat;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/Chord.java 0000664 0000000 0000000 00000002216 11676375214 0023520 0 ustar 00root root 0000000 0000000 // Copyright 2002-2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Arc2D;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* Chord TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class Chord extends AbstractArc {
private Rectangle bounds;
private Point start, end;
public Chord() {
super(46, 1, null, null, null);
}
public Chord(Rectangle bounds, Point start, Point end) {
super(46, 1, bounds, start, end);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new Chord(
emf.readRECTL(),
emf.readPOINTL(),
emf.readPOINTL());
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.fillAndDrawOrAppend(
getShape(renderer, Arc2D.CHORD));
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/CloseFigure.java 0000664 0000000 0000000 00000001370 11676375214 0024670 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* CloseFigure TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class CloseFigure extends EMFTag {
public CloseFigure() {
super(61, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return this;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.closeFigure();
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/CreateBrushIndirect.java 0000664 0000000 0000000 00000003276 11676375214 0026361 0 ustar 00root root 0000000 0000000 // Copyright 2001, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* CreateBrushIndirect TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class CreateBrushIndirect extends EMFTag {
private int index;
private LogBrush32 brush;
public CreateBrushIndirect() {
super(39, 1);
}
public CreateBrushIndirect(int index, LogBrush32 brush) {
this();
this.index = index;
this.brush = brush;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new CreateBrushIndirect(
emf.readDWORD(),
new LogBrush32(emf));
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(index);
brush.write(emf);
}
public String toString() {
return super.toString() +
"\n index: 0x" + Integer.toHexString(index) +
"\n" + brush.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// CreateBrushIndirect
//
// The CreateBrushIndirect function creates a logical brush that has the
// specified style, color, and pattern.
//
// HBRUSH CreateBrushIndirect(
// CONST LOGBRUSH *lplb // brush information
// );
renderer.storeGDIObject(index, brush);
}
} a/src/main/java/org/freehep/graphicsio/emf/gdi/CreateDIBPatternBrushPt.java 0000664 0000000 0000000 00000005774 11676375214 0027065 0 ustar 00root root 0000000 0000000 /**
* $Id$
*
* Copyright (c) 1998-2006
* semture GmbH
*
* Alle Rechte vorbehalten
*/
package org.freehep.graphicsio.emf.gdi;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFImageLoader;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFRenderer;
import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.TexturePaint;
import java.awt.Rectangle;
/**
* @author Steffen Greiffenberg
* @version $Revision$
*/
public class CreateDIBPatternBrushPt extends EMFTag {
private int usage;
private BitmapInfo bmi;
private BufferedImage image;
private int index;
public CreateDIBPatternBrushPt() {
super(94, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
CreateDIBPatternBrushPt tag = new CreateDIBPatternBrushPt();
// read the index for storing the GDIObject
tag.index = emf.readDWORD();
// read whatever
/*byte[] bytes =*/ emf.readByte(24);
tag.bmi = new BitmapInfo(emf);
// not used but read:
// DIB_PAL_COLORS A color table is provided and
// consists of an array of 16-bit indexes into the
// logical palette of the device context into which
// the brush is to be selected.
// DIB_RGB_COLORS A color table is provided and
// contains literal RGB values.
tag.usage = emf.readDWORD();
tag.image = EMFImageLoader.readImage(
tag.bmi.getHeader(),
tag.bmi.getHeader().getWidth(),
tag.bmi.getHeader().getHeight(),
emf,
len - 4 - 24 - BitmapInfoHeader.size - 4, null);
return tag;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
logger.warning("not implemented");
}
public String toString() {
return super.toString() +
"\n usage: " + usage +
"\n" + bmi.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// The StretchDIBits function copies the color data for a rectangle of pixels in a
// DIB to the specified destination rectangle. If the destination rectangle is larger
// than the source rectangle, this function stretches the rows and columns of color
// data to fit the destination rectangle. If the destination rectangle is smaller
// than the source rectangle, this function compresses the rows and columns by using
// the specified raster operation.
renderer.storeGDIObject(index, new GDIObject() {
public void render(EMFRenderer renderer) {
if (image != null) {
renderer.setBrushPaint(new TexturePaint(image, new Rectangle(0, 0, 16, 16)));
}
}
});
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/CreatePen.java 0000664 0000000 0000000 00000003504 11676375214 0024330 0 ustar 00root root 0000000 0000000 // Copyright 2001, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* CreatePen TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class CreatePen extends EMFTag {
private int index;
private LogPen pen;
public CreatePen() {
super(38, 1);
}
public CreatePen(int index, LogPen pen) {
this();
this.index = index;
this.pen = pen;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new CreatePen(emf.readDWORD(), new LogPen(emf));
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(index);
pen.write(emf);
}
public String toString() {
return super.toString() +
"\n index: 0x" + Integer.toHexString(index) +
"\n" + pen.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// ExtCreatePen
//
// The ExtCreatePen function creates a logical cosmetic or
// geometric pen that has the specified style, width,
// and brush attributes.
//
// HPEN ExtCreatePen(
// DWORD dwPenStyle, // pen style
// DWORD dwWidth, // pen width
// CONST LOGBRUSH *lplb, // brush attributes
// DWORD dwStyleCount, // length of custom style array
// CONST DWORD *lpStyle // custom style array
//);
renderer.storeGDIObject(index, pen);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/DeleteObject.java 0000664 0000000 0000000 00000002274 11676375214 0025016 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* DeleteObject TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class DeleteObject extends EMFTag {
private int index;
public DeleteObject() {
super(40, 1);
}
public DeleteObject(int index) {
this();
this.index = index;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new DeleteObject(emf.readDWORD());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(index);
}
public String toString() {
return super.toString() +
"\n index: 0x" + Integer.toHexString(index);
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.storeGDIObject(index, null);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/EMFPolygon.java 0000664 0000000 0000000 00000003322 11676375214 0024437 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* PolylineTo TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFPolygon extends AbstractPolygon {
public EMFPolygon() {
super(3, 1, null, 0, null);
}
public EMFPolygon(Rectangle bounds, int numberOfPoints, Point[] points) {
super(3, 1, bounds, numberOfPoints, points);
}
protected EMFPolygon (int id, int version, Rectangle bounds, int numberOfPoints, Point[] points) {
super(id, version, bounds, numberOfPoints, points);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
Rectangle r = emf.readRECTL();
int n = emf.readDWORD();
return new EMFPolygon(r, n, emf.readPOINTL(n));
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
Point[] points = getPoints();
// Safety check.
if (points.length > 1) {
GeneralPath path = new GeneralPath(
renderer.getWindingRule());
path.moveTo((float)points[0].getX(), (float)points[0].getY());
for (int i = 1; i < points.length; i++) {
path.lineTo((float)points[i].getX(), (float)points[i].getY());
}
path.closePath();
renderer.fillAndDrawOrAppend(path);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/EMFRectangle.java 0000664 0000000 0000000 00000002304 11676375214 0024713 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* Rectangle TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EMFRectangle extends EMFTag {
private Rectangle bounds;
public EMFRectangle() {
super(43, 1);
}
public EMFRectangle(Rectangle bounds) {
this();
this.bounds = bounds;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new EMFRectangle(emf.readRECTL());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
}
public String toString() {
return super.toString() + "\n bounds: " + bounds;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.fillAndDrawOrAppend(bounds);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/EOF.java 0000664 0000000 0000000 00000002126 11676375214 0023072 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* Rectangle TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EOF extends EMFTag {
public EOF() {
super(14, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
/* int[] bytes = */ emf.readUnsignedByte(len);
return new EOF();
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(0); // # of palette entries
emf.writeDWORD(0x10); // offset for palette
// ... palette
emf.writeDWORD(0x14); // offset to start of record
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// do nothing
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/Ellipse.java 0000664 0000000 0000000 00000003224 11676375214 0024056 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* Ellipse TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class Ellipse extends EMFTag {
private Rectangle bounds;
public Ellipse(Rectangle bounds) {
this();
this.bounds = bounds;
}
public Ellipse() {
super(42, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new Ellipse(emf.readRECTL());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
}
public String toString() {
return super.toString() + "\n bounds: " + bounds;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// The Ellipse function draws an ellipse. The center of the ellipse
// is the center of the specified bounding rectangle.
// The ellipse is outlined by using the current pen and is filled by
// using the current brush.
// The current position is neither used nor updated by Ellipse.
renderer.fillAndDrawOrAppend(new Ellipse2D.Double(
bounds.getX(),
bounds.getY(),
bounds.getWidth(),
bounds.getHeight()));
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/EndPath.java 0000664 0000000 0000000 00000002234 11676375214 0024004 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* EndPath TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class EndPath extends EMFTag {
public EndPath() {
super(60, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return this;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
// TODO: fix EMFGraphics2D?
// this happens only when EMF is created by EMFGraphics2D
// there could be an open figure (created with LineTo, PolylineTo etc.)
// that is not closed and therefore not written to the currentPath
renderer.closeFigure();
// The EndPath function closes a path bracket and selects the path
// defined by the bracket into the specified device context.
renderer.closePath();
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExcludeClipRect.java 0000664 0000000 0000000 00000001675 11676375214 0025510 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* ExcludeClipRect TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExcludeClipRect extends EMFTag {
private Rectangle bounds;
public ExcludeClipRect() {
super(29, 1);
}
public ExcludeClipRect(Rectangle bounds) {
this();
this.bounds = bounds;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ExcludeClipRect(emf.readRECTL());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
}
public String toString() {
return super.toString() + "\n bounds: " + bounds;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtCreateFontIndirectW.java 0000664 0000000 0000000 00000002646 11676375214 0027014 0 ustar 00root root 0000000 0000000 // Copyright 2001, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* ExtCreateFontIndirectW TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtCreateFontIndirectW extends EMFTag {
private int index;
private ExtLogFontW font;
public ExtCreateFontIndirectW() {
super(82, 1);
}
public ExtCreateFontIndirectW(int index, ExtLogFontW font) {
this();
this.index = index;
this.font = font;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ExtCreateFontIndirectW(
emf.readDWORD(),
new ExtLogFontW(emf));
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(index);
font.write(emf);
}
public String toString() {
return super.toString() +
"\n index: 0x" + Integer.toHexString(index) +
"\n" + font.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.storeGDIObject(index, font);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtCreatePen.java 0000664 0000000 0000000 00000003343 11676375214 0025012 0 ustar 00root root 0000000 0000000 // Copyright 2001, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* ExtCreatePen TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtCreatePen extends EMFTag {
private int index;
private ExtLogPen pen;
public ExtCreatePen() {
super(95, 1);
}
public ExtCreatePen(int index, ExtLogPen pen) {
this();
this.index = index;
this.pen = pen;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
int index = emf.readDWORD();
/* int bmiOffset = */ emf.readDWORD();
/* int bmiSize = */ emf.readDWORD();
/* int brushOffset = */ emf.readDWORD();
/* int brushSize = */ emf.readDWORD();
return new ExtCreatePen(index, new ExtLogPen(emf));
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(index);
emf.writeDWORD(0); // offset to bmi
emf.writeDWORD(0); // size of bmi
emf.writeDWORD(0); // offset to brush bitmap
emf.writeDWORD(0); // size of brush bitmap
pen.write(emf);
}
public String toString() {
return super.toString() +
"\n index: 0x" + Integer.toHexString(index) +
"\n" + pen.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.storeGDIObject(index, pen);
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtFloodFill.java 0000664 0000000 0000000 00000002526 11676375214 0025020 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Color;
import java.awt.Point;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* ExtFloodFill TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtFloodFill extends EMFTag implements EMFConstants {
private Point start;
private Color color;
private int mode;
public ExtFloodFill() {
super(53, 1);
}
public ExtFloodFill(Point start, Color color, int mode) {
this();
this.start = start;
this.color = color;
this.mode = mode;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ExtFloodFill(
emf.readPOINTL(),
emf.readCOLORREF(),
emf.readDWORD());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writePOINTL(start);
emf.writeCOLORREF(color);
emf.writeDWORD(mode);
}
public String toString() {
return super.toString() +
"\n start: " + start +
"\n color: " + color +
"\n mode: " + mode;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtLogFontW.java 0000664 0000000 0000000 00000006067 11676375214 0024651 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Font;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* EMF ExtLogFontW
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtLogFontW implements EMFConstants, GDIObject {
private LogFontW font;
private String fullName;
private String style;
private int version;
private int styleSize;
private int match;
private byte[] vendorID;
private int culture;
private Panose panose;
public ExtLogFontW(LogFontW font, String fullName, String style,
int version, int styleSize, int match, byte[] vendorID,
int culture, Panose panose) {
this.font = font;
this.fullName = fullName;
this.style = style;
this.version = version;
this.styleSize = styleSize;
this.match = match;
this.vendorID = vendorID;
this.culture = culture;
this.panose = panose;
}
public ExtLogFontW(Font font) {
this.font = new LogFontW(font);
this.fullName = "";
this.style = "";
this.version = 0;
this.styleSize = 0;
this.match = 0;
this.vendorID = new byte[] { 0, 0, 0, 0 };
this.culture = 0;
this.panose = new Panose();
}
public ExtLogFontW(EMFInputStream emf) throws IOException {
font = new LogFontW(emf);
fullName = emf.readWCHAR(64);
style = emf.readWCHAR(32);
version = emf.readDWORD();
styleSize = emf.readDWORD();
match = emf.readDWORD();
emf.readDWORD();
vendorID = emf.readBYTE(4);
culture = emf.readDWORD();
panose = new Panose(emf);
emf.readWORD(); // Pad to 4-byte boundary
// to avoid an eception
emf.popBuffer();
}
public void write(EMFOutputStream emf) throws IOException {
font.write(emf);
emf.writeWCHAR(fullName, 64);
emf.writeWCHAR(style, 32);
emf.writeDWORD(version);
emf.writeDWORD(styleSize);
emf.writeDWORD(match);
emf.writeDWORD(0); // reserved
emf.writeBYTE(vendorID);
emf.writeDWORD(culture);
panose.write(emf);
emf.writeWORD(0);
}
public String toString() {
return super.toString() +
"\n LogFontW\n" + font.toString() +
"\n fullname: " + fullName +
"\n style: " + style +
"\n version: " + version +
"\n stylesize: " + styleSize +
"\n match: " + match +
"\n vendorID: " + vendorID +
"\n culture: " + culture +
"\n" + panose.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.setFont(font.getFont());
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtLogPen.java 0000664 0000000 0000000 00000005513 11676375214 0024331 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Color;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* EMF ExtLogPen
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtLogPen extends AbstractPen {
private int penStyle;
private int width;
private int brushStyle;
private Color color;
private int hatch;
private int[] style;
public ExtLogPen(
int penStyle,
int width,
int brushStyle,
Color color,
int hatch,
int[] style) {
this.penStyle = penStyle;
this.width = width;
this.brushStyle = brushStyle;
this.color = color;
this.hatch = hatch;
this.style = style;
}
public ExtLogPen(EMFInputStream emf) throws IOException {
penStyle = emf.readDWORD();
width = emf.readDWORD();
brushStyle = emf.readUINT();
color = emf.readCOLORREF();
hatch = emf.readULONG();
int nStyle = emf.readDWORD();
// it seems we always have to read one!
if (nStyle == 0)
emf.readDWORD();
style = emf.readDWORD(nStyle);
}
public void write(EMFOutputStream emf) throws IOException {
emf.writeDWORD(penStyle);
emf.writeDWORD(width);
emf.writeUINT(brushStyle);
emf.writeCOLORREF(color);
emf.writeULONG(hatch);
emf.writeDWORD(style.length);
// it seems we always have to write one!
if (style.length == 0)
emf.writeDWORD(0);
emf.writeDWORD(style);
}
public String toString() {
StringBuffer s = new StringBuffer();
s.append(" ExtLogPen\n");
s.append(" penStyle: ");
s.append(Integer.toHexString(penStyle));
s.append("\n");
s.append(" width: ");
s.append(width);
s.append("\n");
s.append(" brushStyle: ");
s.append(brushStyle);
s.append("\n");
s.append(" color: ");
s.append(color);
s.append("\n");
s.append(" hatch: ");
s.append(hatch);
s.append("\n");
for (int i = 0; i < style.length; i++) {
s.append(" style[");
s.append(i);
s.append("]: ");
s.append(style[i]);
s.append("\n");
}
return s.toString();
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
renderer.setUseCreatePen(false);
renderer.setPenPaint(color);
renderer.setPenStroke(
createStroke(renderer, penStyle, style, width));
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtSelectClipRgn.java 0000664 0000000 0000000 00000002704 11676375214 0025642 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* ExtSelectClipRgn TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtSelectClipRgn extends AbstractClipPath {
private Region rgn;
public ExtSelectClipRgn() {
super(75, 1, EMFConstants.RGN_COPY);
}
public ExtSelectClipRgn(int mode, Region rgn) {
super(75, 1, mode);
this.rgn = rgn;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
int length = emf.readDWORD();
int mode = emf.readDWORD();
return new ExtSelectClipRgn(
mode,
length > 8 ? new Region(emf) : null);
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeDWORD(rgn.length());
emf.writeDWORD(getMode());
rgn.write(emf);
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
if (rgn == null || rgn.getBounds() == null) {
return;
}
render(renderer, rgn.getBounds());
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtTextOutA.java 0000664 0000000 0000000 00000002065 11676375214 0024661 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* ExtTextOutA TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtTextOutA extends AbstractExtTextOut implements EMFConstants {
private TextA text;
public ExtTextOutA() {
super(83, 1, null, 0, 1, 1);
}
public ExtTextOutA(
Rectangle bounds,
int mode,
float xScale,
float yScale,
TextA text) {
super(83, 1, bounds, mode, xScale, yScale);
this.text = text;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ExtTextOutA(
emf.readRECTL(),
emf.readDWORD(),
emf.readFLOAT(),
emf.readFLOAT(),
TextA.read(emf));
}
public Text getText() {
return text;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/ExtTextOutW.java 0000664 0000000 0000000 00000002072 11676375214 0024705 0 ustar 00root root 0000000 0000000 // Copyright 2002-2007, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* ExtTextOutW TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class ExtTextOutW extends AbstractExtTextOut implements EMFConstants {
private TextW text;
public ExtTextOutW() {
super(84, 1, null, 0, 1, 1);
}
public ExtTextOutW(
Rectangle bounds,
int mode,
float xScale,
float yScale,
TextW text) {
super(84, 1, bounds, mode, xScale, yScale);
this.text = text;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new ExtTextOutW(
emf.readRECTL(),
emf.readDWORD(),
emf.readFLOAT(),
emf.readFLOAT(),
TextW.read(emf));
}
public Text getText() {
return text;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/FillPath.java 0000664 0000000 0000000 00000002575 11676375214 0024174 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Rectangle;
import java.awt.geom.GeneralPath;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.graphicsio.emf.EMFRenderer;
/**
* FillPath TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class FillPath extends EMFTag {
private Rectangle bounds;
public FillPath() {
super(62, 1);
}
public FillPath(Rectangle bounds) {
this();
this.bounds = bounds;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return new FillPath(emf.readRECTL());
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
emf.writeRECTL(bounds);
}
public String toString() {
return super.toString() + "\n bounds: " + bounds;
}
/**
* displays the tag using the renderer
*
* @param renderer EMFRenderer storing the drawing session data
*/
public void render(EMFRenderer renderer) {
GeneralPath currentPath = renderer.getPath();
// fills the current path
if (currentPath != null) {
renderer.fillShape(currentPath);
renderer.setPath(null);
}
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/FlattenPath.java 0000664 0000000 0000000 00000000756 11676375214 0024702 0 ustar 00root root 0000000 0000000 // Copyright 2002, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.io.IOException;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFTag;
/**
* FlattenPath TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class FlattenPath extends EMFTag {
public FlattenPath() {
super(65, 1);
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
return this;
}
}
a/src/main/java/org/freehep/graphicsio/emf/gdi/GDIComment.java 0000664 0000000 0000000 00000006540 11676375214 0024413 0 ustar 00root root 0000000 0000000 // Copyright 2001-2006, FreeHEP.
package org.freehep.graphicsio.emf.gdi;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.freehep.graphicsio.emf.EMFConstants;
import org.freehep.graphicsio.emf.EMFInputStream;
import org.freehep.graphicsio.emf.EMFOutputStream;
import org.freehep.graphicsio.emf.EMFRenderer;
import org.freehep.graphicsio.emf.EMFTag;
import org.freehep.util.io.Tag;
/**
* GDIComment TAG.
*
* @author Mark Donszelmann
* @version $Id$
*/
public class GDIComment extends EMFTag {
private static final String EMF_PLUS = "EMF+";
private byte[] bytes;
private EMFTag tag;
public GDIComment() {
super(70, 1);
}
public GDIComment(String comment) {
this(comment.getBytes());
}
public GDIComment(byte[] bytes) {
this();
this.bytes = bytes;
}
// FIXME should be EMFPlusTag
public GDIComment(EMFTag tag) {
this();
this.tag = tag;
}
public EMFTag read(int tagID, EMFInputStream emf, int len)
throws IOException {
// FIXME decode internal EMFPlus Tags
int l = emf.readDWORD();
GDIComment tag = new GDIComment(emf.readBYTE(l));
// Align to 4-byte boundary
if (l % 4 != 0)
emf.readBYTE(4 - l % 4);
return tag;
}
public void write(int tagID, EMFOutputStream emf) throws IOException {
if (tag != null) {
emf.pushBuffer();
emf.writeBYTE(EMF_PLUS.getBytes());
emf.writeTag(tag, true);
int len = emf.popBuffer();
emf.writeDWORD(len);
emf.append();
} else {
emf.writeDWORD(bytes.length);
emf.writeBYTE(bytes);
if (bytes.length % 4 != 0) {
for (int i = 0; i < 4 - bytes.length % 4; i++) {
emf.writeBYTE(0);
}
}
}
}
public String toString() {
StringBuffer sb = new StringBuffer(super.toString());
sb.append("\n");
sb.append(" length: ");
sb.append(bytes.length);
sb.append("\n");
String s = new String(bytes);
if (s.startsWith(EMF_PLUS)) {
try {
EMFInputStream emf = new EMFInputStream(new ByteArrayInputStream(bytes, 4, bytes.length-4), 0x4001);
sb.append(" --> Embedding:\n");
Tag emfPlusTag = emf.readTag();
while (emfPlusTag != null) {
sb.append(emfPlusTag);
emfPlusTag = emf.readTag();
if (emfPlusTag != null) sb.append("\n");
}
emf.close();
} catch (IOException e) {
System.err.println(e);
}
} else {
int n = Math.min(bytes.length, 40);
sb.append(" bytes: ");
for (int i=0; i