void k2pdfopt_reflow_bmp(KOPTContext *kctx) { K2PDFOPT_SETTINGS _k2settings, *k2settings; MASTERINFO _masterinfo, *masterinfo; WILLUSBITMAP _srcgrey, *srcgrey; WILLUSBITMAP *src, *dst; BMPREGION region; int i, bw, marbot, marleft; src = &kctx->src; srcgrey = &_srcgrey; bmp_init(srcgrey); k2settings = &_k2settings; masterinfo = &_masterinfo; /* Initialize settings */ k2pdfopt_settings_init_from_koptcontext(k2settings, kctx); k2pdfopt_settings_quick_sanity_check(k2settings); /* Init for new source doc */ k2pdfopt_settings_new_source_document_init(k2settings); /* Init master output structure */ masterinfo_init(masterinfo, k2settings); wrapbmp_init(&masterinfo->wrapbmp, k2settings->dst_color); /* Init new source bitmap */ bmpregion_init(®ion); masterinfo_new_source_page_init(masterinfo, k2settings, src, srcgrey, NULL, ®ion, k2settings->src_rot, NULL, NULL, 1, -1, NULL ); /* Set output size */ k2pdfopt_settings_set_margins_and_devsize(k2settings,®ion,masterinfo,-1.,0); /* Process single source page */ bmpregion_source_page_add(®ion, k2settings, masterinfo, 1, 0); wrapbmp_flush(masterinfo, k2settings, 0); if (fabs(k2settings->dst_gamma - 1.0) > .001) bmp_gamma_correct(&masterinfo->bmp, &masterinfo->bmp, k2settings->dst_gamma); /* copy master bitmap to context dst bitmap */ dst = &kctx->dst; marbot = (int) (k2settings->dst_dpi * k2settings->dstmargins.box[1] + .5); marleft = (int) (k2settings->dst_dpi * k2settings->dstmargins.box[0] + .5); dst->bpp = masterinfo->bmp.bpp; dst->width = masterinfo->bmp.width; dst->height = masterinfo->rows > kctx->page_height ? masterinfo->rows + marbot : kctx->page_height; bmp_alloc(dst); bmp_fill(dst, 255, 255, 255); bw = bmp_bytewidth(&masterinfo->bmp); for (i = 0; i < masterinfo->rows; i++) memcpy(bmp_rowptr_from_top(dst, i), bmp_rowptr_from_top(&masterinfo->bmp, i), bw); kctx->page_width = kctx->dst.width; kctx->page_height = kctx->dst.height; kctx->precache = 0; int j; BOXA *rboxa = boxaCreate(masterinfo->rectmaps.n); BOXA *nboxa = boxaCreate(masterinfo->rectmaps.n); for (j = 0; j < masterinfo->rectmaps.n; j++) { WRECTMAP * rectmap = &masterinfo->rectmaps.wrectmap[j]; rectmap->coords[1].x += marleft; BOX* rlbox = boxCreate(rectmap->coords[1].x, rectmap->coords[1].y, rectmap->coords[2].x, rectmap->coords[2].y); BOX* nlbox = boxCreate(rectmap->coords[0].x*k2settings->src_dpi/rectmap->srcdpiw/kctx->zoom + kctx->bbox.x0, rectmap->coords[0].y*k2settings->src_dpi/rectmap->srcdpih/kctx->zoom + kctx->bbox.y0, rectmap->coords[2].x*k2settings->src_dpi/rectmap->srcdpiw/kctx->zoom, rectmap->coords[2].y*k2settings->src_dpi/rectmap->srcdpih/kctx->zoom); boxaAddBox(rboxa, rlbox, L_INSERT); boxaAddBox(nboxa, nlbox, L_INSERT); wrectmaps_add_wrectmap(&kctx->rectmaps, rectmap); /*printf("rectmap:coords:\t%.1f %.1f\t%.1f %.1f\t%.1f %.1f\t%.1f %.1f\n", rectmap->coords[0].x, rectmap->coords[0].y, rectmap->coords[1].x, rectmap->coords[1].y, rectmap->coords[2].x, rectmap->coords[2].y, rectmap->srcdpiw, rectmap->srcdpih);*/ } /* 2D sort the bounding boxes of these words. */ BOXAA *rbaa = boxaSort2d(rboxa, NULL, 3, -5, 5); BOXAA *nbaa = boxaSort2d(nboxa, NULL, 3, -5, 5); /* Flatten the boxaa, saving the boxa index for each box */ kctx->rboxa = boxaaFlattenToBoxa(rbaa, &kctx->rnai, L_CLONE); kctx->nboxa = boxaaFlattenToBoxa(nbaa, &kctx->nnai, L_CLONE); boxaDestroy(&rboxa); boxaaDestroy(&rbaa); boxaDestroy(&nboxa); boxaaDestroy(&nbaa); bmp_free(src); bmp_free(srcgrey); bmpregion_free(®ion); masterinfo_free(masterinfo, k2settings); }
// static int bcount=0; void wrapbmp_add(WRAPBMP *wrapbmp,BMPREGION *region,K2PDFOPT_SETTINGS *k2settings, MASTERINFO *masterinfo,int colgap,int just_flags) { WILLUSBITMAP *tmp,_tmp; int i,rh,th,bw,new_base,h2,bpp,width0; // static char filename[256]; #if (WILLUSDEBUGX & 205) k2printf("@wrapbmp->add %d x %d (w=%d).\n",region->c2-region->c1+1,region->r2-region->r1+1,wrapbmp->bmp.width); printf(" line_spacing=%d\n",region->bbox.rowheight); #endif /* Figure out if what we're adding ends in a hyphen */ bmpregion_hyphen_detect(region,k2settings->hyphen_detect,k2settings->src_left_to_right); if (wrapbmp_ends_in_hyphen(wrapbmp)) colgap=0; wrapbmp_hyphen_erase(wrapbmp,k2settings); wrapbmp->just_flushed_internal=0; // Reset "just flushed" flag if (wrapbmp->bmp.width==0) wrapbmp->textrow=region->bbox; else { if (region->bbox.rowheight > wrapbmp->textrow.rowheight) wrapbmp->textrow.rowheight = region->bbox.rowheight; if (region->bbox.gap > wrapbmp->textrow.gap) wrapbmp->textrow.gap = region->bbox.gap; if (region->bbox.gapblank > wrapbmp->textrow.gapblank) wrapbmp->textrow.gapblank = region->bbox.gapblank; } wrapbmp->bgcolor=region->bgcolor; wrapbmp->just=just_flags; if (wrapbmp->mandatory_region_gap<0) { wrapbmp->mandatory_region_gap=masterinfo->mandatory_region_gap; wrapbmp->page_region_gap_in=masterinfo->page_region_gap_in; masterinfo->mandatory_region_gap=0; masterinfo->page_region_gap_in=-1.; #if (WILLUSDEBUGX & 0x200) aprintf(ANSI_RED "mi->mandatory_region_gap change to %d by wrap_add." ANSI_NORMAL "\n",masterinfo->mandatory_region_gap); #endif } #if (WILLUSDEBUGX & 4) k2printf(" c1=%d, c2=%d, r1=%d, r2=%d\n",region->c1,region->c2,region->r1,region->r2); k2printf(" colgap=%d, line_spacing=%d, rowbase=%d, row gap=%d\n",colgap,region->bbox.rowheight,region->bbox.rowbase,region->bbox.gap); #endif bpp=k2settings->dst_color?3:1; rh=region->bbox.rowbase-region->r1+1; if (rh > wrapbmp->rhmax) wrapbmp->rhmax=rh; th = rh + (region->r2-region->bbox.rowbase); if (th > wrapbmp->thmax) wrapbmp->thmax=th; #if (WILLUSDEBUGX & 4) { static int bcount=0; char filename[256]; sprintf(filename,"out%05d.png",bcount++); bmpregion_write(region,filename); } #endif if (wrapbmp->bmp.width==0) { /* Put appropriate gap in */ /* if (k2settings->last_rowbase_internal>=0 && rh < wrapbmp->textrow.rowheight-k2settings->last_rowbase_internal) { rh = wrapbmp->textrow.rowheight - k2settings->last_rowbase_internal; if (rh<2) rh=2; th = rh + (region->r2-region->bbox.rowbase); wrapbmp->height_extended=0; } else wrapbmp->height_extended=(k2settings->last_rowbase_internal>=0); */ wrapbmp->base = rh-1; wrapbmp->bmp.height = th; #if (WILLUSDEBUGX & 4) k2printf(" bmpheight set to %d (line spacing=%d)\n",wrapbmp->bmp.height,wrapbmp->textrow.rowheight); #endif wrapbmp->bmp.width=region->c2-region->c1+1; bmp_alloc(&wrapbmp->bmp); bw=bmp_bytewidth(&wrapbmp->bmp); memset(bmp_rowptr_from_top(&wrapbmp->bmp,0),255,bw*wrapbmp->bmp.height); for (i=region->r1;i<=region->r2;i++) { unsigned char *d,*s; d=bmp_rowptr_from_top(&wrapbmp->bmp,wrapbmp->base+(i-region->bbox.rowbase)); s=bmp_rowptr_from_top(k2settings->dst_color?region->bmp:region->bmp8,i)+bpp*region->c1; memcpy(d,s,bw); } #ifdef WILLUSDEBUG if (wrapbmp->bmp.height<=wrapbmp->base) { k2printf("1. SCREEECH!\n"); k2printf("wrapbmp = %d x %d, base=%d\n",wrapbmp->bmp.width,wrapbmp->bmp.height,wrapbmp->base); exit(10); } #endif /* Copy hyphen info from added region */ wrapbmp->hyphen = region->bbox.hyphen; if (wrapbmp_ends_in_hyphen(wrapbmp)) { wrapbmp->hyphen.r1 += (wrapbmp->base-region->bbox.rowbase); wrapbmp->hyphen.r2 += (wrapbmp->base-region->bbox.rowbase); wrapbmp->hyphen.ch -= region->c1; wrapbmp->hyphen.c2 -= region->c1; } /* Map to source page */ { WRECTMAP _wrmap,*wrmap; wrmap=&_wrmap; wrmap->srcpageno = region->pageno; wrmap->srcwidth = region->bmp8->width; wrmap->srcheight = region->bmp8->height; wrmap->srcdpiw = wrmap->srcdpih = region->dpi; wrmap->srcrot = region->rotdeg; wrmap->coords[0].x = region->c1; wrmap->coords[0].y = region->r1; wrmap->coords[1].x = 0; wrmap->coords[1].y = wrapbmp->base+(region->r1-region->bbox.rowbase); wrmap->coords[2].x = region->c2-region->c1+1; wrmap->coords[2].y = region->r2-region->r1+1; #if (WILLUSDEBUGX & 0x400) printf("@wrapbmp: (x0,y0) = (%5.1f,%5.1f)\n",region->c1*72./region->dpi,region->r1*72./region->dpi); printf(" %5.1f x %5.1f\n",(region->c2-region->c1+1)*72./region->dpi,(region->r2-region->r1+1)*72./region->dpi); printf(" New bitmap = %d x %d\n",wrapbmp->bmp.width,wrapbmp->bmp.height); #endif wrectmaps_add_wrectmap(&wrapbmp->wrectmaps,wrmap); } return; } width0=wrapbmp->bmp.width; /* Starting wrapbmp width */ tmp=&_tmp; bmp_init(tmp); bmp_copy(tmp,&wrapbmp->bmp); tmp->width += colgap+region->c2-region->c1+1; if (rh > wrapbmp->base) { /* wrapbmp->height_extended=1; */ new_base = rh-1; } else new_base = wrapbmp->base; if (region->r2-region->bbox.rowbase > wrapbmp->bmp.height-1-wrapbmp->base) h2=region->r2-region->bbox.rowbase; else h2=wrapbmp->bmp.height-1-wrapbmp->base; tmp->height = new_base + h2 + 1; bmp_alloc(tmp); bw=bmp_bytewidth(tmp); memset(bmp_rowptr_from_top(tmp,0),255,bw*tmp->height); bw=bmp_bytewidth(&wrapbmp->bmp); #if (WILLUSDEBUGX & 4) k2printf("3. wbh=%d x %d, tmp=%d x %d x %d, new_base=%d, wbbase=%d\n",wrapbmp->bmp.width,wrapbmp->bmp.height,tmp->width,tmp->height,tmp->bpp,new_base,wrapbmp->base); #endif /* Adjust previous mappings to source pages since WRAPBMP rectangle has been re-sized */ if (new_base!=wrapbmp->base) for (i=0;i<wrapbmp->wrectmaps.n;i++) { wrapbmp->wrectmaps.wrectmap[i].coords[1].y += (new_base-wrapbmp->base); if (k2settings->src_left_to_right==0) wrapbmp->wrectmaps.wrectmap[i].coords[1].x += tmp->width-1-wrapbmp->bmp.width; } for (i=0;i<wrapbmp->bmp.height;i++) { unsigned char *d,*s; d=bmp_rowptr_from_top(tmp,i+new_base-wrapbmp->base) + (k2settings->src_left_to_right ? 0 : tmp->width-1-wrapbmp->bmp.width)*bpp; s=bmp_rowptr_from_top(&wrapbmp->bmp,i); memcpy(d,s,bw); } bw=bpp*(region->c2-region->c1+1); if (region->r1+new_base-region->bbox.rowbase<0 || region->r2+new_base-region->bbox.rowbase>tmp->height-1) { k2printf(ANSI_YELLOW "INTERNAL ERROR--TMP NOT DIMENSIONED PROPERLY.\n"); k2printf("(%d-%d), tmp->height=%d\n" ANSI_NORMAL, region->r1+new_base-region->bbox.rowbase, region->r2+new_base-region->bbox.rowbase,tmp->height); exit(10); } for (i=region->r1;i<=region->r2;i++) { unsigned char *d,*s; d=bmp_rowptr_from_top(tmp,i+new_base-region->bbox.rowbase) + (k2settings->src_left_to_right ? wrapbmp->bmp.width+colgap : 0)*bpp; s=bmp_rowptr_from_top(k2settings->dst_color?region->bmp:region->bmp8,i)+bpp*region->c1; memcpy(d,s,bw); } { WRECTMAP _wrmap,*wrmap; wrmap=&_wrmap; wrmap->srcpageno = region->pageno; wrmap->srcwidth = region->bmp8->width; wrmap->srcheight = region->bmp8->height; wrmap->srcdpiw = wrmap->srcdpih = region->dpi; wrmap->srcrot = region->rotdeg; wrmap->coords[0].x = region->c1; wrmap->coords[0].y = region->r1; wrmap->coords[1].x = k2settings->src_left_to_right ? wrapbmp->bmp.width+colgap : 0; wrmap->coords[1].y = region->r1+new_base-region->bbox.rowbase; wrmap->coords[2].x = region->c2-region->c1+1; wrmap->coords[2].y = region->r2-region->r1+1; #if (WILLUSDEBUGX & 0x400) printf("@wrapbmp: (x0,y0) = (%5.1f,%5.1f)\n",region->c1*72./region->dpi,region->r1*72./region->dpi); printf(" org bmp = %d x %d\n",wrapbmp->bmp.width,wrapbmp->bmp.height); printf(" new_base=%d, r_base=%d\n",new_base,region->bbox.rowbase); printf(" (x1,y1) = (%g,%g)\n",wrmap->coords[1].x,wrmap->coords[1].y); printf(" %5.1f x %5.1f\n",(region->c2-region->c1+1)*72./region->dpi,(region->r2-region->r1+1)*72./region->dpi); printf(" New bitmap = %d x %d\n",tmp->width,tmp->height); #endif wrectmaps_add_wrectmap(&wrapbmp->wrectmaps,wrmap); } bmp_copy(&wrapbmp->bmp,tmp); #if (WILLUSDEBUGX & 4) { static int rcount=0; char filename[256]; sprintf(filename,"result%03d.png",rcount++); bmp_write(tmp,filename,stdout,100); } #endif bmp_free(tmp); /* Copy region's hyphen info */ wrapbmp->hyphen = region->bbox.hyphen; if (wrapbmp_ends_in_hyphen(wrapbmp)) { wrapbmp->hyphen.r1 += (new_base-region->bbox.rowbase); wrapbmp->hyphen.r2 += (new_base-region->bbox.rowbase); if (k2settings->src_left_to_right) { wrapbmp->hyphen.ch += width0+colgap-region->c1; wrapbmp->hyphen.c2 += width0+colgap-region->c1; } else { wrapbmp->hyphen.ch -= region->c1; wrapbmp->hyphen.c2 -= region->c1; } } wrapbmp->base=new_base; /* Doesn't seem to work? v2.00 */ /* wrapbmp->textrow.gap = (wrapbmp->bmp.height-1)-new_base; wrapbmp->textrow.gapblank = 0; */ #ifdef WILLUSDEBUG if (wrapbmp->bmp.height<=wrapbmp->base) { k2printf("2. SCREEECH!\n"); k2printf("wrapbmp = %d x %d, base=%d\n",wrapbmp->bmp.width,wrapbmp->bmp.height,wrapbmp->base); exit(10); } #endif }