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