/* p_intern.h
 * Copyright (C) 1997-98 Thomas Merz. All rights reserved.
 *
 * PDFlib internal definitions
 */

#ifndef P_INTERN_H
#define P_INTERN_H

#include "pdf.h"

/* Several limits -- change if too small (or too large) */
#define MAX_CONTENTS	512		/* maximum number of content sections */

#ifndef DOS
#define MAX_ID		((id) 10000)	/* maximum number of objects in file */
#define MAX_PAGES 	1000		/* maximum number of pages in file */
#else
#define MAX_ID		((id) 1000)
#define MAX_PAGES 	100
#endif

typedef enum { ImageB = 1, ImageC = 2, ImageI = 4, Text = 8 } pdf_procset;

typedef enum { 
    res_procset, res_font, res_encoding, 
    res_fontdescriptor, res_colorspace, res_xobject
} pdf_res_type;

typedef enum { c_none, c_stream, c_text } pdf_content_type;

typedef long id;

#define NEW_ID		0L
#define BAD_ID		-1L

/* Note: pdf_begin_obj() is a function */
#define pdf_end_obj(p)		(void) fputs("endobj\n", p->fp)

#define pdf_begin_dict(p)	(void) fputs("<<", p->fp)
#define pdf_end_dict(p)		(void) fputs(">>\n", p->fp)

#define pdf_begin_stream(p)	(void) fputs("stream\n", p->fp)
#define pdf_end_stream(p)	(void) fputs("endstream\n", p->fp)

typedef struct {
    char	*name;
    float	size;
    FILE	*file;
    char	fontName[64];		/* AFM key: FontName */
    char	weight[64];		/* AFM key: Weight */
    char	encodingScheme[64];	/* AFM key: EncodingScheme */
    float	italicAngle;		/* AFM key: ItalicAngle */
    bool	isFixedPitch;		/* AFM key: IsFixedPitch */
    int		llx;			/* AFM key: FontBBox */
    int		lly;			/* AFM key: FontBBox */
    int		urx;			/* AFM key: FontBBox */
    int		ury;			/* AFM key: FontBBox */
    int		underlinePosition;  	/* AFM key: UnderlinePosition */
    int		underlineThickness; 	/* AFM key: UnderlineThickness */
    int		capHeight;		/* AFM key: CapHeight */
    int		ascender;		/* AFM key: Ascender */
    int		descender;		/* AFM key: Descender */
    int		StdVW;			/* AFM key: StdVW */
    int		StdHW;			/* AFM key: StdHW */
    PDF_encoding	encoding;
    int        	FontWidths[256];	/* From AFM char metrics and encoding */
} pdf_font;

typedef struct pdf_item_s pdf_item;
struct pdf_item_s {
    char	*name;
    char	*basename;
    id		obj_id;
    pdf_item	*next;
};

typedef struct {
    pdf_procset	procset;
    pdf_item	*font;
    pdf_item	*encoding;
    pdf_item	*fontdescriptor;
    pdf_item	*colorspace;
    pdf_item	*xobject;
} pdf_res;

typedef struct {
    id		self;		/* id of this outline object */
    id		parent;		/* ancestor's id */
    id		prev;		/* previous entry at this level */
    id		next;		/* next entry at this level */
    id		first;		/* first sub-entry */
    id		page;		/* id of destination page */
    char 	*text;		/* bookmark text */
} pdf_outline;

struct PDF_s {
    FILE	*fp;

    /* general stuff */
    PDF_info	*info;
    id		currentobj;

    id		root_id;
    id		info_id;
    id		pages_id;
    id		outlines_id;
    id		open_action;

    long	file_offset[MAX_ID];
    id		pages[MAX_PAGES];
    int		font_number;
    int		xobject_number;
    int		image_number;
    int		open_outlines;
    int		outline_count;			/* HACK */
    pdf_outline	outlines[MAX_PAGES];		/* HACK */

    /* page specific stuff */
    id		res_id;
    id		contents_length;
    id		contents_ids[MAX_CONTENTS];
    id		next_content;
    pdf_content_type	contents;
    PDF_transition	transition;
    float	duration;

    pdf_res	res;
    int 	current_page;
    long	start_contents_pos;

    float	width;
    float	height;

    /* general graphics state */
    /* NYI */

    /* text state */
    float	char_spacing;
    float	leading;
    pdf_font	*current_font;

    /* miscellaneous */
    int		chars_on_this_line;
};

/* p_basic.c */
extern const char	*pdf_filter_names[compression_count];
extern const char	*pdf_colorspace_names[colorspace_count];
extern const char	*pdf_encoding_names[encoding_count];
void	pdf_begin_contents_section(PDF *p);
void	pdf_end_contents_section(PDF *p);
void	pdf_default_error_handler(int level, const char* fmt, va_list ap);
void	pdf_error(PDF *, int level, const char *fmt, ...);
id	pdf_begin_obj(PDF *p, id obj_id);
id	pdf_alloc_id(PDF *p);
pdf_item *pdf_add_res_font(PDF *p, char *basename);
void	pdf_add_res_xobject(PDF *p, id xobj_id);

/* p_text.c */
void pdf_put_fonts(PDF *p);
void pdf_begin_text(PDF *p);
void pdf_end_text(PDF *p);
void pdf_quote_string(PDF *p, char *string);

/* p_draw.c */
void pdf_concat(PDF *p, PDF_matrix m);

/* p_image.c */

/* p_filter.c */
void pdf_ASCII85Encode(PDF *p, PDF_data_source *src);
void pdf_ASCIIHexEncode(PDF *p, PDF_data_source *src);

/* p_font.c */
bool pdf_read_afm(PDF *p, char *fontname, PDF_encoding enc);
void pdf_put_t1font(PDF *p, char *fontname, id font_id, int fontnumber, bool embed);

/* p_util.c */
char	*pdf_float(float f);

/* p_hyper.c */
void pdf_write_outlines(PDF *p);

#endif				/* P_INTERN_H */
