1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
/**
* Copyright: Mike Wey 2011
* License: zlib (See accompanying LICENSE file)
* Authors: Mike Wey
*/
module dmagick.Geometry;
import std.conv;
import std.ascii;
import std.string;
import core.sys.posix.sys.types;
import dmagick.c.geometry;
import dmagick.c.magickString;
import dmagick.c.magickType;
/**
* Geometry provides a convenient means to specify a geometry argument.
*/
struct Geometry
{
size_t width; ///
size_t height; ///
ssize_t xOffset; ///
ssize_t yOffset; ///
bool percent; /// The width and/or height are percentages of the original.
bool minimum; /// The specified width and/or height is the minimum value.
bool keepAspect = true; ///Retain the aspect ratio.
bool greater; /// Resize only if the image is greater than the width and/or height.
bool less; /// Resize only if the image is smaller than the width and/or height.
/**
* Create a Geometry form a Imagemagick / X11 geometry string.
*/
//TODO: expand the documentation for this constructor.
this(string geometry)
{
MagickStatusType flags;
//If the string starts with a letter assume it's a Page Geometry.
if ( isAlpha(geometry[0]) )
{
char* geo = GetPageGeometry(toStringz(geometry));
if( geo !is null )
{
geometry = to!(string)(geo);
DestroyString(geo);
}
}
flags = GetGeometry(toStringz(geometry), &xOffset, &yOffset, &width, &height);
percent = ( flags & GeometryFlags.PercentValue ) != 0;
minimum = ( flags & GeometryFlags.MinimumValue ) != 0;
keepAspect = ( flags & GeometryFlags.AspectValue ) == 0;
greater = ( flags & GeometryFlags.GreaterValue ) != 0;
less = ( flags & GeometryFlags.LessValue ) != 0;
}
unittest
{
Geometry geo = Geometry("200x150-50+25!");
assert( geo.width == 200 && geo.xOffset == -50 );
assert( geo.keepAspect == false );
geo = Geometry("A4");
assert( geo.width == 595 && geo.height == 842);
}
this(RectangleInfo rectangle)
{
this.width = rectangle.width;
this.height = rectangle.height;
this.xOffset = rectangle.x;
this.yOffset = rectangle.y;
}
/**
* Initialize with width heigt and offsets.
*/
this(size_t width, size_t height, ssize_t xOffset = 0, ssize_t yOffset = 0)
{
this.width = width;
this.height = height;
this.xOffset = xOffset;
this.yOffset = yOffset;
}
/**
* Convert Geometry into a Imagemagick geometry string.
*/
string toString()
{
string geometry;
if ( width > 0 )
geometry ~= to!(string)(width);
if ( height > 0 )
geometry ~= "x" ~ to!(string)(height);
geometry ~= format("%s%s%s%s%s",
percent ? "%" : "",
minimum ? "^" : "",
keepAspect ? "" : "!",
less ? "<" : "",
greater ? ">" : "");
if ( xOffset != 0 && yOffset != 0 )
geometry ~= format("%+s%+s", xOffset, yOffset);
return geometry;
}
unittest
{
Geometry geo = Geometry("200x150!-50+25");
assert( geo.toString == "200x150!-50+25");
}
/**
* Calculate the absolute width and height based on the flags,
* and the profided width and height.
*/
Geometry toAbsolute(size_t width, size_t height)
{
ssize_t x, y;
ParseMetaGeometry(toStringz(toString()), &x, &y, &width, &height);
return Geometry(width, height, x, y);
}
unittest
{
Geometry percentage = Geometry("50%");
Geometry absolute = percentage.toAbsolute(100, 100);
assert(absolute.width == 50);
assert(absolute.height == 50);
}
RectangleInfo rectangleInfo()
{
RectangleInfo info;
info.width = width;
info.height = height;
info.x = xOffset;
info.y = yOffset;
return info;
}
size_t opCmp(ref const Geometry geometry)
{
return width*height - geometry.width*geometry.height;
}
}
|