Ejemplo n.º 1
0
void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum)
{
    int i_old, *p;
    struct avl_traverser t;
    assert(glyph_names != NULL);
    assert(tx_tree != NULL);
    assert(fe_objnum != 0);
    pdf_begin_dict(fe_objnum, 1);
    pdf_puts("/Type /Encoding\n");
    pdf_printf("/Differences [");
    avl_t_init(&t, tx_tree);
    for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL;
         p = (int *) avl_t_next(&t)) {
        if (*p == i_old + 1)    /* no gap */
            pdf_printf("/%s", glyph_names[*p]);
        else {
            if (i_old == -2)
                pdf_printf("%i/%s", *p, glyph_names[*p]);
            else
                pdf_printf(" %i/%s", *p, glyph_names[*p]);
        }
        i_old = *p;
    }
    pdf_puts("]\n");
    pdf_end_dict();
}
Ejemplo n.º 2
0
static void
pdf_write_pnode(PDF *p,
	id node_id,
	id parent_id,
	id *kids,
	int n_kids,
	int n_pages)
{
    pdf_begin_obj(p, node_id);
    pdf_begin_dict(p);
    pdf_puts(p, "/Type/Pages\n");
    pdf_printf(p, "/Count %d\n", n_pages);

    if (parent_id != BAD_ID)
	pdf_printf(p, "/Parent %d 0 R\n", parent_id);

    pdf_puts(p, "/Kids[");

    do
    {
	pdf_printf(p, "%ld 0 R", *kids++);
	pdf_putc(p, PDF_NEWLINE);
    } while (--n_kids > 0);

    pdf_puts(p, "]");
    pdf_end_dict(p);
    pdf_end_obj(p);
}
Ejemplo n.º 3
0
static void set_font(PDF pdf)
{
    pdfstructure *p = pdf->pstruct;

    if (p->need_width != 0) {
        pdf_printf(pdf, "%0.3f w\n",((7227.0/7200.0)/1000.0) * p->need_width );
        p->done_width = 1;
    } else if (p->done_width) {
        pdf_puts(pdf, "0 w\n");
        p->done_width = 0;
    }
    if (p->need_mode != 0) {
        pdf_printf(pdf, "%d Tr\n", (int) p->need_mode);
        p->done_mode = 1;
    } else if (p->done_mode) {
        pdf_puts(pdf, "0 Tr\n");
        p->done_mode = 0;
    }
    pdf_printf(pdf, "/F%d", (int) p->f_pdf);
    pdf_print_resname_prefix(pdf);
    pdf_out(pdf, ' ');
    print_pdffloat(pdf, p->fs);
    pdf_puts(pdf, " Tf\n");
    p->f_pdf_cur = p->f_pdf;
    p->fs_cur.m = p->fs.m;
    p->need_tf = false;
    /*tex Always follow |Tf| by |Tm|: */
    p->need_tm = true;
}
Ejemplo n.º 4
0
void
pdf_begin_contents_section(PDF *p)
{
    if (p->contents != c_none)
	return;

    if (p->next_content >= p->contents_ids_capacity) {
	p->contents_ids_capacity *= 2;
	p->contents_ids = (id *) p->realloc(p, p->contents_ids,
			    sizeof(long) * p->contents_ids_capacity,
			    "pdf_begin_contents_section");
    }

    p->contents_ids[p->next_content] = pdf_begin_obj(p, NEW_ID);
    p->contents	= c_page;
    pdf_begin_dict(p);
    p->contents_length_id = pdf_alloc_id(p);
    pdf_printf(p, "/Length %ld 0 R\n", p->contents_length_id);

    if (p->compresslevel)
	pdf_puts(p, "/Filter/FlateDecode\n");

    pdf_end_dict(p);

    pdf_begin_stream(p);

    pdf_compress_init(p);
    							/* Contents object */
    p->start_contents_pos = pdf_tell(p);
    p->next_content++;
}
Ejemplo n.º 5
0
void
pdf_write_xobjects(PDF *p)
{
    if (p->xobjects_number > 0)
    {
	pdf_bool hit = pdf_false;
	int i;

	for (i = 0; i < p->xobjects_capacity; ++i)
	{
	    if (p->xobjects[i].flags & xobj_flag_write)
	    {
		if (!hit)
		{
		    pdf_puts(p, "/XObject");
		    pdf_begin_dict(p);
		    hit = pdf_true;
		}

		pdf_printf(p, "/I%d %ld 0 R\n", i, p->xobjects[i].obj_id);
		p->xobjects[i].flags &= ~xobj_flag_write;
	    }
	}

	if (hit)
	    pdf_end_dict(p);
    }
}
Ejemplo n.º 6
0
void
pdf_write_annots_root(PDF *p)
{
    pdf_annot *ann;

    /* Annotations array */
    if (p->annots) {
	pdf_puts(p, "/Annots[");

	for (ann = p->annots; ann != NULL; ann = ann->next) {
	    ann->obj_id = pdf_alloc_id(p);
	    pdf_printf(p, "%ld 0 R ", ann->obj_id);
	}

	pdf_puts(p, "]\n");
    }
}
Ejemplo n.º 7
0
static void write_fontname(fd_entry * fd, const char *key)
{
    assert(fd->fontname != NULL);
    pdf_puts("/");
    if (key != NULL)
        pdf_printf("%s /", key);
    if (fd->subset_tag != NULL)
        pdf_printf("%s+", fd->subset_tag);
    pdf_printf("%s\n", fd->fontname);
}
Ejemplo n.º 8
0
static void
pdf_write_header(PDF *p)
{
    /* Write the document header */
    /*
     * Although the %PDF-1.3 header also works with older Acrobat viewers,
     * we need a 1.2 header for special applications (controlled by the
     * client).
    */

    if (p->compatibility == PDF_1_4)
	pdf_puts(p, "%PDF-1.4\n");	      	/* PDF 1.4 header */
    else if (p->compatibility == PDF_1_3)
	pdf_puts(p, "%PDF-1.3\n");	      	/* PDF 1.3 header */
    else
	pdf_puts(p, "%PDF-1.2\n");	      	/* PDF 1.2 header */

    /* binary magic number */
    pdf_write(p, PDF_MAGIC_BINARY, sizeof(PDF_MAGIC_BINARY) - 1);
}
Ejemplo n.º 9
0
/* Write annotation border style and color */
static void
pdf_write_border_style(PDF *p, pdf_annot *ann)
{
    /* don't write the default values */
    if (ann->border_style == border_solid && ann->border_width == (float) 1.0 &&
	p->border_red == (float) 0.0 && p->border_green == (float) 0.0 &&
	p->border_blue == (float) 0.0 &&
	p->border_dash1 == (float) 3.0 && p->border_dash2 == (float) 3.0)
	return;

    if (ann->type != ann_attach) {
	pdf_puts(p, "/BS");
	pdf_begin_dict(p);			/* BS dict */
	pdf_puts(p, "/Type/Border\n");

	if (ann->border_style != border_solid)
	    pdf_printf(p, "/S/%s\n", pdf_border_style_names[ann->border_style]);

	if (ann->border_style == border_dashed)
	    pdf_printf(p, "/D[%f %f]\n", ann->border_dash1, ann->border_dash2);

	pdf_end_dict(p);			/* BS dict */

	/* Write the Border key in old-style PDF 1.1 format */
	pdf_printf(p, "/Border[0 0 %f", ann->border_width);

	if (ann->border_style == border_dashed &&
	    (ann->border_dash1 != (float) 0.0 || ann->border_dash2 !=
	    (float) 0.0))
	    /* set dashed border */
	    pdf_printf(p, "[%f %f]", ann->border_dash1, ann->border_dash2);

	pdf_puts(p, "]\n");

    }

    /* write annotation color */
    pdf_printf(p, "/C[%f %f %f]\n",
		    ann->border_red, ann->border_green, ann->border_blue);
}
Ejemplo n.º 10
0
void write_jpg(integer img)
{
    long unsigned l;
    FILE *f;
    pdf_puts("/Type /XObject\n/Subtype /Image\n");
    pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
               (int) img_width(img),
               (int) img_height(img),
               (int) jpg_ptr(img)->bits_per_component,
               (int) jpg_ptr(img)->length);
    pdf_puts("/ColorSpace ");
    if (img_colorspace_ref(img) != 0) {
        pdf_printf("%i 0 R\n", (int) img_colorspace_ref(img));
    } else {
        switch (jpg_ptr(img)->color_space) {
        case JPG_GRAY:
            pdf_puts("/DeviceGray\n");
            break;
        case JPG_RGB:
            pdf_puts("/DeviceRGB\n");
            break;
        case JPG_CMYK:
            pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
            break;
        default:
            pdftex_fail("Unsupported color space %i",
                        (int) jpg_ptr(img)->color_space);
        }
    }
    pdf_puts("/Filter /DCTDecode\n>>\nstream\n");
    for (l = jpg_ptr(img)->length, f = jpg_ptr(img)->file; l > 0; l--)
        pdfout(xgetc(f));
    pdfendstream();
}
Ejemplo n.º 11
0
void
pdf_printf(PDF *p, const char *fmt, ...)
{
    char	buf[LINEBUFLEN];	/* formatting buffer */
    va_list ap;

    va_start(ap, fmt);

    vsprintf(buf, fmt, ap);
    pdf_puts(p, buf);

    va_end(ap);
}
Ejemplo n.º 12
0
void epdf_write_enc(char **glyph_names, integer fe_objnum)
{
    int i, i_old;
    assert(glyph_names != NULL);
    assert(fe_objnum != 0);
    pdf_begin_dict(fe_objnum, 1);
    pdf_puts("/Type /Encoding\n");
    pdf_printf("/Differences [");
    for (i = 0, i_old = -2; i < 256; i++)
        if (glyph_names[i] != notdef) {
            if (i == i_old + 1) /* no gap */
                pdf_printf("/%s", glyph_names[i]);
            else {
                if (i_old == -2)
                    pdf_printf("%i/%s", i, glyph_names[i]);
                else
                    pdf_printf(" %i/%s", i, glyph_names[i]);
            }
            i_old = i;
        }
    pdf_puts("]\n");
    pdf_end_dict();
}
Ejemplo n.º 13
0
static void set_textmatrix(PDF pdf, scaledpos pos)
{
    boolean move;
    pdfstructure *p = pdf->pstruct;
    if (!is_textmode(p))
        normal_error("pdf backend","text mode expected in set_textmatrix");
    move = calc_pdfpos(p, pos);
    if (p->need_tm || move) {
        print_pdf_matrix(pdf, p->tm);
        pdf_puts(pdf, " Tm ");
        /*tex |Tm| replaces */
        p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m;
        p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m;
        p->need_tm = false;
    }
    p->tm0_cur.m = p->tm[0].m;
}
Ejemplo n.º 14
0
void
pdf_write_page_procsets(PDF *p)
{
    pdf_puts(p, "/ProcSet[/PDF");

    if (p->procset & ImageB)	pdf_puts(p, "/ImageB");
    if (p->procset & ImageC)	pdf_puts(p, "/ImageC");
    if (p->procset & ImageI)	pdf_puts(p, "/ImageI");
    if (p->procset & Text)	pdf_puts(p, "/Text");

    pdf_puts(p, "]\n");
}
Ejemplo n.º 15
0
void
pdf_write_page_colorspaces(PDF *p)
{
    int i, total = 0;

    for (i = 0; i < p->colorspaces_number; i++)
        if (p->colorspaces[i].used_on_current_page)
            total++;

    if (total > 0) {
        pdf_puts(p, "/ColorSpace");

        pdf_begin_dict(p);			/* color space names */

        for (i = 0; i < p->colorspaces_number; i++) {
            if (p->colorspaces[i].used_on_current_page) {
                p->colorspaces[i].used_on_current_page = pdf_false; /* reset */
                pdf_printf(p, "/CS%d %ld 0 R\n", i, p->colorspaces[i].obj_id);
            }
        }

        pdf_end_dict(p);			/* color space names */
    }
}
Ejemplo n.º 16
0
void
pdf_write_page_pattern(PDF *p)
{
    int i, total = 0;

    for (i = 0; i < p->pattern_number; i++)
	if (p->pattern[i].used_on_current_page)
	    total++;

    if (total > 0) {
	pdf_puts(p, "/Pattern");

	pdf_begin_dict(p);			/* pattern */

	for (i = 0; i < p->pattern_number; i++) {
	    if (p->pattern[i].used_on_current_page) {
		p->pattern[i].used_on_current_page = pdf_false; /* reset */
		pdf_printf(p, "/P%d %ld 0 R\n", i, p->pattern[i].obj_id);
	    }
	}

	pdf_end_dict(p);			/* pattern */
    }
}
Ejemplo n.º 17
0
/* Write all pending document information up to the xref table and trailer */
static void
pdf_wrapup_document(PDF *p)
{
    static const char bin2hex[] = PDF_STRING_0123456789ABCDEF;

    long	pos;
    id		i;
    id		pages_id;
    unsigned char digest[MD5_DIGEST_LENGTH];

    pdf_write_info(p);

    pdf_write_doc_fonts(p);			/* font objects */

    pdf_write_doc_colorspaces(p);		/* color space resources */

    pages_id = pdf_make_tree(p, BAD_ID, p->pnodes, p->pages+1, p->current_page);

    pdf_begin_obj(p, p->root_id);		/* Catalog or Root object */
    pdf_begin_dict(p);
    pdf_puts(p, "/Type/Catalog\n");

    /* 
     * specify the open action (display of the first page) 
     * default = retain: top of the first page at default zoom level
     */
    if (p->open_action == fitpage) {
	pdf_printf(p, "/OpenAction[%ld 0 R/Fit]\n", p->pages[1]);

    } else if (p->open_action == fitwidth) {
	pdf_printf(p, "/OpenAction[%ld 0 R/FitH]\n", p->pages[1]);

    } else if (p->open_action == fitheight) {
	pdf_printf(p, "/OpenAction[%ld 0 R/FitV 0]\n", p->pages[1]);

    } else if (p->open_action == fitbbox) {
	pdf_printf(p, "/OpenAction[%ld 0 R/FitB]\n", p->pages[1]);
    }

    /* 
     * specify the document's open mode
     * default = open_none: open document with neither bookmarks nor 
     * thumbnails visible
     */
    if (p->open_mode == open_bookmarks) {
	pdf_printf(p, "/PageMode/UseOutlines\n");

    } else if (p->open_mode == open_thumbnails) {
	pdf_printf(p, "/PageMode/UseThumbs\n");

    } else if (p->open_mode == open_fullscreen) {
	pdf_printf(p, "/PageMode/FullScreen\n");
    }

    if (p->base) {
	pdf_printf(p, "/URI<</Base", p->base);
        pdf_quote_string(p, p->base);
	pdf_printf(p, ">>\n", p->base);
    }
    						/* Pages object */
    pdf_printf(p, "/Pages %ld 0 R\n", pages_id);

    pdf_write_outline_root(p);

    pdf_end_dict(p);				/* Catalog */
    pdf_end_obj(p);

    pdf_write_outlines(p);

#ifdef DEBUG
    if (p->debug['s']) {
	fprintf(stderr, "PDF document statistics:\n");
	fprintf(stderr, "    %d pages\n", p->current_page);
	fprintf(stderr, "    %d fonts\n", p->fonts_number);
	fprintf(stderr, "    %d xobjects\n", p->xobjects_number);
	fprintf(stderr, "    %ld objects\n", p->currentobj + 1);
    }
#endif

    /* Don't write any object after this check! */
    for (i = 1; i <= p->currentobj; i++) {
	if (p->file_offset[i] == BAD_ID) {
	    pdf_error(p, PDF_NonfatalError,
		"Object %ld allocated but not used", i);
	    pdf_begin_obj(p, i);
	    pdf_end_obj(p);
	}
    }

    pos = pdf_tell(p);				/* xref table */
    pdf_puts(p, "xref\n");
    pdf_printf(p, "0 %ld\n", p->currentobj + 1);
    pdf_puts(p, "0000000000 65535 f \n");
    for (i = 1; i <= p->currentobj; i++) {
	pdf_printf(p, "%010ld 00000 n \n", p->file_offset[i]);
    }

    pdf_puts(p, "trailer\n");

    pdf_begin_dict(p);				/* trailer */
    pdf_printf(p, "/Size %ld\n", p->currentobj + 1);
    pdf_printf(p, "/Info %ld 0 R\n", p->info_id);
    pdf_printf(p, "/Root %ld 0 R\n", p->root_id);

    /* put some more data into the MD5 digest */
    MD5_Update(p->md5, (unsigned char *) &pos, sizeof pos);
    MD5_Update(p->md5, (unsigned char *) p, sizeof (PDF));
    if (p->filename && strcmp(p->filename, "-") != 0)
	MD5_Update(p->md5, (unsigned char *) p->filename, strlen(p->filename));

    /* write the digest to the ID array */
    MD5_Final(digest, p->md5);
    pdf_puts(p, "/ID[<");
    for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
    {
	pdf_putc(p, bin2hex[digest[i] >> 4]);
	pdf_putc(p, bin2hex[digest[i] & 0x0F]);
    }
    pdf_puts(p, "><");
    for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
    {
	pdf_putc(p, bin2hex[digest[i] >> 4]);
	pdf_putc(p, bin2hex[digest[i] & 0x0F]);
    }
    pdf_puts(p, ">]\n");

    pdf_end_dict(p);				/* trailer */

    pdf_puts(p, "startxref\n");
    pdf_printf(p, "%ld\n", pos);
    pdf_puts(p, "%%EOF\n");
}
Ejemplo n.º 18
0
void pdf_place_rule(PDF pdf,halfword q,scaledpos size,int callback_id)
{
pdfpos dim;
pdfstructure*p= pdf->pstruct;
scaledpos pos= pdf->posstruct->pos;

if(subtype(q)==box_rule){
pdf_place_form(pdf,q);
}else if(subtype(q)==image_rule){
pdf_place_image(pdf,q);
}else if(subtype(q)==empty_rule){

}else if(subtype(q)==user_rule){
if(callback_id!=0){
pdf_goto_pagemode(pdf);
pdf_puts(pdf,"q\n");
pdf_set_pos_temp(pdf,pos);
run_callback(callback_id,"Ndd->",q,size.h,size.v);
pdf_puts(pdf,"\nQ\n");
}
}else{

pdf_goto_pagemode(pdf);
dim.h.m= i64round(size.h*p->k1);
dim.h.e= p->pdf.h.e;
dim.v.m= i64round(size.v*p->k1);
dim.v.e= p->pdf.v.e;
pdf_puts(pdf,"q\n");
if(size.v<=one_bp){
pos.v+= i64round(0.5*size.v);
pdf_set_pos_temp(pdf,pos);
pdf_puts(pdf,"[]0 d 0 J ");
print_pdffloat(pdf,dim.v);
pdf_puts(pdf," w 0 0 m ");
print_pdffloat(pdf,dim.h);
pdf_puts(pdf," 0 l S\n");
}else if(size.h<=one_bp){
pos.h+= i64round(0.5*size.h);
pdf_set_pos_temp(pdf,pos);
pdf_puts(pdf,"[]0 d 0 J ");
print_pdffloat(pdf,dim.h);
pdf_puts(pdf," w 0 0 m 0 ");
print_pdffloat(pdf,dim.v);
pdf_puts(pdf," l S\n");
}else{
pdf_set_pos_temp(pdf,pos);
pdf_puts(pdf,"0 0 ");
print_pdffloat(pdf,dim.h);
pdf_out(pdf,' ');
print_pdffloat(pdf,dim.v);
pdf_puts(pdf," re f\n");
}
pdf_puts(pdf,"Q\n");
}
}/*:2*/
Ejemplo n.º 19
0
void
pdf_put_image(PDF *p, int im, pdf_bool firststrip)
{
    id		length_id;
    long	length;
    pdf_image	*image;
    int		i;

    image = &p->images[im];

    /* york: how to check? see also F-imagecolor!
    switch (image->colorspace) {
        case ImageMask:
        case DeviceGray:
        case Indexed:
        case DeviceRGB:
        case DeviceCMYK:
	    break;

	default:
	    pdf_error(p, PDF_SystemError, "Unknown color space");
	    break;
    }
    */

    /* Images may also be written to the output before the first page */
    if (PDF_GET_STATE(p) == pdf_state_page)
	pdf_end_contents_section(p);

    /* Image object */

    image->no = pdf_new_xobject(p, image_xobject, NEW_ID);

    pdf_begin_dict(p); 		/* XObject */

    pdf_puts(p, "/Type/XObject\n");
    pdf_puts(p, "/Subtype/Image\n");

    pdf_printf(p,"/Width %d\n", (int) image->width);
    pdf_printf(p,"/Height %d\n", (int) image->height);
    pdf_printf(p,"/BitsPerComponent %d\n", image->bpc);

    /* 
     * Transparency handling
     */

    /* Masking by color: single transparent color value */
    if (image->transparent) {
	if (image->colorspace == Indexed || image->colorspace == DeviceGray)
	    pdf_printf(p,"/Mask[%d %d]\n",
		(int) image->transval[0], (int) image->transval[0]);

	else if (image->colorspace == DeviceRGB)
	    pdf_printf(p,"/Mask[%d %d %d %d %d %d]\n",
		(int) image->transval[0], (int) image->transval[0],
		(int) image->transval[1], (int) image->transval[1],
		(int) image->transval[2], (int) image->transval[2]);

	else if (image->colorspace == DeviceCMYK)
	    pdf_printf(p,"/Mask[%d %d %d %d %d %d %d %d]\n",
		(int) image->transval[0], (int) image->transval[0],
		(int) image->transval[1], (int) image->transval[1],
		(int) image->transval[2], (int) image->transval[2],
		(int) image->transval[3], (int) image->transval[3]);
	else
	    pdf_error(p, PDF_SystemError,
	    	"Unknown color space with transparency");

    /* Masking by position: separate bitmap mask */
    } else if (image->mask != -1) {
	pdf_printf(p, "/Mask %ld 0 R\n",
	    p->xobjects[p->images[image->mask].no].obj_id);
    }

    switch (image->colorspace) {
	case ImageMask:
	    pdf_puts(p, "/ImageMask true\n");
	    break;

	case Indexed:
	    if (firststrip)
		image->colormap_id = pdf_alloc_id(p);

	    pdf_puts(p, "/ColorSpace[/Indexed/DeviceRGB ");
	    pdf_printf(p, "%d %ld 0 R]\n", image->palette_size - 1,
	    	image->colormap_id);
	    break;
	
	default:
            /* colorize the image with a spot color */
            if (image->colorspace >= LastCS) {
                /* TODO: reconsider spot color numbering scheme */
                int spot = image->colorspace - LastCS;
                p->colorspaces[spot].used_on_current_page = pdf_true;
                pdf_printf(p, "/ColorSpace %ld 0 R\n",
                    p->colorspaces[spot].obj_id);

                /* the following is tricky: /Separation color space
                 * always works as a subtractive color space. The
                 * image, however, is Grayscale, and therefore
                 * additive.
                 */
                if (firststrip) {
                    image->invert = !image->invert;
                }
            } else {
                pdf_printf(p, "/ColorSpace/%s\n",
                    pdf_colorspace_names[image->colorspace]);
            }
	    break;
    }

    /* special case: referenced image data instead of direct data */
    if (image->reference != pdf_ref_direct) {

	if (image->compression != none) {
	    pdf_printf(p, "/FFilter[/%s]\n",
		    pdf_filter_names[image->compression]);
	}

	if (image->compression == ccitt) {
	    pdf_puts(p, "/FDecodeParms[<<");

	    if ((int) image->width != 1728)	/* CCITT default width */
		pdf_printf(p, "/Columns %d", (int) image->width);

	    pdf_printf(p, "/Rows %d", (int) image->height);

	    /* write CCITT parameters if required */
	    if (image->params)
		pdf_puts(p, image->params);

	    pdf_puts(p, ">>]\n");

	}

	if (image->reference == pdf_ref_file) {

	    /* LATER: make image file name platform-neutral:
	     * Change : to / on the Mac
	     * Change \ to / on Windows
	     */
	    pdf_printf(p, "/F(%s)/Length 0", image->filename);

	} else if (image->reference == pdf_ref_url) {

	    pdf_printf(p, "/F<</FS/URL/F(%s)>>/Length 0", image->filename);
	}

	pdf_end_dict(p);		/* XObject */

	pdf_begin_stream(p);		/* dummy image data */
	pdf_end_stream(p);		/* dummy image data */

	if (PDF_GET_STATE(p) == pdf_state_page)
	    pdf_begin_contents_section(p);

	pdf_end_obj(p);			/* XObject */

	return;
    }

    /* 
     * Now the (more common) handling of actual image
     * data to be included in the PDF output.
     */
    /* do we need a filter (either ASCII or decompression)? */

    if (p->debug['a']) {
	pdf_puts(p, "/Filter[/ASCIIHexDecode");
	if (image->compression != none)
	    pdf_printf(p, "/%s", pdf_filter_names[image->compression]);
	pdf_puts(p, "]\n");

    } else {
	/* force compression if not a recognized precompressed image format */
	if (!image->use_raw && p->compresslevel)
	    image->compression = flate;

	if (image->compression != none)
	    pdf_printf(p, "/Filter[/%s]\n",
		    pdf_filter_names[image->compression]);
    }

    /* prepare precompressed (raw) image data */
    if (image->use_raw) {
	pdf_printf(p, "/DecodeParms[%s<<", (p->debug['a'] ? "null" : ""));

	/* write EarlyChange or CCITT parameters if required */
	if (image->params)
	    pdf_puts(p, image->params);

	if (image->compression == flate || image->compression == lzw) {
	    if (image->predictor != pred_default) {
		pdf_printf(p, "/Predictor %d", (int) image->predictor);
		pdf_printf(p, "/Columns %d", (int) image->width);
		if (image->bpc != 8)
		    pdf_printf(p, "/BitsPerComponent %d", image->bpc);

		if (image->colorspace < LastCS) {
		    switch (image->colorspace) {
			case Indexed:
			case ImageMask:
			case DeviceGray:
			    /* 1 is default */
			    break;
			case DeviceRGB:
			    pdf_puts(p, "/Colors 3");
			    break;
			case DeviceCMYK:
			    pdf_puts(p, "/Colors 4");
			    break;
			default:
			    pdf_error(p, PDF_SystemError,
			"Unknown colorspace (%d)", (int )image->colorspace);
			    break;
		    }
		}
	    }
	}

	if (image->compression == ccitt) {
	    if ((int) image->width != 1728)	/* CCITT default width */
		pdf_printf(p, "/Columns %d", (int) image->width);

	    pdf_printf(p, "/Rows %d", (int) image->height);
	}
	pdf_puts(p, ">>]\n");		/* DecodeParms dict and array */
    }

    if (image->invert) {
	pdf_puts(p, "/Decode[1 0");
	for (i = 1; i < image->components; i++)
	    pdf_puts(p, " 1 0");
	pdf_puts(p, "]\n");
    }

    /* Write the actual image data */
    length_id = pdf_alloc_id(p);

    pdf_printf(p,"/Length %ld 0 R\n", length_id);
    pdf_end_dict(p);		/* XObject */

    pdf_begin_stream(p);	/* image data */
    p->start_contents_pos = pdf_tell(p);

    /* image data */

    if (p->debug['a'])
	pdf_ASCIIHexEncode(p, &image->src);
    else {
	if (image->use_raw)
	    pdf_copy(p, &image->src);
	else
	    pdf_compress(p, &image->src);
    }

    length = pdf_tell(p) - p->start_contents_pos;

    pdf_end_stream(p);	/* image data */
    pdf_end_obj(p);	/* XObject */

    pdf_begin_obj(p, length_id);		/* Length object */
    pdf_printf(p,"%ld\n", length);
    pdf_end_obj(p);

    if (p->flush & PDF_FLUSH_CONTENT)
	pdf_flush_stream(p);

    /* Image data done */

    /*
     * Write colormap information for indexed color spaces
     */
    if (firststrip && image->colorspace == Indexed) {
	pdf_begin_obj(p, image->colormap_id);		/* colormap object */
	pdf_begin_dict(p); 		

	if (p->debug['a'])
	    pdf_puts(p, "/Filter[/ASCIIHexDecode]\n");
	else if (p->compresslevel)
	    pdf_puts(p, "/Filter[/FlateDecode]\n");

	/* Length of colormap object */
	length_id = pdf_alloc_id(p);
	pdf_printf(p,"/Length %ld 0 R\n", length_id);
	pdf_end_dict(p);

	pdf_begin_stream(p);			/* colormap data */
	p->start_contents_pos = pdf_tell(p);

	if (image->components != 1) {
	    pdf_error(p, PDF_SystemError,
	    	"Bogus indexed colorspace (%d color components)",
		image->components);
	}

	image->src.init		= pdf_noop;
	image->src.fill		= pdf_data_source_buf_fill;
	image->src.terminate	= pdf_noop;

	image->src.buffer_start	= (unsigned char *) image->colormap;
	image->src.buffer_length= (size_t) (image->palette_size * 3);

	image->src.bytes_available = 0;
	image->src.next_byte	= NULL;

	/* Write colormap data */
	if (p->debug['a'])
	    pdf_ASCIIHexEncode(p, &image->src);
	else {
	    pdf_compress(p, &image->src);
	}

	length = pdf_tell(p) - p->start_contents_pos;

	pdf_end_stream(p);			/* Colormap data */
	pdf_end_obj(p);				/* Colormap object */

	pdf_begin_obj(p, length_id);		/* Length object for colormap */
	pdf_printf(p, "%ld\n", length);
	pdf_end_obj(p);				/* Length object for colormap */
    }

    if (PDF_GET_STATE(p) == pdf_state_page)
	pdf_begin_contents_section(p);

    if (p->flush & PDF_FLUSH_CONTENT)
	pdf_flush_stream(p);
}
Ejemplo n.º 20
0
PDFLIB_API void PDFLIB_CALL
PDF_end_page(PDF *p)
{
    static const char fn[] = "PDF_end_page";
    int index;


    PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p));

    if (PDF_SANITY_CHECK_FAILED(p))
	return;

    PDF_CHECK_SCOPE(p, fn, pdf_state_page);

    /* check whether PDF_save() and PDF_restore() calls are balanced */
    if (p->sl > 0)
	pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of page");


    /* restore text parameter and color defaults for out-of-page usage.
    */
    pdf_init_tstate(p);
    pdf_init_cstate(p);

    pdf_end_contents_section(p);

    /* Page object */
    pdf_begin_obj(p, p->pages[p->current_page]);

    pdf_begin_dict(p);
    pdf_puts(p, "/Type/Page\n");
    pdf_printf(p, "/Parent %ld 0 R\n", pdf_get_pnode_id(p));

    p->res_id = pdf_alloc_id(p);
    pdf_printf(p, "/Resources %ld 0 R\n", p->res_id);

    pdf_printf(p, "/MediaBox[0 0 %f %f]\n", p->width, p->height);

    if (p->CropBox.llx != (float) 0 || p->CropBox.lly != (float) 0 ||
        p->CropBox.urx != (float) 0 || p->CropBox.ury != (float) 0 )
    {
	if (p->CropBox.urx <= p->CropBox.llx ||
	    p->CropBox.ury <= p->CropBox.lly)
		pdf_error(p, PDF_ValueError, "Illegal CropBox dimensions");

	pdf_printf(p, "/CropBox[%f %f %f %f]\n",
	    p->CropBox.llx, p->CropBox.lly, p->CropBox.urx, p->CropBox.ury);
    }

    if (p->BleedBox.llx != (float) 0 || p->BleedBox.lly != (float) 0 ||
        p->BleedBox.urx != (float) 0 || p->BleedBox.ury != (float) 0 )
    {
	if (p->BleedBox.urx <= p->BleedBox.llx ||
	    p->BleedBox.ury <= p->BleedBox.lly)
		pdf_error(p, PDF_ValueError, "Illegal BleedBox dimensions");

	pdf_printf(p, "/BleedBox[%f %f %f %f]\n",
	    p->BleedBox.llx, p->BleedBox.lly, p->BleedBox.urx, p->BleedBox.ury);
    }

    if (p->TrimBox.llx != (float) 0 || p->TrimBox.lly != (float) 0 ||
        p->TrimBox.urx != (float) 0 || p->TrimBox.ury != (float) 0 )
    {
	if (p->TrimBox.urx <= p->TrimBox.llx ||
	    p->TrimBox.ury <= p->TrimBox.lly)
		pdf_error(p, PDF_ValueError, "Illegal TrimBox dimensions");

	pdf_printf(p, "/TrimBox[%f %f %f %f]\n",
	    p->TrimBox.llx, p->TrimBox.lly, p->TrimBox.urx, p->TrimBox.ury);
    }

    if (p->ArtBox.llx != (float) 0 || p->ArtBox.lly != (float) 0 ||
        p->ArtBox.urx != (float) 0 || p->ArtBox.ury != (float) 0 )
    {
	if (p->ArtBox.urx <= p->ArtBox.llx ||
	    p->ArtBox.ury <= p->ArtBox.lly)
		pdf_error(p, PDF_ValueError, "Illegal ArtBox dimensions");

	pdf_printf(p, "/ArtBox[%f %f %f %f]\n",
	    p->ArtBox.llx, p->ArtBox.lly, p->ArtBox.urx, p->ArtBox.ury);
    }

    /*
     * The duration can be placed in the transition dictionary (/D)
     * or in the page dictionary (/Dur). We put it here so it can
     * be used without setting a transition effect.
     */

    if (p->duration > 0)
	pdf_printf(p, "/Dur %f\n", p->duration);

    pdf_write_page_transition(p);

    pdf_puts(p, "/Contents[");
    for (index = 0; index < p->next_content; index++) {
	pdf_printf(p, "%ld 0 R", p->contents_ids[index]);
	pdf_putc(p, (char) (index + 1 % 8 ? PDF_SPACE : PDF_NEWLINE));
    }
    pdf_puts(p, "]\n");

    /* Thumbnail image */
    if (p->thumb_id != BAD_ID)
	pdf_printf(p, "/Thumb %ld 0 R\n", p->thumb_id);

    pdf_write_annots_root(p);

    pdf_end_dict(p);				/* Page object */
    pdf_end_obj(p);

    pdf_write_page_annots(p);			/* Annotation dicts */
    
    pdf_begin_obj(p, p->res_id);		/* resource object */
    pdf_begin_dict(p);				/* resource dict */

    pdf_write_page_procsets(p);			/* ProcSet resources */

    pdf_write_page_fonts(p);			/* Font resources */

    pdf_write_page_colorspaces(p);		/* Color space resources */

    pdf_write_page_pattern(p);			/* Pattern resources */

    pdf_write_xobjects(p);			/* XObject resources */

    pdf_end_dict(p);				/* resource dict */
    pdf_end_obj(p);				/* resource object */

    pdf_cleanup_page(p);

    PDF_SET_STATE(p, fn, pdf_state_document);

    if (p->flush & PDF_FLUSH_PAGE)
	pdf_flush_stream(p);
}
Ejemplo n.º 21
0
void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform)
{
    /*tex A transformation matrix: */
    double a[6];
    double xoff, yoff, tmp;
    pdfstructure *p = pdf->pstruct;
    scaledpos pos = pdf->posstruct->pos;
    /*tex The number of digits after the decimal point: */
    int r;
    int k;
    scaledpos tmppos;
    pdffloat cm[6];
    int groupref;
    a[0] = a[3] = 1.0e6;
    a[1] = a[2] = 0;
    if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM
        || img_type(idict) == IMG_TYPE_PDFSTREAM) {
        a[0] /= (double) img_xsize(idict);
        a[3] /= (double) img_ysize(idict);
        xoff = (double) img_xorig(idict) / (double) img_xsize(idict);
        yoff = (double) img_yorig(idict) / (double) img_ysize(idict);
        r = 6;
    } else {
        if (img_type(idict) == IMG_TYPE_PNG) {
            groupref = img_group_ref(idict);
            if ((groupref > 0) && (pdf->img_page_group_val == 0))
                pdf->img_page_group_val = groupref;
        }
        a[0] /= (double) one_hundred_bp;
        a[3] = a[0];
        xoff = yoff = 0;
        r = 4;
    }
    if ((transform & 7) > 3) {
        /*tex Mirror cases: */
        a[0] *= -1;
        xoff *= -1;
    }
    switch ((transform + img_rotation(idict)) & 3) {
        case 0:
            /*tex No transform. */
            break;
        case 1:
            /*tex rotation over 90 degrees (counterclockwise) */
            a[1] = a[0];
            a[2] = -a[3];
            a[3] = a[0] = 0;
            tmp = yoff;
            yoff = xoff;
            xoff = -tmp;
            break;
        case 2:
            /*tex rotation over 180 degrees (counterclockwise) */
            a[0] *= -1;
            a[3] *= -1;
            xoff *= -1;
            yoff *= -1;
            break;
        case 3:
            /*tex rotation over 270 degrees (counterclockwise) */
            a[1] = -a[0];
            a[2] = a[3];
            a[3] = a[0] = 0;
            tmp = yoff;
            yoff = -xoff;
            xoff = tmp;
            break;
        default:;
    }
    xoff *= (double) dim.wd;
    yoff *= (double) (dim.ht + dim.dp);
    a[0] *= (double) dim.wd;
    a[1] *= (double) (dim.ht + dim.dp);
    a[2] *= (double) dim.wd;
    a[3] *= (double) (dim.ht + dim.dp);
    a[4] = (double) pos.h - xoff;
    a[5] = (double) pos.v - yoff;
    k = transform + img_rotation(idict);
    if ((transform & 7) > 3)
        k++;
    switch (k & 3) {
        case 0:
            /*tex No transform */
            break;
        case 1:
            /*tex rotation over 90 degrees (counterclockwise) */
            a[4] += (double) dim.wd;
            break;
        case 2:
            /*tex rotation over 180 degrees (counterclockwise) */
            a[4] += (double) dim.wd;
            a[5] += (double) (dim.ht + dim.dp);
            break;
        case 3:
            /*tex rotation over 270 degrees (counterclockwise) */
            a[5] += (double) (dim.ht + dim.dp);
            break;
        default:;
    }
    setpdffloat(cm[0], i64round(a[0]), r);
    setpdffloat(cm[1], i64round(a[1]), r);
    setpdffloat(cm[2], i64round(a[2]), r);
    setpdffloat(cm[3], i64round(a[3]), r);
    tmppos.h = round(a[4]);
    tmppos.v = round(a[5]);
    pdf_goto_pagemode(pdf);
    (void) calc_pdfpos(p, tmppos);
    cm[4] = p->cm[4];
    cm[5] = p->cm[5];
    if (pdf->img_page_group_val == 0)
        pdf->img_page_group_val = img_group_ref(idict);
    pdf_puts(pdf, "q\n");
    pdf_print_cm(pdf, cm);
    pdf_puts(pdf, "/Im");
    pdf_print_int(pdf, img_index(idict));
    pdf_print_resname_prefix(pdf);
    pdf_puts(pdf, " Do\nQ\n");
    addto_page_resources(pdf, obj_type_ximage, img_objnum(idict));
    if (img_state(idict) < DICT_OUTIMG)
        img_state(idict) = DICT_OUTIMG;
}
Ejemplo n.º 22
0
void
pdf_write_page_annots(PDF *p)
{
    pdf_annot	*ann;
    long	length, start_pos;
    id		length_id;
    PDF_data_source src;

    for (ann = p->annots; ann != NULL; ann = ann->next) {
	pdf_begin_obj(p, ann->obj_id);	/* Annotation object */
	pdf_begin_dict(p);		/* Annotation dict */

	pdf_puts(p, "/Type/Annot\n");
	switch (ann->type) {
	    case ann_text:
		pdf_puts(p, "/Subtype/Text\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		if (ann->open)
		    pdf_puts(p, "/Open true\n");

		if (ann->icon != icon_text_note)	/* note is default */
		    pdf_printf(p, "/Name/%s\n", pdf_icon_names[ann->icon]);

		/* Contents key is required, but may be empty */
		pdf_puts(p, "/Contents");

		if (ann->contents) {
		    pdf_quote_string(p, ann->contents);
		    pdf_putc(p, PDF_NEWLINE);
		} else
		    pdf_puts(p, "()\n"); /* empty contents is OK */

		/* title is optional */
		if (ann->title) {
		    pdf_puts(p, "/T");
		    pdf_quote_string(p, ann->title);
		    pdf_putc(p, PDF_NEWLINE);
		}

		break;

	    case ann_locallink:
		pdf_puts(p, "/Subtype/Link\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		/* preallocate page object id for a later page */
		if (ann->dest.page > p->current_page) {
		    while (ann->dest.page >= p->pages_capacity)
			pdf_grow_pages(p);

		    /* if this page has already been used as a link target
		     * it will already have an object id.
		     */
		    if (p->pages[ann->dest.page] == BAD_ID)
			p->pages[ann->dest.page] = pdf_alloc_id(p);
		}

		if (ann->dest.type == retain) {
		    pdf_printf(p, "/Dest[%ld 0 R/XYZ null null 0]\n",
			    p->pages[ann->dest.page]);
		} else if (ann->dest.type == fitpage) {
		    pdf_printf(p, "/Dest[%ld 0 R/Fit]\n",
			    p->pages[ann->dest.page]);
		} else if (ann->dest.type == fitwidth) {
		    pdf_printf(p, "/Dest[%ld 0 R/FitH 0]\n",
			    p->pages[ann->dest.page]);
		} else if (ann->dest.type == fitheight) {
		    pdf_printf(p, "/Dest[%ld 0 R/FitV 0]\n",
			    p->pages[ann->dest.page]);
		} else if (ann->dest.type == fitbbox) {
		    pdf_printf(p, "/Dest[%ld 0 R/FitB]\n",
			    p->pages[ann->dest.page]);
		}

		break;

	    case ann_pdflink:
		pdf_puts(p, "/Subtype/Link\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		pdf_puts(p, "/A");
		pdf_begin_dict(p);			/* A dict */
		pdf_puts(p, "/Type/Action/S/GoToR\n");

		if (ann->dest.type == retain) {
		    pdf_printf(p, "/D[%d 0 R/XYZ null null 0]\n",
			    ann->dest.page-1);	/* zero-based */
		} else if (ann->dest.type == fitpage) {
		    /* zero-based */
		    pdf_printf(p, "/D[%d 0 R/Fit]\n", ann->dest.page-1);
		} else if (ann->dest.type == fitwidth) {
		    /* Trick: we don't know the height of a future page yet,
		     * so we use a "large" value for top which will do for
		     * most pages. If it doesn't work, not much harm is done.
		     */
		    /* zero-based */
		    pdf_printf(p, "/D[%d 0 R/FitH 2000]\n", ann->dest.page-1);
		} else if (ann->dest.type == fitheight) {
		    /* zero-based */
		    pdf_printf(p, "/D[%d 0 R/FitV 0]\n", ann->dest.page-1);
		} else if (ann->dest.type == fitbbox) {
		    /* zero-based */
		    pdf_printf(p, "/D[%d 0 R/FitB]\n", ann->dest.page-1);
		}

		pdf_puts(p, "/F");
		pdf_begin_dict(p);			/* F dict */
		pdf_puts(p, "/Type/FileSpec\n");
		pdf_printf(p, "/F(");
		pdf_puts(p, ann->filename);
		pdf_puts(p,")\n");
		pdf_end_dict(p);			/* F dict */

		pdf_end_dict(p);			/* A dict */

		break;

	    case ann_launchlink:
		pdf_puts(p, "/Subtype/Link\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		pdf_puts(p, "/A");
		pdf_begin_dict(p);			/* A dict */
		pdf_puts(p, "/Type/Action/S/Launch\n");

		pdf_puts(p, "/F");
		pdf_begin_dict(p);			/* F dict */
		pdf_puts(p, "/Type/FileSpec\n");
		pdf_printf(p, "/F(");
		pdf_puts(p, ann->filename);
		pdf_puts(p,")\n");
		pdf_end_dict(p);			/* F dict */

		pdf_end_dict(p);			/* A dict */

		break;

	    case ann_weblink:
		pdf_puts(p, "/Subtype/Link\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		pdf_printf(p, "/A<</S/URI/URI(");
		pdf_puts(p, ann->filename);
		pdf_puts(p, ")>>\n");
		break;

	    case ann_attach:
		pdf_puts(p, "/Subtype/FileAttachment\n");
		pdf_printf(p, "/Rect[%f %f %f %f]\n", 
		    ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury);

		pdf_write_border_style(p, ann);

		if (ann->icon != icon_file_pushpin)	/* pushpin is default */
		    pdf_printf(p, "/Name/%s\n",
		    	pdf_icon_names[ann->icon]);

		if (ann->title) {
		    pdf_puts(p, "/T");
		    pdf_quote_string(p, ann->title);
		    pdf_putc(p, PDF_NEWLINE);
		}

		if (ann->contents) {
		    pdf_puts(p, "/Contents");
		    pdf_quote_string(p, ann->contents);
		    pdf_putc(p, PDF_NEWLINE);
		}
		    
		/* the icon is too small without these flags (=28) */
		pdf_printf(p, "/F %d\n",
			pdf_ann_flag_print |
			pdf_ann_flag_nozoom | 
			pdf_ann_flag_norotate);

		pdf_puts(p, "/FS");
		pdf_begin_dict(p);			/* FS dict */
		pdf_puts(p, "/Type/FileSpec\n");

		pdf_printf(p, "/F(");
		pdf_puts(p, ann->filename);
		pdf_puts(p, ")\n");

		/* alloc id for the actual embedded file stream */
		ann->obj_id = pdf_alloc_id(p);
		pdf_printf(p, "/EF<</F %ld 0 R>>\n", ann->obj_id);
		pdf_end_dict(p);			/* FS dict */

		break;

	    default:
		pdf_error(p, PDF_SystemError, "Unknown annotation type %d",
				ann->type);
	}

	pdf_end_dict(p);		/* Annotation dict */
	pdf_end_obj(p);			/* Annotation object */
    }

    /* Write the actual embedded files with preallocated ids */
    for (ann = p->annots; ann != NULL; ann = ann->next) {
	if (ann->type != ann_attach)
	    continue;

	pdf_begin_obj(p, ann->obj_id);	/* EmbeddedFile */
	pdf_puts(p, "<</Type/EmbeddedFile\n");

	if (ann->mimetype)
	    pdf_printf(p, "/Subtype (%s)\n", ann->mimetype);

	if (p->compresslevel)
	    pdf_puts(p, "/Filter/FlateDecode\n");

	length_id = pdf_alloc_id(p);
	pdf_printf(p, "/Length %ld 0 R\n", length_id);
	pdf_end_dict(p);		/* F dict */

	pdf_begin_stream(p);		/* Embedded file stream */
	start_pos = pdf_tell(p);

	/* write the file in the PDF */
	src.private_data = (void *) ann->filename;
	src.init	= pdf_data_source_file_init;
	src.fill	= pdf_data_source_file_fill;
	src.terminate	= pdf_data_source_file_terminate;
	src.length	= (long) 0;
	src.offset	= (long) 0;

	pdf_compress(p, &src);

	length = pdf_tell(p) - start_pos;
	pdf_end_stream(p);		/* Embedded file stream */
	pdf_end_obj(p);			/* EmbeddedFile object */

	pdf_begin_obj(p, length_id);	/* Length object */
	pdf_printf(p, "%ld\n", length);
	pdf_end_obj(p);			/* Length object */

	if (p->flush & PDF_FLUSH_CONTENT)
	    pdf_flush_stream(p);
    }
}
Ejemplo n.º 23
0
void
pdf_write_doc_colorspaces(PDF *p)
{
    int i;

    pdf_csresource *cs;

    for (i = 0; i < p->colorspaces_number; i++) {
        cs = &p->colorspaces[i];

        pdf_begin_obj(p, cs->obj_id);		/* color space resource */

        /* Separation color space, or pattern based on separation */
        if (cs->cs == Separation ||
                (cs->cs == PatternCS && cs->alternate.cs == Separation)) {
            const char *name;

            if (cs->cs == PatternCS) {
                pdf_printf(p, "[/Pattern");	/* pattern color space */
                name = p->colorspaces[cs->alternate.val.sep.cs].name;
            } else
                name = cs->name;

            pdf_puts(p, "[/Separation/");
            pdf_puts(p, name);		/* this is already quoted */
            pdf_puts(p, "\n");

            if (cs->alternate.cs == DeviceGray) {
                pdf_puts(p, "/DeviceGray<<\n");
                pdf_puts(p, "/Range[0 1]\n");
                pdf_printf(p, "/C0[0]\n");
                pdf_printf(p, "/C1[%f]\n", cs->alternate.val.gray);

            } else if (cs->alternate.cs == DeviceRGB) {
                pdf_puts(p, "/DeviceRGB<<\n");
                pdf_puts(p, "/Range[0 1 0 1 0 1]\n");
                pdf_printf(p, "/C0[0 0 0]\n");
                pdf_printf(p, "/C1[%f %f %f]\n", cs->alternate.val.rgb.r,
                           cs->alternate.val.rgb.g, cs->alternate.val.rgb.b);

            } else if (cs->alternate.cs == DeviceCMYK) {
                pdf_puts(p, "/DeviceCMYK<<\n");
                pdf_puts(p, "/Range[0 1 0 1 0 1 0 1]\n");
                pdf_printf(p, "/C0[0 0 0 0]\n");
                pdf_printf(p, "/C1[%f %f %f %f]\n",
                           cs->alternate.val.cmyk.c, cs->alternate.val.cmyk.m,
                           cs->alternate.val.cmyk.y, cs->alternate.val.cmyk.k);

            } else if (cs->alternate.cs != Separation)
                pdf_error(p, PDF_SystemError,
                          "Unknown alternate color space in pdf_write_doc_colorspaces");

            pdf_puts(p, "/FunctionType 2\n");
            pdf_puts(p, "/Domain[0 1]\n");
            pdf_puts(p, "/N 1\n");

            pdf_end_dict(p);		/* alternate color space */
            pdf_puts(p, "]\n");		/* separation color space */

            if (cs->cs == PatternCS)
                pdf_puts(p, "]\n");	/* pattern color space */

            /* Pattern color space based on simple color space */
        } else if (cs->cs == PatternCS) {
            pdf_printf(p, "[/Pattern/%s]\n",
                       pdf_colorspace_names[cs->alternate.cs]);

        } else {
            pdf_error(p, PDF_SystemError,
                      "Unknown base or alternate color space in pdf_write_doc_colorspaces");
        }

        pdf_end_obj(p);			/* color space resource */
    }
}
Ejemplo n.º 24
0
/* Start a new pattern definition. */
PDFLIB_API int PDFLIB_CALL
PDF_begin_pattern(
    PDF *p,
    float width,
    float height,
    float xstep,
    float ystep,
    int painttype)
{
    static const char fn[] = "PDF_begin_pattern";

    PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f, %f, %d);\n",
	fn, (void *) p, width, height, xstep, ystep, painttype));

    if (PDF_SANITY_CHECK_FAILED(p))
	return -1;

    PDF_CHECK_SCOPE(p, fn, pdf_state_document);
    
    if (width <= 0 || height <= 0)
	pdf_error(p, PDF_ValueError, "Pattern size must be positive");
    
    /* Acrobat 3 doesn't display patterns on screen so we disable it */
    if (p->compatibility == PDF_1_2)
	pdf_error(p, PDF_RuntimeError,
	    "Patterns not fully supported in Acrobat 3");

    if (painttype != 1 && painttype != 2)
	pdf_error(p, PDF_ValueError,
	    "Bad pattern paint type %d in PDF_begin_pattern", painttype);

    if (p->pattern_number == p->pattern_capacity)
	pdf_grow_pattern(p);

    p->pattern[p->pattern_number].obj_id = pdf_begin_obj(p, NEW_ID);
    p->pattern[p->pattern_number].painttype = painttype;

    p->height		= height;
    p->width		= width;
    p->thumb_id		= BAD_ID;
    PDF_PUSH_STATE(p, fn, pdf_state_pattern);
    p->next_content	= 0;
    p->contents 	= c_page;
    p->procset		= 0;
    p->sl		= 0;

    pdf_init_tstate(p);
    pdf_init_gstate(p);
    pdf_init_cstate(p);

    pdf_begin_dict(p);				/* pattern dict*/

    p->res_id = pdf_alloc_id(p);
	
    pdf_puts(p, "/PatternType 1\n");

    /* colored or uncolored pattern */
    pdf_printf(p, "/PaintType %d\n", painttype);
    pdf_puts(p, "/TilingType 1\n");		/* constant spacing */

    pdf_printf(p, "/BBox[0 0 %f %f]\n", p->width, p->height);

    pdf_printf(p, "/XStep %f\n", xstep);
    pdf_printf(p, "/YStep %f\n", ystep);

    pdf_printf(p, "/Resources %ld 0 R\n", p->res_id);

    p->contents_length_id = pdf_alloc_id(p);
    pdf_printf(p, "/Length %ld 0 R\n", p->contents_length_id);

    if (p->compresslevel)
	pdf_puts(p, "/Filter/FlateDecode\n");

    pdf_end_dict(p);				/* pattern dict*/
    pdf_begin_stream(p);

    pdf_compress_init(p);

    p->start_contents_pos = pdf_tell(p);
    p->next_content++;

    return p->pattern_number++;
}
Ejemplo n.º 25
0
void
pdf_setpatterncolor(PDF *p, const char *type, int pattern)
{
    if (PDF_SANITY_CHECK_FAILED(p))
	return;

    if (!type || !*type)
	pdf_error(p, PDF_ValueError, "Missing type in pdf_setspotcolor");

    if (strcmp(type, "fill") && strcmp(type, "stroke") && strcmp(type, "both"))
	pdf_error(p, PDF_ValueError, "Unknown type in pdf_spotcolor");

    if (pattern < 0 || pattern >= p->pattern_number)
	pdf_error(p, PDF_ValueError,
	    "Invalid pattern number %d in PDF_setcolor", pattern);

    if (PDF_GET_STATE(p) == pdf_state_pattern
	&& pattern == p->pattern_number-1) {
	pdf_error(p, PDF_ValueError,
	    "Can't use pattern within its own definition");
    }

    if (!strcmp(type, "fill") || !strcmp(type, "both")) {
	if (p->pattern[pattern].painttype == 1) {
	    pdf_puts(p, "/Pattern cs\n");

	} else if (p->pattern[pattern].painttype == 2) {
	    /* TODO: find spot color name */
	    if (p->cstate[p->sl].fill.cs == Separation)
		pdf_error(p, PDF_ValueError, "Separation NYI for patterns");
	    pdf_printf(p, "/CS%d cs\n",
		pdf_add_colorspace(p, PatternCS, (char *) NULL));
		/* TODO: add spot name if based on separation color space */
	    pdf_write_pattern_color(p, pdf_true);
	}

	pdf_printf(p, "/P%d scn\n", pattern);

	if (p->pattern[pattern].painttype == 1) {
	    p->cstate[p->sl].fill.cs = PatternCS;
	    p->cstate[p->sl].fill.val.pattern = pattern;

	} else if (p->pattern[pattern].painttype == 2) {
	    /* TODO: deal with color */
	}
    }

    if (!strcmp(type, "stroke") || !strcmp(type, "both")) {
	if (p->pattern[pattern].painttype == 1) {
	    pdf_puts(p, "/Pattern CS\n");

	} else if (p->pattern[pattern].painttype == 2) {
	    /* TODO */
	    if (p->cstate[p->sl].fill.cs == Separation)
		pdf_error(p, PDF_ValueError, "Separation NYI for patterns");
	    pdf_printf(p, "/CS%d CS\n",
		pdf_add_colorspace(p, PatternCS, (char *) NULL));
		/* TODO: add spot name if based on separation color space */
	    pdf_write_pattern_color(p, pdf_false);
	}

	pdf_printf(p, "/P%d SCN\n", pattern);

	if (p->pattern[pattern].painttype == 1) {
	    p->cstate[p->sl].stroke.cs = PatternCS;
	    p->cstate[p->sl].stroke.val.pattern = pattern;

	} else if (p->pattern[pattern].painttype == 2) {
	    /* TODO */
	}
    }

    p->pattern[pattern].used_on_current_page = pdf_true;
}