5
// Jonathan Pobst <monkey@jpobst.com>
7
// Copyright (c) 2010 Jonathan Pobst
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34
public ImageSurface Surface { get; set; }
35
public double Opacity { get; set; }
36
public bool Hidden { get; set; }
37
public string Name { get; set; }
38
public bool Tiled { get; set; }
39
public PointD Offset { get; set; }
41
public Layer () : this (null)
45
public Layer (ImageSurface surface) : this (surface, false, 1f, "")
49
public Layer (ImageSurface surface, bool hidden, double opacity, string name)
55
Offset = new PointD (0, 0);
60
using (Context g = new Context (Surface)) {
61
g.Operator = Operator.Clear;
66
public void FlipHorizontal ()
68
Layer dest = PintaCore.Layers.CreateLayer ();
70
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
71
g.Matrix = new Matrix (-1, 0, 0, 1, Surface.Width, 0);
72
g.SetSource (Surface);
77
Surface old = Surface;
78
Surface = dest.Surface;
79
(old as IDisposable).Dispose ();
82
public void FlipVertical ()
84
Layer dest = PintaCore.Layers.CreateLayer ();
86
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
87
g.Matrix = new Matrix (1, 0, 0, -1, 0, Surface.Height);
88
g.SetSource (Surface);
93
Surface old = Surface;
94
Surface = dest.Surface;
95
(old as IDisposable).Dispose ();
98
public void Rotate180 ()
100
Layer dest = PintaCore.Layers.CreateLayer ();
102
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
103
g.Matrix = new Matrix (-1, 0, 0, -1, Surface.Width, Surface.Height);
104
g.SetSource (Surface);
109
Surface old = Surface;
110
Surface = dest.Surface;
111
(old as IDisposable).Dispose ();
114
public void Rotate90CW ()
116
double w = PintaCore.Workspace.ImageSize.X;
117
double h = PintaCore.Workspace.ImageSize.Y;
119
Layer dest = PintaCore.Layers.CreateLayer ("", (int)h, (int)w);
121
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
122
g.Translate (h / 2, w / 2);
123
g.Rotate (Math.PI / 2);
124
g.Translate (-w / 2, -h / 2);
125
g.SetSource (Surface);
130
Surface old = Surface;
131
Surface = dest.Surface;
132
(old as IDisposable).Dispose ();
135
public void Rotate90CCW ()
137
double w = PintaCore.Workspace.ImageSize.X;
138
double h = PintaCore.Workspace.ImageSize.Y;
140
Layer dest = PintaCore.Layers.CreateLayer ("", (int)h, (int)w);
142
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
143
g.Translate (h / 2, w / 2);
144
g.Rotate (Math.PI / -2);
145
g.Translate (-w / 2, -h / 2);
146
g.SetSource (Surface);
151
Surface old = Surface;
152
Surface = dest.Surface;
153
(old as IDisposable).Dispose ();
156
public unsafe void Sepia ()
160
UnaryPixelOp op = new UnaryPixelOps.Level(
163
new float[] { 1.2f, 1.0f, 0.8f },
167
ImageSurface dest = Surface.Clone ();
169
ColorBgra* dstPtr = (ColorBgra*)dest.DataPtr;
170
int len = Surface.Data.Length / 4;
172
op.Apply (dstPtr, len);
174
using (Context g = new Context (Surface)) {
175
g.AppendPath (PintaCore.Layers.SelectionPath);
176
g.FillRule = FillRule.EvenOdd;
183
(dest as IDisposable).Dispose ();
186
public unsafe void Invert ()
188
ImageSurface dest = Surface.Clone ();
190
ColorBgra* dstPtr = (ColorBgra*)dest.DataPtr;
191
int len = Surface.Data.Length / 4;
193
for (int i = 0; i < len; i++) {
195
*dstPtr = (ColorBgra.FromBgra((byte)(255 - dstPtr->B), (byte)(255 - dstPtr->G), (byte)(255 - dstPtr->R), dstPtr->A));
199
using (Context g = new Context (Surface)) {
200
g.AppendPath (PintaCore.Layers.SelectionPath);
201
g.FillRule = FillRule.EvenOdd;
208
(dest as IDisposable).Dispose ();
211
public unsafe void Desaturate ()
213
ImageSurface dest = Surface.Clone ();
215
ColorBgra* dstPtr = (ColorBgra*)dest.DataPtr;
216
int len = Surface.Data.Length / 4;
218
for (int i = 0; i < len; i++) {
219
byte ib = dstPtr->GetIntensityByte();
227
using (Context g = new Context (Surface)) {
228
g.AppendPath (PintaCore.Layers.SelectionPath);
229
g.FillRule = FillRule.EvenOdd;
236
(dest as IDisposable).Dispose ();
239
public unsafe void AutoLevel ()
241
ImageSurface dest = Surface.Clone ();
242
ColorBgra* dstPtr = (ColorBgra*)dest.DataPtr;
243
ColorBgra* srcPtr = (ColorBgra*)Surface.DataPtr;
245
int len = Surface.Data.Length / 4;
247
UnaryPixelOps.Level levels = null;
249
HistogramRgb histogram = new HistogramRgb();
250
histogram.UpdateHistogram (Surface, new Rectangle (0, 0, Surface.Width, Surface.Height));
251
levels = histogram.MakeLevelsAuto();
254
levels.Apply (dstPtr, srcPtr, len);
256
using (Context g = new Context (Surface)) {
257
g.AppendPath (PintaCore.Layers.SelectionPath);
258
g.FillRule = FillRule.EvenOdd;
265
(dest as IDisposable).Dispose ();
268
public void Resize (int width, int height)
270
ImageSurface dest = new ImageSurface (Format.Argb32, width, height);
272
using (Context g = new Context (dest)) {
273
g.Scale ((double)width / (double)Surface.Width, (double)height / (double)Surface.Height);
274
g.SetSourceSurface (Surface, 0, 0);
278
(Surface as IDisposable).Dispose ();
282
public void ResizeCanvas (int width, int height, Anchor anchor)
284
ImageSurface dest = new ImageSurface (Format.Argb32, width, height);
286
int delta_x = Surface.Width - width;
287
int delta_y = Surface.Height - height;
289
using (Context g = new Context (dest)) {
292
g.SetSourceSurface (Surface, 0, 0);
295
g.SetSourceSurface (Surface, -delta_x / 2, 0);
298
g.SetSourceSurface (Surface, -delta_x, 0);
301
g.SetSourceSurface (Surface, -delta_x, -delta_y / 2);
304
g.SetSourceSurface (Surface, -delta_x, -delta_y);
307
g.SetSourceSurface (Surface, -delta_x / 2, -delta_y);
310
g.SetSourceSurface (Surface, 0, -delta_y);
313
g.SetSourceSurface (Surface, 0, -delta_y / 2);
316
g.SetSourceSurface (Surface, -delta_x / 2, -delta_y / 2);
323
(Surface as IDisposable).Dispose ();
327
public void Crop (Rectangle rect)
329
ImageSurface dest = new ImageSurface (Format.Argb32, (int)rect.Width, (int)rect.Height);
331
using (Context g = new Context (dest)) {
332
g.SetSourceSurface (Surface, -(int)rect.X, -(int)rect.Y);
336
(Surface as IDisposable).Dispose ();