Input file is cropped and printed. We don't do scaling in crop-to-fit.
Fixes #65. imagetoraster, imagetopdf and pdftopdf filters are mutually exclusive.
"-o fill" option is now equivalent to "print-scaling=fill".
ppd_attr_t *attr;
int pl,pr;
int fillprint = 0; /* print-scaling = fill */
+ int cropfit = 0; /* -o crop-to-fit = true */
/*
* Make sure status messages are not buffered...
*/
fillprint = 1;
}
}
+ else if((val = cupsGetOption("fill",num_options,options))!=0) {
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ fillprint = 1;
+ }
+ }
+ /*
+ * crop-to-fit
+ */
+ if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ cropfit=1;
+ }
+ }
if ((val = cupsGetOption("OutputOrder",num_options,options)) != 0) {
if (!strcasecmp(val, "Reverse")) {
colorspace = ColorDevice ? CUPS_IMAGE_RGB_CMYK : CUPS_IMAGE_WHITE;
img = cupsImageOpen(filename, colorspace, CUPS_IMAGE_WHITE, sat, hue, NULL);
-
- if(fillprint)
+ if(fillprint||cropfit)
{
float w = (float)cupsImageGetWidth(img);
float h = (float)cupsImageGetHeight(img);
float pw = PageRight-PageLeft;
float ph = PageTop-PageBottom;
- char temp[3072];
- char tempfilename[1024];
int tempOrientation = Orientation;
- if ((cupsTempFd(tempfilename, sizeof(tempfilename))) < 0)
- {
- perror("ERROR: Unable to copy image file");
- return (1);
- }
char *val;
+ int flag = 3;
if((val = cupsGetOption("orientation-requested",num_options,options))!=NULL)
{
tempOrientation = atoi(val);
}
+ else if((val = cupsGetOption("landscape",num_options,options))!=NULL)
+ {
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ tempOrientation = 4;
+ }
+ }
if(tempOrientation>0)
{
if(tempOrientation==4||tempOrientation==5)
float temp = pw;
pw = ph;
ph = temp;
+ flag = 4;
}
}
if(tempOrientation==0)
{
- float ratio = ph/pw;
- if(h/w < ratio)
+ int temp1 = pw,
+ temp2 = ph,
+ temp3 = pw,
+ temp4 = ph;
+ if(temp1>w) temp1 = w;
+ if(temp2>h) temp2 = h;
+ if(temp3>h) temp3 = h;
+ if(temp4>w) temp4 = w;
+ if(temp1*temp2<temp3*temp4)
{
- float temp = pw;
+ int temp = pw;
pw = ph;
ph = temp;
+ flag = 4;
}
}
- float final_w,final_h;
- if(w*ph/pw <=h){
- final_w =w;
- final_h =w*ph/pw;
+ if(fillprint){
+ float final_w,final_h;
+ if(w*ph/pw <=h){
+ final_w =w;
+ final_h =w*ph/pw;
+ }
+ else{
+ final_w = h*pw/ph;
+ final_h = h;
+ }
+ float posw=(w-final_w)/2,posh=(h-final_h)/2;
+ posw = (1+XPosition)*posw;
+ posh = (1-YPosition)*posh;
+ cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
+ cupsImageClose(img);
+ img = img2;
}
- else{
- final_w = h*pw/ph;
- final_h = h;
+ else {
+ float final_w=w,final_h=h;
+ if(final_w>pw)
+ {
+ final_w = pw;
+ }
+ if(final_h>ph)
+ {
+ final_h = ph;
+ }
+ if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h))
+ {
+ fprintf(stderr,"[DEBUG]: Ignoring crop-to-fit option!\n");
+ cropfit=0;
+ }
+ else{
+ float posw=(w-final_w)/2,posh=(h-final_h)/2;
+ posw = (1+XPosition)*posw;
+ posh = (1-YPosition)*posh;
+ cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
+ cupsImageClose(img);
+ img = img2;
+ if(flag==4)
+ {
+ PageBottom+=(PageTop-PageBottom-final_w)/2;
+ PageTop = PageBottom+final_w;
+ PageLeft +=(PageRight-PageLeft-final_h)/2;
+ PageRight = PageLeft+final_h;
+ }
+ else{
+ PageBottom+=(PageTop-PageBottom-final_h)/2;
+ PageTop = PageBottom+final_h;
+ PageLeft +=(PageRight-PageLeft-final_w)/2;
+ PageRight = PageLeft+final_w;
+ }
+ if(PageBottom<0) PageBottom = 0;
+ if(PageLeft<0) PageLeft = 0;
+ }
}
- float posw=(w-final_w)/2,posh=(h-final_h)/2;
- posw = (1+XPosition)*posw;
- posh = (1-YPosition)*posh;
- cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
- cupsImageClose(img);
- img = img2;
}
#if defined(USE_CONVERT_CMD) && defined(CONVERT_CMD)
cm_calibration_t cm_calibrate; /* Are we color calibrating the device? */
int cm_disabled; /* Color management disabled? */
int fillprint = 0; /* print-scaling = fill */
+ int cropfit = 0; /* -o crop-to-fit */
/*
* Make sure status messages are not buffered...
*/
fillprint = 1;
}
}
+ else if((val = cupsGetOption("fill",num_options,options))!=0) {
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ fillprint = 1;
+ }
+ }
+ if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ cropfit=1;
+ }
+ }
if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
{
img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
if(img!=NULL)
{
- if(fillprint)
+ if(fillprint||cropfit)
{
float w = (float)cupsImageGetWidth(img);
float h = (float)cupsImageGetHeight(img);
float pw = PageRight-PageLeft;
float ph = PageTop-PageBottom;
- char temp[3072],*val;
- char tempfilename[1024];
+ char *val;
int tempOrientation = Orientation;
- if ((cupsTempFd(tempfilename, sizeof(tempfilename))) < 0)
- {
- perror("ERROR: Unable to copy image file");
- return (1);
- }
+ int flag =3;
if((val = cupsGetOption("orientation-requested",num_options,options))!=NULL)
{
tempOrientation = atoi(val);
}
+ else if((val = cupsGetOption("landscape",num_options,options))!=NULL)
+ {
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ tempOrientation = 4;
+ }
+ }
if(tempOrientation>0)
{
if(tempOrientation==4||tempOrientation==5)
float temp = pw;
pw = ph;
ph = temp;
+ flag = 4;
}
}
if(tempOrientation==0)
{
- float ratio = ph/pw;
- if(h/w < ratio)
+ if(min(pw,w)*min(ph,h)<min(pw,h)*min(ph,w))
{
- float temp = pw;
+ int temp = pw;
pw = ph;
ph = temp;
+ flag = 4;
}
}
- // Final width and height of cropped image.
- float final_w,final_h;
- if(w*ph/pw <=h){
- final_w =w;
- final_h =w*ph/pw;
- }
- else{
- final_w = h*pw/ph;
- final_h = h;
+ if(fillprint)
+ {
+ // Final width and height of cropped image.
+ float final_w,final_h;
+ if(w*ph/pw <=h){
+ final_w =w;
+ final_h =w*ph/pw;
+ }
+ else{
+ final_w = h*pw/ph;
+ final_h = h;
+ }
+ // posw and posh are position of the cropped image along width and height.
+ float posw=(w-final_w)/2,posh=(h-final_h)/2;
+ posw = (1+XPosition)*posw;
+ posh = (1-YPosition)*posh;
+ cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
+ cupsImageClose(img);
+ img = img2;
}
- // posw and posh are position of the cropped image along width and height.
- float posw=(w-final_w)/2,posh=(h-final_h)/2;
- posw = (1+XPosition)*posw;
- posh = (1-YPosition)*posh;
- cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
- cupsImageClose(img);
- img = img2;
+ else {
+ float final_w=w,final_h=h;
+ if(w>pw)
+ {
+ final_w = pw;
+ }
+ if(h>ph)
+ {
+ final_h = ph;
+ }
+ if((fabs(final_w-w)>0.5*w)||(fabs(final_h-h)>0.5*h))
+ {
+ fprintf(stderr,"[DEBUG]: Ignoring crop-to-fit option!\n");
+ cropfit=0;
+ }
+ else{
+ float posw=(w-final_w)/2,posh=(h-final_h)/2;
+ posw = (1+XPosition)*posw;
+ posh = (1-YPosition)*posh;
+ cups_image_t *img2 = cupsImageCrop(img,posw,posh,final_w,final_h);
+ cupsImageClose(img);
+ img = img2;
+ if(flag==4)
+ {
+ PageBottom+=(PageTop-PageBottom-final_w)/2;
+ PageTop = PageBottom+final_w;
+ PageLeft +=(PageRight-PageLeft-final_h)/2;
+ PageRight = PageLeft+final_h;
+ }
+ else{
+ PageBottom+=(PageTop-PageBottom-final_h)/2;
+ PageTop = PageBottom+final_h;
+ PageLeft +=(PageRight-PageLeft-final_w)/2;
+ PageRight = PageLeft+final_w;
+ }
+ if(PageBottom<0) PageBottom = 0;
+ if(PageLeft<0) PageLeft = 0;
+ }
+ }
}
}
if (argc == 6)
param.fillprint=true;
}
}
+ else if((val = cupsGetOption("fill",num_options,options))!=0) {
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ param.fillprint = true;
+ }
+ }
+ /*
+ * crop-to-fit
+ */
+ if((val = cupsGetOption("crop-to-fit",num_options,options))!= NULL){
+ if(!strcasecmp(val,"true")||!strcasecmp(val,"yes"))
+ {
+ param.cropfit=1;
+ }
+ }
if (ppd && (ppd->landscape < 0)) { // direction the printer rotates landscape (90 or -90)
param.normal_landscape=ROT_270;
}
const int numPages=std::max(shuffle.size(),pages.size());
- if(param.fillprint){
- fprintf(stderr,"Cropping input pdf and Enabling fitplot.%d\n");
- for(int i=0;i<pages.size();i++)
+ if(param.fillprint||param.cropfit){
+ fprintf(stderr,"[DEBUG]: Cropping input pdf and Enabling fitplot.\n");
+ for(int i=0;i<(int)pages.size();i++)
{
std::shared_ptr<PDFTOPDF_PageHandle> page = pages[i];
- Rotation currRot = page->crop(param.page,param.orientation,param.xpos,param.ypos);
+ Rotation currRot = page->crop(param.page,param.orientation,param.xpos,param.ypos,!param.cropfit);
}
param.fitplot = 1;
}
if (!param.fitplot) {
curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale,&rect);
} else {
- curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale);
+ if(param.cropfit){
+ double xpos2 = (param.page.right-param.page.left-(page->getRect().width))/2;
+ double ypos2 = (param.page.top-param.page.bottom-(page->getRect().height))/2;
+ if(param.orientation==ROT_270||param.orientation==ROT_90)
+ {
+ xpos2 = (param.page.right-param.page.left-(page->getRect().height))/2;
+ ypos2 = (param.page.top-param.page.bottom-(page->getRect().width))/2;
+ curpage->add_subpage(page,ypos2+param.page.bottom,xpos2+param.page.left,1);
+ }else{
+ curpage->add_subpage(page,xpos2+param.page.left,ypos2+param.page.bottom,1);
+ }
+ }
+ else
+ curpage->add_subpage(page,pgedit.xpos+xpos,pgedit.ypos+ypos,pgedit.scale);
}
#ifdef DEBUG
user(0),title(0),
fitplot(false),
fillprint(false), //print-scaling = fill
+ cropfit(false),
orientation(ROT_0),normal_landscape(ROT_270),
paper_is_landscape(false),
duplex(false),
const char *user, *title; // will stay around
bool fitplot;
bool fillprint; //print-scaling = fill
+ bool cropfit; // -o crop-to-fit
PageRect page;
Rotation orientation,normal_landscape; // normal_landscape (i.e. default direction) is e.g. needed for number-up=2
bool paper_is_landscape;
// fscale: inverse_scale (from nup, fitplot)
virtual void add_border_rect(const PageRect &rect,BorderType border,float fscale) =0;
// TODO?! add standalone crop(...) method (not only for subpages)
- virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos) =0;
+ virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale) =0;
virtual void add_subpage(const std::shared_ptr<PDFTOPDF_PageHandle> &sub,float xpos,float ypos,float scale,const PageRect *crop=NULL) =0;
virtual void mirror() =0;
virtual void rotate(Rotation rot) =0;
/*
* This crop function is written for print-scaling=fill option.
* Trim Box is used for trimming the page in required size.
+ * scale tells if we need to scale input file.
*/
-Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos)
+Rotation QPDF_PDFTOPDF_PageHandle::crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale)
{
page.assertInitialized();
if(orientation==ROT_0||orientation==ROT_180)
{
std::swap(pageHeight,pageWidth);
}
- if(width*pageHeight/pageWidth<=height)
+ if(scale)
{
- final_w = width;
- final_h = width*pageHeight/pageWidth;
+ if(width*pageHeight/pageWidth<=height)
+ {
+ final_w = width;
+ final_h = width*pageHeight/pageWidth;
+ }
+ else{
+ final_w = height*pageWidth/pageHeight;
+ final_h = height;
+ }
}
else{
- final_w = height*pageWidth/pageHeight;
- final_h = height;
+ final_w = std::min(width,pageWidth);
+ final_h = std::min(height,pageHeight);
}
-
+ fprintf(stderr,"After Cropping: %lf %lf %lf %lf\n",width,height,final_w,final_h);
double posw = (width-final_w)/2,
posh = (height-final_h)/2;
// posw, posh : Position along width and height respectively.
virtual void mirror();
virtual void rotate(Rotation rot);
virtual void add_label(const PageRect &rect, const std::string label);
- virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos);
+ virtual Rotation crop(const PageRect &cropRect,Rotation orientation,Position xpos,Position ypos,bool scale);
void debug(const PageRect &rect,float xpos,float ypos);
private:
bool isExisting() const;