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 28 GPParameterVisitor::GPParameterVisitor() 29 : 30 fVariables(NULL), 31 fHasResolutionParameter(false) 32 { 33 } 34 35 36 GPParameterVisitor::~GPParameterVisitor() 37 { 38 } 39 40 41 void 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 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 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 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 int width; 207 int height; 208 stp_get_media_size(fVariables, &width, &height); 209 BSize pageSize(width, height); 210 211 int 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 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 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 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 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 int lower = description->bounds.dimension.lower; 270 int upper = description->bounds.dimension.upper; 271 int defaultValue = description->deflt.dimension; 272 if (lower <= defaultValue && defaultValue <= upper) 273 DimensionParameter(name, text, lower, upper, defaultValue, 274 parameterClass); 275 } 276