Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

update k2pdfopt to version v2.12

  • Loading branch information...
commit e36230b59ba92e9da5ed261253acd805eba5baa9 2 parents 991484c + d988c98
Huang Xin chrox authored
5 k2pdfoptlib/bmpregion.c
@@ -1331,7 +1331,12 @@ printf("1. textrow[%d] = figure.\n",textrows->n-1);
1331 1331
1332 1332 /* Remove rows with text height that seems to be too small */
1333 1333 if (remove_small_rows)
  1334 + {
  1335 + /* textrows_remove_small_rows needs types determined */
  1336 + for (i=0;i<textrows->n;i++)
  1337 + textrow_determine_type(region,k2settings,i);
1334 1338 textrows_remove_small_rows(textrows,k2settings,0.25,0.5,region);
  1339 + }
1335 1340
1336 1341 /* Compute gaps between rows and row heights again */
1337 1342 textrows_compute_row_gaps(textrows,region->r2);
87 k2pdfoptlib/k2bmp.c
@@ -519,7 +519,8 @@ fclose(f);
519 519 }
520 520
521 521 /*
522   -** bmp must be grayscale! (cbmp = color, can be null)
  522 +** bmp must be grayscale! (cbmp might be color, might be grayscale, can be null)
  523 +** Handles cbmp either 8-bit or 24-bit in v2.10.
523 524 */
524 525 void bmp_detect_vertical_lines(WILLUSBITMAP *bmp,WILLUSBITMAP *cbmp,
525 526 double dpi,/* double minwidth_in, */
@@ -673,6 +674,8 @@ exit(10);
673 674 /*
674 675 ** Calculate max vert line length. Line is terminated by nw consecutive white pixels
675 676 ** on either side.
  677 +**
  678 +** v2.10--handle cbmp 8-bit correctly.
676 679 */
677 680 static int vert_line_erase(WILLUSBITMAP *bmp,WILLUSBITMAP *cbmp,WILLUSBITMAP *tmp,
678 681 int row0,int col0,double tanth,double minheight_in,
@@ -680,10 +683,22 @@ static int vert_line_erase(WILLUSBITMAP *bmp,WILLUSBITMAP *cbmp,WILLUSBITMAP *tm
680 683 double dpi,int erase_vertical_lines)
681 684
682 685 {
683   - int lw,cc,maxdev,nw,dir,i,n;
  686 + int lw,cc,maxdev,nw,dir,i,n,cbpp;
684 687 int *c1,*c2,*w;
685 688 static char *funcname="vert_line_erase";
686 689
  690 +#if (WILLUSDEBUGX & 0x8000)
  691 +printf("@vert_line_erase(row0=%d,col0=%d,tanth=%g,minheight_in=%g\n"
  692 + " maxwidth_in=%g,white_thresh=%d,dpi=%g,evl=%d\n",
  693 +row0,col0,tanth,minheight_in,
  694 +maxwidth_in,white_thresh,dpi,erase_vertical_lines);
  695 +printf(" bmp = %d x %d x %d\n",bmp->width,bmp->height,bmp->bpp);
  696 +if (cbmp!=NULL)
  697 +printf(" cbmp = %d x %d x %d\n",cbmp->width,cbmp->height,cbmp->bpp);
  698 +if (tmp!=NULL)
  699 +printf(" tmp = %d x %d x %d\n",tmp->width,tmp->height,tmp->bpp);
  700 +#endif
  701 + cbpp = (cbmp!=NULL && cbmp->bpp==24) ? 3 : 1;
687 702 willus_dmem_alloc_warn(26,(void **)&c1,sizeof(int)*3*bmp->height,funcname,10);
688 703 c2=&c1[bmp->height];
689 704 w=&c2[bmp->height];
@@ -703,12 +718,18 @@ static int vert_line_erase(WILLUSBITMAP *bmp,WILLUSBITMAP *cbmp,WILLUSBITMAP *tm
703 718 {
704 719 int del,brc;
705 720
  721 +#if (WILLUSDEBUGX & 0x8000)
  722 +printf("dir=%d\n",dir);
  723 +#endif
706 724 brc = 0;
707 725 for (del=(dir==-1)?0:1;1;del++)
708 726 {
709 727 int r,c;
710 728 unsigned char *p;
711 729
  730 +#if (WILLUSDEBUGX & 0x8000)
  731 +printf("del=%d\n",del);
  732 +#endif
712 733 r=row0+dir*del;
713 734 if (r<0 || r>bmp->height-1)
714 735 break;
@@ -766,6 +787,9 @@ static int vert_line_erase(WILLUSBITMAP *bmp,WILLUSBITMAP *cbmp,WILLUSBITMAP *tm
766 787 c2[r]=bmp->width-1;
767 788 }
768 789 }
  790 +#if (WILLUSDEBUGX & 0x8000)
  791 +printf("n=%d\n",n);
  792 +#endif
769 793 if (n>1)
770 794 sorti(w,n);
771 795 /*
@@ -776,6 +800,9 @@ printf("n=%d, w[%d]=%d, w[%d]=%d (mw=%g)\n",n,n/4,w[n/4],3*n/4,w[3*n/4],maxwidth
776 800 || w[3*n/4] > (int)(maxwidth_in*dpi)
777 801 || (erase_vertical_lines==1 && w[n-1] > maxwidth_in*dpi))
778 802 {
  803 +#if (WILLUSDEBUGX & 0x8000)
  804 +printf("Erasing area in temp bitmap.\n");
  805 +#endif
779 806 /* Erase area in temp bitmap */
780 807 for (i=0;i<bmp->height;i++)
781 808 {
@@ -792,15 +819,27 @@ printf("n=%d, w[%d]=%d, w[%d]=%d (mw=%g)\n",n,n/4,w[n/4],3*n/4,w[3*n/4],maxwidth
792 819 }
793 820 else
794 821 {
  822 +#if (WILLUSDEBUGX & 0x8000)
  823 +printf("Erasing line width in source\n");
  824 +#endif
795 825 /* Erase line width in source bitmap */
796 826 lw=w[3*n/4]+nw*2;
  827 +#if (WILLUSDEBUGX & 0x8000)
  828 +printf("1. lw=%d\n",lw);
  829 +#endif
797 830 if (lw > maxwidth_in*dpi/2)
798 831 lw=maxwidth_in*dpi/2;
  832 +#if (WILLUSDEBUGX & 0x8000)
  833 +printf("2. lw=%d\n",lw);
  834 +#endif
799 835 for (i=0;i<bmp->height;i++)
800 836 {
801 837 unsigned char *p;
802 838 int c0,cmin,cmax,count,white;
803 839
  840 +#if (WILLUSDEBUGX & 0x8000)
  841 +printf("i=%d\n",i);
  842 +#endif
804 843 if (c1[i]<0 || c2[i]<0)
805 844 continue;
806 845 c0=col0+(i-row0)*tanth;
@@ -810,32 +849,60 @@ printf("n=%d, w[%d]=%d, w[%d]=%d (mw=%g)\n",n,n/4,w[n/4],3*n/4,w[3*n/4],maxwidth
810 849 cmax=c0+lw+1;
811 850 if (cmax>c2[i])
812 851 cmax=c2[i];
  852 +#if (WILLUSDEBUGX & 0x8000)
  853 +printf("A\n");
  854 +#endif
813 855 p=bmp_rowptr_from_top(bmp,i);
814 856 c0 = (p[cmin] > p[cmax]) ? cmin : cmax;
815 857 white=p[c0];
  858 +#if (WILLUSDEBUGX & 0x8000)
  859 +printf("B\n");
  860 +#endif
816 861 if (white <= white_thresh)
817 862 white = white_thresh+1;
818 863 if (white>255)
819 864 white=255;
  865 +#if (WILLUSDEBUGX & 0x8000)
  866 +printf("C\n");
  867 +#endif
820 868 count=(cmax-cmin)+1;
821 869 p=&p[cmin];
  870 +#if (WILLUSDEBUGX & 0x8000)
  871 +printf("D\n");
  872 +#endif
822 873 for (;count>0;count--,p++)
823 874 (*p)=white;
  875 +#if (WILLUSDEBUGX & 0x8000)
  876 +printf("E\n");
  877 +#endif
824 878 if (cbmp!=NULL)
825 879 {
826 880 unsigned char *p0;
  881 +
827 882 p=bmp_rowptr_from_top(cbmp,i);
828   - p0=p+c0*3;
829   - p=p+cmin*3;
  883 + p0=p+c0*cbpp;
  884 + p=p+cmin*cbpp;
830 885 count=(cmax-cmin)+1;
831   - for (;count>0;count--,p+=3)
832   - {
833   - p[0]=p0[0];
834   - p[1]=p0[1];
835   - p[2]=p0[2];
836   - }
  886 +#if (WILLUSDEBUGX & 0x8000)
  887 +printf("F width=%d, ht=%d, bpp=%d, c0=%d, cmin=%d, i=%d, count=%d\n",cbmp->width,cbmp->height,cbmp->bpp,c0,cmin,i,count);
  888 +#endif
  889 + if (cbpp==3)
  890 + for (;count>0;count--,p+=3)
  891 + {
  892 + p[0]=p0[0];
  893 + p[1]=p0[1];
  894 + p[2]=p0[2];
  895 + }
  896 + else
  897 + memset(p,p0[0],count);
  898 +#if (WILLUSDEBUGX & 0x8000)
  899 +printf("G\n");
  900 +#endif
837 901 }
838 902 }
  903 +#if (WILLUSDEBUGX & 0x8000)
  904 +printf(" done.\n");
  905 +#endif
839 906 }
840 907 willus_dmem_free(26,(double **)&c1,funcname);
841 908 return(1);
144 k2pdfoptlib/k2file.c
@@ -31,6 +31,9 @@ static int k2_handle_preview(K2PDFOPT_SETTINGS *k2settings,MASTERINFO *masterinf
31 31 static int filename_comp(char *name1,char *name2);
32 32 static void filename_substitute(char *dst,char *fmt,char *src,int count,char *defext0);
33 33 static int overwrite_fail(char *outname,double overwrite_minsize_mb);
  34 +static int toclist_valid(char *s,FILE *out);
  35 +static WPDFOUTLINE *wpdfoutline_from_pagelist(char *pagelist,int maxpages);
  36 +static int tocwrites=0;
34 37
35 38
36 39 /*
@@ -228,7 +231,7 @@ static double k2pdfopt_proc_one(K2PDFOPT_SETTINGS *k2settings0,char *filename,do
228 231 WILLUSBITMAP _marked,*marked;
229 232 WILLUSBITMAP preview_internal;
230 233 int i,status,pw,np,src_type,second_time_through,or_detect,orep_detect,preview;
231   - int pagecount,pagestep,pages_done;
  234 + int pagecount,pagestep,pages_done,local_tocwrites;
232 235 int errcnt,pixwarn;
233 236 FILELIST *fl,_fl;
234 237 int folder,dpi;
@@ -245,6 +248,7 @@ static double k2pdfopt_proc_one(K2PDFOPT_SETTINGS *k2settings0,char *filename,do
245 248 /*
246 249 printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",filename,rot_deg,k2out->bmp);
247 250 */
  251 + local_tocwrites=0;
248 252 k2out->status = 1;
249 253 k2settings=&_k2settings;
250 254 k2pdfopt_settings_copy(k2settings,k2settings0);
@@ -449,6 +453,32 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
449 453 strcpy(mupdffilename,filename);
450 454 }
451 455 #endif
  456 + /* Get bookmarks / outline from PDF file */
  457 + if (!or_detect && k2settings->use_toc!=0 && !toclist_valid(k2settings->toclist,NULL))
  458 + {
  459 + masterinfo->outline=wpdfoutline_read_from_pdf_file(mupdffilename);
  460 + /* Save TOC if requested */
  461 + if (k2settings->tocsavefile[0]!='\0')
  462 + {
  463 + FILE *f;
  464 + f=fopen(k2settings->tocsavefile,tocwrites==0?"w":"a");
  465 + if (f!=NULL)
  466 + {
  467 + int i;
  468 + fprintf(f,"%sFILE: %s\n",tocwrites==0?"":"\n\n",mupdffilename);
  469 + for (i=strlen(mupdffilename)+6;i>0;i--)
  470 + fputc('-',f);
  471 + fprintf(f,"\n");
  472 + if (masterinfo->outline!=NULL)
  473 + wpdfoutline_echo2(masterinfo->outline,0,f);
  474 + else
  475 + fprintf(f,"(No outline info in file.)\n");
  476 + fclose(f);
  477 + tocwrites++;
  478 + local_tocwrites++;
  479 + }
  480 + }
  481 + }
452 482 }
453 483 else
454 484 #endif
@@ -484,6 +514,14 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
484 514 filelist_free(fl);
485 515 return(0.);
486 516 }
  517 + masterinfo->srcpages = np;
  518 + if (!or_detect && toclist_valid(k2settings->toclist,stdout))
  519 + {
  520 + if (pagelist_valid_page_range(k2settings->toclist))
  521 + masterinfo->outline=wpdfoutline_from_pagelist(k2settings->toclist,masterinfo->srcpages);
  522 + else
  523 + masterinfo->outline=wpdfoutline_read_from_text_file(k2settings->toclist);
  524 + }
487 525 pagecount = np<0 ? -1 : pagelist_count(k2settings->pagelist,np);
488 526 #ifdef HAVE_K2GUI
489 527 if (k2gui_active())
@@ -659,23 +697,23 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
659 697 /* Reset the display order for this source page */
660 698 if (k2settings->show_marked_source)
661 699 mark_source_page(k2settings,NULL,0,0xf);
662   - /* If we haven't just kicked out a page... */
663   - if (!k2settings_gap_override(k2settings))
  700 + /*
  701 + ** v2.10 Call masterinfo_publish() no matter what. If we've just kicked out a
  702 + ** page, it doesn't matter. It will do nothing.
  703 + */
  704 + masterinfo_publish(masterinfo,k2settings,
  705 + masterinfo_should_flush(masterinfo,k2settings));
  706 + if (preview && k2_handle_preview(k2settings,masterinfo,k2mark_page_count,
  707 + k2settings->dst_color?marked:src,k2out))
664 708 {
665   - masterinfo_publish(masterinfo,k2settings,
666   - k2settings->dst_break_pages>0 ? k2settings->dst_break_pages : 0);
667   - if (preview && k2_handle_preview(k2settings,masterinfo,k2mark_page_count,
668   - k2settings->dst_color?marked:src,k2out))
669   - {
670   - bmp_free(marked);
671   - bmp_free(srcgrey);
672   - bmp_free(src);
673   - masterinfo_free(masterinfo,k2settings);
674   - if (folder)
675   - filelist_free(fl);
676   - k2out->status=0;
677   - return(0.);
678   - }
  709 + bmp_free(marked);
  710 + bmp_free(srcgrey);
  711 + bmp_free(src);
  712 + masterinfo_free(masterinfo,k2settings);
  713 + if (folder)
  714 + filelist_free(fl);
  715 + k2out->status=0;
  716 + return(0.);
679 717 }
680 718 if (k2settings->show_marked_source && !preview)
681 719 publish_marked_page(mpdf,k2settings->dst_color ? marked : src,k2settings->src_dpi);
@@ -739,7 +777,14 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
739 777 k2out->status=0;
740 778 return(0.);
741 779 }
  780 + /*
  781 + ** v2.10 -- Calling masterinfo_flush() without checking if a page has just been
  782 + ** been flushed is fine at the end. If there is nothing left
  783 + ** in the master output bitmap, it won't do anything.
  784 + */
  785 + /*
742 786 if (k2settings->dst_break_pages<=0 && !k2settings_gap_override(k2settings))
  787 + */
743 788 masterinfo_flush(masterinfo,k2settings);
744 789 {
745 790 char cdate[128],author[256],title[256];
@@ -759,6 +804,8 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
759 804 author[0]=title[0]=cdate[0]='\0';
760 805 if (!k2settings->use_crop_boxes)
761 806 {
  807 + if (masterinfo->outline!=NULL)
  808 + pdffile_add_outline(&masterinfo->outfile,masterinfo->outline);
762 809 pdffile_finish(&masterinfo->outfile,title,author,masterinfo->pageinfo.producer,cdate);
763 810 pdffile_close(&masterinfo->outfile);
764 811 }
@@ -769,7 +816,7 @@ printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",file
769 816 wpdfboxes_echo(&masterinfo->pageinfo.boxes,stdout);
770 817 #endif
771 818 #ifdef HAVE_MUPDF_LIB
772   - wmupdf_remake_pdf(mupdffilename,dstfile,&masterinfo->pageinfo,1,stdout);
  819 + wmupdf_remake_pdf(mupdffilename,dstfile,&masterinfo->pageinfo,1,masterinfo->outline,stdout);
773 820 #endif
774 821 }
775 822 if (k2settings->show_marked_source)
@@ -804,6 +851,8 @@ wpdfboxes_echo(&masterinfo->pageinfo.boxes,stdout);
804 851 k2printf(TTEXT_BOLD "%d words" TTEXT_NORMAL " written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL " (%.1f MB).\n\n",masterinfo->wordcount,masterinfo->ocrfilename,size/1024./1024.);
805 852 }
806 853 #endif
  854 + if (local_tocwrites>0)
  855 + k2printf(TTEXT_BOLD "%d bytes" TTEXT_NORMAL " written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL ".\n\n",(int)(wfile_size(k2settings->tocsavefile)+.5),k2settings->tocsavefile);
807 856 masterinfo_free(masterinfo,k2settings);
808 857 if (folder)
809 858 filelist_free(fl);
@@ -855,10 +904,11 @@ static int k2_handle_preview(K2PDFOPT_SETTINGS *k2settings,MASTERINFO *masterinf
855 904 printf("Got preview bitmap: %d x %d x %d.\n",
856 905 masterinfo->preview_bitmap->width,masterinfo->preview_bitmap->height,masterinfo->preview_bitmap->bpp);
857 906 */
858   - if (k2settings->preview_page>0)
859   - bmp_write(masterinfo->preview_bitmap,"k2pdfopt_out.png",NULL,100);
860 907 if (k2out->bmp==NULL)
  908 + {
  909 + bmp_write(masterinfo->preview_bitmap,"k2pdfopt_out.png",NULL,100);
861 910 bmp_free(masterinfo->preview_bitmap);
  911 + }
862 912 }
863 913 return(status);
864 914 }
@@ -1014,3 +1064,57 @@ static int overwrite_fail(char *outname,double overwrite_minsize_mb)
1014 1064 strcpy(outname,newname);
1015 1065 return(0);
1016 1066 }
  1067 +
  1068 +
  1069 +static int toclist_valid(char *s,FILE *out)
  1070 +
  1071 + {
  1072 + if (s[0]=='\0')
  1073 + return(0);
  1074 + if (pagelist_valid_page_range(s))
  1075 + return(1);
  1076 + if (wfile_status(s)==1)
  1077 + return(1);
  1078 + if (out!=NULL)
  1079 + k2printf(ANSI_RED "\nTOC page list '%s' is not valid page range or file name."
  1080 + ANSI_NORMAL "\n\n",s);
  1081 + return(0);
  1082 + }
  1083 +
  1084 +
  1085 +/*
  1086 +** Create outline from page list
  1087 +*/
  1088 +static WPDFOUTLINE *wpdfoutline_from_pagelist(char *pagelist,int maxpages)
  1089 +
  1090 + {
  1091 + int i;
  1092 + WPDFOUTLINE *outline,*outline0;
  1093 +
  1094 + outline0=outline=NULL;
  1095 + for (i=0;1;i++)
  1096 + {
  1097 + int page;
  1098 + char buf[64];
  1099 + WPDFOUTLINE *oline;
  1100 +
  1101 + page=pagelist_page_by_index(pagelist,i,maxpages);
  1102 + if (page<0)
  1103 + break;
  1104 + sprintf(buf,"Chapter %d",i+1);
  1105 + oline=malloc(sizeof(WPDFOUTLINE));
  1106 + wpdfoutline_init(oline);
  1107 + oline->title=malloc(strlen(buf)+1);
  1108 + strcpy(oline->title,buf);
  1109 + oline->srcpage=page-1;
  1110 + oline->dstpage=-1;
  1111 + if (i==0)
  1112 + {
  1113 + outline0=outline=oline;
  1114 + continue;
  1115 + }
  1116 + outline->next=oline;
  1117 + outline=outline->next;
  1118 + }
  1119 + return(outline0);
  1120 + }
33 k2pdfoptlib/k2gui.c
@@ -834,22 +834,39 @@ printf("settings->src_trim=%d\n",k2settings->src_trim);
834 834 if (!strcmp(control->name,"straighten"))
835 835 k2settings->src_autostraighten = checked ? 4. : -1.;
836 836 else if (!strcmp(control->name,"break"))
837   - k2settings->dst_break_pages= checked ? 1 : 0;
  837 + k2settings->dst_break_pages= checked ? 2 : 1;
838 838 else if (!strcmp(control->name,"color"))
839 839 k2settings->dst_color= checked ? 1 : 0;
840 840 else if (!strcmp(control->name,"landscape"))
841 841 k2settings->dst_landscape = checked ? 1 : 0;
842 842 else if (!strcmp(control->name,"native"))
  843 + {
843 844 k2settings->use_crop_boxes = checked ? 1 : 0;
  845 + if (k2settings->use_crop_boxes)
  846 + {
  847 +#ifdef HAVE_OCR_LIB
  848 + k2settings->dst_ocr=0;
  849 +#endif
  850 + k2settings->text_wrap=0;
  851 + }
  852 + }
844 853 else if (!strcmp(control->name,"r2l"))
845 854 k2settings->src_left_to_right = checked ? 0 : 1;
846 855 else if (!strcmp(control->name,"markup"))
847 856 k2settings->show_marked_source = checked ? 1 : 0;
848 857 else if (!strcmp(control->name,"wrap"))
  858 + {
849 859 k2settings->text_wrap = checked ? 2 : 0;
  860 + if (k2settings->text_wrap)
  861 + k2settings->use_crop_boxes=0;
  862 + }
850 863 #ifdef HAVE_OCR_LIB
851 864 else if (!strcmp(control->name,"ocr"))
  865 + {
852 866 k2settings->dst_ocr = checked ? 't' : 'm';
  867 + if (k2settings->dst_ocr)
  868 + k2settings->use_crop_boxes=0;
  869 + }
853 870 #endif
854 871 else if (!strcmp(control->name,"evl"))
855 872 k2settings->erase_vertical_lines = checked ? 1 : 0;
@@ -1359,6 +1376,9 @@ static WILLUSGUICONTROL *k2gui_control_with_focus(int *index)
1359 1376 static void k2gui_update_controls(void)
1360 1377
1361 1378 {
  1379 + /* Make checkboxes consistent */
  1380 + if (k2gui!=NULL && k2gui->k2conv!=NULL)
  1381 + k2pdfopt_settings_quick_sanity_check(&k2gui->k2conv->k2settings);
1362 1382 if (needs_redraw!=2)
1363 1383 needs_redraw=1;
1364 1384 willusgui_control_redraw(&k2gui->mainwin,1);
@@ -1876,7 +1896,7 @@ printf("dst_userwidth_units = %d\n",k2settings->dst_userwidth_units);
1876 1896 ** Mode select menu
1877 1897 */
1878 1898 {
1879   - static char *modes[]={"default","copy","fitwidth","2-column",""};
  1899 + static char *modes[]={"default","copy","trim","fitwidth","fitpage","2-column",""};
1880 1900 int nmodes;
1881 1901
1882 1902 for (nmodes=0;modes[nmodes][0]!='\0';nmodes++);
@@ -2407,7 +2427,7 @@ printf("cmdxtra.s='%s'\n",k2gui->cmdxtra.s);
2407 2427 checked=k2settings->src_autostraighten>=0.;
2408 2428 break;
2409 2429 case 1:
2410   - checked=k2settings->dst_break_pages;
  2430 + checked=(k2settings->dst_break_pages==2);
2411 2431 break;
2412 2432 case 2:
2413 2433 checked=k2settings->dst_color;
@@ -2648,6 +2668,13 @@ static WILLUSGUICONTROL *k2gui_control_by_name(char *name)
2648 2668 }
2649 2669
2650 2670
  2671 +int k2gui_previewing(void)
  2672 +
  2673 + {
  2674 + return(k2gui->preview_processing);
  2675 + }
  2676 +
  2677 +
2651 2678 static void k2gui_preview_start(void)
2652 2679
2653 2680 {
14 k2pdfoptlib/k2gui_cbox.c
@@ -407,6 +407,8 @@ void k2gui_cbox_error(char *filename,int statuscode)
407 407 "File overwrite not allowed","","Uknown error"};
408 408 char buf[512];
409 409
  410 + if (k2gui_cbox==NULL || !k2gui_cbox->converting)
  411 + return;
410 412 if (statuscode<1 || statuscode>5)
411 413 statuscode=1;
412 414 sprintf(buf,"Conversion of file %s aborted (%s).",filename,err[statuscode-1]);
@@ -580,7 +582,7 @@ void k2gui_cbox_set_files_completed(int nfiles,char *message)
580 582 char buf[256];
581 583 int color;
582 584
583   - if (k2gui_cbox==NULL)
  585 + if (k2gui_cbox==NULL || !k2gui_cbox->converting)
584 586 return;
585 587 if (message==NULL)
586 588 sprintf(buf,"%d of %d file%s completed.",nfiles,k2gui_cbox->num_files,k2gui_cbox->num_files==1?"":"s");
@@ -617,7 +619,7 @@ void k2gui_cbox_set_pages_completed(int n,char *message)
617 619 int color;
618 620 double progress;
619 621
620   - if (k2gui_cbox==NULL)
  622 + if (k2gui_cbox==NULL || !k2gui_cbox->converting)
621 623 return;
622 624 color=0xd0ffd0;
623 625 if (k2gui_cbox->num_pages>0)
@@ -639,7 +641,7 @@ void k2gui_cbox_set_pages_completed(int n,char *message)
639 641 void k2gui_cbox_set_num_files(int nfiles)
640 642
641 643 {
642   - if (k2gui_cbox!=NULL)
  644 + if (k2gui_cbox!=NULL && k2gui_cbox->converting)
643 645 k2gui_cbox->num_files=nfiles;
644 646 }
645 647
@@ -647,7 +649,7 @@ void k2gui_cbox_set_num_files(int nfiles)
647 649 void k2gui_cbox_set_num_pages(int npages)
648 650
649 651 {
650   - if (k2gui_cbox!=NULL)
  652 + if (k2gui_cbox!=NULL && k2gui_cbox->converting)
651 653 k2gui_cbox->num_pages=npages;
652 654 }
653 655
@@ -655,7 +657,7 @@ void k2gui_cbox_set_num_pages(int npages)
655 657 void k2gui_cbox_set_filename(char *name)
656 658
657 659 {
658   - if (k2gui_cbox!=NULL)
  660 + if (k2gui_cbox!=NULL && k2gui_cbox->converting)
659 661 {
660 662 strncpy(k2gui_cbox->filename,k2gui_short_name(name),255);
661 663 k2gui_cbox->filename[255]='\0';
@@ -679,7 +681,7 @@ printf("\n error count set to %d\n\n",k2gui_cbox->error_count);
679 681 void k2gui_cbox_increment_error_count(void)
680 682
681 683 {
682   - if (k2gui_cbox!=NULL)
  684 + if (k2gui_cbox!=NULL && k2gui_cbox->converting)
683 685 {
684 686 k2gui_cbox->error_count++;
685 687 #if (WILLUSDEBUG & 0x2000)
206 k2pdfoptlib/k2master.c
@@ -42,7 +42,7 @@ static void find_word_gaps_using_wrectmaps(WRECTMAPS *wrectmaps,int **pgappos,
42 42 static void find_word_gaps_using_textrow(WILLUSBITMAP *src,K2PDFOPT_SETTINGS *k2settings,
43 43 int **pgappos,int **pgapsize,int *png,int whitethresh,
44 44 int dpi);
45   -static int masterinfo_break_point(MASTERINFO *masterinfo,int maxsize);
  45 +static int masterinfo_break_point(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings,int maxsize);
46 46
47 47
48 48 void masterinfo_init(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings)
@@ -51,9 +51,13 @@ void masterinfo_init(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings)
51 51 extern char *k2pdfopt_version;
52 52 int i;
53 53
  54 + /* Init outline / bookmarks */
  55 + masterinfo->outline=NULL;
  56 + masterinfo->outline_srcpage_completed=-1;
54 57 masterinfo->preview_bitmap=NULL;
55 58 masterinfo->preview_captured=0;
56 59 masterinfo->published_pages=0;
  60 + masterinfo->srcpages = -1;
57 61 masterinfo->wordcount=0;
58 62 masterinfo->debugfolder[0]='\0';
59 63 bmp_init(&masterinfo->bmp);
@@ -102,6 +106,7 @@ void masterinfo_free(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings)
102 106 wrapbmp_free(&masterinfo->wrapbmp);
103 107 bmp_free(&masterinfo->bmp);
104 108 wrectmaps_free(&masterinfo->rectmaps);
  109 + wpdfoutline_free(masterinfo->outline);
105 110 }
106 111
107 112
@@ -133,9 +138,9 @@ int masterinfo_new_source_page_init(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2
133 138 int white;
134 139
135 140 white=k2settings->src_whitethresh;
  141 + masterinfo->pageinfo.srcpage = pageno;
136 142 if (k2settings->use_crop_boxes)
137 143 {
138   - masterinfo->pageinfo.srcpage = pageno;
139 144 masterinfo->pageinfo.srcpage_rot_deg=0.;
140 145 masterinfo->pageinfo.srcpage_fine_rot_deg = 0.;
141 146 }
@@ -667,7 +672,9 @@ printf("maxgap_pixels=%d\n",maxgap_pixels);
667 672 ** mandatory_region_gap==4 means this is the first bitmap being added for the whole
668 673 ** document, so we don't need to add a gap in that case, either.
669 674 */
670   - if (masterinfo->mandatory_region_gap==1)
  675 + if (k2settings->dst_fit_to_page==-2)
  676 + gap_pixels = 0;
  677 + else if (masterinfo->mandatory_region_gap==1)
671 678 gap_pixels= k2settings_gap_override(k2settings) ? 0
672 679 : masterinfo->page_region_gap_in*region->dpi;
673 680 else if (textrow[0].type==REGION_TYPE_FIGURE || lastrow->type==REGION_TYPE_FIGURE)
@@ -889,7 +896,7 @@ k2printf("start: mi->rows=%d, rr=%d\n",masterinfo->rows,rr);
889 896 return(0);
890 897
891 898 /* Get a suitable breaking point for the next page */
892   - bp=masterinfo_break_point(masterinfo,maxsize);
  899 + bp=masterinfo_break_point(masterinfo,k2settings,maxsize);
893 900 if (k2settings->verbose)
894 901 k2printf("bp: maxsize=%d, bp=%d, r0=%d\n",maxsize,bp,r0);
895 902 #if (WILLUSDEBUGX & 64)
@@ -1088,6 +1095,30 @@ k2printf("mi->published_pages=%d\n",masterinfo->published_pages);
1088 1095
1089 1096
1090 1097 /*
  1098 +** Return 0 if master bitmap should not be flushed.
  1099 +** NZ if it should be flushed.
  1100 +** Based on user settings for page breaks.
  1101 +** v2.10
  1102 +**
  1103 +*/
  1104 +int masterinfo_should_flush(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings)
  1105 +
  1106 + {
  1107 + if (k2settings_gap_override(k2settings))
  1108 + return(0);
  1109 + if (k2settings->dst_break_pages==0)
  1110 + return(0);
  1111 + if (k2settings->dst_break_pages>1)
  1112 + return(1);
  1113 + /* Check list of pages where user has requested a page break */
  1114 + if (k2settings->bpl[0]!='\0' && pagelist_includes_page(k2settings->bpl,masterinfo->pageinfo.srcpage+1,masterinfo->srcpages))
  1115 + return(1);
  1116 + /* Check outline / bookmarks if available */
  1117 + return(wpdfoutline_includes_srcpage(masterinfo->outline,masterinfo->pageinfo.srcpage+1,1)>0 ? 1 : 0);
  1118 + }
  1119 +
  1120 +
  1121 +/*
1091 1122 ** Correctly complete crop boxes that are associated with this output page
1092 1123 **
1093 1124 ** box->x1,y1,userx,usery start out as:
@@ -1236,7 +1267,23 @@ static void bmp_pad_and_mark(WILLUSBITMAP *dst,WILLUSBITMAP *src,K2PDFOPT_SETTIN
1236 1267
1237 1268 {
1238 1269 int i,r,r0,bw,bytespp,pl,pr,pt,pb;
1239   -
  1270 +/*
  1271 +printf("Pad: %d,%d,%d,%d\n",k2settings->pad_left,
  1272 +k2settings->pad_top,
  1273 +k2settings->pad_right,
  1274 +k2settings->pad_bottom);
  1275 +printf("OM: %g,%g,%g,%g\n",
  1276 +k2settings->dst_marleft,
  1277 +k2settings->dst_martop,
  1278 +k2settings->dst_marright,
  1279 +k2settings->dst_marbot);
  1280 +printf("Mar: %g,%g,%g,%g\n",
  1281 +k2settings->mar_left,
  1282 +k2settings->mar_top,
  1283 +k2settings->mar_right,
  1284 +k2settings->mar_bot);
  1285 +printf("usecropboxes=%d\n",k2settings->use_crop_boxes);
  1286 +*/
1240 1287 r0=(int)(bmpdpi*k2settings->dst_martop+.5);
1241 1288 if (k2settings->dst_landscape)
1242 1289 {
@@ -1579,6 +1626,7 @@ static void find_word_gaps_using_textrow(WILLUSBITMAP *src,K2PDFOPT_SETTINGS *k2
1579 1626 }
1580 1627
1581 1628
  1629 +#if 0
1582 1630 /*
1583 1631 ** Find gaps in the master bitmap so that it can be broken into regions
1584 1632 ** which go onto separate pages.
@@ -1592,10 +1640,14 @@ static int masterinfo_break_point(MASTERINFO *masterinfo,int maxsize)
1592 1640 int bp1f,bp2f;
1593 1641 int bp1e,bp2e;
1594 1642
1595   -/*
1596 1643 k2printf("@breakpoint, mi->rows=%d, maxsize=%d\n",masterinfo->rows,maxsize);
1597 1644 k2printf(" fit_to_page=%d\n",(int)masterinfo->fit_to_page);
1598   -*/
  1645 +{
  1646 +static int count=1;
  1647 +char filename[256];
  1648 +sprintf(filename,"page%04d.png",count++);
  1649 +bmp_write(&masterinfo->bmp,filename,stdout,100);
  1650 +}
1599 1651 /* masterinfo->fit_to_page==-2 means user specified -f2p -2 which means */
1600 1652 /* flush entire contents of master to single page every time. */
1601 1653 if (masterinfo->rows<maxsize || masterinfo->fit_to_page==-2)
@@ -1609,10 +1661,8 @@ k2printf(" fit_to_page=%d\n",(int)masterinfo->fit_to_page);
1609 1661 else
1610 1662 scanheight=maxsize;
1611 1663 /* If available rows almost exactly fit page, just send the whole thing */
1612   -/*
1613 1664 k2printf(" scanheight=%d, mi->rows=%d, fabs=%g\n",scanheight,masterinfo->rows,
1614 1665 fabs((double)scanheight/masterinfo->rows-1.));
1615   -*/
1616 1666 if (masterinfo->fit_to_page==0 && (abs(scanheight-masterinfo->rows)<=1
1617 1667 || fabs((double)scanheight/masterinfo->rows-1.)<.002))
1618 1668 return(masterinfo->rows);
@@ -1647,8 +1697,8 @@ fabs((double)scanheight/masterinfo->rows-1.));
1647 1697 {
1648 1698 if (rowcount[i]==0)
1649 1699 {
1650   -// if (cw==0)
1651   -// k2printf("%d black\n",fc);
  1700 +if (cw==0)
  1701 +k2printf("%d black\n",fc);
1652 1702 cw++;
1653 1703 if (fc>figure)
1654 1704 {
@@ -1678,29 +1728,27 @@ fabs((double)scanheight/masterinfo->rows-1.));
1678 1728 }
1679 1729 else
1680 1730 {
1681   -// if (fc==0)
1682   -// k2printf("%d white\n",cw);
  1731 +if (fc==0)
  1732 +k2printf("%d white\n",cw);
1683 1733 cw=0;
1684 1734 nwc++;
1685 1735 fc++;
1686 1736 }
1687 1737 }
1688   -/*
1689 1738 {
1690 1739 static int count=0;
1691 1740 FILE *out;
1692 1741 count++;
1693 1742 k2printf("rows=%d, gs=%d, scanheight=%d, bp1=%d, bp2=%d\n",masterinfo->rows,goodsize,scanheight,bp1,bp2);
1694 1743 k2printf(" bp1f=%d, bp2f=%d, bp1e=%d, bp2e=%d\n",bp1f,bp2f,bp1e,bp2e);
1695   -bmp_write(&masterinfo->bmp,"master.png",stdout,100);
1696   -out=fopen("rc.dat","w");
1697   -for (i=0;i<scanheight;i++)
1698   -fprintf(out,"%d\n",rowcount[i]);
1699   -fclose(out);
1700   -if (count==2)
1701   -exit(10);
  1744 +//bmp_write(&masterinfo->bmp,"master.png",stdout,100);
  1745 +//out=fopen("rc.dat","w");
  1746 +//for (i=0;i<scanheight;i++)
  1747 +//fprintf(out,"%d\n",rowcount[i]);
  1748 +//fclose(out);
  1749 +// if (count==2)
  1750 +// exit(10);
1702 1751 }
1703   -*/
1704 1752 willus_dmem_free(29,(double **)&rowcount,funcname);
1705 1753 if (masterinfo->fit_to_page==0)
1706 1754 {
@@ -1722,3 +1770,117 @@ exit(10);
1722 1770 return(bp2e);
1723 1771 return(bp1e);
1724 1772 }
  1773 +#endif /* 0 */
  1774 +
  1775 +
  1776 +/*
  1777 +** Find gaps in the master bitmap so that it can be broken into regions
  1778 +** which go onto separate pages.
  1779 +**
  1780 +** maxsize is the ideal desired bitmap size to fit the page.
  1781 +** Depending on the fit_to_page setting, the bitmap can actually go
  1782 +** beyond this.
  1783 +**
  1784 +** Re-written to use bmpregion_find_textrows() in v2.10.
  1785 +**
  1786 +*/
  1787 +static int masterinfo_break_point(MASTERINFO *masterinfo,K2PDFOPT_SETTINGS *k2settings,int maxsize)
  1788 +
  1789 + {
  1790 + int scanheight,j,r1,r2,r1a,r2a;
  1791 + BMPREGION region;
  1792 + WILLUSBITMAP *bmp,_bmp;
  1793 +
  1794 +/*
  1795 +k2printf("@breakpoint, mi->rows=%d, maxsize=%d\n",masterinfo->rows,maxsize);
  1796 +k2printf(" fit_to_page=%d\n",(int)masterinfo->fit_to_page);
  1797 +{
  1798 +static int count=1;
  1799 +char filename[256];
  1800 +sprintf(filename,"page%04d.png",count++);
  1801 +bmp_write(&masterinfo->bmp,filename,stdout,100);
  1802 +}
  1803 +*/
  1804 + /* masterinfo->fit_to_page==-2 means user specified -f2p -2 which means */
  1805 + /* flush entire contents of master to single page every time. */
  1806 + if (masterinfo->rows<maxsize || masterinfo->fit_to_page==-2)
  1807 + return(masterinfo->rows);
  1808 +
  1809 + /* scanheight tells how far down the master bitmap to scan */
  1810 + if (masterinfo->fit_to_page==-1)
  1811 + scanheight=masterinfo->rows;
  1812 + else if (masterinfo->fit_to_page>0)
  1813 + scanheight=(int)(((1.+masterinfo->fit_to_page/100.)*maxsize)+.5);
  1814 + else
  1815 + scanheight=maxsize;
  1816 + /* If available rows almost exactly fit page, just send the whole thing */
  1817 +/*
  1818 +k2printf(" scanheight=%d, mi->rows=%d, fabs=%g\n",scanheight,masterinfo->rows,
  1819 +fabs((double)scanheight/masterinfo->rows-1.));
  1820 +*/
  1821 + if (masterinfo->fit_to_page==0 && (abs(scanheight-masterinfo->rows)<=1
  1822 + || fabs((double)scanheight/masterinfo->rows-1.)<.002))
  1823 + return(masterinfo->rows);
  1824 + if (scanheight > masterinfo->rows)
  1825 + scanheight=masterinfo->rows;
  1826 +
  1827 + /*
  1828 + ** Find text rows (and gaps between)
  1829 + */
  1830 + bmp=&_bmp;
  1831 + bmp_init(bmp);
  1832 + if (bmp_is_grayscale(&masterinfo->bmp))
  1833 + bmp_copy(bmp,&masterinfo->bmp);
  1834 + else
  1835 + bmp_convert_to_grayscale_ex(bmp,&masterinfo->bmp);
  1836 + bmp->height=scanheight*1.4;
  1837 + if (bmp->height > masterinfo->rows)
  1838 + bmp->height = masterinfo->rows;
  1839 + bmpregion_init(&region);
  1840 + region.bgcolor=masterinfo->bgcolor;
  1841 + region.c1=0;
  1842 + region.c2=bmp->width-1;
  1843 + region.r1=0;
  1844 + region.r2=bmp->height-1;
  1845 + region.bmp8=bmp;
  1846 + region.bmp=bmp;
  1847 + region.dpi=k2settings->dst_dpi;
  1848 + bmpregion_find_textrows(&region,k2settings,0,1);
  1849 +/*
  1850 +{
  1851 +static int count=1;
  1852 +char filename[256];
  1853 +sprintf(filename,"page%04d.png",count);
  1854 +bmp_write(bmp,filename,stdout,100);
  1855 +printf("\nmaxsize=%d, scanheight=%d, dst_dpi=%d\n",maxsize,scanheight,k2settings->dst_dpi);
  1856 +printf("OUTPUT PAGE %d\n",count++);
  1857 +for (j=0;j<region.textrows.n;j++)
  1858 +{
  1859 +printf("%d. ",j+1);
  1860 +textrow_echo(&region.textrows.textrow[j],stdout);
  1861 +}
  1862 +}
  1863 +*/
  1864 + bmp_free(bmp);
  1865 + for (r1a=r2a=r1=r2=j=0;j<region.textrows.n;j++)
  1866 + {
  1867 + TEXTROW *row;
  1868 +
  1869 + row=&region.textrows.textrow[j];
  1870 + r2=row->r2+1;
  1871 + if (j<region.textrows.n-1)
  1872 + r2a=(row->r2+region.textrows.textrow[j+1].r1)/2; /* Midpoint */
  1873 + else
  1874 + r2a=r2;
  1875 + if (row->r2 > maxsize)
  1876 + break;
  1877 + r1=r2;
  1878 + r1a=r2a;
  1879 + }
  1880 + bmpregion_free(&region);
  1881 + if (r1a<=maxsize)
  1882 + r1=r1a;
  1883 + if (r2a<=scanheight)
  1884 + r2=r2a;
  1885 + return(r1<maxsize*.25 ? (r2<scanheight ? r2:scanheight) : r1);
  1886 + }
27 k2pdfoptlib/k2menu.c
@@ -278,11 +278,18 @@ int k2pdfopt_menu(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,STRBUF
278 278 }
279 279 else if (!stricmp(buf,"bp"))
280 280 {
281   - status=userinput_string("Break output pages at end of each input page",ansyesno,k2settings->dst_break_pages?"y":"n");
  281 + int bpo;
  282 + printf("Page breaking options:\n"
  283 + "1. Absolutely no special page breaks.\n"
  284 + "2. Special page breaks at bookmark positions only.\n"
  285 + "3. Break pages after each source page.\n"
  286 + "4. Break pages at each \"green\" boundary.\n"
  287 + "5. Put a gap between each source page.\n");
  288 + bpo = k2settings->dst_break_pages < 0 ? 5 : k2settings->dst_break_pages+1;
  289 + status=userinput_integer("Enter option",bpo,&bpo,1,5);
282 290 if (status<0)
283 291 return(status);
284   - k2settings->dst_break_pages=(status==0) ? 1 : 0;
285   - if (!k2settings->dst_break_pages)
  292 + if (bpo==5)
286 293 {
287 294 double x;
288 295 x=0.;
@@ -295,10 +302,16 @@ int k2pdfopt_menu(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,STRBUF
295 302 strbuf_sprintf(usermenu,"-bp %g",x);
296 303 }
297 304 else
  305 + {
  306 + k2settings->dst_break_pages=1;
298 307 strbuf_sprintf(usermenu,"-bp-");
  308 + }
299 309 }
300 310 else
301   - strbuf_sprintf(usermenu,"-bp");
  311 + {
  312 + k2settings->dst_break_pages=bpo-1;
  313 + strbuf_sprintf(usermenu,"-bp%s",bpo==4?"+":(bpo==3?"":(bpo==2?"-":"--")));
  314 + }
302 315 status=userinput_integer("Fit-to-page value",k2settings->dst_fit_to_page,&k2settings->dst_fit_to_page,
303 316 -2,999);
304 317 if (status<0)
@@ -559,8 +572,8 @@ int k2pdfopt_menu(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,STRBUF
559 572 }
560 573 else if (!stricmp(buf,"mo"))
561 574 {
562   - static char *modename[]={"default","copy","fitwidth","2-column","grid",""};
563   - static char *shortname[]={"def","copy","fw","2col","grid"};
  575 + static char *modename[]={"default","copy","trim","crop","fitwidth","fitpage","2-column","grid",""};
  576 + static char *shortname[]={"def","copy","tm","crop","fw","fp","2col","grid"};
564 577 double v[3];
565 578
566 579 status=userinput_string("Operating mode",modename,"default");
@@ -862,11 +875,13 @@ int k2pdfopt_menu(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,STRBUF
862 875 if (!status)
863 876 k2settings->text_wrap=2;
864 877 strbuf_sprintf(usermenu,"-wrap%s",k2settings->text_wrap==2?"+":"");
  878 + /*
865 879 status=userinput_string("Preserve indentation",ansyesno,k2settings->preserve_indentation?"y":"n");
866 880 if (status<0)
867 881 return(status);
868 882 k2settings->preserve_indentation=!status;
869 883 strbuf_sprintf(usermenu,"-pi%s",k2settings->preserve_indentation?"":"-");
  884 + */
870 885 status=userinput_string("Detect/eliminate hyphens",ansyesno,k2settings->hyphen_detect?"y":"n");
871 886 if (status<0)
872 887 return(status);
114 k2pdfoptlib/k2parsecmd.c
@@ -105,6 +105,7 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
105 105 MINUS_OPTION("-guimin",guimin,2)
106 106 #endif
107 107 MINUS_OPTION("-?",show_usage,2)
  108 + MINUS_OPTION("-toc",use_toc,1)
108 109 MINUS_OPTION("-sp",echo_source_page_count,1)
109 110 MINUS_OPTION("-neg",dst_negative,1)
110 111 MINUS_OPTION("-hy",hyphen_detect,1)
@@ -250,25 +251,32 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
250 251 if (setvals==1)
251 252 {
252 253 if (!stricmp(cl->cmdarg,"pdfr")
253   - || !stricmp(cl->cmdarg,"copy"))
  254 + || !stricmp(cl->cmdarg,"copy")
  255 + || !stricmp(cl->cmdarg,"trim")
  256 + || !stricmp(cl->cmdarg,"crop")
  257 + || !stricmp(cl->cmdarg,"tm"))
254 258 {
  259 + int tm,crop;
  260 +
  261 + crop=(!stricmp(cl->cmdarg,"crop"));
  262 + tm=(!stricmp(cl->cmdarg,"trim") || !stricmp(cl->cmdarg,"tm"));
255 263 /* -n- -wrap- -col 1 -vb -2 -w -1 -h -1 -dpi 150 -rt 0 -c -t- -f2p -2 */
256 264 /* -m 0 -om 0 -pl 0 -pr 0 -pt 0 -pb 0 -mc- */
257   - k2settings->use_crop_boxes=0;
  265 + k2settings->use_crop_boxes= (tm||crop) ? 1 : 0;
258 266 #ifdef HAVE_OCR_LIB
259   - k2settings->dst_ocr='m';
  267 + k2settings->dst_ocr=(tm||crop) ? 0 : 'm';
260 268 #endif
261 269 k2settings->text_wrap=0;
262 270 k2settings->max_columns=1;
263 271 k2settings->vertical_break_threshold=-2;
264 272 k2settings->dst_userwidth=1.0;
265   - k2settings->dst_userwidth_units=UNITS_SOURCE;
  273 + k2settings->dst_userwidth_units=(tm||crop) ? UNITS_TRIMMED : UNITS_SOURCE;
266 274 k2settings->dst_userheight=1.0;
267   - k2settings->dst_userheight_units=UNITS_SOURCE;
  275 + k2settings->dst_userheight_units=(tm||crop) ? UNITS_TRIMMED : UNITS_SOURCE;
268 276 k2settings->dst_dpi=150;
269 277 k2settings->src_rot=0.;
270 278 k2settings->dst_color=1;
271   - k2settings->src_trim=0;
  279 + k2settings->src_trim=tm ? 1 : 0;
272 280 k2settings->dst_fit_to_page=-2;
273 281 k2settings->mar_left=k2settings->mar_top=k2settings->mar_right=k2settings->mar_bot=0.;
274 282 k2settings->dst_mar=k2settings->dst_marleft=k2settings->dst_martop=k2settings->dst_marright=k2settings->dst_marbot=0.;
@@ -277,8 +285,13 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
277 285 }
278 286 else if (!stricmp(cl->cmdarg,"fw")
279 287 || !stricmp(cl->cmdarg,"sopdf")
280   - || !stricmp(cl->cmdarg,"fitwidth"))
  288 + || !stricmp(cl->cmdarg,"fitwidth")
  289 + || !stricmp(cl->cmdarg,"fp")
  290 + || !stricmp(cl->cmdarg,"fitpage"))
281 291 {
  292 + int fitpage;
  293 +
  294 + fitpage=(!stricmp(cl->cmdarg,"fp") || !stricmp(cl->cmdarg,"fitpage"));
282 295 /* -wrap- -col 1 -vb -2 -t -ls */
283 296 k2settings->use_crop_boxes=1;
284 297 #ifdef HAVE_OCR_LIB
@@ -288,7 +301,9 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
288 301 k2settings->max_columns=1;
289 302 k2settings->vertical_break_threshold=-2;
290 303 k2settings->src_trim=1;
291   - k2settings->dst_landscape=1;
  304 + if (fitpage)
  305 + k2settings->dst_fit_to_page=-2;
  306 + k2settings->dst_landscape=fitpage ? 0 : 1;
292 307 }
293 308 else if (!stricmp(cl->cmdarg,"2col")
294 309 || !stricmp(cl->cmdarg,"2-column")
@@ -406,18 +421,19 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
406 421 continue;
407 422 }
408 423 if (!stricmp(cl->cmdarg,"-bp") || !stricmp(cl->cmdarg,"-bp-")
  424 + || !stricmp(cl->cmdarg,"-bp--")
409 425 || !stricmp(cl->cmdarg,"-bp+"))
410 426 {
411 427 if (cl->cmdarg[3]=='-')
412 428 {
413 429 if (setvals==1)
414   - k2settings->dst_break_pages=0;
  430 + k2settings->dst_break_pages = (cl->cmdarg[4]=='-' ? 0 : 1);
415 431 continue;
416 432 }
417 433 if (cl->cmdarg[3]=='+')
418 434 {
419 435 if (setvals==1)
420   - k2settings->dst_break_pages=2;
  436 + k2settings->dst_break_pages=3;
421 437 continue;
422 438 }
423 439 if (cmdlineinput_next(cl)==NULL)
@@ -430,7 +446,7 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
430 446 else
431 447 {
432 448 if (setvals==1)
433   - k2settings->dst_break_pages=1;
  449 + k2settings->dst_break_pages=2;
434 450 readnext=0;
435 451 }
436 452 continue;
@@ -876,6 +892,79 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
876 892 }
877 893 continue;
878 894 }
  895 + if (!stricmp(cl->cmdarg,"-cbox-"))
  896 + {
  897 + if (setvals==1)
  898 + k2settings->cropboxes.n=0;
  899 + continue;
  900 + }
  901 + if (!stricmp(cl->cmdarg,"-cbox")
  902 + || !stricmp(cl->cmdarg,"-cboxe")
  903 + || !stricmp(cl->cmdarg,"-cboxo"))
  904 + {
  905 + int c;
  906 +
  907 + c=tolower(cl->cmdarg[5]);
  908 + if (cmdlineinput_next(cl)==NULL)
  909 + break;
  910 + if (setvals==1)
  911 + {
  912 + double v[4];
  913 + int na,index;
  914 +
  915 + if (k2settings->cropboxes.n>=MAXK2CROPBOXES)
  916 + {
  917 + static int warned=0;
  918 + if (!warned && !quiet)
  919 + {
  920 + k2printf(TTEXT_WARN "\a\n** Max crop boxes exceeded (max=%d). **\n\n",
  921 + MAXK2CROPBOXES);
  922 + k2printf(TTEXT_WARN "\a\n** Crop box %s and subsequent ignored. **\n\n",
  923 + cl->cmdarg);
  924 + }
  925 + warned=1;
  926 + continue;
  927 + }
  928 + na=string_read_doubles(cl->cmdarg,v,4);
  929 + if (na!=4)
  930 + {
  931 + if (!quiet)
  932 + k2printf(TTEXT_WARN "\a\n** Crop box %s is invalid and will be ignored. **\n\n"
  933 + TTEXT_NORMAL,cl->cmdarg);
  934 + }
  935 + else
  936 + {
  937 + index=k2settings->cropboxes.n;
  938 + k2settings->cropboxes.cropbox[index].flags=(c=='e')?1:(c=='o'?2:3);
  939 + k2settings->cropboxes.cropbox[index].left=v[0];
  940 + k2settings->cropboxes.cropbox[index].top=v[1];
  941 + k2settings->cropboxes.cropbox[index].width=v[2];
  942 + k2settings->cropboxes.cropbox[index].height=v[3];
  943 + k2settings->cropboxes.n++;
  944 + }
  945 + }
  946 + continue;
  947 + }
  948 + if (!stricmp(cl->cmdarg,"-pad"))
  949 + {
  950 + if (cmdlineinput_next(cl)==NULL)
  951 + break;
  952 + if (setvals==1)
  953 + {
  954 + double v[4];
  955 + int na;
  956 + na=string_read_doubles(cl->cmdarg,v,4);
  957 + if (na>=1)
  958 + k2settings->pad_left=k2settings->pad_top=k2settings->pad_right=k2settings->pad_bottom=v[0];
  959 + if (na>=2)
  960 + k2settings->pad_top=k2settings->pad_right=k2settings->pad_bottom=v[1];
  961 + if (na>=3)
  962 + k2settings->pad_right=k2settings->pad_bottom=v[2];
  963 + if (na>=4)
  964 + k2settings->pad_bottom=v[3];
  965 + }
  966 + continue;
  967 + }
879 968 if (!strnicmp(cl->cmdarg,"-hq",3))
880 969 {
881 970 if (setvals==1)
@@ -915,6 +1004,9 @@ int parse_cmd_args(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline,
915 1004 readnext=0;
916 1005 continue;
917 1006 }
  1007 + NEEDS_STRING("-toclist",toclist,2047);
  1008 + NEEDS_STRING("-tocsave",tocsavefile,MAXFILENAMELEN-1);
  1009 + NEEDS_STRING("-bpl",bpl,2047);
918 1010 NEEDS_STRING("-p",pagelist,1023)
919 1011 #ifdef HAVE_OCR_LIB
920 1012 NEEDS_STRING("-ocrout",ocrout,127)
40 k2pdfoptlib/k2pdfopt.h