1 /**
2  * Copyright: Mike Wey 2011
3  * License:   zlib (See accompanying LICENSE file)
4  * Authors:   Mike Wey
5  * 
6  * A montage is a single image which is composed of thumbnail images
7  * composed in a uniform grid. The size of the montage image is determined
8  * by the size of the individual thumbnails and the number of rows and
9  * columns in the grid.
10  */
11 
12 module dmagick.Montage;
13 
14 import std.conv;
15 
16 import dmagick.Color;
17 import dmagick.Geometry;
18 import dmagick.Utils;
19 
20 import dmagick.c.geometry;
21 import dmagick.c.memory;
22 import dmagick.c.montage;
23 
24 /**
25  * Montage is used to provide montage options and provides methods
26  * to set all options required to render simple (unframed) montages.
27  */
28 class Montage
29 {
30 	alias RefCounted!( DestroyMontageInfo, MontageInfo ) MontageInfoRef;
31 
32 	MontageInfoRef montageInfoRef;
33 
34 	/** */
35 	this()
36 	{
37 		montageInfoRef = MontageInfoRef(cast(MontageInfo*)AcquireMagickMemory(MontageInfo.sizeof));
38 	}
39 
40 	/**
41 	 * Specifies the background color that thumbnails are imaged upon.
42 	 */
43 	void backgroundColor(Color color)
44 	{
45 		montageInfoRef.background_color = color.pixelPacket;
46 	}
47 	///ditto
48 	Color backgroundColor()
49 	{
50 		return new Color(montageInfoRef.background_color);
51 	}
52 
53 	/**
54 	 * Specifies the maximum number of columns in the montage.
55 	 */
56 	void columns(size_t columns)
57 	{
58 		Geometry size;
59 
60 		if ( montageInfoRef.tile !is null )
61 			size = Geometry( to!(string)(montageInfoRef.tile) );
62 
63 		size.width = columns;
64 	}
65 	///ditto
66 	size_t columns()
67 	{
68 		Geometry size;
69 
70 		if ( montageInfoRef.tile !is null )
71 			size = Geometry( to!(string)(montageInfoRef.tile) );
72 
73 		return size.width;
74 	}
75 
76 	/**
77 	 * Specifies the fill color to use for the label text.
78 	 */
79 	void fillColor(Color color)
80 	{
81 		montageInfoRef.fill = color.pixelPacket;
82 	}
83 	///ditto
84 	Color fillColor()
85 	{
86 		return new Color(montageInfoRef.fill);
87 	}
88 
89 	/**
90 	 * Specifies the thumbnail label font.
91 	 */
92 	void font(string font)
93 	{
94 		copyString(montageInfoRef.font, font);
95 	}
96 	///ditto
97 	string font()
98 	{
99 		return to!(string)(montageInfoRef.font);
100 	}
101 
102 	/**
103 	 * Specifies the size of the generated thumbnail.
104 	 */
105 	void geometry(Geometry geometry)
106 	{
107 		copyString(montageInfoRef.geometry, geometry.toString());
108 	}
109 	///ditto
110 	Geometry geometry()
111 	{
112 		return Geometry( to!(string)(montageInfoRef.geometry) );
113 	}
114 
115 	/**
116 	 * Specifies the thumbnail positioning within the specified geometry
117 	 * area. If the thumbnail is smaller in any dimension than the geometry,
118 	 * then it is placed according to this specification.
119 	 */
120 	void gravity(GravityType gravity)
121 	{
122 		montageInfoRef.gravity = gravity;
123 	}
124 	///ditto
125 	GravityType gravity()
126 	{
127 		return montageInfoRef.gravity;
128 	}
129 
130 	/**
131 	 * Specifies the format used for the image label. Special format
132 	 * characters may be embedded in the format string to include
133 	 * information about the image.
134 	 * 
135 	 * See_Also: dmagick.Image.Image.annotate for the format characters.
136 	 */
137 	void label(string label)
138 	{
139 		copyString(montageInfoRef.title, label);
140 	}
141 	///ditto
142 	string label()
143 	{
144 		return to!(string)(montageInfoRef.title);
145 	}
146 
147 	/**
148 	 * Specifies the thumbnail label font size.
149 	 */
150 	void pointSize(double size)
151 	{
152 		montageInfoRef.pointsize = size;
153 	}
154 	///ditto
155 	double pointSize()
156 	{
157 		return montageInfoRef.pointsize;
158 	}
159 
160 	/**
161 	 * Specifies the maximum number of rows in the montage.
162 	 */
163 	void rows(size_t rows)
164 	{
165 		Geometry size;
166 
167 		if ( montageInfoRef.tile !is null )
168 			size = Geometry( to!(string)(montageInfoRef.tile) );
169 
170 		size.height = rows;
171 	}
172 	///ditto
173 	size_t rows()
174 	{
175 		Geometry size;
176 
177 		if ( montageInfoRef.tile !is null )
178 			size = Geometry( to!(string)(montageInfoRef.tile) );
179 
180 		return size.height;
181 	}
182 
183 	/**
184 	 * Enable/disable drop-shadow on thumbnails.
185 	 */
186 	void shadow(bool shadow)
187 	{
188 		montageInfoRef.shadow = shadow;
189 	}
190 	///ditto
191 	bool shadow()
192 	{
193 		return montageInfoRef.shadow == 1;
194 	}
195 
196 	/**
197 	 * Specifies the stroke color to use for the label text.
198 	 */
199 	void strokeColor(Color color)
200 	{
201 		montageInfoRef.stroke = color.pixelPacket;
202 	}
203 	///ditto
204 	Color strokeColor()
205 	{
206 		return new Color(montageInfoRef.stroke);
207 	}
208 
209 	/**
210 	 * Specifies a texture image to use as montage background. The built-in
211 	 * textures "$(D granite:)" and "$(D plasma:)" are available. A texture
212 	 * is the same as a background image.
213 	 */
214 	void texture(string texture)
215 	{
216 		copyString(montageInfoRef.texture, texture);
217 	}
218 	///ditto
219 	string texture()
220 	{
221 		return to!(string)(montageInfoRef.texture);
222 	}
223 }
224 
225 /**
226  * MontageFramed provides the means to specify montage options when it is
227  * desired to have decorative frames around the image thumbnails.
228  */
229 class MontageFramed : Montage
230 {
231 	/**
232 	 * Construct the info to use for a framed montage.
233 	 * 
234 	 * Params:
235 	 *     frameGeometry = The size portion indicates the width and height
236 	 *         of the frame. If no offsets are given then the border
237 	 *         added is a solid color. Offsets x and y, if present,
238 	 *         specify that the width and height of the border is
239 	 *         partitioned to form an outer bevel of thickness x
240 	 *         pixels and an inner bevel of thickness y pixels.
241 	 *         Negative offsets make no sense as frame arguments.
242 	 */
243 	this(Geometry frameGeometry)
244 	{
245 		super();
246 
247 		this.frameGeometry = frameGeometry;
248 	}
249 
250 	/**
251 	 * Specifies the background color within the thumbnail frame.
252 	 */
253 	void borderColor(Color color)
254 	{
255 		montageInfoRef.background_color = color.pixelPacket;
256 	}
257 	///ditto
258 	Color borderColor()
259 	{
260 		return new Color(montageInfoRef.background_color);
261 	}
262 
263 	/**
264 	 * Specifies the border to place between a thumbnail and its surrounding
265 	 * frame. This option only takes effect if geometry specification
266 	 * doesn't also specify the thumbnail border width.
267 	 */
268 	void borderWidth(size_t width)
269 	{
270 		montageInfoRef.border_width = width;
271 	}
272 	///ditto
273 	size_t borderWidth()
274 	{
275 		return montageInfoRef.border_width;
276 	}
277 
278 	/**
279 	 * Specifies the geometry specification for frame to place around
280 	 * thumbnail. If this parameter is not specified, then the montage is
281 	 * unframed.
282 	 * 
283 	 * Params:
284 	 *     geometry = The size portion indicates the width and height of
285 	 *                the frame. If no offsets are given then the border
286 	 *                added is a solid color. Offsets x and y, if present,
287 	 *                specify that the width and height of the border is
288 	 *                partitioned to form an outer bevel of thickness x
289 	 *                pixels and an inner bevel of thickness y pixels.
290 	 *                Negative offsets make no sense as frame arguments.
291 	 */
292 	void frameGeometry(Geometry geometry)
293 	{
294 		copyString(montageInfoRef.frame, geometry.toString());
295 	}
296 	///ditto
297 	Geometry frameGeometry()
298 	{
299 		return Geometry( to!(string)(montageInfoRef.frame));
300 	}
301 
302 	void matteColor(Color color)
303 	{
304 		montageInfoRef.matte_color = color.pixelPacket;
305 	}
306 	///ditto
307 	Color matteColor()
308 	{
309 		return new Color(montageInfoRef.matte_color);
310 	}
311 }