xref: /haiku/src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp (revision 89f1fd6512c10854013d231a85289797e47c7543)
1 /*
2 * Copyright 2010, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Michael Pfeiffer
7 */
8 #include "GPParameterVisitor.h"
9 
10 #include <String.h>
11 
12 
13 const char* kJobMode = "JobMode";
14 const char* kJob = "Job";
15 
16 const char* kPrintingMode = "PrintingMode";
17 const char* kColor = "Color";
18 const char* kBlackAndWhite = "BW";
19 
20 const char* kResolution = "Resolution";
21 const char* kFakeResolutionKey = "";
22 
23 const char* kPageSize = "PageSize";
24 
25 const char* kChannelBitDepth = "ChannelBitDepth";
26 
27 
GPParameterVisitor()28 GPParameterVisitor::GPParameterVisitor()
29 	:
30 	fVariables(NULL),
31 	fHasResolutionParameter(false)
32 {
33 }
34 
35 
~GPParameterVisitor()36 GPParameterVisitor::~GPParameterVisitor()
37 {
38 }
39 
40 
41 void
Visit(const stp_printer_t * printer)42 GPParameterVisitor::Visit(const stp_printer_t* printer)
43 {
44 	// this code is based on Gutenprint printer_options.c
45 	const stp_vars_t* defaultVariables = stp_printer_get_defaults(printer);
46 	stp_vars_t* variables = stp_vars_create_copy(defaultVariables);
47 	fVariables = variables;
48 
49 	stp_set_string_parameter(variables, kJobMode, kJob);
50 
51 	stp_parameter_t printingMode;
52 	stp_describe_parameter(variables, kPrintingMode, &printingMode);
53 	bool isColorPrinter = stp_string_list_is_present(printingMode.bounds.str,
54 		kColor) != 0;
55 	stp_parameter_description_destroy(&printingMode);
56 
57 	if (isColorPrinter)
58 		stp_set_string_parameter(variables, kPrintingMode, kColor);
59 	else
60 		stp_set_string_parameter(variables, kPrintingMode, kBlackAndWhite);
61 
62 	stp_set_string_parameter(variables, kChannelBitDepth, "8");
63 
64 	stp_parameter_list_t list = stp_get_parameter_list(variables);
65 	int size = stp_parameter_list_count(list);
66 
67 	for (int i = 0; i < size; i ++) {
68 		const stp_parameter_t* parameter = stp_parameter_list_param(list, i);
69 		stp_parameter_t description;
70 		stp_describe_parameter(fVariables, parameter->name, &description);
71 		VisitParameter(list, parameter, &description);
72 		stp_parameter_description_destroy(&description);
73 	}
74 
75 	// TODO check if this can really happen
76 	if (!fHasResolutionParameter) {
77 		AddMissingResolution();
78 	}
79 
80 	EndVisit();
81 
82 	stp_parameter_list_destroy(list);
83 	stp_vars_destroy(variables);
84 	fVariables = NULL;
85 }
86 
87 
88 void
AddMissingResolution()89 GPParameterVisitor::AddMissingResolution()
90 {
91 	// some printer definitions don't have resolution parameter
92 	// however "libprint" needs to know it for rasterization
93 
94 	// TODO find out if other parameters influence the resolution
95 	// e.g. color vs black and white
96 	int x, y;
97 	stp_describe_resolution(fVariables, &x, &y);
98 
99 	BeginParameter(kResolution, "Resolution", STP_PARAMETER_CLASS_FEATURE);
100 	DefaultStringParameter(kResolution, kFakeResolutionKey);
101 	StringParameterSize(kResolution, 1);
102 
103 	if (x <= 0 || y <= 0) {
104 		// TODO decide if more resolutions (150, 600) should be possible
105 		x = 300;
106 		y = 300;
107 	}
108 
109 	BString displayName;
110 	if (x != y)
111 		displayName << x << " x " << y << " DPI";
112 	else
113 		displayName << x << " DPI";
114 
115 	ResolutionParameter(kResolution, kFakeResolutionKey, displayName.String(),
116 		x, y);
117 
118 	EndParameter(kResolution);
119 }
120 
121 
122 void
VisitParameter(stp_parameter_list_t list,const stp_parameter_t * parameter,stp_parameter_t * description)123 GPParameterVisitor::VisitParameter(stp_parameter_list_t list,
124 	const stp_parameter_t* parameter, stp_parameter_t* description)
125 {
126 	// TODO decide which parameters should be revealed to user
127 	// e.g. up to STP_PARAMETER_LEVEL_ADVANCED4;
128 	// const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_ADVANCED4;
129 	const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_BASIC;
130 	stp_parameter_class_t parameterClass = parameter->p_class;
131 	if (parameter->read_only ||
132 		(parameter->p_level > kMaxLevel
133 			&& strcmp(parameter->name, kResolution) != 0)
134 		|| (parameterClass != STP_PARAMETER_CLASS_OUTPUT
135 			&& parameterClass != STP_PARAMETER_CLASS_CORE
136 			&& parameterClass != STP_PARAMETER_CLASS_FEATURE))
137 		return;
138 
139 	if (!description->is_active)
140 		return;
141 
142 	switch (description->p_type) {
143 		case STP_PARAMETER_TYPE_STRING_LIST:
144 			if (!BeginParameter(description->name, description->text,
145 				parameterClass))
146 				return;
147 			VisitStringList(description);
148 			EndParameter(description->name);
149 			break;
150 
151 		case STP_PARAMETER_TYPE_BOOLEAN:
152 			VisitBooleanParameter(description, parameterClass);
153 			break;
154 
155 		case STP_PARAMETER_TYPE_DOUBLE:
156 			VisitDoubleParameter(description, parameterClass);
157 			break;
158 
159 		case STP_PARAMETER_TYPE_INT:
160 			VisitIntParameter(description, parameterClass);
161 			break;
162 
163 		case STP_PARAMETER_TYPE_DIMENSION:
164 			VisitDimensionParameter(description, parameterClass);
165 			break;
166 
167 		default:
168 			break;
169 	}
170 
171 }
172 
173 
174 void
VisitStringList(stp_parameter_t * parameter)175 GPParameterVisitor::VisitStringList(stp_parameter_t* parameter)
176 {
177 	stp_string_list_t* list = parameter->bounds.str;
178 	int count = stp_string_list_count(list);
179 	if (count <= 0)
180 		return;
181 
182 	const char* name = parameter->name;
183 	if (parameter->is_mandatory)
184 		DefaultStringParameter(name, parameter->deflt.str);
185 	else
186 		DefaultStringParameter(name, NULL);
187 
188 	StringParameterSize(name, count);
189 
190 	for (int i = 0; i < count; i ++) {
191 		const stp_param_string_t* entry = stp_string_list_param(list, i);
192 		const char* key = entry->name;
193 		const char* displayName = entry->text;
194 		if (strcmp(name, kResolution) == 0) {
195 			stp_set_string_parameter(fVariables, kResolution, key);
196 
197 			int x, y;
198 			stp_describe_resolution(fVariables, &x, &y);
199 
200 			ResolutionParameter(name, key, displayName, x, y);
201 
202 			fHasResolutionParameter = true;
203 		} else if (strcmp(name, kPageSize) == 0) {
204 			stp_set_string_parameter(fVariables, kPageSize, key);
205 
206 			stp_dimension_t width;
207 			stp_dimension_t height;
208 			stp_get_media_size(fVariables, &width, &height);
209 			BSize pageSize(width, height);
210 
211 			stp_dimension_t left, right, top, bottom;
212 			stp_get_imageable_area(fVariables, &left, &right, &bottom, &top);
213 			BRect imageableArea(left, top, right, bottom);
214 
215 			PageSizeParameter(name, key, displayName, pageSize, imageableArea);
216 		} else {
217 			StringParameter(name, key, displayName);
218 		}
219 	}
220 }
221 
222 
223 void
VisitBooleanParameter(stp_parameter_t * description,stp_parameter_class_t parameterClass)224 GPParameterVisitor::VisitBooleanParameter(stp_parameter_t* description,
225 	stp_parameter_class_t parameterClass)
226 {
227 	bool defaultValue = true;
228 	if (description->is_mandatory)
229 		defaultValue = description->deflt.boolean;
230 	BooleanParameter(description->name, description->text, defaultValue,
231 		parameterClass);
232 }
233 
234 
235 void
VisitDoubleParameter(stp_parameter_t * description,stp_parameter_class_t parameterClass)236 GPParameterVisitor::VisitDoubleParameter(stp_parameter_t* description,
237 			stp_parameter_class_t parameterClass)
238 {
239 	const char* name = description->name;
240 	const char* text = description->text;
241 	double lower = description->bounds.dbl.lower;
242 	double upper = description->bounds.dbl.upper;
243 	double defaultValue = description->deflt.dbl;
244 	if (lower <= defaultValue && defaultValue <= upper)
245 		DoubleParameter(name, text, lower, upper, defaultValue, parameterClass);
246 }
247 
248 
249 void
VisitIntParameter(stp_parameter_t * description,stp_parameter_class_t parameterClass)250 GPParameterVisitor::VisitIntParameter(stp_parameter_t* description,
251 			stp_parameter_class_t parameterClass)
252 {
253 	const char* name = description->name;
254 	const char* text = description->text;
255 	int lower = description->bounds.integer.lower;
256 	int upper = description->bounds.integer.upper;
257 	int defaultValue = description->deflt.integer;
258 	if (lower <= defaultValue && defaultValue <= upper)
259 		IntParameter(name, text, lower, upper, defaultValue, parameterClass);
260 }
261 
262 
263 void
VisitDimensionParameter(stp_parameter_t * description,stp_parameter_class_t parameterClass)264 GPParameterVisitor::VisitDimensionParameter(stp_parameter_t* description,
265 			stp_parameter_class_t parameterClass)
266 {
267 	const char* name = description->name;
268 	const char* text = description->text;
269 	double lower = description->bounds.dimension.lower;
270 	double upper = description->bounds.dimension.upper;
271 	double defaultValue = description->deflt.dimension;
272 	if (lower <= defaultValue && defaultValue <= upper)
273 		DimensionParameter(name, text, lower, upper, defaultValue,
274 			parameterClass);
275 }
276