summaryrefslogtreecommitdiff
path: root/dmagick/Geometry.d
blob: 0547f49e5da2ff59c1cc9c01b73df69c34538cc6 (plain)
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
/**
 * A class to specify a geometry argument.
 *
 * Copyright: Mike Wey 2011
 * License:   To be determined
 * Authors:   Mike Wey
 */

module dmagick.Geometry;

import std.conv;
import std.ctype;
import std.string;
import core.sys.posix.sys.types;

import dmagick.c.geometry;
import dmagick.c.magickString;
import dmagick.c.magickType;

struct Geometry
{
	size_t width;
	size_t height;
	ssize_t xOffset;
	ssize_t yOffset;
	bool percent;
	bool minimum;
	bool keepAspect = true;
	bool greater;
	bool less;

	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(size_t width, size_t height, ssize_t xOffset, ssize_t yOffset)
	{
		this.width   = width;
		this.height  = height;
		this.xOffset = xOffset;
		this.yOffset = yOffset;
	}

	string toString()
	{
		string geometry;

		if ( width > 0 )
			geometry ~= to!(string)(width);

		if ( height > 0 )
			geometry ~= "x" ~ to!(string)(height);

		if ( xOffset != 0 && yOffset != 0 )
			geometry ~= format("%+s%+s", xOffset, yOffset);

		geometry ~= format("%s%s%s%s%s",
			percent ? "%" : "",
			minimum ? "^" : "",
			keepAspect ? "" : "!",
			less ? "<" : "",
			greater ? ">" : "");

		return geometry;
	}

	unittest
	{
		Geometry geo = Geometry("200x150-50+25!");
		assert( geo.toString == "200x150-50+25!");
	}

	int opCmp(ref const Geometry geometry)
	{
		return width*height - geometry.width*geometry.height;
	}
}