<commit_before>/*
 * Resources and other graphics related objects.
 */

typedef struct fz_pixmap_s fz_pixmap;
typedef struct fz_colorspace_s fz_colorspace;
typedef struct fz_path_s fz_path;
typedef struct fz_text_s fz_text;
typedef struct fz_font_s fz_font;
typedef struct fz_shade_s fz_shade;

enum { FZ_MAXCOLORS = 32 };

typedef enum fz_blendkind_e
{
	/* PDF 1.4 -- standard separable */
	FZ_BNORMAL,
	FZ_BMULTIPLY,
	FZ_BSCREEN,
	FZ_BOVERLAY,
	FZ_BDARKEN,
	FZ_BLIGHTEN,
	FZ_BCOLORDODGE,
	FZ_BCOLORBURN,
	FZ_BHARDLIGHT,
	FZ_BSOFTLIGHT,
	FZ_BDIFFERENCE,
	FZ_BEXCLUSION,

	/* PDF 1.4 -- standard non-separable */
	FZ_BHUE,
	FZ_BSATURATION,
	FZ_BCOLOR,
	FZ_BLUMINOSITY
} fz_blendkind;

/*
pixmaps have n components per pixel. the first is always alpha.
premultiplied alpha when rendering, but non-premultiplied for colorspace
conversions and rescaling.
*/

extern fz_colorspace *pdf_devicegray;
extern fz_colorspace *pdf_devicergb;
extern fz_colorspace *pdf_devicecmyk;
extern fz_colorspace *pdf_devicelab;
extern fz_colorspace *pdf_devicepattern;

struct fz_pixmap_s
{
	int refs;
	int x, y, w, h, n;
	fz_colorspace *colorspace;
	unsigned char *samples;
};

fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_bbox bbox);
fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h);
fz_pixmap *fz_keeppixmap(fz_pixmap *map);
void fz_droppixmap(fz_pixmap *map);

void fz_debugpixmap(fz_pixmap *map, char *prefix);
void fz_clearpixmap(fz_pixmap *map, unsigned char value);

fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom);

/*
 * The device interface.
 */

typedef struct fz_device_s fz_device;

struct fz_device_s
{
	void *user;
	void (*freeuser)(void *);

	void (*fillpath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*strokepath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*clippath)(void *, fz_path *, fz_matrix);

	void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*stroketext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*cliptext)(void *, fz_text *, fz_matrix);
	void (*ignoretext)(void *, fz_text *, fz_matrix);

	void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm);
	void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm);
	void (*fillimagemask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
	void (*clipimagemask)(void *, fz_pixmap *img, fz_matrix ctm);

	void (*popclip)(void *);
};

fz_device *fz_newdevice(void *user);
void fz_freedevice(fz_device *dev);

fz_device *fz_newtracedevice(void);

/* Text extraction device */

typedef struct fz_textspan_s fz_textspan;
typedef struct fz_textchar_s fz_textchar;

struct fz_textchar_s
{
	int c, x, y, w;
};

struct fz_textspan_s
{
	int ascender, descender;
	int len, cap;
	fz_textchar *text;
	fz_textspan *next;
};

fz_textspan * fz_newtextspan(void);
void fz_freetextspan(fz_textspan *line);
void fz_debugtextspan(fz_textspan *line);

fz_device *fz_newtextdevice(fz_textspan *text);

/* Display list device -- record and play back device commands. */

typedef struct fz_displaylist_s fz_displaylist;
typedef struct fz_displaynode_s fz_displaynode;

typedef enum fz_displaycommand_e
{
	FZ_CMDFILLPATH,
	FZ_CMDSTROKEPATH,
	FZ_CMDCLIPPATH,
	FZ_CMDFILLTEXT,
	FZ_CMDSTROKETEXT,
	FZ_CMDCLIPTEXT,
	FZ_CMDIGNORETEXT,
	FZ_CMDFILLSHADE,
	FZ_CMDFILLIMAGE,
	FZ_CMDFILLIMAGEMASK,
	FZ_CMDCLIPIMAGEMASK,
	FZ_CMDPOPCLIP,
} fz_displaycommand;

struct fz_displaylist_s
{
	fz_displaynode *first;
	fz_displaynode *last;
};

struct fz_displaynode_s
{
	fz_displaycommand cmd;
	fz_displaynode *next;
	union {
		fz_path *path;
		fz_text *text;
		fz_shade *shade;
		fz_pixmap *image;
	} item;
	fz_matrix ctm;
	fz_colorspace *colorspace;
	float alpha;
	float color[FZ_MAXCOLORS];
};

fz_displaylist *fz_newdisplaylist(void);
void fz_freedisplaylist(fz_displaylist *list);
fz_device *fz_newlistdevice(fz_displaylist *list);
void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm);

/*
 * Vector path buffer.
 * It can be stroked and dashed, or be filled.
 * It has a fill rule (nonzero or evenodd).
 *
 * When rendering, they are flattened, stroked and dashed straight
 * into the Global Edge List.
 */

typedef struct fz_stroke_s fz_stroke;
typedef union fz_pathel_s fz_pathel;

typedef enum fz_pathelkind_e
{
	FZ_MOVETO,
	FZ_LINETO,
	FZ_CURVETO,
	FZ_CLOSEPATH
} fz_pathelkind;

union fz_pathel_s
{
	fz_pathelkind k;
	float v;
};

struct fz_path_s
{
	int evenodd;
	int linecap;
	int linejoin;
	float linewidth;
	float miterlimit;
	float dashphase;
	int dashlen;
	float dashlist[32];
	int len, cap;
	fz_pathel *els;
};

fz_path *fz_newpath(void);
void fz_moveto(fz_path*, float x, float y);
void fz_lineto(fz_path*, float x, float y);
void fz_curveto(fz_path*, float, float, float, float, float, float);
void fz_curvetov(fz_path*, float, float, float, float);
void fz_curvetoy(fz_path*, float, float, float, float);
void fz_closepath(fz_path*);
void fz_resetpath(fz_path *path);
void fz_freepath(fz_path *path);

fz_path *fz_clonepath(fz_path *old);

fz_rect fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke);
void fz_debugpath(fz_path *, int indent);

/*
 * Text buffer.
 *
 * The trm field contains the a, b, c and d coefficients.
 * The e and f coefficients come from the individual elements,
 * together they form the transform matrix for the glyph.
 *
 * Glyphs are referenced by glyph ID.
 * The Unicode text equivalent is kept in a separate array
 * with indexes into the glyph array.
 */

typedef struct fz_textel_s fz_textel;

struct fz_textel_s
{
	float x, y;
	int gid;
	int ucs;
};

struct fz_text_s
{
	fz_font *font;
	fz_matrix trm;
	int len, cap;
	fz_textel *els;
};

fz_text * fz_newtext(fz_font *face);
void fz_addtext(fz_text *text, int gid, int ucs, float x, float y);
void fz_endtext(fz_text *text);
void fz_resettext(fz_text *text);
void fz_freetext(fz_text *text);
void fz_debugtext(fz_text*, int indent);

fz_text *fz_clonetext(fz_text *old);

/*
 * Colorspace resources.
 *
 * TODO: use lcms
 */

struct fz_colorspace_s
{
	int refs;
	char name[16];
	int n;
	void (*convpixmap)(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
	void (*convcolor)(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv);
	void (*toxyz)(fz_colorspace *, float *src, float *xyz);
	void (*fromxyz)(fz_colorspace *, float *xyz, float *dst);
	void (*freefunc)(fz_colorspace *);
};

fz_colorspace *fz_keepcolorspace(fz_colorspace *cs);
void fz_dropcolorspace(fz_colorspace *cs);

void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);

void fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);

/*
 * Fonts.
 *
 * Fonts come in three variants:
 *	Regular fonts are handled by FreeType.
 *	Type 3 fonts have callbacks to the interpreter.
 *	Substitute fonts are a thin wrapper over a regular font that adjusts metrics.
 */

char *ft_errorstring(int err);

struct fz_font_s
{
	int refs;
	char name[32];

	void *ftface; /* has an FT_Face if used */
	int ftsubstitute; /* ... substitute metrics */
	int fthint; /* ... force hinting for DynaLab fonts */

	fz_matrix t3matrix;
	fz_obj *t3resources;
	fz_buffer **t3procs; /* has 256 entries if used */
	float *t3widths; /* has 256 entries if used */
	void *t3xref; /* a pdf_xref for the callback */
	fz_error (*t3runcontentstream)(fz_device *dev, fz_matrix ctm,
		struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents);

	fz_rect bbox;
};

struct fz_glyph_s
{
	int x, y, w, h;
	unsigned char *samples;
};

fz_error fz_newfreetypefont(fz_font **fontp, char *name, int substitute);
fz_error fz_loadfreetypefontfile(fz_font *font, char *path, int index);
fz_error fz_loadfreetypefontbuffer(fz_font *font, unsigned char *data, int len, int index);
fz_font * fz_newtype3font(char *name, fz_matrix matrix);

fz_error fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index);
fz_error fz_newfontfromfile(fz_font **fontp, char *path, int index);

fz_font * fz_keepfont(fz_font *font);
void fz_dropfont(fz_font *font);

void fz_debugfont(fz_font *font);
void fz_setfontbbox(fz_font *font, float xmin, float ymin, float xmax, float ymax);

/*
 * The shading code is in rough shape but the general architecture is sound.
 */

struct fz_shade_s
{
	int refs;

	fz_rect bbox;		/* can be fz_infiniterect */
	fz_colorspace *cs;

	/* used by build.c -- not used in drawshade.c */
	fz_matrix matrix;	/* matrix from pattern dict */<commit_msg>Remove incorrect comment from fz_shade.<commit_after>/*
 * Resources and other graphics related objects.
 */

typedef struct fz_pixmap_s fz_pixmap;
typedef struct fz_colorspace_s fz_colorspace;
typedef struct fz_path_s fz_path;
typedef struct fz_text_s fz_text;
typedef struct fz_font_s fz_font;
typedef struct fz_shade_s fz_shade;

enum { FZ_MAXCOLORS = 32 };

typedef enum fz_blendkind_e
{
	/* PDF 1.4 -- standard separable */
	FZ_BNORMAL,
	FZ_BMULTIPLY,
	FZ_BSCREEN,
	FZ_BOVERLAY,
	FZ_BDARKEN,
	FZ_BLIGHTEN,
	FZ_BCOLORDODGE,
	FZ_BCOLORBURN,
	FZ_BHARDLIGHT,
	FZ_BSOFTLIGHT,
	FZ_BDIFFERENCE,
	FZ_BEXCLUSION,

	/* PDF 1.4 -- standard non-separable */
	FZ_BHUE,
	FZ_BSATURATION,
	FZ_BCOLOR,
	FZ_BLUMINOSITY
} fz_blendkind;

/*
pixmaps have n components per pixel. the first is always alpha.
premultiplied alpha when rendering, but non-premultiplied for colorspace
conversions and rescaling.
*/

extern fz_colorspace *pdf_devicegray;
extern fz_colorspace *pdf_devicergb;
extern fz_colorspace *pdf_devicecmyk;
extern fz_colorspace *pdf_devicelab;
extern fz_colorspace *pdf_devicepattern;

struct fz_pixmap_s
{
	int refs;
	int x, y, w, h, n;
	fz_colorspace *colorspace;
	unsigned char *samples;
};

fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_bbox bbox);
fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h);
fz_pixmap *fz_keeppixmap(fz_pixmap *map);
void fz_droppixmap(fz_pixmap *map);

void fz_debugpixmap(fz_pixmap *map, char *prefix);
void fz_clearpixmap(fz_pixmap *map, unsigned char value);

fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom);

/*
 * The device interface.
 */

typedef struct fz_device_s fz_device;

struct fz_device_s
{
	void *user;
	void (*freeuser)(void *);

	void (*fillpath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*strokepath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*clippath)(void *, fz_path *, fz_matrix);

	void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*stroketext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
	void (*cliptext)(void *, fz_text *, fz_matrix);
	void (*ignoretext)(void *, fz_text *, fz_matrix);

	void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm);
	void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm);
	void (*fillimagemask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
	void (*clipimagemask)(void *, fz_pixmap *img, fz_matrix ctm);

	void (*popclip)(void *);
};

fz_device *fz_newdevice(void *user);
void fz_freedevice(fz_device *dev);

fz_device *fz_newtracedevice(void);

/* Text extraction device */

typedef struct fz_textspan_s fz_textspan;
typedef struct fz_textchar_s fz_textchar;

struct fz_textchar_s
{
	int c, x, y, w;
};

struct fz_textspan_s
{
	int ascender, descender;
	int len, cap;
	fz_textchar *text;
	fz_textspan *next;
};

fz_textspan * fz_newtextspan(void);
void fz_freetextspan(fz_textspan *line);
void fz_debugtextspan(fz_textspan *line);

fz_device *fz_newtextdevice(fz_textspan *text);

/* Display list device -- record and play back device commands. */

typedef struct fz_displaylist_s fz_displaylist;
typedef struct fz_displaynode_s fz_displaynode;

typedef enum fz_displaycommand_e
{
	FZ_CMDFILLPATH,
	FZ_CMDSTROKEPATH,
	FZ_CMDCLIPPATH,
	FZ_CMDFILLTEXT,
	FZ_CMDSTROKETEXT,
	FZ_CMDCLIPTEXT,
	FZ_CMDIGNORETEXT,
	FZ_CMDFILLSHADE,
	FZ_CMDFILLIMAGE,
	FZ_CMDFILLIMAGEMASK,
	FZ_CMDCLIPIMAGEMASK,
	FZ_CMDPOPCLIP,
} fz_displaycommand;

struct fz_displaylist_s
{
	fz_displaynode *first;
	fz_displaynode *last;
};

struct fz_displaynode_s
{
	fz_displaycommand cmd;
	fz_displaynode *next;
	union {
		fz_path *path;
		fz_text *text;
		fz_shade *shade;
		fz_pixmap *image;
	} item;
	fz_matrix ctm;
	fz_colorspace *colorspace;
	float alpha;
	float color[FZ_MAXCOLORS];
};

fz_displaylist *fz_newdisplaylist(void);
void fz_freedisplaylist(fz_displaylist *list);
fz_device *fz_newlistdevice(fz_displaylist *list);
void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm);

/*
 * Vector path buffer.
 * It can be stroked and dashed, or be filled.
 * It has a fill rule (nonzero or evenodd).
 *
 * When rendering, they are flattened, stroked and dashed straight
 * into the Global Edge List.
 */

typedef struct fz_stroke_s fz_stroke;
typedef union fz_pathel_s fz_pathel;

typedef enum fz_pathelkind_e
{
	FZ_MOVETO,
	FZ_LINETO,
	FZ_CURVETO,
	FZ_CLOSEPATH
} fz_pathelkind;

union fz_pathel_s
{
	fz_pathelkind k;
	float v;
};

struct fz_path_s
{
	int evenodd;
	int linecap;
	int linejoin;
	float linewidth;
	float miterlimit;
	float dashphase;
	int dashlen;
	float dashlist[32];
	int len, cap;
	fz_pathel *els;
};

fz_path *fz_newpath(void);
void fz_moveto(fz_path*, float x, float y);
void fz_lineto(fz_path*, float x, float y);
void fz_curveto(fz_path*, float, float, float, float, float, float);
void fz_curvetov(fz_path*, float, float, float, float);
void fz_curvetoy(fz_path*, float, float, float, float);
void fz_closepath(fz_path*);
void fz_resetpath(fz_path *path);
void fz_freepath(fz_path *path);

fz_path *fz_clonepath(fz_path *old);

fz_rect fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke);
void fz_debugpath(fz_path *, int indent);

/*
 * Text buffer.
 *
 * The trm field contains the a, b, c and d coefficients.
 * The e and f coefficients come from the individual elements,
 * together they form the transform matrix for the glyph.
 *
 * Glyphs are referenced by glyph ID.
 * The Unicode text equivalent is kept in a separate array
 * with indexes into the glyph array.
 */

typedef struct fz_textel_s fz_textel;

struct fz_textel_s
{
	float x, y;
	int gid;
	int ucs;
};

struct fz_text_s
{
	fz_font *font;
	fz_matrix trm;
	int len, cap;
	fz_textel *els;
};

fz_text * fz_newtext(fz_font *face);
void fz_addtext(fz_text *text, int gid, int ucs, float x, float y);
void fz_endtext(fz_text *text);
void fz_resettext(fz_text *text);
void fz_freetext(fz_text *text);
void fz_debugtext(fz_text*, int indent);

fz_text *fz_clonetext(fz_text *old);

/*
 * Colorspace resources.
 *
 * TODO: use lcms
 */

struct fz_colorspace_s
{
	int refs;
	char name[16];
	int n;
	void (*convpixmap)(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
	void (*convcolor)(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv);
	void (*toxyz)(fz_colorspace *, float *src, float *xyz);
	void (*fromxyz)(fz_colorspace *, float *xyz, float *dst);
	void (*freefunc)(fz_colorspace *);
};

fz_colorspace *fz_keepcolorspace(fz_colorspace *cs);
void fz_dropcolorspace(fz_colorspace *cs);

void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);

void fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);

/*
 * Fonts.
 *
 * Fonts come in three variants:
 *	Regular fonts are handled by FreeType.
 *	Type 3 fonts have callbacks to the interpreter.
 *	Substitute fonts are a thin wrapper over a regular font that adjusts metrics.
 */

char *ft_errorstring(int err);

struct fz_font_s
{
	int refs;
	char name[32];

	void *ftface; /* has an FT_Face if used */
	int ftsubstitute; /* ... substitute metrics */
	int fthint; /* ... force hinting for DynaLab fonts */

	fz_matrix t3matrix;
	fz_obj *t3resources;
	fz_buffer **t3procs; /* has 256 entries if used */
	float *t3widths; /* has 256 entries if used */
	void *t3xref; /* a pdf_xref for the callback */
	fz_error (*t3runcontentstream)(fz_device *dev, fz_matrix ctm,
		struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents);

	fz_rect bbox;
};

struct fz_glyph_s
{
	int x, y, w, h;
	unsigned char *samples;
};

fz_error fz_newfreetypefont(fz_font **fontp, char *name, int substitute);
fz_error fz_loadfreetypefontfile(fz_font *font, char *path, int index);
fz_error fz_loadfreetypefontbuffer(fz_font *font, unsigned char *data, int len, int index);
fz_font * fz_newtype3font(char *name, fz_matrix matrix);

fz_error fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index);
fz_error fz_newfontfromfile(fz_font **fontp, char *path, int index);

fz_font * fz_keepfont(fz_font *font);
void fz_dropfont(fz_font *font);

void fz_debugfont(fz_font *font);
void fz_setfontbbox(fz_font *font, float xmin, float ymin, float xmax, float ymax);

/*
 * The shading code is in rough shape but the general architecture is sound.
 */

struct fz_shade_s
{
	int refs;

	fz_rect bbox;		/* can be fz_infiniterect */
	fz_colorspace *cs;

	fz_matrix matrix;	/* matrix from pattern dict */
{'fraction_non_alphanumeric': 0.10438996579247435, 'fraction_numerical': 0.0029646522234891676, 'mean_word_length': 5.437064220183486, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5675099', 'n_tokens_mistral': 7409, 'n_tokens_neox': 7206, 'n_words': 1823}