Implementation for some of alpha composite blending

This commit is contained in:
smallsql 2010-11-01 12:30:14 +00:00
Родитель c7c7ca100c
Коммит 71210ee5d7
4 изменённых файлов: 183 добавлений и 59 удалений

Просмотреть файл

@ -34,6 +34,7 @@
<include name="converter.cs" /> <include name="converter.cs" />
<include name="fonts-0.95.cs" /> <include name="fonts-0.95.cs" />
<include name="graphics.cs" /> <include name="graphics.cs" />
<include name="composite.cs" />
<include name="images.cs" /> <include name="images.cs" />
<include name="native.cs" /> <include name="native.cs" />
<include name="printing.cs" /> <include name="printing.cs" />

143
awt/composite.cs Normal file
Просмотреть файл

@ -0,0 +1,143 @@
/*
Copyright (C) 2010 Volker Berlin (i-net software)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace ikvm.awt {
internal class CompositeHelper {
private readonly ImageAttributes imageAttributes = new ImageAttributes();
/// <summary>
/// Create a default CompositeHelper. Is used from Create only.
/// </summary>
protected CompositeHelper() {
}
internal static CompositeHelper Create(java.awt.Composite comp, Graphics graphics){
if (comp is java.awt.AlphaComposite) {
var alphaComp = (java.awt.AlphaComposite)comp;
var alpha = alphaComp.getAlpha();
switch (alphaComp.getRule()) {
case java.awt.AlphaComposite.CLEAR:
graphics.CompositingMode = CompositingMode.SourceCopy;
return new ClearCompositeHelper();
case java.awt.AlphaComposite.SRC:
graphics.CompositingMode = CompositingMode.SourceCopy;
break;
case java.awt.AlphaComposite.SRC_OVER:
graphics.CompositingMode = CompositingMode.SourceOver;
break;
case java.awt.AlphaComposite.DST:
graphics.CompositingMode = CompositingMode.SourceOver;
alpha = 0.0F;
break;
default:
graphics.CompositingMode = CompositingMode.SourceOver;
Console.Error.WriteLine("AlphaComposite with Rule " + alphaComp.getRule() + " not supported.");
break;
}
if (alpha == 1.0) {
return new CompositeHelper();
} else {
return new AlphaCompositeHelper(alpha);
}
} else {
graphics.CompositingMode = CompositingMode.SourceOver;
Console.Error.WriteLine("Composite not supported: " + comp.GetType().FullName);
return new CompositeHelper();
}
}
internal virtual int GetArgb(java.awt.Color color) {
return color.getRGB();
}
internal virtual Color GetColor( java.awt.Color color ){
return color == null ? Color.Empty : Color.FromArgb(GetArgb(color));
}
internal virtual int ToArgb(Color color) {
return color.ToArgb();
}
internal virtual java.awt.Color GetColor(Color color) {
return color == Color.Empty ? null : new java.awt.Color(ToArgb(color), true);
}
/// <summary>
/// Get the ImageAttributes instance. Does not change it bcause it is not a copy.
/// </summary>
/// <returns></returns>
internal virtual ImageAttributes GetImageAttributes(){
return imageAttributes;
}
}
internal sealed class AlphaCompositeHelper : CompositeHelper {
private readonly float alpha;
/// <summary>
/// Create a AlphaCompositeHelper
/// </summary>
/// <param name="alpha">a value in the range from 0.0 to 1.0</param>
internal AlphaCompositeHelper(float alpha) {
this.alpha = alpha;
var matrix = new ColorMatrix();
matrix.Matrix33 = alpha;
GetImageAttributes().SetColorMatrix(matrix);
}
internal override int GetArgb(java.awt.Color color) {
var argb = (uint)color.getRGB();
var newAlpha = (uint)((0xff000000 & argb) * alpha + 0x800000);
var newArgb = (0xff000000 & newAlpha) | (0xffffff & argb);
return (int)newArgb;
}
internal override int ToArgb(Color color) {
var argb = (uint)color.ToArgb();
var newAlpha = (uint)((0xff000000 & argb) / alpha + 0x800000);
var newArgb = (0xff000000 & newAlpha) | (0xffffff & argb);
return (int)newArgb;
}
}
internal sealed class ClearCompositeHelper : CompositeHelper {
internal ClearCompositeHelper()
{
var matrix = new ColorMatrix();
matrix.Matrix00 = matrix.Matrix11 = matrix.Matrix22 = matrix.Matrix33 = 0.0F;
GetImageAttributes().SetColorMatrix(matrix);
}
internal override int GetArgb(java.awt.Color color) {
return 0;
}
}
}

Просмотреть файл

@ -175,11 +175,6 @@ namespace ikvm.awt
return gp; return gp;
} }
internal static Brush CreateBrush(java.awt.Color color)
{
return new SolidBrush(Color.FromArgb(color.getRGB()));
}
internal static LineJoin ConvertLineJoin(int join) internal static LineJoin ConvertLineJoin(int join)
{ {
switch (join) switch (join)

Просмотреть файл

@ -163,7 +163,8 @@ namespace ikvm.awt
private Font netfont; private Font netfont;
private Brush brush; private Brush brush;
private Pen pen; private Pen pen;
private java.awt.Composite composite = java.awt.AlphaComposite.SrcOver; private CompositeHelper composite;
private java.awt.Composite javaComposite = java.awt.AlphaComposite.SrcOver;
protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor) protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor)
{ {
@ -175,6 +176,7 @@ namespace ikvm.awt
netfont = font.getNetFont(); netfont = font.getNetFont();
this.color = fgcolor; this.color = fgcolor;
this.bgcolor = bgcolor; this.bgcolor = bgcolor;
composite = CompositeHelper.Create(javaComposite, g);
init(g); init(g);
} }
@ -190,6 +192,7 @@ namespace ikvm.awt
graphics.PixelOffsetMode = g.PixelOffsetMode; graphics.PixelOffsetMode = g.PixelOffsetMode;
graphics.TextRenderingHint = g.TextRenderingHint; graphics.TextRenderingHint = g.TextRenderingHint;
graphics.InterpolationMode = g.InterpolationMode; graphics.InterpolationMode = g.InterpolationMode;
graphics.CompositingMode = g.CompositingMode;
} }
g = graphics; g = graphics;
brush = new SolidBrush(color); brush = new SolidBrush(color);
@ -268,14 +271,12 @@ namespace ikvm.awt
return false; return false;
} }
Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1); Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1);
Rectangle srcRect = new Rectangle(sx1, sy1, sx2 - sx1, sy2 - sy1); using (Brush brush = new SolidBrush(composite.GetColor(color))) {
using (Brush brush = J2C.CreateBrush(color))
{
g.FillRectangle(brush, destRect); g.FillRectangle(brush, destRect);
} }
lock (image) lock (image)
{ {
g.DrawImage(image, destRect, srcRect, GraphicsUnit.Pixel); g.DrawImage(image, destRect, sx1, sy1, sx2 - sx1, sy2 - sy1, GraphicsUnit.Pixel, composite.GetImageAttributes());
} }
return true; return true;
} }
@ -288,10 +289,9 @@ namespace ikvm.awt
return false; return false;
} }
Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1); Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1);
Rectangle srcRect = new Rectangle(sx1, sy1, sx2 - sx1, sy2 - sy1);
lock (image) lock (image)
{ {
g.DrawImage(image, destRect, srcRect, GraphicsUnit.Pixel); g.DrawImage(image, destRect, sx1, sy1, sx2 - sx1, sy2 - sy1, GraphicsUnit.Pixel, composite.GetImageAttributes());
} }
return true; return true;
} }
@ -303,36 +303,22 @@ namespace ikvm.awt
{ {
return false; return false;
} }
using (Brush brush = J2C.CreateBrush(bgcolor)) using (Brush brush = new SolidBrush(composite.GetColor(bgcolor))) {
{ g.FillRectangle(brush, x, y, width, height);
g.FillRectangle(brush, x, y, width, height); }
}
lock (image) lock (image)
{ {
g.DrawImage(image, x, y, width, height); g.DrawImage(image, new Rectangle( x, y, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, composite.GetImageAttributes());
} }
return true; return true;
} }
public override bool drawImage(java.awt.Image img, int x, int y, java.awt.Color bgcolor, java.awt.image.ImageObserver observer) public override bool drawImage(java.awt.Image img, int x, int y, java.awt.Color bgcolor, java.awt.image.ImageObserver observer)
{ {
Image image = J2C.ConvertImage(img); if (img == null) {
if (image == null) return false;
{
return false;
}
if (bgcolor != null)
{
using (Brush brush = J2C.CreateBrush(bgcolor))
{
g.FillRectangle(brush, x, y, image.Width, image.Height);
}
} }
lock (image) return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), bgcolor, observer);
{
g.DrawImage(image, x, y);
}
return true;
} }
public override bool drawImage(java.awt.Image img, int x, int y, int width, int height, java.awt.image.ImageObserver observer) public override bool drawImage(java.awt.Image img, int x, int y, int width, int height, java.awt.image.ImageObserver observer)
@ -344,23 +330,17 @@ namespace ikvm.awt
} }
lock (image) lock (image)
{ {
g.DrawImage(image, x, y, width, height); g.DrawImage(image, new Rectangle(x, y, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, composite.GetImageAttributes());
} }
return true; return true;
} }
public override bool drawImage(java.awt.Image img, int x, int y, java.awt.image.ImageObserver observer) public override bool drawImage(java.awt.Image img, int x, int y, java.awt.image.ImageObserver observer)
{ {
Image image = J2C.ConvertImage(img); if (img == null) {
if (image == null) return false;
{ }
return false; return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
}
lock (image)
{
g.DrawImage(image, x, y);
}
return true;
} }
public override void drawLine(int x1, int y1, int x2, int y2) public override void drawLine(int x1, int y1, int x2, int y2)
@ -533,7 +513,7 @@ namespace ikvm.awt
{ {
if (javaColor == null) if (javaColor == null)
{ {
javaColor = new java.awt.Color(color.ToArgb()); javaColor = composite.GetColor(color);
} }
return javaColor; return javaColor;
} }
@ -580,7 +560,7 @@ namespace ikvm.awt
return; return;
} }
this.javaPaint = this.javaColor = color; this.javaPaint = this.javaColor = color;
this.color = Color.FromArgb(color.getRGB()); this.color = composite.GetColor(color);
if (brush is SolidBrush) if (brush is SolidBrush)
{ {
((SolidBrush)brush).Color = this.color; ((SolidBrush)brush).Color = this.color;
@ -736,7 +716,11 @@ namespace ikvm.awt
{ {
throw new java.lang.IllegalArgumentException("null Composite"); throw new java.lang.IllegalArgumentException("null Composite");
} }
this.composite = comp; this.javaComposite = comp;
composite = CompositeHelper.Create(comp,g);
java.awt.Paint oldPaint = javaPaint;
javaPaint = null;
setPaint(oldPaint);
} }
public override void setPaint(java.awt.Paint paint) public override void setPaint(java.awt.Paint paint)
@ -762,16 +746,16 @@ namespace ikvm.awt
linear = new LinearGradientBrush( linear = new LinearGradientBrush(
J2C.ConvertPoint(gradient.getPoint1()), J2C.ConvertPoint(gradient.getPoint1()),
J2C.ConvertPoint(gradient.getPoint2()), J2C.ConvertPoint(gradient.getPoint2()),
J2C.ConvertColor(gradient.getColor1()), composite.GetColor(gradient.getColor1()),
J2C.ConvertColor(gradient.getColor2())); composite.GetColor(gradient.getColor2()));
} }
else else
{ {
//HACK because .NET does not support continue gradient like Java else Tile Gradient //HACK because .NET does not support continue gradient like Java else Tile Gradient
//that we receize the rectangle very large (factor z) and set 4 color values //that we receize the rectangle very large (factor z) and set 4 color values
// a exact solution will calculate the size of the Graphics with the current transform // a exact solution will calculate the size of the Graphics with the current transform
Color color1 = J2C.ConvertColor(gradient.getColor1()); Color color1 = composite.GetColor(gradient.getColor1());
Color color2 = J2C.ConvertColor(gradient.getColor2()); Color color2 = composite.GetColor(gradient.getColor2());
float x1 = (float)gradient.getPoint1().getX(); float x1 = (float)gradient.getPoint1().getX();
float x2 = (float)gradient.getPoint2().getX(); float x2 = (float)gradient.getPoint2().getX();
float y1 = (float)gradient.getPoint1().getY(); float y1 = (float)gradient.getPoint1().getY();
@ -805,7 +789,8 @@ namespace ikvm.awt
java.awt.TexturePaint texture = (java.awt.TexturePaint)paint; java.awt.TexturePaint texture = (java.awt.TexturePaint)paint;
brush = new TextureBrush( brush = new TextureBrush(
J2C.ConvertImage(texture.getImage()), J2C.ConvertImage(texture.getImage()),
J2C.ConvertRect(texture.getAnchorRect())); J2C.ConvertRect(texture.getAnchorRect()),
composite.GetImageAttributes());
pen.Brush = brush; pen.Brush = brush;
return; return;
} }
@ -838,18 +823,18 @@ namespace ikvm.awt
float[] fractions = gradient.getFractions(); float[] fractions = gradient.getFractions();
float[] positions = colorBlend.Positions; float[] positions = colorBlend.Positions;
for (int i = 0; i < javaColors.Length; i++) { for (int i = 0; i < javaColors.Length; i++) {
colors[i + 1] = J2C.ConvertColor(javaColors[i]); colors[i + 1] = composite.GetColor(javaColors[i]);
positions[i + 1] = (z + fractions[i]) / (2 * z + 1); positions[i + 1] = (z + fractions[i]) / (2 * z + 1);
} }
colors[0] = colors[1]; colors[0] = colors[1];
colors[colors.Length - 1] = colors[colors.Length - 1]; colors[colors.Length - 1] = colors[colors.Length - 2];
positions[positions.Length - 1] = 1.0f; positions[positions.Length - 1] = 1.0f;
} else { } else {
colorBlend = new ColorBlend(javaColors.Length); colorBlend = new ColorBlend(javaColors.Length);
colors = colorBlend.Colors; colors = colorBlend.Colors;
colorBlend.Positions = gradient.getFractions(); colorBlend.Positions = gradient.getFractions();
for (int i = 0; i < javaColors.Length; i++) { for (int i = 0; i < javaColors.Length; i++) {
colors[i] = J2C.ConvertColor(javaColors[i]); colors[i] = composite.GetColor(javaColors[i]);
} }
} }
LinearGradientBrush linear = new LinearGradientBrush(start, end, colors[0], colors[colors.Length - 1]); LinearGradientBrush linear = new LinearGradientBrush(start, end, colors[0], colors[colors.Length - 1]);
@ -1188,24 +1173,24 @@ namespace ikvm.awt
public override java.awt.Paint getPaint() public override java.awt.Paint getPaint()
{ {
if( javaPaint == null ) { if( javaPaint == null ) {
javaPaint = new java.awt.Color(color.ToArgb()); javaPaint = composite.GetColor(color);
} }
return javaPaint; return javaPaint;
} }
public override java.awt.Composite getComposite() public override java.awt.Composite getComposite()
{ {
return composite; return javaComposite;
} }
public override void setBackground(java.awt.Color color) public override void setBackground(java.awt.Color color)
{ {
bgcolor = J2C.ConvertColor(color); bgcolor = composite.GetColor(color);
} }
public override java.awt.Color getBackground() public override java.awt.Color getBackground()
{ {
return C2J.ConvertColor(bgcolor); return composite.GetColor(bgcolor);
} }
public override java.awt.Stroke getStroke() public override java.awt.Stroke getStroke()