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="fonts-0.95.cs" />
<include name="graphics.cs" />
<include name="composite.cs" />
<include name="images.cs" />
<include name="native.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;
}
internal static Brush CreateBrush(java.awt.Color color)
{
return new SolidBrush(Color.FromArgb(color.getRGB()));
}
internal static LineJoin ConvertLineJoin(int join)
{
switch (join)

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

@ -163,7 +163,8 @@ namespace ikvm.awt
private Font netfont;
private Brush brush;
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)
{
@ -175,6 +176,7 @@ namespace ikvm.awt
netfont = font.getNetFont();
this.color = fgcolor;
this.bgcolor = bgcolor;
composite = CompositeHelper.Create(javaComposite, g);
init(g);
}
@ -190,6 +192,7 @@ namespace ikvm.awt
graphics.PixelOffsetMode = g.PixelOffsetMode;
graphics.TextRenderingHint = g.TextRenderingHint;
graphics.InterpolationMode = g.InterpolationMode;
graphics.CompositingMode = g.CompositingMode;
}
g = graphics;
brush = new SolidBrush(color);
@ -268,14 +271,12 @@ namespace ikvm.awt
return false;
}
Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1);
Rectangle srcRect = new Rectangle(sx1, sy1, sx2 - sx1, sy2 - sy1);
using (Brush brush = J2C.CreateBrush(color))
{
using (Brush brush = new SolidBrush(composite.GetColor(color))) {
g.FillRectangle(brush, destRect);
}
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;
}
@ -288,10 +289,9 @@ namespace ikvm.awt
return false;
}
Rectangle destRect = new Rectangle(dx1, dy1, dx2 - dx1, dy2 - dy1);
Rectangle srcRect = new Rectangle(sx1, sy1, sx2 - sx1, sy2 - sy1);
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;
}
@ -303,36 +303,22 @@ namespace ikvm.awt
{
return false;
}
using (Brush brush = J2C.CreateBrush(bgcolor))
{
g.FillRectangle(brush, x, y, width, height);
}
using (Brush brush = new SolidBrush(composite.GetColor(bgcolor))) {
g.FillRectangle(brush, x, y, width, height);
}
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;
}
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 (image == null)
{
return false;
}
if (bgcolor != null)
{
using (Brush brush = J2C.CreateBrush(bgcolor))
{
g.FillRectangle(brush, x, y, image.Width, image.Height);
}
if (img == null) {
return false;
}
lock (image)
{
g.DrawImage(image, x, y);
}
return true;
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), bgcolor, 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)
{
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;
}
public override bool drawImage(java.awt.Image img, int x, int y, java.awt.image.ImageObserver observer)
{
Image image = J2C.ConvertImage(img);
if (image == null)
{
return false;
}
lock (image)
{
g.DrawImage(image, x, y);
}
return true;
if (img == null) {
return false;
}
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
}
public override void drawLine(int x1, int y1, int x2, int y2)
@ -533,7 +513,7 @@ namespace ikvm.awt
{
if (javaColor == null)
{
javaColor = new java.awt.Color(color.ToArgb());
javaColor = composite.GetColor(color);
}
return javaColor;
}
@ -580,7 +560,7 @@ namespace ikvm.awt
return;
}
this.javaPaint = this.javaColor = color;
this.color = Color.FromArgb(color.getRGB());
this.color = composite.GetColor(color);
if (brush is SolidBrush)
{
((SolidBrush)brush).Color = this.color;
@ -736,7 +716,11 @@ namespace ikvm.awt
{
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)
@ -762,16 +746,16 @@ namespace ikvm.awt
linear = new LinearGradientBrush(
J2C.ConvertPoint(gradient.getPoint1()),
J2C.ConvertPoint(gradient.getPoint2()),
J2C.ConvertColor(gradient.getColor1()),
J2C.ConvertColor(gradient.getColor2()));
composite.GetColor(gradient.getColor1()),
composite.GetColor(gradient.getColor2()));
}
else
{
//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
// a exact solution will calculate the size of the Graphics with the current transform
Color color1 = J2C.ConvertColor(gradient.getColor1());
Color color2 = J2C.ConvertColor(gradient.getColor2());
Color color1 = composite.GetColor(gradient.getColor1());
Color color2 = composite.GetColor(gradient.getColor2());
float x1 = (float)gradient.getPoint1().getX();
float x2 = (float)gradient.getPoint2().getX();
float y1 = (float)gradient.getPoint1().getY();
@ -805,7 +789,8 @@ namespace ikvm.awt
java.awt.TexturePaint texture = (java.awt.TexturePaint)paint;
brush = new TextureBrush(
J2C.ConvertImage(texture.getImage()),
J2C.ConvertRect(texture.getAnchorRect()));
J2C.ConvertRect(texture.getAnchorRect()),
composite.GetImageAttributes());
pen.Brush = brush;
return;
}
@ -838,18 +823,18 @@ namespace ikvm.awt
float[] fractions = gradient.getFractions();
float[] positions = colorBlend.Positions;
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);
}
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;
} else {
colorBlend = new ColorBlend(javaColors.Length);
colors = colorBlend.Colors;
colorBlend.Positions = gradient.getFractions();
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]);
@ -1188,24 +1173,24 @@ namespace ikvm.awt
public override java.awt.Paint getPaint()
{
if( javaPaint == null ) {
javaPaint = new java.awt.Color(color.ToArgb());
javaPaint = composite.GetColor(color);
}
return javaPaint;
}
public override java.awt.Composite getComposite()
{
return composite;
return javaComposite;
}
public override void setBackground(java.awt.Color color)
{
bgcolor = J2C.ConvertColor(color);
bgcolor = composite.GetColor(color);
}
public override java.awt.Color getBackground()
{
return C2J.ConvertColor(bgcolor);
return composite.GetColor(bgcolor);
}
public override java.awt.Stroke getStroke()