1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <math.h>
20 #include "lib_printable_area.h"
21 #include "wprint_debug.h"
22 #include "../plugins/media.h"
23 
24 #define TAG "printable_area"
25 
printable_area_get(wprint_job_params_t * job_params,float top_margin,float left_margin,float right_margin,float bottom_margin)26 void printable_area_get(wprint_job_params_t *job_params, float top_margin,
27         float left_margin, float right_margin, float bottom_margin) {
28     if (job_params == NULL) return;
29 
30     job_params->printable_area_width = job_params->printable_area_height = 0.0f;
31     job_params->width = job_params->height = 0.0f;
32     job_params->page_top_margin = job_params->page_bottom_margin = 0.0f;
33     job_params->page_right_margin = job_params->page_left_margin = 0.0f;
34 
35     job_params->page_width = 0.0f;
36     job_params->page_height = 0.0f;
37     int i;
38     for (i = 0; i < SUPPORTED_MEDIA_SIZE_COUNT; i++) {
39         if (job_params->media_size == SupportedMediaSizes[i].media_size) {
40             job_params->page_width = SupportedMediaSizes[i].WidthInInches / 1000;
41             job_params->page_height = SupportedMediaSizes[i].HeightInInches / 1000;
42         }
43     }
44 
45     // Threshold value for catering slight variation b/w source dims and page dims
46     const float PAGE_SIZE_EPSILON = 0.04f;
47     if (fabsf(job_params->source_width - job_params->page_width) < PAGE_SIZE_EPSILON &&
48         fabsf(job_params->source_height - job_params->page_height) < PAGE_SIZE_EPSILON) {
49         top_margin = left_margin = right_margin = bottom_margin = 0.0f;
50         job_params->preserve_scaling = true;
51     }
52 
53     // don't adjust for margins if job is PCLm.  dimensions of image will not
54     // match (will be bigger than) the dimensions of the page size and a corrupt image will render
55     // in genPCLm
56     if (job_params->pcl_type == PCLm) {
57         if (job_params->borderless) {
58             job_params->printable_area_width = (unsigned int) _MI_TO_PIXELS(
59                     job_params->page_width * 1000, job_params->pixel_units);
60             job_params->printable_area_height = (unsigned int) _MI_TO_PIXELS(
61                     job_params->page_height * 1000, job_params->pixel_units);
62         } else {
63             job_params->printable_area_width =
64                     (unsigned int) _MI_TO_PIXELS(job_params->page_width * 1000,
65                                                  job_params->pixel_units)
66                     - floorf(left_margin * (float) job_params->pixel_units)
67                     - floorf(right_margin * (float) job_params->pixel_units);
68             job_params->printable_area_height =
69                     (unsigned int) _MI_TO_PIXELS(job_params->page_height * 1000,
70                                                  job_params->pixel_units)
71                     - floorf(top_margin * (float) job_params->pixel_units)
72                     - floorf(bottom_margin * (float) job_params->pixel_units);
73         }
74     } else {
75         job_params->printable_area_width = (unsigned int) floorf(((job_params->page_width -
76                 (left_margin + right_margin)) * (float)job_params->pixel_units));
77         job_params->printable_area_height =  (unsigned int) floorf(((job_params->page_height -
78                 (top_margin + bottom_margin)) * (float)job_params->pixel_units));
79     }
80 
81     job_params->page_top_margin = top_margin;
82     job_params->page_left_margin = left_margin;
83     job_params->page_right_margin = right_margin;
84     job_params->page_bottom_margin = bottom_margin;
85 
86     if (!job_params->borderless) {
87         if (job_params->job_top_margin > top_margin) {
88             job_params->print_top_margin = floorf(
89                     ((job_params->job_top_margin - top_margin) * (float) job_params->pixel_units));
90         } else {
91             job_params->print_top_margin = floorf(((top_margin) * (float) job_params->pixel_units));
92         }
93         if (job_params->job_left_margin > left_margin) {
94             job_params->print_left_margin = floorf(((job_params->job_left_margin - left_margin) *
95                     (float) job_params->pixel_units));
96         } else {
97             job_params->print_left_margin = floorf(
98                     ((left_margin) * (float) job_params->pixel_units));
99         }
100         if (job_params->job_right_margin > right_margin) {
101             job_params->print_right_margin = floorf(((job_params->job_right_margin - right_margin) *
102                     (float) job_params->pixel_units));
103         } else {
104             job_params->print_right_margin = floorf(
105                     ((right_margin) * (float) job_params->pixel_units));
106         }
107         if (job_params->job_bottom_margin > bottom_margin) {
108             job_params->print_bottom_margin = floorf(
109                     ((job_params->job_bottom_margin - bottom_margin) *
110                             (float) job_params->pixel_units));
111         } else {
112             job_params->print_bottom_margin = floorf(
113                     ((bottom_margin) * (float) job_params->pixel_units));
114         }
115     }
116 
117     job_params->width = (job_params->printable_area_width -
118             (job_params->print_left_margin + job_params->print_right_margin));
119     job_params->height = (job_params->printable_area_height -
120             (job_params->print_top_margin + job_params->print_bottom_margin));
121 
122     LOGD("printable_area_get(): source dimensions: %fx%f",
123          job_params->source_width, job_params->source_height);
124     LOGD("printable_area_get(): page dimensions: %fx%f",
125          job_params->page_width, job_params->page_height);
126 }
127 
printable_area_get_default_margins(const wprint_job_params_t * job_params,const printer_capabilities_t * printer_cap,float * top_margin,float * left_margin,float * right_margin,float * bottom_margin)128 void printable_area_get_default_margins(const wprint_job_params_t *job_params,
129         const printer_capabilities_t *printer_cap,
130         float *top_margin,
131         float *left_margin, float *right_margin,
132         float *bottom_margin) {
133     if ((job_params == NULL) || (printer_cap == NULL)) {
134         return;
135     }
136 
137     bool useDefaultMargins = true;
138 
139     if (job_params->borderless) {
140         useDefaultMargins = false;
141         switch (job_params->pcl_type) {
142             case PCLm:
143             case PCLPWG:
144                 *top_margin = 0.0f;
145                 *left_margin = 0.0f;
146                 *right_margin = 0.0f;
147                 *bottom_margin = 0.00f;
148                 break;
149             default:
150                 *top_margin = -0.065f;
151                 *left_margin = -0.10f;
152                 *right_margin = -0.118f;
153                 *bottom_margin = -0.10f;
154                 break;
155         }
156     } else {
157         switch (job_params->pcl_type) {
158             case PCLm:
159                 *top_margin = (float) printer_cap->printerTopMargin / 2540;
160                 *bottom_margin = (float) printer_cap->printerBottomMargin / 2540;
161                 *left_margin = (float) printer_cap->printerLeftMargin / 2540;
162                 *right_margin = (float) printer_cap->printerRightMargin / 2540;
163                 useDefaultMargins = false;
164                 break;
165             case PCLPWG:
166                 *top_margin = 0.0f;
167                 *left_margin = 0.0f;
168                 *right_margin = 0.0f;
169                 *bottom_margin = 0.00f;
170                 useDefaultMargins = false;
171                 break;
172             default:
173                 break;
174         }
175     }
176 
177     if (useDefaultMargins) {
178         if (!printer_cap->inkjet) {
179             // default laser margins
180             *top_margin = 0.2f;
181             *left_margin = 0.25f;
182             *right_margin = 0.25f;
183             *bottom_margin = 0.2f;
184         } else {
185             // default inkjet margins
186             *top_margin = 0.125f;
187             *left_margin = 0.125f;
188             *right_margin = 0.125f;
189             if ((job_params->duplex != DUPLEX_MODE_NONE) || !printer_cap->borderless) {
190                 *bottom_margin = 0.5f;
191             } else {
192                 *bottom_margin = 0.125f;
193             }
194         }
195     }
196 
197     LOGD("printable_area_get_default_margins(): top_margin=%f, left_margin=%f, "
198             "right_margin=%f, bottom_margin=%f", *top_margin, *left_margin, *right_margin,
199             *bottom_margin);
200 }