Exemplo n.º 1
0
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(&region);
    masterinfo_new_source_page_init(masterinfo, k2settings, src, srcgrey, NULL,
            &region, k2settings->src_rot, NULL, NULL, 1, -1, NULL );
    /* Set output size */
    k2pdfopt_settings_set_margins_and_devsize(k2settings,&region,masterinfo,-1.,0);
    /* Process single source page */
    bmpregion_source_page_add(&region, 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(&region);
    masterinfo_free(masterinfo, k2settings);
}
Exemplo n.º 2
0
// 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
    }