first commit

This commit is contained in:
2023-10-17 17:51:53 +02:00
commit 9c7f9cfea0
107 changed files with 22995 additions and 0 deletions

View File

@ -0,0 +1,373 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_ARCHIVE_H
#define MUPDF_FITZ_ARCHIVE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/tree.h"
/* PUBLIC API */
/**
fz_archive:
fz_archive provides methods for accessing "archive" files.
An archive file is a conceptual entity that contains multiple
files, which can be counted, enumerated, and read.
Implementations of fz_archive based upon directories, zip
and tar files are included.
*/
typedef struct fz_archive fz_archive;
/**
Open a zip or tar archive
Open a file and identify its archive type based on the archive
signature contained inside.
filename: a path to a file as it would be given to open(2).
*/
fz_archive *fz_open_archive(fz_context *ctx, const char *filename);
/**
Open zip or tar archive stream.
Open an archive using a seekable stream object rather than
opening a file or directory on disk.
*/
fz_archive *fz_open_archive_with_stream(fz_context *ctx, fz_stream *file);
/**
Open zip or tar archive stream.
Does the same as fz_open_archive_with_stream, but will not throw
an error in the event of failing to recognise the format. Will
still throw errors in other cases though!
*/
fz_archive *fz_try_open_archive_with_stream(fz_context *ctx, fz_stream *file);
/**
Open a directory as if it was an archive.
A special case where a directory is opened as if it was an
archive.
Note that for directories it is not possible to retrieve the
number of entries or list the entries. It is however possible
to check if the archive has a particular entry.
path: a path to a directory as it would be given to opendir(3).
*/
fz_archive *fz_open_directory(fz_context *ctx, const char *path);
/**
Determine if a given path is a directory.
*/
int fz_is_directory(fz_context *ctx, const char *path);
/**
Drop a reference to an archive.
When the last reference is dropped, this closes and releases
any memory or filehandles associated with the archive.
*/
void fz_drop_archive(fz_context *ctx, fz_archive *arch);
/**
Keep a reference to an archive.
*/
fz_archive *
fz_keep_archive(fz_context *ctx, fz_archive *arch);
/**
Return a pointer to a string describing the format of the
archive.
The lifetime of the string is unspecified (in current
implementations the string will persist until the archive
is closed, but this is not guaranteed).
*/
const char *fz_archive_format(fz_context *ctx, fz_archive *arch);
/**
Number of entries in archive.
Will always return a value >= 0.
May throw an exception if this type of archive cannot count the
entries (such as a directory).
*/
int fz_count_archive_entries(fz_context *ctx, fz_archive *arch);
/**
Get listed name of entry position idx.
idx: Must be a value >= 0 < return value from
fz_count_archive_entries. If not in range NULL will be
returned.
May throw an exception if this type of archive cannot list the
entries (such as a directory).
*/
const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx);
/**
Check if entry by given name exists.
If named entry does not exist 0 will be returned, if it does
exist 1 is returned.
name: Entry name to look for, this must be an exact match to
the entry name in the archive.
*/
int fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/**
Opens an archive entry as a stream.
name: Entry name to look for, this must be an exact match to
the entry name in the archive.
Throws an exception if a matching entry cannot be found.
*/
fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/**
Opens an archive entry as a stream.
Returns NULL if a matching entry cannot be found, otherwise
behaves exactly as fz_open_archive_entry.
*/
fz_stream *fz_try_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/**
Reads all bytes in an archive entry
into a buffer.
name: Entry name to look for, this must be an exact match to
the entry name in the archive.
Throws an exception if a matching entry cannot be found.
*/
fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/**
Reads all bytes in an archive entry
into a buffer.
name: Entry name to look for, this must be an exact match to
the entry name in the archive.
Returns NULL if a matching entry cannot be found. Otherwise behaves
the same as fz_read_archive_entry. Exceptions may be thrown.
*/
fz_buffer *fz_try_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
/**
fz_archive: tar implementation
*/
/**
Detect if stream object is a tar achieve.
Assumes that the stream object is seekable.
*/
int fz_is_tar_archive(fz_context *ctx, fz_stream *file);
/**
Open a tar archive file.
An exception is throw if the file is not a tar archive as
indicated by the presence of a tar signature.
filename: a path to a tar archive file as it would be given to
open(2).
*/
fz_archive *fz_open_tar_archive(fz_context *ctx, const char *filename);
/**
Open a tar archive stream.
Open an archive using a seekable stream object rather than
opening a file or directory on disk.
An exception is throw if the stream is not a tar archive as
indicated by the presence of a tar signature.
*/
fz_archive *fz_open_tar_archive_with_stream(fz_context *ctx, fz_stream *file);
/**
fz_archive: zip implementation
*/
/**
Detect if stream object is a zip archive.
Assumes that the stream object is seekable.
*/
int fz_is_zip_archive(fz_context *ctx, fz_stream *file);
/**
Open a zip archive file.
An exception is throw if the file is not a zip archive as
indicated by the presence of a zip signature.
filename: a path to a zip archive file as it would be given to
open(2).
*/
fz_archive *fz_open_zip_archive(fz_context *ctx, const char *path);
/**
Open a zip archive stream.
Open an archive using a seekable stream object rather than
opening a file or directory on disk.
An exception is throw if the stream is not a zip archive as
indicated by the presence of a zip signature.
*/
fz_archive *fz_open_zip_archive_with_stream(fz_context *ctx, fz_stream *file);
/**
fz_zip_writer offers methods for creating and writing zip files.
It can be seen as the reverse of the fz_archive zip
implementation.
*/
typedef struct fz_zip_writer fz_zip_writer;
/**
Create a new zip writer that writes to a given file.
Open an archive using a seekable stream object rather than
opening a file or directory on disk.
*/
fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename);
/**
Create a new zip writer that writes to a given output stream.
Ownership of out passes in immediately upon calling this function.
The caller should never drop the fz_output, even if this function throws
an exception.
*/
fz_zip_writer *fz_new_zip_writer_with_output(fz_context *ctx, fz_output *out);
/**
Given a buffer of data, (optionally) compress it, and add it to
the zip file with the given name.
*/
void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress);
/**
Close the zip file for writing.
This flushes any pending data to the file. This can throw
exceptions.
*/
void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip);
/**
Drop the reference to the zipfile.
In common with other 'drop' methods, this will never throw an
exception.
*/
void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip);
/**
Create an archive that holds named buffers.
tree can either be a preformed tree with fz_buffers as values,
or it can be NULL for an empty tree.
*/
fz_archive *fz_new_tree_archive(fz_context *ctx, fz_tree *tree);
/**
Add a named buffer to an existing tree archive.
The tree will take a new reference to the buffer. Ownership
is not transferred.
*/
void fz_tree_archive_add_buffer(fz_context *ctx, fz_archive *arch_, const char *name, fz_buffer *buf);
/**
Add a named block of data to an existing tree archive.
The data will be copied into a buffer, and so the caller
may free it as soon as this returns.
*/
void fz_tree_archive_add_data(fz_context *ctx, fz_archive *arch_, const char *name, const void *data, size_t size);
/**
Create a new multi archive (initially empty).
*/
fz_archive *fz_new_multi_archive(fz_context *ctx);
/**
Add an archive to the set of archives handled by a multi
archive.
If path is NULL, then the archive contents will appear at the
top level, otherwise, the archives contents will appear prefixed
by path.
*/
void fz_mount_multi_archive(fz_context *ctx, fz_archive *arch_, fz_archive *sub, const char *path);
/**
Implementation details: Subject to change.
*/
struct fz_archive
{
int refs;
fz_stream *file;
const char *format;
void (*drop_archive)(fz_context *ctx, fz_archive *arch);
int (*count_entries)(fz_context *ctx, fz_archive *arch);
const char *(*list_entry)(fz_context *ctx, fz_archive *arch, int idx);
int (*has_entry)(fz_context *ctx, fz_archive *arch, const char *name);
fz_buffer *(*read_entry)(fz_context *ctx, fz_archive *arch, const char *name);
fz_stream *(*open_entry)(fz_context *ctx, fz_archive *arch, const char *name);
};
fz_archive *fz_new_archive_of_size(fz_context *ctx, fz_stream *file, int size);
#define fz_new_derived_archive(C,F,M) \
((M*)Memento_label(fz_new_archive_of_size(C, F, sizeof(M)), #M))
#endif

View File

@ -0,0 +1,117 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_BAND_WRITER_H
#define MUPDF_FITZ_BAND_WRITER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/color.h"
#include "mupdf/fitz/separation.h"
/**
fz_band_writer
*/
typedef struct fz_band_writer fz_band_writer;
/**
Cause a band writer to write the header for
a banded image with the given properties/dimensions etc. This
also configures the bandwriter for the format of the data to be
passed in future calls.
w, h: Width and Height of the entire page.
n: Number of components (including spots and alphas).
alpha: Number of alpha components.
xres, yres: X and Y resolutions in dpi.
cs: Colorspace (NULL for bitmaps)
seps: Separation details (or NULL).
*/
void fz_write_header(fz_context *ctx, fz_band_writer *writer, int w, int h, int n, int alpha, int xres, int yres, int pagenum, fz_colorspace *cs, fz_separations *seps);
/**
Cause a band writer to write the next band
of data for an image.
stride: The byte offset from the first byte of the data
for a pixel to the first byte of the data for the same pixel
on the row below.
band_height: The number of lines in this band.
samples: Pointer to first byte of the data.
*/
void fz_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_height, const unsigned char *samples);
/**
Finishes up the output and closes the band writer. After this
call no more headers or bands may be written.
*/
void fz_close_band_writer(fz_context *ctx, fz_band_writer *writer);
/**
Drop the reference to the band writer, causing it to be
destroyed.
Never throws an exception.
*/
void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer);
/* Implementation details: subject to change. */
typedef void (fz_write_header_fn)(fz_context *ctx, fz_band_writer *writer, fz_colorspace *cs);
typedef void (fz_write_band_fn)(fz_context *ctx, fz_band_writer *writer, int stride, int band_start, int band_height, const unsigned char *samples);
typedef void (fz_write_trailer_fn)(fz_context *ctx, fz_band_writer *writer);
typedef void (fz_close_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
typedef void (fz_drop_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
struct fz_band_writer
{
fz_drop_band_writer_fn *drop;
fz_close_band_writer_fn *close;
fz_write_header_fn *header;
fz_write_band_fn *band;
fz_write_trailer_fn *trailer;
fz_output *out;
int w;
int h;
int n;
int s;
int alpha;
int xres;
int yres;
int pagenum;
int line;
fz_separations *seps;
};
fz_band_writer *fz_new_band_writer_of_size(fz_context *ctx, size_t size, fz_output *out);
#define fz_new_band_writer(C,M,O) ((M *)Memento_label(fz_new_band_writer_of_size(ctx, sizeof(M), O), #M))
#endif

90
include/mupdf/fitz/bidi.h Normal file
View File

@ -0,0 +1,90 @@
/**
Bidirectional text processing.
Derived from the SmartOffice code, which is itself derived
from the example unicode standard code. Original copyright
messages follow:
Copyright (C) Picsel, 2004-2008. All Rights Reserved.
Processes Unicode text by arranging the characters into an order
suitable for display. E.g. Hebrew text will be arranged from
right-to-left and any English within the text will remain in the
left-to-right order.
This is an implementation of the Unicode Bidirectional Algorithm
which can be found here: http://www.unicode.org/reports/tr9/ and
is based on the reference implementation found on Unicode.org.
*/
#ifndef FITZ_BIDI_H
#define FITZ_BIDI_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/* Implementation details: subject to change. */
typedef enum
{
FZ_BIDI_LTR = 0,
FZ_BIDI_RTL = 1,
FZ_BIDI_NEUTRAL = 2
}
fz_bidi_direction;
typedef enum
{
FZ_BIDI_CLASSIFY_WHITE_SPACE = 1,
FZ_BIDI_REPLACE_TAB = 2
}
fz_bidi_flags;
/**
Prototype for callback function supplied to fz_bidi_fragment_text.
@param fragment first character in fragment
@param fragmentLen number of characters in fragment
@param bidiLevel The bidirectional level for this text.
The bottom bit will be set iff block
should concatenate with other blocks as
right-to-left
@param script the script in use for this fragment (other
than common or inherited)
@param arg data from caller of Bidi_fragmentText
*/
typedef void (fz_bidi_fragment_fn)(const uint32_t *fragment,
size_t fragmentLen,
int bidiLevel,
int script,
void *arg);
/**
Partitions the given Unicode sequence into one or more
unidirectional fragments and invokes the given callback
function for each fragment.
For example, if directionality of text is:
0123456789
rrlllrrrrr,
we'll invoke callback with:
&text[0], length == 2
&text[2], length == 3
&text[5], length == 5
@param[in] text start of Unicode sequence
@param[in] textlen number of Unicodes to analyse
@param[in] baseDir direction of paragraph (specify FZ_BIDI_NEUTRAL to force auto-detection)
@param[in] callback function to be called for each fragment
@param[in] arg data to be passed to the callback function
@param[in] flags flags to control operation (see fz_bidi_flags above)
*/
void fz_bidi_fragment_text(fz_context *ctx,
const uint32_t *text,
size_t textlen,
fz_bidi_direction *baseDir,
fz_bidi_fragment_fn *callback,
void *arg,
int flags);
#endif

168
include/mupdf/fitz/bitmap.h Normal file
View File

@ -0,0 +1,168 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_BITMAP_H
#define MUPDF_FITZ_BITMAP_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/pixmap.h"
/**
Bitmaps have 1 bit per component. Only used for creating
halftoned versions of contone buffers, and saving out. Samples
are stored msb first, akin to pbms.
The internals of this struct are considered implementation
details and subject to change. Where possible, accessor
functions should be used in preference.
*/
typedef struct
{
int refs;
int w, h, stride, n;
int xres, yres;
unsigned char *samples;
} fz_bitmap;
/**
Take an additional reference to the bitmap. The same pointer
is returned.
Never throws exceptions.
*/
fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
/**
Drop a reference to the bitmap. When the reference count reaches
zero, the bitmap will be destroyed.
Never throws exceptions.
*/
void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit);
/**
A halftone is a set of threshold tiles, one per component. Each
threshold tile is a pixmap, possibly of varying sizes and
phases. Currently, we only provide one 'default' halftone tile
for operating on 1 component plus alpha pixmaps (where the alpha
is ignored). This is signified by a fz_halftone pointer to NULL.
*/
typedef struct fz_halftone fz_halftone;
/**
Make a bitmap from a pixmap and a halftone.
pix: The pixmap to generate from. Currently must be a single
color component with no alpha.
ht: The halftone to use. NULL implies the default halftone.
Returns the resultant bitmap. Throws exceptions in the case of
failure to allocate.
*/
fz_bitmap *fz_new_bitmap_from_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht);
/**
Make a bitmap from a pixmap and a
halftone, allowing for the position of the pixmap within an
overall banded rendering.
pix: The pixmap to generate from. Currently must be a single
color component with no alpha.
ht: The halftone to use. NULL implies the default halftone.
band_start: Vertical offset within the overall banded rendering
(in pixels)
Returns the resultant bitmap. Throws exceptions in the case of
failure to allocate.
*/
fz_bitmap *fz_new_bitmap_from_pixmap_band(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht, int band_start);
/**
Create a new bitmap.
w, h: Width and Height for the bitmap
n: Number of color components (assumed to be a divisor of 8)
xres, yres: X and Y resolutions (in pixels per inch).
Returns pointer to created bitmap structure. The bitmap
data is uninitialised.
*/
fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n, int xres, int yres);
/**
Retrieve details of a given bitmap.
bitmap: The bitmap to query.
w: Pointer to storage to retrieve width (or NULL).
h: Pointer to storage to retrieve height (or NULL).
n: Pointer to storage to retrieve number of color components (or
NULL).
stride: Pointer to storage to retrieve bitmap stride (or NULL).
*/
void fz_bitmap_details(fz_bitmap *bitmap, int *w, int *h, int *n, int *stride);
/**
Set the entire bitmap to 0.
Never throws exceptions.
*/
void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
/**
Create a 'default' halftone structure
for the given number of components.
num_comps: The number of components to use.
Returns a simple default halftone. The default halftone uses
the same halftone tile for each plane, which may not be ideal
for all purposes.
*/
fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps);
/**
Take an additional reference to the halftone. The same pointer
is returned.
Never throws exceptions.
*/
fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
/**
Drop a reference to the halftone. When the reference count
reaches zero, the halftone is destroyed.
Never throws exceptions.
*/
void fz_drop_halftone(fz_context *ctx, fz_halftone *ht);
#endif

250
include/mupdf/fitz/buffer.h Normal file
View File

@ -0,0 +1,250 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_BUFFER_H
#define MUPDF_FITZ_BUFFER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/**
fz_buffer is a wrapper around a dynamically allocated array of
bytes.
Buffers have a capacity (the number of bytes storage immediately
available) and a current size.
The contents of the structure are considered implementation
details and are subject to change. Users should use the accessor
functions in preference.
*/
typedef struct
{
int refs;
unsigned char *data;
size_t cap, len;
int unused_bits;
int shared;
} fz_buffer;
/**
Take an additional reference to the buffer. The same pointer
is returned.
Never throws exceptions.
*/
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
/**
Drop a reference to the buffer. When the reference count reaches
zero, the buffer is destroyed.
Never throws exceptions.
*/
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
/**
Retrieve internal memory of buffer.
datap: Output parameter that will be pointed to the data.
Returns the current size of the data in bytes.
*/
size_t fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap);
/**
Ensure that a buffer's data ends in a
0 byte, and return a pointer to it.
*/
const char *fz_string_from_buffer(fz_context *ctx, fz_buffer *buf);
fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);
/**
Create a new buffer with existing data.
data: Pointer to existing data.
size: Size of existing data.
Takes ownership of data. Does not make a copy. Calls fz_free on
the data when the buffer is deallocated. Do not use 'data' after
passing to this function.
Returns pointer to new buffer. Throws exception on allocation
failure.
*/
fz_buffer *fz_new_buffer_from_data(fz_context *ctx, unsigned char *data, size_t size);
/**
Like fz_new_buffer, but does not take ownership.
*/
fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, const unsigned char *data, size_t size);
/**
Create a new buffer containing a copy of the passed data.
*/
fz_buffer *fz_new_buffer_from_copied_data(fz_context *ctx, const unsigned char *data, size_t size);
/**
Make a new buffer, containing a copy of the data used in
the original.
*/
fz_buffer *fz_clone_buffer(fz_context *ctx, fz_buffer *buf);
/**
Create a new buffer with data decoded from a base64 input string.
*/
fz_buffer *fz_new_buffer_from_base64(fz_context *ctx, const char *data, size_t size);
/**
Ensure that a buffer has a given capacity,
truncating data if required.
capacity: The desired capacity for the buffer. If the current
size of the buffer contents is smaller than capacity, it is
truncated.
*/
void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, size_t capacity);
/**
Make some space within a buffer (i.e. ensure that
capacity > size).
*/
void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
/**
Trim wasted capacity from a buffer by resizing internal memory.
*/
void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
/**
Empties the buffer. Storage is not freed, but is held ready
to be reused as the buffer is refilled.
Never throws exceptions.
*/
void fz_clear_buffer(fz_context *ctx, fz_buffer *buf);
/**
Create a new buffer with a (subset of) the data from the buffer.
start: if >= 0, offset from start of buffer, if < 0 offset from end of buffer.
end: if >= 0, offset from start of buffer, if < 0 offset from end of buffer.
*/
fz_buffer *fz_slice_buffer(fz_context *ctx, fz_buffer *buf, int64_t start, int64_t end);
/**
Append the contents of the source buffer onto the end of the
destination buffer, extending automatically as required.
Ownership of buffers does not change.
*/
void fz_append_buffer(fz_context *ctx, fz_buffer *destination, fz_buffer *source);
/**
Write a base64 encoded data block, optionally with periodic newlines.
*/
void fz_append_base64(fz_context *ctx, fz_buffer *out, const unsigned char *data, size_t size, int newline);
/**
Append a base64 encoded fz_buffer, optionally with periodic newlines.
*/
void fz_append_base64_buffer(fz_context *ctx, fz_buffer *out, fz_buffer *data, int newline);
/**
fz_append_*: Append data to a buffer.
The buffer will automatically grow as required.
*/
void fz_append_data(fz_context *ctx, fz_buffer *buf, const void *data, size_t len);
void fz_append_string(fz_context *ctx, fz_buffer *buf, const char *data);
void fz_append_byte(fz_context *ctx, fz_buffer *buf, int c);
void fz_append_rune(fz_context *ctx, fz_buffer *buf, int c);
void fz_append_int32_le(fz_context *ctx, fz_buffer *buf, int x);
void fz_append_int16_le(fz_context *ctx, fz_buffer *buf, int x);
void fz_append_int32_be(fz_context *ctx, fz_buffer *buf, int x);
void fz_append_int16_be(fz_context *ctx, fz_buffer *buf, int x);
void fz_append_bits(fz_context *ctx, fz_buffer *buf, int value, int count);
void fz_append_bits_pad(fz_context *ctx, fz_buffer *buf);
/**
fz_append_pdf_string: Append a string with PDF syntax quotes and
escapes.
The buffer will automatically grow as required.
*/
void fz_append_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text);
/**
fz_append_printf: Format and append data to buffer using
printf-like formatting (see fz_vsnprintf).
The buffer will automatically grow as required.
*/
void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...);
/**
fz_append_vprintf: Format and append data to buffer using
printf-like formatting with varargs (see fz_vsnprintf).
*/
void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
/**
Zero-terminate buffer in order to use as a C string.
This byte is invisible and does not affect the length of the
buffer as returned by fz_buffer_storage. The zero byte is
written *after* the data, and subsequent writes will overwrite
the terminating byte.
Subsequent changes to the size of the buffer (such as by
fz_buffer_trim, fz_buffer_grow, fz_resize_buffer, etc) may
invalidate this.
*/
void fz_terminate_buffer(fz_context *ctx, fz_buffer *buf);
/**
Create an MD5 digest from buffer contents.
Never throws exceptions.
*/
void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]);
/**
Take ownership of buffer contents.
Performs the same task as fz_buffer_storage, but ownership of
the data buffer returns with this call. The buffer is left
empty.
Note: Bad things may happen if this is called on a buffer with
multiple references that is being used from multiple threads.
data: Pointer to place to retrieve data pointer.
Returns length of stream.
*/
size_t fz_buffer_extract(fz_context *ctx, fz_buffer *buf, unsigned char **data);
#endif

427
include/mupdf/fitz/color.h Normal file
View File

@ -0,0 +1,427 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_COLOR_H
#define MUPDF_FITZ_COLOR_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/store.h"
#if FZ_ENABLE_ICC
/**
Opaque type for an ICC Profile.
*/
typedef struct fz_icc_profile fz_icc_profile;
#endif
/**
Describes a given colorspace.
*/
typedef struct fz_colorspace fz_colorspace;
/**
Pixmaps represent a set of pixels for a 2 dimensional region of
a plane. Each pixel has n components per pixel. The components
are in the order process-components, spot-colors, alpha, where
there can be 0 of any of those types. The data is in
premultiplied alpha when rendering, but non-premultiplied for
colorspace conversions and rescaling.
*/
typedef struct fz_pixmap fz_pixmap;
/* Color handling parameters: rendering intent, overprint, etc. */
enum
{
/* Same order as needed by lcms */
FZ_RI_PERCEPTUAL,
FZ_RI_RELATIVE_COLORIMETRIC,
FZ_RI_SATURATION,
FZ_RI_ABSOLUTE_COLORIMETRIC,
};
typedef struct
{
uint8_t ri; /* rendering intent */
uint8_t bp; /* black point compensation */
uint8_t op; /* overprinting */
uint8_t opm; /* overprint mode */
} fz_color_params;
FZ_DATA extern const fz_color_params fz_default_color_params;
/**
Map from (case sensitive) rendering intent string to enumeration
value.
*/
int fz_lookup_rendering_intent(const char *name);
/**
Map from enumerated rendering intent to string.
The returned string is static and therefore must not be freed.
*/
const char *fz_rendering_intent_name(int ri);
/**
The maximum number of colorants available in any given
color/colorspace (not including alpha).
Changing this value will alter the amount of memory being used
(both stack and heap space), but not hugely. Speed should
(largely) be determined by the number of colors actually used.
*/
enum { FZ_MAX_COLORS = 32 };
enum fz_colorspace_type
{
FZ_COLORSPACE_NONE,
FZ_COLORSPACE_GRAY,
FZ_COLORSPACE_RGB,
FZ_COLORSPACE_BGR,
FZ_COLORSPACE_CMYK,
FZ_COLORSPACE_LAB,
FZ_COLORSPACE_INDEXED,
FZ_COLORSPACE_SEPARATION,
};
enum
{
FZ_COLORSPACE_IS_DEVICE = 1,
FZ_COLORSPACE_IS_ICC = 2,
FZ_COLORSPACE_HAS_CMYK = 4,
FZ_COLORSPACE_HAS_SPOTS = 8,
FZ_COLORSPACE_HAS_CMYK_AND_SPOTS = 4|8,
};
/**
Creates a new colorspace instance and returns a reference.
No internal checking is done that the colorspace type (e.g.
CMYK) matches with the flags (e.g. FZ_COLORSPACE_HAS_CMYK) or
colorant count (n) or name.
The reference should be dropped when it is finished with.
Colorspaces are immutable once created (with the exception of
setting up colorant names for separation spaces).
*/
fz_colorspace *fz_new_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, int n, const char *name);
/**
Increment the reference count for the colorspace.
Returns the same pointer. Never throws an exception.
*/
fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
/**
Drops a reference to the colorspace.
When the reference count reaches zero, the colorspace is
destroyed.
*/
void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
/**
Create an indexed colorspace.
The supplied lookup table is high palette entries long. Each
entry is n bytes long, where n is given by the number of
colorants in the base colorspace, one byte per colorant.
Ownership of lookup is passed it; it will be freed on
destruction, so must be heap allocated.
The colorspace will keep an additional reference to the base
colorspace that will be dropped on destruction.
The returned reference should be dropped when it is finished
with.
Colorspaces are immutable once created.
*/
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup);
/**
Create a colorspace from an ICC profile supplied in buf.
Limited checking is done to ensure that the colorspace type is
appropriate for the supplied ICC profile.
An additional reference is taken to buf, which will be dropped
on destruction. Ownership is NOT passed in.
The returned reference should be dropped when it is finished
with.
Colorspaces are immutable once created.
*/
fz_colorspace *fz_new_icc_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, const char *name, fz_buffer *buf);
/**
Create a calibrated gray colorspace.
The returned reference should be dropped when it is finished
with.
Colorspaces are immutable once created.
*/
fz_colorspace *fz_new_cal_gray_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma);
/**
Create a calibrated rgb colorspace.
The returned reference should be dropped when it is finished
with.
Colorspaces are immutable once created.
*/
fz_colorspace *fz_new_cal_rgb_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma[3], float matrix[9]);
/**
Query the type of colorspace.
*/
enum fz_colorspace_type fz_colorspace_type(fz_context *ctx, fz_colorspace *cs);
/**
Query the name of a colorspace.
The returned string has the same lifespan as the colorspace
does. Caller should not free it.
*/
const char *fz_colorspace_name(fz_context *ctx, fz_colorspace *cs);
/**
Query the number of colorants in a colorspace.
*/
int fz_colorspace_n(fz_context *ctx, fz_colorspace *cs);
/**
True for CMYK, Separation and DeviceN colorspaces.
*/
int fz_colorspace_is_subtractive(fz_context *ctx, fz_colorspace *cs);
/**
True if DeviceN color space has only colorants from the CMYK set.
*/
int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, fz_colorspace *cs);
/**
True if DeviceN color space has cyan magenta yellow or black as
one of its colorants.
*/
int fz_colorspace_device_n_has_cmyk(fz_context *ctx, fz_colorspace *cs);
/**
Tests for particular types of colorspaces
*/
int fz_colorspace_is_gray(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_rgb(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_cmyk(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_lab(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_indexed(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_device_n(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_device(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_device_gray(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_device_cmyk(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_lab_icc(fz_context *ctx, fz_colorspace *cs);
/**
Check to see that a colorspace is appropriate to be used as
a blending space (i.e. only grey, rgb or cmyk).
*/
int fz_is_valid_blend_colorspace(fz_context *ctx, fz_colorspace *cs);
/**
Get the 'base' colorspace for a colorspace.
For indexed colorspaces, this is the colorspace the index
decodes into. For all other colorspaces, it is the colorspace
itself.
The returned colorspace is 'borrowed' (i.e. no additional
references are taken or dropped).
*/
fz_colorspace *fz_base_colorspace(fz_context *ctx, fz_colorspace *cs);
/**
Retrieve global default colorspaces.
These return borrowed references that should not be dropped,
unless they are kept first.
*/
fz_colorspace *fz_device_gray(fz_context *ctx);
fz_colorspace *fz_device_rgb(fz_context *ctx);
fz_colorspace *fz_device_bgr(fz_context *ctx);
fz_colorspace *fz_device_cmyk(fz_context *ctx);
fz_colorspace *fz_device_lab(fz_context *ctx);
/**
Assign a name for a given colorant in a colorspace.
Used while initially setting up a colorspace. The string is
copied into local storage, so need not be retained by the
caller.
*/
void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int n, const char *name);
/**
Retrieve a the name for a colorant.
Returns a pointer with the same lifespan as the colorspace.
*/
const char *fz_colorspace_colorant(fz_context *ctx, fz_colorspace *cs, int n);
/* Color conversion */
/**
Clamp the samples in a color to the correct ranges for a
given colorspace.
*/
void fz_clamp_color(fz_context *ctx, fz_colorspace *cs, const float *in, float *out);
/**
Convert color values sv from colorspace ss into colorvalues dv
for colorspace ds, via an optional intervening space is,
respecting the given color_params.
*/
void fz_convert_color(fz_context *ctx, fz_colorspace *ss, const float *sv, fz_colorspace *ds, float *dv, fz_colorspace *is, fz_color_params params);
/* Default (fallback) colorspace handling */
/**
Structure to hold default colorspaces.
*/
typedef struct
{
int refs;
fz_colorspace *gray;
fz_colorspace *rgb;
fz_colorspace *cmyk;
fz_colorspace *oi;
} fz_default_colorspaces;
/**
Create a new default colorspace structure with values inherited
from the context, and return a reference to it.
These can be overridden using fz_set_default_xxxx.
These should not be overridden while more than one caller has
the reference for fear of race conditions.
The caller should drop this reference once finished with it.
*/
fz_default_colorspaces *fz_new_default_colorspaces(fz_context *ctx);
/**
Keep an additional reference to the default colorspaces
structure.
Never throws exceptions.
*/
fz_default_colorspaces* fz_keep_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
/**
Drop a reference to the default colorspaces structure. When the
reference count reaches 0, the references it holds internally
to the underlying colorspaces will be dropped, and the structure
will be destroyed.
Never throws exceptions.
*/
void fz_drop_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
/**
Returns a reference to a newly cloned default colorspaces
structure.
The new clone may safely be altered without fear of race
conditions as the caller is the only reference holder.
*/
fz_default_colorspaces *fz_clone_default_colorspaces(fz_context *ctx, fz_default_colorspaces *base);
/**
Retrieve default colorspaces (typically page local).
If default_cs is non NULL, the default is retrieved from there,
otherwise the global default is retrieved.
These return borrowed references that should not be dropped,
unless they are kept first.
*/
fz_colorspace *fz_default_gray(fz_context *ctx, const fz_default_colorspaces *default_cs);
fz_colorspace *fz_default_rgb(fz_context *ctx, const fz_default_colorspaces *default_cs);
fz_colorspace *fz_default_cmyk(fz_context *ctx, const fz_default_colorspaces *default_cs);
fz_colorspace *fz_default_output_intent(fz_context *ctx, const fz_default_colorspaces *default_cs);
/**
Set new defaults within the default colorspace structure.
New references are taken to the new default, and references to
the old defaults dropped.
Never throws exceptions.
*/
void fz_set_default_gray(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
void fz_set_default_rgb(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
void fz_set_default_cmyk(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
void fz_set_default_output_intent(fz_context *ctx, fz_default_colorspaces *default_cs, fz_colorspace *cs);
/* Implementation details: subject to change. */
struct fz_colorspace
{
fz_key_storable key_storable;
enum fz_colorspace_type type;
int flags;
int n;
char *name;
union {
#if FZ_ENABLE_ICC
struct {
fz_buffer *buffer;
unsigned char md5[16];
fz_icc_profile *profile;
} icc;
#endif
struct {
fz_colorspace *base;
int high;
unsigned char *lookup;
} indexed;
struct {
fz_colorspace *base;
void (*eval)(fz_context *ctx, void *tint, const float *s, int sn, float *d, int dn);
void (*drop)(fz_context *ctx, void *tint);
void *tint;
char *colorant[FZ_MAX_COLORS];
} separation;
} u;
};
void fz_drop_colorspace_imp(fz_context *ctx, fz_storable *cs_);
#endif

View File

@ -0,0 +1,87 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_COMPRESS_H
#define MUPDF_FITZ_COMPRESS_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/buffer.h"
typedef enum
{
FZ_DEFLATE_NONE = 0,
FZ_DEFLATE_BEST_SPEED = 1,
FZ_DEFLATE_BEST = 9,
FZ_DEFLATE_DEFAULT = -1
} fz_deflate_level;
/**
Returns the upper bound on the
size of flated data of length size.
*/
size_t fz_deflate_bound(fz_context *ctx, size_t size);
/**
Compress source_length bytes of data starting
at source, into a buffer of length *destLen, starting at dest.
*compressed_length will be updated on exit to contain the size
actually used.
*/
void fz_deflate(fz_context *ctx, unsigned char *dest, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_deflate_level level);
/**
Compress source_length bytes of data starting
at source, into a new memory block malloced for that purpose.
*compressed_length is updated on exit to contain the size used.
Ownership of the block is returned from this function, and the
caller is therefore responsible for freeing it. The block may be
considerably larger than is actually required. The caller is
free to fz_realloc it down if it wants to.
*/
unsigned char *fz_new_deflated_data(fz_context *ctx, size_t *compressed_length, const unsigned char *source, size_t source_length, fz_deflate_level level);
/**
Compress the contents of a fz_buffer into a
new block malloced for that purpose. *compressed_length is
updated on exit to contain the size used. Ownership of the block
is returned from this function, and the caller is therefore
responsible for freeing it. The block may be considerably larger
than is actually required. The caller is free to fz_realloc it
down if it wants to.
*/
unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_deflate_level level);
/**
Compress bitmap data as CCITT Group 3 1D fax image.
Creates a stream assuming the default PDF parameters,
except the number of columns.
*/
fz_buffer *fz_compress_ccitt_fax_g3(fz_context *ctx, const unsigned char *data, int columns, int rows);
/**
Compress bitmap data as CCITT Group 4 2D fax image.
Creates a stream assuming the default PDF parameters, except
K=-1 and the number of columns.
*/
fz_buffer *fz_compress_ccitt_fax_g4(fz_context *ctx, const unsigned char *data, int columns, int rows);
#endif

View File

@ -0,0 +1,173 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_COMPRESSED_BUFFER_H
#define MUPDF_FITZ_COMPRESSED_BUFFER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/filter.h"
/**
Compression parameters used for buffers of compressed data;
typically for the source data for images.
*/
typedef struct
{
int type;
union {
struct {
int color_transform; /* Use -1 for unset */
} jpeg;
struct {
int smask_in_data;
} jpx;
struct {
fz_jbig2_globals *globals;
int embedded;
} jbig2;
struct {
int columns;
int rows;
int k;
int end_of_line;
int encoded_byte_align;
int end_of_block;
int black_is_1;
int damaged_rows_before_error;
} fax;
struct
{
int columns;
int colors;
int predictor;
int bpc;
}
flate;
struct
{
int columns;
int colors;
int predictor;
int bpc;
int early_change;
} lzw;
} u;
} fz_compression_params;
/**
Buffers of compressed data; typically for the source data
for images.
*/
typedef struct
{
fz_compression_params params;
fz_buffer *buffer;
} fz_compressed_buffer;
/**
Return the storage size used for a buffer and its data.
Used in implementing store handling.
Never throws exceptions.
*/
size_t fz_compressed_buffer_size(fz_compressed_buffer *buffer);
/**
Open a stream to read the decompressed version of a buffer.
*/
fz_stream *fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *);
/**
Open a stream to read the decompressed version of a buffer,
with optional log2 subsampling.
l2factor = NULL for no subsampling, or a pointer to an integer
containing the maximum log2 subsample factor acceptable (0 =
none, 1 = halve dimensions, 2 = quarter dimensions etc). If
non-NULL, then *l2factor will be updated on exit with the actual
log2 subsample factor achieved.
*/
fz_stream *fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *, int *l2factor);
/**
Open a stream to read the decompressed version of another stream
with optional log2 subsampling.
*/
fz_stream *fz_open_image_decomp_stream(fz_context *ctx, fz_stream *, fz_compression_params *, int *l2factor);
/**
Recognise image format strings in the first 8 bytes from image
data.
*/
int fz_recognize_image_format(fz_context *ctx, unsigned char p[8]);
/**
Map from FZ_IMAGE_* value to string.
The returned string is static and therefore must not be freed.
*/
const char *fz_image_type_name(int type);
/**
Map from (case sensitive) image type string to FZ_IMAGE_*
type value.
*/
int fz_lookup_image_type(const char *type);
enum
{
FZ_IMAGE_UNKNOWN = 0,
/* Uncompressed samples */
FZ_IMAGE_RAW,
/* Compressed samples */
FZ_IMAGE_FAX,
FZ_IMAGE_FLATE,
FZ_IMAGE_LZW,
FZ_IMAGE_RLD,
/* Full image formats */
FZ_IMAGE_BMP,
FZ_IMAGE_GIF,
FZ_IMAGE_JBIG2,
FZ_IMAGE_JPEG,
FZ_IMAGE_JPX,
FZ_IMAGE_JXR,
FZ_IMAGE_PNG,
FZ_IMAGE_PNM,
FZ_IMAGE_TIFF,
FZ_IMAGE_PSD,
};
/**
Drop a reference to a compressed buffer. Destroys the buffer
and frees any storage/other references held by it.
Never throws exceptions.
*/
void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf);
#endif

222
include/mupdf/fitz/config.h Normal file
View File

@ -0,0 +1,222 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef FZ_CONFIG_H
#define FZ_CONFIG_H
/**
Enable the following for spot (and hence overprint/overprint
simulation) capable rendering. This forces FZ_PLOTTERS_N on.
*/
/* #define FZ_ENABLE_SPOT_RENDERING 1 */
/**
Choose which plotters we need.
By default we build all the plotters in. To avoid building
plotters in that aren't needed, define the unwanted
FZ_PLOTTERS_... define to 0.
*/
/* #define FZ_PLOTTERS_G 1 */
/* #define FZ_PLOTTERS_RGB 1 */
/* #define FZ_PLOTTERS_CMYK 1 */
/* #define FZ_PLOTTERS_N 1 */
/**
Choose which document agents to include.
By default all are enabled. To avoid building unwanted
ones, define FZ_ENABLE_... to 0.
*/
/* #define FZ_ENABLE_PDF 1 */
/* #define FZ_ENABLE_XPS 1 */
/* #define FZ_ENABLE_SVG 1 */
/* #define FZ_ENABLE_CBZ 1 */
/* #define FZ_ENABLE_IMG 1 */
/* #define FZ_ENABLE_HTML 1 */
/* #define FZ_ENABLE_EPUB 1 */
/**
Choose which document writers to include.
By default all are enabled. To avoid building unwanted
ones, define FZ_ENABLE_..._OUTPUT to 0.
*/
/* #define FZ_ENABLE_OCR_OUTPUT 1 */
/* #define FZ_ENABLE_DOCX_OUTPUT 1 */
/* #define FZ_ENABLE_ODT_OUTPUT 1 */
/**
Choose whether to enable ICC color profiles.
*/
/* #define FZ_ENABLE_ICC 1 */
/**
Choose whether to enable JPEG2000 decoding.
By default, it is enabled, but due to frequent security
issues with the third party libraries we support disabling
it with this flag.
*/
/* #define FZ_ENABLE_JPX 1 */
/**
Choose whether to enable JavaScript.
By default JavaScript is enabled both for mutool and PDF
interactivity.
*/
/* #define FZ_ENABLE_JS 1 */
/**
Choose which fonts to include.
By default we include the base 14 PDF fonts,
DroidSansFallback from Android for CJK, and
Charis SIL from SIL for epub/html.
Enable the following defines to AVOID including
unwanted fonts.
*/
/* To avoid all noto fonts except CJK, enable: */
#define TOFU 1
/* To skip the CJK font, enable: (this implicitly enables TOFU_CJK_EXT
* and TOFU_CJK_LANG) */
#define TOFU_CJK 1
/* To skip CJK Extension A, enable: (this implicitly enables
* TOFU_CJK_LANG) */
/* #define TOFU_CJK_EXT */
/* To skip CJK language specific fonts, enable: */
/* #define TOFU_CJK_LANG */
/* To skip the Emoji font, enable: */
/* #define TOFU_EMOJI */
/* To skip the ancient/historic scripts, enable: */
/* #define TOFU_HISTORIC */
/* To skip the symbol font, enable: */
/* #define TOFU_SYMBOL */
/* To skip the SIL fonts, enable: */
/* #define TOFU_SIL */
/* To skip the Base14 fonts, enable: */
/* #define TOFU_BASE14 */
/* (You probably really don't want to do that except for measurement
* purposes!) */
/* ---------- DO NOT EDIT ANYTHING UNDER THIS LINE ---------- */
#ifndef FZ_ENABLE_SPOT_RENDERING
#define FZ_ENABLE_SPOT_RENDERING 1
#endif
#if FZ_ENABLE_SPOT_RENDERING
#undef FZ_PLOTTERS_N
#define FZ_PLOTTERS_N 1
#endif /* FZ_ENABLE_SPOT_RENDERING */
#ifndef FZ_PLOTTERS_G
#define FZ_PLOTTERS_G 1
#endif /* FZ_PLOTTERS_G */
#ifndef FZ_PLOTTERS_RGB
#define FZ_PLOTTERS_RGB 1
#endif /* FZ_PLOTTERS_RGB */
#ifndef FZ_PLOTTERS_CMYK
#define FZ_PLOTTERS_CMYK 1
#endif /* FZ_PLOTTERS_CMYK */
#ifndef FZ_PLOTTERS_N
#define FZ_PLOTTERS_N 1
#endif /* FZ_PLOTTERS_N */
/* We need at least 1 plotter defined */
#if FZ_PLOTTERS_G == 0 && FZ_PLOTTERS_RGB == 0 && FZ_PLOTTERS_CMYK == 0
#undef FZ_PLOTTERS_N
#define FZ_PLOTTERS_N 1
#endif
#ifndef FZ_ENABLE_PDF
#define FZ_ENABLE_PDF 1
#endif /* FZ_ENABLE_PDF */
#ifndef FZ_ENABLE_XPS
#define FZ_ENABLE_XPS 1
#endif /* FZ_ENABLE_XPS */
#ifndef FZ_ENABLE_SVG
#define FZ_ENABLE_SVG 1
#endif /* FZ_ENABLE_SVG */
#ifndef FZ_ENABLE_CBZ
#define FZ_ENABLE_CBZ 1
#endif /* FZ_ENABLE_CBZ */
#ifndef FZ_ENABLE_IMG
#define FZ_ENABLE_IMG 1
#endif /* FZ_ENABLE_IMG */
#ifndef FZ_ENABLE_HTML
#define FZ_ENABLE_HTML 1
#endif /* FZ_ENABLE_HTML */
#ifndef FZ_ENABLE_EPUB
#define FZ_ENABLE_EPUB 1
#endif /* FZ_ENABLE_EPUB */
#ifndef FZ_ENABLE_OCR_OUTPUT
#define FZ_ENABLE_OCR_OUTPUT 1
#endif /* FZ_ENABLE_OCR_OUTPUT */
#ifndef FZ_ENABLE_ODT_OUTPUT
#define FZ_ENABLE_ODT_OUTPUT 1
#endif /* FZ_ENABLE_ODT_OUTPUT */
#ifndef FZ_ENABLE_DOCX_OUTPUT
#define FZ_ENABLE_DOCX_OUTPUT 1
#endif /* FZ_ENABLE_DOCX_OUTPUT */
#ifndef FZ_ENABLE_JPX
#define FZ_ENABLE_JPX 1
#endif /* FZ_ENABLE_JPX */
#ifndef FZ_ENABLE_JS
#define FZ_ENABLE_JS 1
#endif /* FZ_ENABLE_JS */
#ifndef FZ_ENABLE_ICC
#define FZ_ENABLE_ICC 1
#endif /* FZ_ENABLE_ICC */
/* If Epub and HTML are both disabled, disable SIL fonts */
#if FZ_ENABLE_HTML == 0 && FZ_ENABLE_EPUB == 0
#undef TOFU_SIL
#define TOFU_SIL
#endif
#if !defined(HAVE_LEPTONICA) || !defined(HAVE_TESSERACT)
#ifndef OCR_DISABLED
#define OCR_DISABLED
#endif
#endif
#endif /* FZ_CONFIG_H */

View File

@ -0,0 +1,942 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_CONTEXT_H
#define MUPDF_FITZ_CONTEXT_H
#include "mupdf/fitz/version.h"
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/geometry.h"
#ifndef FZ_VERBOSE_EXCEPTIONS
#define FZ_VERBOSE_EXCEPTIONS 0
#endif
typedef struct fz_font_context fz_font_context;
typedef struct fz_colorspace_context fz_colorspace_context;
typedef struct fz_style_context fz_style_context;
typedef struct fz_tuning_context fz_tuning_context;
typedef struct fz_store fz_store;
typedef struct fz_glyph_cache fz_glyph_cache;
typedef struct fz_document_handler_context fz_document_handler_context;
typedef struct fz_output fz_output;
typedef struct fz_context fz_context;
/**
Allocator structure; holds callbacks and private data pointer.
*/
typedef struct
{
void *user;
void *(*malloc)(void *, size_t);
void *(*realloc)(void *, void *, size_t);
void (*free)(void *, void *);
} fz_alloc_context;
/**
Exception macro definitions. Just treat these as a black box -
pay no attention to the man behind the curtain.
*/
#define fz_var(var) fz_var_imp((void *)&(var))
#define fz_try(ctx) if (!fz_setjmp(*fz_push_try(ctx))) if (fz_do_try(ctx)) do
#define fz_always(ctx) while (0); if (fz_do_always(ctx)) do
#define fz_catch(ctx) while (0); if (fz_do_catch(ctx))
/**
These macros provide a simple exception handling system. Use them as
follows:
fz_try(ctx)
...
fz_catch(ctx)
...
or as:
fz_try(ctx)
...
fz_always(ctx)
...
fz_catch(ctx)
...
Code within the fz_try() section can then throw exceptions using fz_throw()
(or fz_vthrow()).
They are implemented with setjmp/longjmp, which can have unfortunate
consequences for 'losing' local variable values on a throw. To avoid this
we recommend calling 'fz_var(variable)' before the fz_try() for any
local variable whose value may change within the fz_try() block and whose
value will be required afterwards.
Do not call anything in the fz_always() section that can throw.
Any exception can be rethrown from the fz_catch() section using fz_rethrow()
as long as there has been no intervening use of fz_try/fz_catch.
*/
/**
Throw an exception.
This assumes an enclosing fz_try() block within the callstack.
*/
FZ_NORETURN void fz_vthrow(fz_context *ctx, int errcode, const char *, va_list ap);
FZ_NORETURN void fz_throw(fz_context *ctx, int errcode, const char *, ...) FZ_PRINTFLIKE(3,4);
FZ_NORETURN void fz_rethrow(fz_context *ctx);
/**
Called within a catch block this modifies the current
exception's code. If it's of type 'fromcode' it is
modified to 'tocode'. Typically used for 'downgrading'
exception severity.
*/
void fz_morph_error(fz_context *ctx, int fromcode, int tocode);
/**
Log a warning.
This goes to the registered warning stream (stderr by
default).
*/
void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap);
void fz_warn(fz_context *ctx, const char *fmt, ...) FZ_PRINTFLIKE(2,3);
/**
Within an fz_catch() block, retrieve the formatted message
string for the current exception.
This assumes no intervening use of fz_try/fz_catch.
*/
const char *fz_caught_message(fz_context *ctx);
/**
Within an fz_catch() block, retrieve the error code for
the current exception.
This assumes no intervening use of fz_try/fz_catch.
*/
int fz_caught(fz_context *ctx);
/**
Within an fz_catch() block, rethrow the current exception
if the errcode of the current exception matches.
This assumes no intervening use of fz_try/fz_catch.
*/
void fz_rethrow_if(fz_context *ctx, int errcode);
/**
Format an error message, and log it to the registered
error stream (stderr by default).
*/
void fz_log_error_printf(fz_context *ctx, const char *fmt, ...) FZ_PRINTFLIKE(2,3);
void fz_vlog_error_printf(fz_context *ctx, const char *fmt, va_list ap);
/**
Log a (preformatted) string to the registered
error stream (stderr by default).
*/
void fz_log_error(fz_context *ctx, const char *str);
void fz_start_throw_on_repair(fz_context *ctx);
void fz_end_throw_on_repair(fz_context *ctx);
/**
Now, a debugging feature. If FZ_VERBOSE_EXCEPTIONS is 1 then
some of the above functions are replaced by versions that print
FILE and LINE information.
*/
#if FZ_VERBOSE_EXCEPTIONS
#define fz_vthrow(CTX, ERRCODE, FMT, VA) fz_vthrowFL(CTX, __FILE__, __LINE__, ERRCODE, FMT, VA)
#define fz_throw(CTX, ERRCODE, ...) fz_throwFL(CTX, __FILE__, __LINE__, ERRCODE, __VA_ARGS__)
#define fz_rethrow(CTX) fz_rethrowFL(CTX, __FILE__, __LINE__)
#define fz_morph_error(CTX, FROM, TO) fz_morph_errorFL(CTX, __FILE__, __LINE__, FROM, TO)
#define fz_vwarn(CTX, FMT, VA) fz_vwarnFL(CTX, __FILE__, __LINE__, FMT, VA)
#define fz_warn(CTX, ...) fz_warnFL(CTX, __FILE__, __LINE__, __VA_ARGS__)
#define fz_rethrow_if(CTX, ERRCODE) fz_rethrow_ifFL(CTX, __FILE__, __LINE__, ERRCODE)
#define fz_log_error_printf(CTX, ...) fz_log_error_printfFL(CTX, __FILE__, __LINE__, __VA_ARGS__)
#define fz_vlog_error_printf(CTX, FMT, VA) fz_log_error_printfFL(CTX, __FILE__, __LINE__, FMT, VA)
#define fz_log_error(CTX, STR) fz_log_error_printfFL(CTX, __FILE__, __LINE__, STR)
FZ_NORETURN void fz_vthrowFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, va_list ap);
FZ_NORETURN void fz_throwFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, ...) FZ_PRINTFLIKE(5,6);
FZ_NORETURN void fz_rethrowFL(fz_context *ctx, const char *file, int line);
void fz_morph_errorFL(fz_context *ctx, const char *file, int line, int fromcode, int tocode);
void fz_vwarnFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap);
void fz_warnFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5);
void fz_rethrow_ifFL(fz_context *ctx, const char *file, int line, int errcode);
void fz_log_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5);
void fz_vlog_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap);
void fz_log_errorFL(fz_context *ctx, const char *file, int line, const char *str);
#endif
enum
{
FZ_ERROR_NONE = 0,
FZ_ERROR_MEMORY = 1,
FZ_ERROR_GENERIC = 2,
FZ_ERROR_SYNTAX = 3,
FZ_ERROR_MINOR = 4,
FZ_ERROR_TRYLATER = 5,
FZ_ERROR_ABORT = 6,
FZ_ERROR_REPAIRED = 7,
FZ_ERROR_COUNT
};
/**
Flush any repeated warnings.
Repeated warnings are buffered, counted and eventually printed
along with the number of repetitions. Call fz_flush_warnings
to force printing of the latest buffered warning and the
number of repetitions, for example to make sure that all
warnings are printed before exiting an application.
*/
void fz_flush_warnings(fz_context *ctx);
/**
Locking functions
MuPDF is kept deliberately free of any knowledge of particular
threading systems. As such, in order for safe multi-threaded
operation, we rely on callbacks to client provided functions.
A client is expected to provide FZ_LOCK_MAX number of mutexes,
and a function to lock/unlock each of them. These may be
recursive mutexes, but do not have to be.
If a client does not intend to use multiple threads, then it
may pass NULL instead of a lock structure.
In order to avoid deadlocks, we have one simple rule
internally as to how we use locks: We can never take lock n
when we already hold any lock i, where 0 <= i <= n. In order
to verify this, we have some debugging code, that can be
enabled by defining FITZ_DEBUG_LOCKING.
*/
typedef struct
{
void *user;
void (*lock)(void *user, int lock);
void (*unlock)(void *user, int lock);
} fz_locks_context;
enum {
FZ_LOCK_ALLOC = 0,
FZ_LOCK_FREETYPE,
FZ_LOCK_GLYPHCACHE,
FZ_LOCK_MAX
};
#if defined(MEMENTO) || !defined(NDEBUG)
#define FITZ_DEBUG_LOCKING
#endif
#ifdef FITZ_DEBUG_LOCKING
void fz_assert_lock_held(fz_context *ctx, int lock);
void fz_assert_lock_not_held(fz_context *ctx, int lock);
void fz_lock_debug_lock(fz_context *ctx, int lock);
void fz_lock_debug_unlock(fz_context *ctx, int lock);
#else
#define fz_assert_lock_held(A,B) do { } while (0)
#define fz_assert_lock_not_held(A,B) do { } while (0)
#define fz_lock_debug_lock(A,B) do { } while (0)
#define fz_lock_debug_unlock(A,B) do { } while (0)
#endif /* !FITZ_DEBUG_LOCKING */
/**
Specifies the maximum size in bytes of the resource store in
fz_context. Given as argument to fz_new_context.
FZ_STORE_UNLIMITED: Let resource store grow unbounded.
FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
devices that are not memory constrained.
*/
enum {
FZ_STORE_UNLIMITED = 0,
FZ_STORE_DEFAULT = 256 << 20,
};
/**
Allocate context containing global state.
The global state contains an exception stack, resource store,
etc. Most functions in MuPDF take a context argument to be
able to reference the global state. See fz_drop_context for
freeing an allocated context.
alloc: Supply a custom memory allocator through a set of
function pointers. Set to NULL for the standard library
allocator. The context will keep the allocator pointer, so the
data it points to must not be modified or freed during the
lifetime of the context.
locks: Supply a set of locks and functions to lock/unlock
them, intended for multi-threaded applications. Set to NULL
when using MuPDF in a single-threaded applications. The
context will keep the locks pointer, so the data it points to
must not be modified or freed during the lifetime of the
context.
max_store: Maximum size in bytes of the resource store, before
it will start evicting cached resources such as fonts and
images. FZ_STORE_UNLIMITED can be used if a hard limit is not
desired. Use FZ_STORE_DEFAULT to get a reasonable size.
May return NULL.
*/
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
/**
Make a clone of an existing context.
This function is meant to be used in multi-threaded
applications where each thread requires its own context, yet
parts of the global state, for example caching, are shared.
ctx: Context obtained from fz_new_context to make a copy of.
ctx must have had locks and lock/functions setup when created.
The two contexts will share the memory allocator, resource
store, locks and lock/unlock functions. They will each have
their own exception stacks though.
May return NULL.
*/
fz_context *fz_clone_context(fz_context *ctx);
/**
Free a context and its global state.
The context and all of its global state is freed, and any
buffered warnings are flushed (see fz_flush_warnings). If NULL
is passed in nothing will happen.
Must not be called for a context that is being used in an active
fz_try(), fz_always() or fz_catch() block.
*/
void fz_drop_context(fz_context *ctx);
/**
Set the user field in the context.
NULL initially, this field can be set to any opaque value
required by the user. It is copied on clones.
*/
void fz_set_user_context(fz_context *ctx, void *user);
/**
Read the user field from the context.
*/
void *fz_user_context(fz_context *ctx);
/**
FIXME: Better not to expose fz_default_error_callback, and
fz_default_warning callback and to allow 'NULL' to be used
int fz_set_xxxx_callback to mean "defaults".
FIXME: Do we need/want functions like
fz_error_callback(ctx, message) to allow callers to inject
stuff into the error/warning streams?
*/
/**
The default error callback. Declared publicly just so that the
error callback can be set back to this after it has been
overridden.
*/
void fz_default_error_callback(void *user, const char *message);
/**
The default warning callback. Declared publicly just so that
the warning callback can be set back to this after it has been
overridden.
*/
void fz_default_warning_callback(void *user, const char *message);
/**
A callback called whenever an error message is generated.
The user pointer passed to fz_set_error_callback() is passed
along with the error message.
*/
typedef void (fz_error_cb)(void *user, const char *message);
/**
A callback called whenever a warning message is generated.
The user pointer passed to fz_set_warning_callback() is
passed along with the warning message.
*/
typedef void (fz_warning_cb)(void *user, const char *message);
/**
Set the error callback. This will be called as part of the
exception handling.
The callback must not throw exceptions!
*/
void fz_set_error_callback(fz_context *ctx, fz_error_cb *error_cb, void *user);
/**
Retrieve the currently set error callback, or NULL if none
has been set. Optionally, if user is non-NULL, the user pointer
given when the warning callback was set is also passed back to
the caller.
*/
fz_error_cb *fz_error_callback(fz_context *ctx, void **user);
/**
Set the warning callback. This will be called as part of the
exception handling.
The callback must not throw exceptions!
*/
void fz_set_warning_callback(fz_context *ctx, fz_warning_cb *warning_cb, void *user);
/**
Retrieve the currently set warning callback, or NULL if none
has been set. Optionally, if user is non-NULL, the user pointer
given when the warning callback was set is also passed back to
the caller.
*/
fz_warning_cb *fz_warning_callback(fz_context *ctx, void **user);
/**
In order to tune MuPDF's behaviour, certain functions can
(optionally) be provided by callers.
*/
/**
Given the width and height of an image,
the subsample factor, and the subarea of the image actually
required, the caller can decide whether to decode the whole
image or just a subarea.
arg: The caller supplied opaque argument.
w, h: The width/height of the complete image.
l2factor: The log2 factor for subsampling (i.e. image will be
decoded to (w>>l2factor, h>>l2factor)).
subarea: The actual subarea required for the current operation.
The tuning function is allowed to increase this in size if
required.
*/
typedef void (fz_tune_image_decode_fn)(void *arg, int w, int h, int l2factor, fz_irect *subarea);
/**
Given the source width and height of
image, together with the actual required width and height,
decide whether we should use mitchell scaling.
arg: The caller supplied opaque argument.
dst_w, dst_h: The actual width/height required on the target
device.
src_w, src_h: The source width/height of the image.
Return 0 not to use the Mitchell scaler, 1 to use the Mitchell
scaler. All other values reserved.
*/
typedef int (fz_tune_image_scale_fn)(void *arg, int dst_w, int dst_h, int src_w, int src_h);
/**
Set the tuning function to use for
image decode.
image_decode: Function to use.
arg: Opaque argument to be passed to tuning function.
*/
void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg);
/**
Set the tuning function to use for
image scaling.
image_scale: Function to use.
arg: Opaque argument to be passed to tuning function.
*/
void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg);
/**
Get the number of bits of antialiasing we are
using (for graphics). Between 0 and 8.
*/
int fz_aa_level(fz_context *ctx);
/**
Set the number of bits of antialiasing we should
use (for both text and graphics).
bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).
*/
void fz_set_aa_level(fz_context *ctx, int bits);
/**
Get the number of bits of antialiasing we are
using for text. Between 0 and 8.
*/
int fz_text_aa_level(fz_context *ctx);
/**
Set the number of bits of antialiasing we
should use for text.
bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).
*/
void fz_set_text_aa_level(fz_context *ctx, int bits);
/**
Get the number of bits of antialiasing we are
using for graphics. Between 0 and 8.
*/
int fz_graphics_aa_level(fz_context *ctx);
/**
Set the number of bits of antialiasing we
should use for graphics.
bits: The number of bits of antialiasing to use (values are
clamped to within the 0 to 8 range).
*/
void fz_set_graphics_aa_level(fz_context *ctx, int bits);
/**
Get the minimum line width to be
used for stroked lines.
min_line_width: The minimum line width to use (in pixels).
*/
float fz_graphics_min_line_width(fz_context *ctx);
/**
Set the minimum line width to be
used for stroked lines.
min_line_width: The minimum line width to use (in pixels).
*/
void fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width);
/**
Get the user stylesheet source text.
*/
const char *fz_user_css(fz_context *ctx);
/**
Set the user stylesheet source text for use with HTML and EPUB.
*/
void fz_set_user_css(fz_context *ctx, const char *text);
/**
Return whether to respect document styles in HTML and EPUB.
*/
int fz_use_document_css(fz_context *ctx);
/**
Toggle whether to respect document styles in HTML and EPUB.
*/
void fz_set_use_document_css(fz_context *ctx, int use);
/**
Enable icc profile based operation.
*/
void fz_enable_icc(fz_context *ctx);
/**
Disable icc profile based operation.
*/
void fz_disable_icc(fz_context *ctx);
/**
Memory Allocation and Scavenging:
All calls to MuPDF's allocator functions pass through to the
underlying allocators passed in when the initial context is
created, after locks are taken (using the supplied locking
function) to ensure that only one thread at a time calls
through.
If the underlying allocator fails, MuPDF attempts to make room
for the allocation by evicting elements from the store, then
retrying.
Any call to allocate may then result in several calls to the
underlying allocator, and result in elements that are only
referred to by the store being freed.
*/
/**
Allocate memory for a structure, clear it, and tag the pointer
for Memento.
Throws exception in the event of failure to allocate.
*/
#define fz_malloc_struct(CTX, TYPE) \
((TYPE*)Memento_label(fz_calloc(CTX, 1, sizeof(TYPE)), #TYPE))
/**
Allocate memory for an array of structures, clear it, and tag
the pointer for Memento.
Throws exception in the event of failure to allocate.
*/
#define fz_malloc_struct_array(CTX, N, TYPE) \
((TYPE*)Memento_label(fz_calloc(CTX, N, sizeof(TYPE)), #TYPE "[]"))
/**
Allocate uninitialized memory for an array of structures, and
tag the pointer for Memento. Does NOT clear the memory!
Throws exception in the event of failure to allocate.
*/
#define fz_malloc_array(CTX, COUNT, TYPE) \
((TYPE*)Memento_label(fz_malloc(CTX, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
#define fz_realloc_array(CTX, OLD, COUNT, TYPE) \
((TYPE*)Memento_label(fz_realloc(CTX, OLD, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
/**
Allocate uninitialized memory of a given size.
Does NOT clear the memory!
May return NULL for size = 0.
Throws exception in the event of failure to allocate.
*/
void *fz_malloc(fz_context *ctx, size_t size);
/**
Allocate array of memory of count entries of size bytes.
Clears the memory to zero.
Throws exception in the event of failure to allocate.
*/
void *fz_calloc(fz_context *ctx, size_t count, size_t size);
/**
Reallocates a block of memory to given size. Existing contents
up to min(old_size,new_size) are maintained. The rest of the
block is uninitialised.
fz_realloc(ctx, NULL, size) behaves like fz_malloc(ctx, size).
fz_realloc(ctx, p, 0); behaves like fz_free(ctx, p).
Throws exception in the event of failure to allocate.
*/
void *fz_realloc(fz_context *ctx, void *p, size_t size);
/**
Free a previously allocated block of memory.
fz_free(ctx, NULL) does nothing.
Never throws exceptions.
*/
void fz_free(fz_context *ctx, void *p);
/**
fz_malloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_malloc_no_throw(fz_context *ctx, size_t size);
/**
fz_calloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);
/**
fz_realloc equivalent that returns NULL rather than throwing
exceptions.
*/
void *fz_realloc_no_throw(fz_context *ctx, void *p, size_t size);
/**
Portable strdup implementation, using fz allocators.
*/
char *fz_strdup(fz_context *ctx, const char *s);
/**
Fill block with len bytes of pseudo-randomness.
*/
void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
/* Implementation details: subject to change. */
/* Implementations exposed for speed, but considered private. */
void fz_var_imp(void *);
fz_jmp_buf *fz_push_try(fz_context *ctx);
int fz_do_try(fz_context *ctx);
int fz_do_always(fz_context *ctx);
int fz_do_catch(fz_context *ctx);
#ifndef FZ_JMPBUF_ALIGN
#define FZ_JMPBUF_ALIGN 32
#endif
typedef struct
{
fz_jmp_buf buffer;
int state, code;
char padding[FZ_JMPBUF_ALIGN-sizeof(int)*2];
} fz_error_stack_slot;
typedef struct
{
fz_error_stack_slot *top;
fz_error_stack_slot stack[256];
fz_error_stack_slot padding;
fz_error_stack_slot *stack_base;
int errcode;
void *print_user;
void (*print)(void *user, const char *message);
char message[256];
} fz_error_context;
typedef struct
{
void *print_user;
void (*print)(void *user, const char *message);
int count;
char message[256];
} fz_warn_context;
typedef struct
{
int hscale;
int vscale;
int scale;
int bits;
int text_bits;
float min_line_width;
} fz_aa_context;
struct fz_context
{
void *user;
fz_alloc_context alloc;
fz_locks_context locks;
fz_error_context error;
fz_warn_context warn;
/* unshared contexts */
fz_aa_context aa;
uint16_t seed48[7];
#if FZ_ENABLE_ICC
int icc_enabled;
#endif
int throw_on_repair;
/* TODO: should these be unshared? */
fz_document_handler_context *handler;
fz_style_context *style;
fz_tuning_context *tuning;
/* shared contexts */
fz_output *stddbg;
fz_font_context *font;
fz_colorspace_context *colorspace;
fz_store *store;
fz_glyph_cache *glyph_cache;
};
fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);
/**
Lock one of the user supplied mutexes.
*/
static inline void
fz_lock(fz_context *ctx, int lock)
{
fz_lock_debug_lock(ctx, lock);
ctx->locks.lock(ctx->locks.user, lock);
}
/**
Unlock one of the user supplied mutexes.
*/
static inline void
fz_unlock(fz_context *ctx, int lock)
{
fz_lock_debug_unlock(ctx, lock);
ctx->locks.unlock(ctx->locks.user, lock);
}
/* Lock-safe reference counting functions */
static inline void *
fz_keep_imp(fz_context *ctx, void *p, int *refs)
{
if (p)
{
(void)Memento_checkIntPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef(p);
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}
static inline void *
fz_keep_imp_locked(fz_context *ctx FZ_UNUSED, void *p, int *refs)
{
if (p)
{
(void)Memento_checkIntPointerOrNull(refs);
if (*refs > 0)
{
(void)Memento_takeRef(p);
++*refs;
}
}
return p;
}
static inline void *
fz_keep_imp8_locked(fz_context *ctx FZ_UNUSED, void *p, int8_t *refs)
{
if (p)
{
(void)Memento_checkIntPointerOrNull(refs);
if (*refs > 0)
{
(void)Memento_takeRef(p);
++*refs;
}
}
return p;
}
static inline void *
fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
{
if (p)
{
(void)Memento_checkBytePointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef(p);
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}
static inline void *
fz_keep_imp16(fz_context *ctx, void *p, int16_t *refs)
{
if (p)
{
(void)Memento_checkShortPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_takeRef(p);
++*refs;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
return p;
}
static inline int
fz_drop_imp(fz_context *ctx, void *p, int *refs)
{
if (p)
{
int drop;
(void)Memento_checkIntPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropIntRef(p);
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}
static inline int
fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
{
if (p)
{
int drop;
(void)Memento_checkBytePointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropByteRef(p);
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}
static inline int
fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs)
{
if (p)
{
int drop;
(void)Memento_checkShortPointerOrNull(refs);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (*refs > 0)
{
(void)Memento_dropShortRef(p);
drop = --*refs == 0;
}
else
drop = 0;
fz_unlock(ctx, FZ_LOCK_ALLOC);
return drop;
}
return 0;
}
#endif

270
include/mupdf/fitz/crypt.h Normal file
View File

@ -0,0 +1,270 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_CRYPT_H
#define MUPDF_FITZ_CRYPT_H
#include "mupdf/fitz/system.h"
/* md5 digests */
/**
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
typedef struct
{
uint32_t lo, hi;
uint32_t a, b, c, d;
unsigned char buffer[64];
} fz_md5;
/**
MD5 initialization. Begins an MD5 operation, writing a new
context.
Never throws an exception.
*/
void fz_md5_init(fz_md5 *state);
/**
MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
Never throws an exception.
*/
void fz_md5_update(fz_md5 *state, const unsigned char *input, size_t inlen);
/**
MD5 block update operation. Continues an MD5 message-digest
operation, processing an int64, and updating the context.
Never throws an exception.
*/
void fz_md5_update_int64(fz_md5 *state, int64_t i);
/**
MD5 finalization. Ends an MD5 message-digest operation, writing
the message digest and zeroizing the context.
Never throws an exception.
*/
void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
/* sha-256 digests */
/**
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
typedef struct
{
unsigned int state[8];
unsigned int count[2];
union {
unsigned char u8[64];
unsigned int u32[16];
} buffer;
} fz_sha256;
/**
SHA256 initialization. Begins an SHA256 operation, initialising
the supplied context.
Never throws an exception.
*/
void fz_sha256_init(fz_sha256 *state);
/**
SHA256 block update operation. Continues an SHA256 message-
digest operation, processing another message block, and updating
the context.
Never throws an exception.
*/
void fz_sha256_update(fz_sha256 *state, const unsigned char *input, size_t inlen);
/**
MD5 finalization. Ends an MD5 message-digest operation, writing
the message digest and zeroizing the context.
Never throws an exception.
*/
void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
/* sha-512 digests */
/**
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
typedef struct
{
uint64_t state[8];
unsigned int count[2];
union {
unsigned char u8[128];
uint64_t u64[16];
} buffer;
} fz_sha512;
/**
SHA512 initialization. Begins an SHA512 operation, initialising
the supplied context.
Never throws an exception.
*/
void fz_sha512_init(fz_sha512 *state);
/**
SHA512 block update operation. Continues an SHA512 message-
digest operation, processing another message block, and updating
the context.
Never throws an exception.
*/
void fz_sha512_update(fz_sha512 *state, const unsigned char *input, size_t inlen);
/**
SHA512 finalization. Ends an SHA512 message-digest operation,
writing the message digest and zeroizing the context.
Never throws an exception.
*/
void fz_sha512_final(fz_sha512 *state, unsigned char digest[64]);
/* sha-384 digests */
typedef fz_sha512 fz_sha384;
/**
SHA384 initialization. Begins an SHA384 operation, initialising
the supplied context.
Never throws an exception.
*/
void fz_sha384_init(fz_sha384 *state);
/**
SHA384 block update operation. Continues an SHA384 message-
digest operation, processing another message block, and updating
the context.
Never throws an exception.
*/
void fz_sha384_update(fz_sha384 *state, const unsigned char *input, size_t inlen);
/**
SHA384 finalization. Ends an SHA384 message-digest operation,
writing the message digest and zeroizing the context.
Never throws an exception.
*/
void fz_sha384_final(fz_sha384 *state, unsigned char digest[64]);
/* arc4 crypto */
/**
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
typedef struct
{
unsigned x;
unsigned y;
unsigned char state[256];
} fz_arc4;
/**
RC4 initialization. Begins an RC4 operation, writing a new
context.
Never throws an exception.
*/
void fz_arc4_init(fz_arc4 *state, const unsigned char *key, size_t len);
/**
RC4 block encrypt operation; encrypt src into dst (both of
length len) updating the RC4 state as we go.
Never throws an exception.
*/
void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, size_t len);
/**
RC4 finalization. Zero the context.
Never throws an exception.
*/
void fz_arc4_final(fz_arc4 *state);
/* AES block cipher implementation from XYSSL */
/**
Structure definitions are public to enable stack
based allocation. Do not access the members directly.
*/
typedef struct
{
int nr; /* number of rounds */
uint32_t *rk; /* AES round keys */
uint32_t buf[68]; /* unaligned data */
} fz_aes;
#define FZ_AES_DECRYPT 0
#define FZ_AES_ENCRYPT 1
/**
AES encryption intialisation. Fills in the supplied context
and prepares for encryption using the given key.
Returns non-zero for error (key size other than 128/192/256).
Never throws an exception.
*/
int fz_aes_setkey_enc(fz_aes *ctx, const unsigned char *key, int keysize);
/**
AES decryption intialisation. Fills in the supplied context
and prepares for decryption using the given key.
Returns non-zero for error (key size other than 128/192/256).
Never throws an exception.
*/
int fz_aes_setkey_dec(fz_aes *ctx, const unsigned char *key, int keysize);
/**
AES block processing. Encrypts or Decrypts (according to mode,
which must match what was initially set up) length bytes (which
must be a multiple of 16), using (and modifying) the insertion
vector iv, reading from input, and writing to output.
Never throws an exception.
*/
void fz_aes_crypt_cbc(fz_aes *ctx, int mode, size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif

595
include/mupdf/fitz/device.h Normal file
View File

@ -0,0 +1,595 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_DEVICE_H
#define MUPDF_FITZ_DEVICE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/shade.h"
#include "mupdf/fitz/path.h"
#include "mupdf/fitz/text.h"
/**
The different format handlers (pdf, xps etc) interpret pages to
a device. These devices can then process the stream of calls
they receive in various ways:
The trace device outputs debugging information for the calls.
The draw device will render them.
The list device stores them in a list to play back later.
The text device performs text extraction and searching.
The bbox device calculates the bounding box for the page.
Other devices can (and will) be written in the future.
*/
typedef struct fz_device fz_device;
enum
{
/* Flags */
FZ_DEVFLAG_MASK = 1,
FZ_DEVFLAG_COLOR = 2,
FZ_DEVFLAG_UNCACHEABLE = 4,
FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8,
FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16,
FZ_DEVFLAG_STARTCAP_UNDEFINED = 32,
FZ_DEVFLAG_DASHCAP_UNDEFINED = 64,
FZ_DEVFLAG_ENDCAP_UNDEFINED = 128,
FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256,
FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512,
FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024,
/* Arguably we should have a bit for the dash pattern itself
* being undefined, but that causes problems; do we assume that
* it should always be set to non-dashing at the start of every
* glyph? */
FZ_DEVFLAG_BBOX_DEFINED = 2048,
FZ_DEVFLAG_GRIDFIT_AS_TILED = 4096,
};
enum
{
/* PDF 1.4 -- standard separable */
FZ_BLEND_NORMAL,
FZ_BLEND_MULTIPLY,
FZ_BLEND_SCREEN,
FZ_BLEND_OVERLAY,
FZ_BLEND_DARKEN,
FZ_BLEND_LIGHTEN,
FZ_BLEND_COLOR_DODGE,
FZ_BLEND_COLOR_BURN,
FZ_BLEND_HARD_LIGHT,
FZ_BLEND_SOFT_LIGHT,
FZ_BLEND_DIFFERENCE,
FZ_BLEND_EXCLUSION,
/* PDF 1.4 -- standard non-separable */
FZ_BLEND_HUE,
FZ_BLEND_SATURATION,
FZ_BLEND_COLOR,
FZ_BLEND_LUMINOSITY,
/* For packing purposes */
FZ_BLEND_MODEMASK = 15,
FZ_BLEND_ISOLATED = 16,
FZ_BLEND_KNOCKOUT = 32
};
/**
Map from (case sensitive) blend mode string to enumeration.
*/
int fz_lookup_blendmode(const char *name);
/**
Map from enumeration to blend mode string.
The string is static, with arbitrary lifespan.
*/
const char *fz_blendmode_name(int blendmode);
/**
The device structure is public to allow devices to be
implemented outside of fitz.
Device methods should always be called using e.g.
fz_fill_path(ctx, dev, ...) rather than
dev->fill_path(ctx, dev, ...)
*/
/**
Devices can keep track of containers (clips/masks/groups/tiles)
as they go to save callers having to do it.
*/
typedef struct
{
fz_rect scissor;
int type;
int user;
} fz_device_container_stack;
enum
{
fz_device_container_stack_is_clip,
fz_device_container_stack_is_mask,
fz_device_container_stack_is_group,
fz_device_container_stack_is_tile,
};
/* Structure types */
typedef enum
{
FZ_STRUCTURE_INVALID = -1,
/* Grouping elements (PDF 1.7 - Table 10.20) */
FZ_STRUCTURE_DOCUMENT,
FZ_STRUCTURE_PART,
FZ_STRUCTURE_ART,
FZ_STRUCTURE_SECT,
FZ_STRUCTURE_DIV,
FZ_STRUCTURE_BLOCKQUOTE,
FZ_STRUCTURE_CAPTION,
FZ_STRUCTURE_TOC,
FZ_STRUCTURE_TOCI,
FZ_STRUCTURE_INDEX,
FZ_STRUCTURE_NONSTRUCT,
FZ_STRUCTURE_PRIVATE,
/* Grouping elements (PDF 2.0 - Table 364) */
FZ_STRUCTURE_DOCUMENTFRAGMENT,
/* Grouping elements (PDF 2.0 - Table 365) */
FZ_STRUCTURE_ASIDE,
/* Grouping elements (PDF 2.0 - Table 366) */
FZ_STRUCTURE_TITLE,
FZ_STRUCTURE_FENOTE,
/* Grouping elements (PDF 2.0 - Table 367) */
FZ_STRUCTURE_SUB,
/* Paragraphlike elements (PDF 1.7 - Table 10.21) */
FZ_STRUCTURE_P,
FZ_STRUCTURE_H,
FZ_STRUCTURE_H1,
FZ_STRUCTURE_H2,
FZ_STRUCTURE_H3,
FZ_STRUCTURE_H4,
FZ_STRUCTURE_H5,
FZ_STRUCTURE_H6,
/* List elements (PDF 1.7 - Table 10.23) */
FZ_STRUCTURE_LIST,
FZ_STRUCTURE_LISTITEM,
FZ_STRUCTURE_LABEL,
FZ_STRUCTURE_LISTBODY,
/* Table elements (PDF 1.7 - Table 10.24) */
FZ_STRUCTURE_TABLE,
FZ_STRUCTURE_TR,
FZ_STRUCTURE_TH,
FZ_STRUCTURE_TD,
FZ_STRUCTURE_THEAD,
FZ_STRUCTURE_TBODY,
FZ_STRUCTURE_TFOOT,
/* Inline elements (PDF 1.7 - Table 10.25) */
FZ_STRUCTURE_SPAN,
FZ_STRUCTURE_QUOTE,
FZ_STRUCTURE_NOTE,
FZ_STRUCTURE_REFERENCE,
FZ_STRUCTURE_BIBENTRY,
FZ_STRUCTURE_CODE,
FZ_STRUCTURE_LINK,
FZ_STRUCTURE_ANNOT,
/* Inline elements (PDF 2.0 - Table 368) */
FZ_STRUCTURE_EM,
FZ_STRUCTURE_STRONG,
/* Ruby inline element (PDF 1.7 - Table 10.26) */
FZ_STRUCTURE_RUBY,
FZ_STRUCTURE_RB,
FZ_STRUCTURE_RT,
FZ_STRUCTURE_RP,
/* Warichu inline element (PDF 1.7 - Table 10.26) */
FZ_STRUCTURE_WARICHU,
FZ_STRUCTURE_WT,
FZ_STRUCTURE_WP,
/* Illustration elements (PDF 1.7 - Table 10.27) */
FZ_STRUCTURE_FIGURE,
FZ_STRUCTURE_FORMULA,
FZ_STRUCTURE_FORM,
/* Artifact structure type (PDF 2.0 - Table 375) */
FZ_STRUCTURE_ARTIFACT
} fz_structure;
const char *fz_structure_to_string(fz_structure type);
fz_structure fz_structure_from_string(const char *str);
typedef enum
{
FZ_METATEXT_ACTUALTEXT,
FZ_METATEXT_ALT,
FZ_METATEXT_ABBREVIATION,
FZ_METATEXT_TITLE
} fz_metatext;
struct fz_device
{
int refs;
int hints;
int flags;
void (*close_device)(fz_context *, fz_device *);
void (*drop_device)(fz_context *, fz_device *);
void (*fill_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
void (*clip_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_rect scissor);
void (*clip_stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_rect scissor);
void (*fill_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
void (*stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params );
void (*clip_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_rect scissor);
void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_rect scissor);
void (*ignore_text)(fz_context *, fz_device *, const fz_text *, fz_matrix );
void (*fill_shade)(fz_context *, fz_device *, fz_shade *shd, fz_matrix ctm, float alpha, fz_color_params color_params);
void (*fill_image)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, float alpha, fz_color_params color_params);
void (*fill_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, const float *color, float alpha, fz_color_params color_params);
void (*clip_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_rect scissor);
void (*pop_clip)(fz_context *, fz_device *);
void (*begin_mask)(fz_context *, fz_device *, fz_rect area, int luminosity, fz_colorspace *, const float *bc, fz_color_params );
void (*end_mask)(fz_context *, fz_device *);
void (*begin_group)(fz_context *, fz_device *, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha);
void (*end_group)(fz_context *, fz_device *);
int (*begin_tile)(fz_context *, fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id);
void (*end_tile)(fz_context *, fz_device *);
void (*render_flags)(fz_context *, fz_device *, int set, int clear);
void (*set_default_colorspaces)(fz_context *, fz_device *, fz_default_colorspaces *);
void (*begin_layer)(fz_context *, fz_device *, const char *layer_name);
void (*end_layer)(fz_context *, fz_device *);
void (*begin_structure)(fz_context *, fz_device *, fz_structure standard, const char *raw, int uid);
void (*end_structure)(fz_context *, fz_device *);
void (*begin_metatext)(fz_context *, fz_device *, fz_metatext meta, const char *text);
void (*end_metatext)(fz_context *, fz_device *);
fz_rect d1_rect;
int container_len;
int container_cap;
fz_device_container_stack *container;
};
/**
Device calls; graphics primitives and containers.
*/
void fz_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
void fz_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
void fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor);
void fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor);
void fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
void fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_rect scissor);
void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor);
void fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm);
void fz_pop_clip(fz_context *ctx, fz_device *dev);
void fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params);
void fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params);
void fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params);
void fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor);
void fz_begin_mask(fz_context *ctx, fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, const float *bc, fz_color_params color_params);
void fz_end_mask(fz_context *ctx, fz_device *dev);
void fz_begin_group(fz_context *ctx, fz_device *dev, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha);
void fz_end_group(fz_context *ctx, fz_device *dev);
void fz_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
int fz_begin_tile_id(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id);
void fz_end_tile(fz_context *ctx, fz_device *dev);
void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear);
void fz_set_default_colorspaces(fz_context *ctx, fz_device *dev, fz_default_colorspaces *default_cs);
void fz_begin_layer(fz_context *ctx, fz_device *dev, const char *layer_name);
void fz_end_layer(fz_context *ctx, fz_device *dev);
void fz_begin_structure(fz_context *ctx, fz_device *dev, fz_structure standard, const char *raw, int uid);
void fz_end_structure(fz_context *ctx, fz_device *dev);
void fz_begin_metatext(fz_context *ctx, fz_device *dev, fz_metatext meta, const char *text);
void fz_end_metatext(fz_context *ctx, fz_device *dev);
/**
Devices are created by calls to device implementations, for
instance: foo_new_device(). These will be implemented by calling
fz_new_derived_device(ctx, foo_device) where foo_device is a
structure "derived from" fz_device, for instance
typedef struct { fz_device base; ...extras...} foo_device;
*/
fz_device *fz_new_device_of_size(fz_context *ctx, int size);
#define fz_new_derived_device(CTX, TYPE) \
((TYPE *)Memento_label(fz_new_device_of_size(ctx,sizeof(TYPE)),#TYPE))
/**
Signal the end of input, and flush any buffered output.
This is NOT called implicitly on fz_drop_device. This
may throw exceptions.
*/
void fz_close_device(fz_context *ctx, fz_device *dev);
/**
Reduce the reference count on a device. When the reference count
reaches zero, the device and its resources will be freed.
Don't forget to call fz_close_device before dropping the device,
or you may get incomplete output!
Never throws exceptions.
*/
void fz_drop_device(fz_context *ctx, fz_device *dev);
/**
Increment the reference count for a device. Returns the same
pointer.
Never throws exceptions.
*/
fz_device *fz_keep_device(fz_context *ctx, fz_device *dev);
/**
Enable (set) hint bits within the hint bitfield for a device.
*/
void fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints);
/**
Disable (clear) hint bits within the hint bitfield for a device.
*/
void fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints);
/**
Find current scissor region as tracked by the device.
*/
fz_rect fz_device_current_scissor(fz_context *ctx, fz_device *dev);
enum
{
/* Hints */
FZ_DONT_INTERPOLATE_IMAGES = 1,
FZ_NO_CACHE = 2,
};
/**
Cookie support - simple communication channel between app/library.
*/
/**
Provide two-way communication between application and library.
Intended for multi-threaded applications where one thread is
rendering pages and another thread wants to read progress
feedback or abort a job that takes a long time to finish. The
communication is unsynchronized without locking.
abort: The application should set this field to 0 before
calling fz_run_page to render a page. At any point when the
page is being rendered the application my set this field to 1
which will cause the rendering to finish soon. This field is
checked periodically when the page is rendered, but exactly
when is not known, therefore there is no upper bound on
exactly when the rendering will abort. If the application
did not provide a set of locks to fz_new_context, it must also
await the completion of fz_run_page before issuing another
call to fz_run_page. Note that once the application has set
this field to 1 after it called fz_run_page it may not change
the value again.
progress: Communicates rendering progress back to the
application and is read only. Increments as a page is being
rendered. The value starts out at 0 and is limited to less
than or equal to progress_max, unless progress_max is -1.
progress_max: Communicates the known upper bound of rendering
back to the application and is read only. The maximum value
that the progress field may take. If there is no known upper
bound on how long the rendering may take this value is -1 and
progress is not limited. Note that the value of progress_max
may change from -1 to a positive value once an upper bound is
known, so take this into consideration when comparing the
value of progress to that of progress_max.
errors: count of errors during current rendering.
incomplete: Initially should be set to 0. Will be set to
non-zero if a TRYLATER error is thrown during rendering.
*/
typedef struct
{
int abort;
int progress;
size_t progress_max; /* (size_t)-1 for unknown */
int errors;
int incomplete;
} fz_cookie;
/**
Create a device to print a debug trace of all device calls.
*/
fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out);
/**
Create a device to output raw information.
*/
fz_device *fz_new_xmltext_device(fz_context *ctx, fz_output *out);
/**
Create a device to compute the bounding
box of all marks on a page.
The returned bounding box will be the union of all bounding
boxes of all objects on a page.
*/
fz_device *fz_new_bbox_device(fz_context *ctx, fz_rect *rectp);
/**
Create a device to test for features.
Currently only tests for the presence of non-grayscale colors.
is_color: Possible values returned:
0: Definitely greyscale
1: Probably color (all colors were grey, but there
were images or shadings in a non grey colorspace).
2: Definitely color
threshold: The difference from grayscale that will be tolerated.
Typical values to use are either 0 (be exact) and 0.02 (allow an
imperceptible amount of slop).
options: A set of bitfield options, from the FZ_TEST_OPT set.
passthrough: A device to pass all calls through to, or NULL.
If set, then the test device can both test and pass through to
an underlying device (like, say, the display list device). This
means that a display list can be created and at the end we'll
know if it's colored or not.
In the absence of a passthrough device, the device will throw
an exception to stop page interpretation when color is found.
*/
fz_device *fz_new_test_device(fz_context *ctx, int *is_color, float threshold, int options, fz_device *passthrough);
enum
{
/* If set, test every pixel of images exhaustively.
* If clear, just look at colorspaces for images. */
FZ_TEST_OPT_IMAGES = 1,
/* If set, test every pixel of shadings. */
/* If clear, just look at colorspaces for shadings. */
FZ_TEST_OPT_SHADINGS = 2
};
/**
Create a device to draw on a pixmap.
dest: Target pixmap for the draw device. See fz_new_pixmap*
for how to obtain a pixmap. The pixmap is not cleared by the
draw device, see fz_clear_pixmap* for how to clear it prior to
calling fz_new_draw_device. Free the device by calling
fz_drop_device.
transform: Transform from user space in points to device space
in pixels.
*/
fz_device *fz_new_draw_device(fz_context *ctx, fz_matrix transform, fz_pixmap *dest);
/**
Create a device to draw on a pixmap.
dest: Target pixmap for the draw device. See fz_new_pixmap*
for how to obtain a pixmap. The pixmap is not cleared by the
draw device, see fz_clear_pixmap* for how to clear it prior to
calling fz_new_draw_device. Free the device by calling
fz_drop_device.
transform: Transform from user space in points to device space
in pixels.
clip: Bounding box to restrict any marking operations of the
draw device.
*/
fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip);
/**
Create a device to draw on a pixmap.
dest: Target pixmap for the draw device. See fz_new_pixmap*
for how to obtain a pixmap. The pixmap is not cleared by the
draw device, see fz_clear_pixmap* for how to clear it prior to
calling fz_new_draw_device. Free the device by calling
fz_drop_device.
transform: Transform from user space in points to device space
in pixels.
proof_cs: Intermediate color space to map though when mapping to
color space defined by pixmap.
*/
fz_device *fz_new_draw_device_with_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, fz_colorspace *proof_cs);
/**
Create a device to draw on a pixmap.
dest: Target pixmap for the draw device. See fz_new_pixmap*
for how to obtain a pixmap. The pixmap is not cleared by the
draw device, see fz_clear_pixmap* for how to clear it prior to
calling fz_new_draw_device. Free the device by calling
fz_drop_device.
transform: Transform from user space in points to device space
in pixels.
clip: Bounding box to restrict any marking operations of the
draw device.
proof_cs: Color space to render to prior to mapping to color
space defined by pixmap.
*/
fz_device *fz_new_draw_device_with_bbox_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip, fz_colorspace *cs);
fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_matrix transform, fz_pixmap *dest);
/**
struct fz_draw_options: Options for creating a pixmap and draw
device.
*/
typedef struct
{
int rotate;
int x_resolution;
int y_resolution;
int width;
int height;
fz_colorspace *colorspace;
int alpha;
int graphics;
int text;
} fz_draw_options;
FZ_DATA extern const char *fz_draw_options_usage;
/**
Parse draw device options from a comma separated key-value string.
*/
fz_draw_options *fz_parse_draw_options(fz_context *ctx, fz_draw_options *options, const char *string);
/**
Create a new pixmap and draw device, using the specified options.
options: Options to configure the draw device, and choose the
resolution and colorspace.
mediabox: The bounds of the page in points.
pixmap: An out parameter containing the newly created pixmap.
*/
fz_device *fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *options, fz_rect mediabox, fz_pixmap **pixmap);
#endif

View File

@ -0,0 +1,142 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_DISPLAY_LIST_H
#define MUPDF_FITZ_DISPLAY_LIST_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/device.h"
/**
Display list device -- record and play back device commands.
*/
/**
fz_display_list is a list containing drawing commands (text,
images, etc.). The intent is two-fold: as a caching-mechanism
to reduce parsing of a page, and to be used as a data
structure in multi-threading where one thread parses the page
and another renders pages.
Create a display list with fz_new_display_list, hand it over to
fz_new_list_device to have it populated, and later replay the
list (once or many times) by calling fz_run_display_list. When
the list is no longer needed drop it with fz_drop_display_list.
*/
typedef struct fz_display_list fz_display_list;
/**
Create an empty display list.
A display list contains drawing commands (text, images, etc.).
Use fz_new_list_device for populating the list.
mediabox: Bounds of the page (in points) represented by the
display list.
*/
fz_display_list *fz_new_display_list(fz_context *ctx, fz_rect mediabox);
/**
Create a rendering device for a display list.
When the device is rendering a page it will populate the
display list with drawing commands (text, images, etc.). The
display list can later be reused to render a page many times
without having to re-interpret the page from the document file
for each rendering. Once the device is no longer needed, free
it with fz_drop_device.
list: A display list that the list device takes a reference to.
*/
fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
/**
(Re)-run a display list through a device.
list: A display list, created by fz_new_display_list and
populated with objects from a page by running fz_run_page on a
device obtained from fz_new_list_device.
ctm: Transform to apply to display list contents. May include
for example scaling and rotation, see fz_scale, fz_rotate and
fz_concat. Set to fz_identity if no transformation is desired.
scissor: Only the part of the contents of the display list
visible within this area will be considered when the list is
run through the device. This does not imply for tile objects
contained in the display list.
cookie: Communication mechanism between caller and library
running the page. Intended for multi-threaded applications,
while single-threaded applications set cookie to NULL. The
caller may abort an ongoing page run. Cookie also communicates
progress information back to the caller. The fields inside
cookie are continually updated while the page is being run.
*/
void fz_run_display_list(fz_context *ctx, fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_rect scissor, fz_cookie *cookie);
/**
Increment the reference count for a display list. Returns the
same pointer.
Never throws exceptions.
*/
fz_display_list *fz_keep_display_list(fz_context *ctx, fz_display_list *list);
/**
Decrement the reference count for a display list. When the
reference count reaches zero, all the references in the display
list itself are dropped, and the display list is freed.
Never throws exceptions.
*/
void fz_drop_display_list(fz_context *ctx, fz_display_list *list);
/**
Return the bounding box of the page recorded in a display list.
*/
fz_rect fz_bound_display_list(fz_context *ctx, fz_display_list *list);
/**
Create a new image from a display list.
w, h: The conceptual width/height of the image.
transform: The matrix that needs to be applied to the given
list to make it render to the unit square.
list: The display list.
*/
fz_image *fz_new_image_from_display_list(fz_context *ctx, float w, float h, fz_display_list *list);
/**
Check for a display list being empty
list: The list to check.
Returns true if empty, false otherwise.
*/
int fz_display_list_is_empty(fz_context *ctx, const fz_display_list *list);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_EXPORT_H
#define MUPDF_FITZ_EXPORT_H
/*
* Support for building/using MuPDF DLL on Windows.
*
* When compiling code that uses MuPDF DLL, FZ_DLL_CLIENT should be defined.
*
* When compiling MuPDF DLL itself, FZ_DLL should be defined.
*/
#if defined(_WIN32) || defined(_WIN64)
#if defined(FZ_DLL)
/* Building DLL. */
#define FZ_FUNCTION __declspec(dllexport)
#define FZ_DATA __declspec(dllexport)
#elif defined(FZ_DLL_CLIENT)
/* Building DLL client code. */
#define FZ_FUNCTION __declspec(dllexport)
#define FZ_DATA __declspec(dllimport)
#else
#define FZ_FUNCTION
#define FZ_DATA
#endif
#else
#define FZ_FUNCTION
#define FZ_DATA
#endif
#endif

251
include/mupdf/fitz/filter.h Normal file
View File

@ -0,0 +1,251 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_FILTER_H
#define MUPDF_FITZ_FILTER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/stream.h"
typedef struct fz_jbig2_globals fz_jbig2_globals;
typedef struct
{
int64_t offset;
uint64_t length;
} fz_range;
/**
The null filter reads a specified amount of data from the
substream.
*/
fz_stream *fz_open_null_filter(fz_context *ctx, fz_stream *chain, uint64_t len, int64_t offset);
/**
The range filter copies data from specified ranges of the
chained stream.
*/
fz_stream *fz_open_range_filter(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges);
/**
The endstream filter reads a PDF substream, and starts to look
for an 'endstream' token after the specified length.
*/
fz_stream *fz_open_endstream_filter(fz_context *ctx, fz_stream *chain, uint64_t len, int64_t offset);
/**
Concat filter concatenates several streams into one.
*/
fz_stream *fz_open_concat(fz_context *ctx, int max, int pad);
/**
Add a chained stream to the end of the concatenate filter.
Ownership of chain is passed in.
*/
void fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain);
/**
arc4 filter performs RC4 decoding of data read from the chained
filter using the supplied key.
*/
fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
/**
aesd filter performs AES decoding of data read from the chained
filter using the supplied key.
*/
fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
/**
a85d filter performs ASCII 85 Decoding of data read
from the chained filter.
*/
fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain);
/**
ahxd filter performs ASCII Hex decoding of data read
from the chained filter.
*/
fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain);
/**
rld filter performs Run Length Decoding of data read
from the chained filter.
*/
fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain);
/**
dctd filter performs DCT (JPEG) decoding of data read
from the chained filter.
color_transform implements the PDF color_transform option;
use 0 to disable YUV-RGB / YCCK-CMYK transforms
use >0 to enable YUV-RGB / YCCK-CMYK transforms
use -1 (default) if not embedded in PDF
use -2 (default) if embedded in PDF
For subsampling on decode, set l2factor to the log2 of the
reduction required (therefore 0 = full size decode).
jpegtables is an optional stream from which the JPEG tables
can be read. Use NULL if not required.
*/
fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables);
/**
faxd filter performs FAX decoding of data read from
the chained filter.
k: see fax specification (fax default is 0).
end_of_line: whether we expect end of line markers (fax default
is 0).
encoded_byte_align: whether we align to bytes after each line
(fax default is 0).
columns: how many columns in the image (fax default is 1728).
rows: 0 for unspecified or the number of rows of data to expect.
end_of_block: whether we expect end of block markers (fax
default is 1).
black_is_1: determines the polarity of the image (fax default is
0).
*/
fz_stream *fz_open_faxd(fz_context *ctx, fz_stream *chain,
int k, int end_of_line, int encoded_byte_align,
int columns, int rows, int end_of_block, int black_is_1);
/**
flated filter performs LZ77 decoding (inflating) of data read
from the chained filter.
window_bits: How large a decompression window to use. Typically
15. A negative number, -n, means to use n bits, but to expect
raw data with no header.
*/
fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits);
/**
lzwd filter performs LZW decoding of data read from the chained
filter.
early_change: (Default 1) specifies whether to change codes 1
bit early.
min_bits: (Default 9) specifies the minimum number of bits to
use.
reverse_bits: (Default 0) allows for compatibility with gif and
old style tiffs (1).
old_tiff: (Default 0) allows for different handling of the clear
code, as found in old style tiffs.
*/
fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff);
/**
predict filter performs pixel prediction on data read from
the chained filter.
predictor: 1 = copy, 2 = tiff, other = inline PNG predictor
columns: width of image in pixels
colors: number of components.
bpc: bits per component (typically 8)
*/
fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc);
/**
Open a filter that performs jbig2 decompression on the chained
stream, using the optional globals record.
*/
fz_stream *fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals, int embedded);
/**
Create a jbig2 globals record from a buffer.
Immutable once created.
*/
fz_jbig2_globals *fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf);
/**
Increment the reference count for a jbig2 globals record.
Never throws an exception.
*/
fz_jbig2_globals *fz_keep_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
/**
Decrement the reference count for a jbig2 globals record.
When the reference count hits zero, the record is freed.
Never throws an exception.
*/
void fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
/**
Special jbig2 globals drop function for use in implementing
store support.
*/
void fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals);
/**
Return buffer containing jbig2 globals data stream.
*/
fz_buffer * fz_jbig2_globals_data(fz_context *ctx, fz_jbig2_globals *globals);
/* Extra filters for tiff */
/**
SGI Log 16bit (greyscale) decode from the chained filter.
Decodes lines of w pixels to 8bpp greyscale.
*/
fz_stream *fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w);
/**
SGI Log 24bit (LUV) decode from the chained filter.
Decodes lines of w pixels to 8bpc rgb.
*/
fz_stream *fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w);
/**
SGI Log 32bit (LUV) decode from the chained filter.
Decodes lines of w pixels to 8bpc rgb.
*/
fz_stream *fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w);
/**
4bit greyscale Thunderscan decoding from the chained filter.
Decodes lines of w pixels to 8bpp greyscale.
*/
fz_stream *fz_open_thunder(fz_context *ctx, fz_stream *chain, int w);
#endif

745
include/mupdf/fitz/font.h Normal file
View File

@ -0,0 +1,745 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_FONT_H
#define MUPDF_FITZ_FONT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/color.h"
/* forward declaration for circular dependency */
struct fz_device;
/* Various font encoding tables and lookup functions */
FZ_DATA extern const char *fz_glyph_name_from_adobe_standard[256];
FZ_DATA extern const char *fz_glyph_name_from_iso8859_7[256];
FZ_DATA extern const char *fz_glyph_name_from_koi8u[256];
FZ_DATA extern const char *fz_glyph_name_from_mac_expert[256];
FZ_DATA extern const char *fz_glyph_name_from_mac_roman[256];
FZ_DATA extern const char *fz_glyph_name_from_win_ansi[256];
FZ_DATA extern const char *fz_glyph_name_from_windows_1252[256];
FZ_DATA extern const unsigned short fz_unicode_from_iso8859_1[256];
FZ_DATA extern const unsigned short fz_unicode_from_iso8859_7[256];
FZ_DATA extern const unsigned short fz_unicode_from_koi8u[256];
FZ_DATA extern const unsigned short fz_unicode_from_pdf_doc_encoding[256];
FZ_DATA extern const unsigned short fz_unicode_from_windows_1250[256];
FZ_DATA extern const unsigned short fz_unicode_from_windows_1251[256];
FZ_DATA extern const unsigned short fz_unicode_from_windows_1252[256];
int fz_iso8859_1_from_unicode(int u);
int fz_iso8859_7_from_unicode(int u);
int fz_koi8u_from_unicode(int u);
int fz_windows_1250_from_unicode(int u);
int fz_windows_1251_from_unicode(int u);
int fz_windows_1252_from_unicode(int u);
int fz_unicode_from_glyph_name(const char *name);
int fz_unicode_from_glyph_name_strict(const char *name);
const char **fz_duplicate_glyph_names_from_unicode(int unicode);
const char *fz_glyph_name_from_unicode_sc(int unicode);
/**
An abstract font handle.
*/
typedef struct fz_font fz_font;
/**
Fonts come in two variants:
Regular fonts are handled by FreeType.
Type 3 fonts have callbacks to the interpreter.
*/
/**
Retrieve the FT_Face handle
for the font.
font: The font to query
Returns the FT_Face handle for the font, or NULL
if not a freetype handled font. (Cast to void *
to avoid nasty header exposure).
*/
void *fz_font_ft_face(fz_context *ctx, fz_font *font);
/**
Retrieve the Type3 procs
for a font.
font: The font to query
Returns the t3_procs pointer. Will be NULL for a
non type-3 font.
*/
fz_buffer **fz_font_t3_procs(fz_context *ctx, fz_font *font);
/* common CJK font collections */
enum { FZ_ADOBE_CNS, FZ_ADOBE_GB, FZ_ADOBE_JAPAN, FZ_ADOBE_KOREA };
/**
Every fz_font carries a set of flags
within it, in a fz_font_flags_t structure.
*/
typedef struct
{
unsigned int is_mono : 1;
unsigned int is_serif : 1;
unsigned int is_bold : 1;
unsigned int is_italic : 1;
unsigned int ft_substitute : 1; /* use substitute metrics */
unsigned int ft_stretch : 1; /* stretch to match PDF metrics */
unsigned int fake_bold : 1; /* synthesize bold */
unsigned int fake_italic : 1; /* synthesize italic */
unsigned int has_opentype : 1; /* has opentype shaping tables */
unsigned int invalid_bbox : 1;
unsigned int cjk : 1;
unsigned int cjk_lang : 2; /* CNS, GB, JAPAN, or KOREA */
unsigned int embed : 1;
unsigned int never_embed : 1;
} fz_font_flags_t;
/**
Retrieve a pointer to the font flags
for a given font. These can then be updated as required.
font: The font to query
Returns a pointer to the flags structure (or NULL, if
the font is NULL).
*/
fz_font_flags_t *fz_font_flags(fz_font *font);
/**
In order to shape a given font, we need to
declare it to a shaper library (harfbuzz, by default, but others
are possible). To avoid redeclaring it every time we need to
shape, we hold a shaper handle and the destructor for it within
the font itself. The handle is initialised by the caller when
first required and the destructor is called when the fz_font is
destroyed.
*/
typedef struct
{
void *shaper_handle;
void (*destroy)(fz_context *ctx, void *); /* Destructor for shape_handle */
} fz_shaper_data_t;
/**
Retrieve a pointer to the shaper data
structure for the given font.
font: The font to query.
Returns a pointer to the shaper data structure (or NULL if
font is NULL).
*/
fz_shaper_data_t *fz_font_shaper_data(fz_context *ctx, fz_font *font);
/**
Retrieve a pointer to the name of the font.
font: The font to query.
Returns a pointer to an internal copy of the font name.
Will never be NULL, but may be the empty string.
*/
const char *fz_font_name(fz_context *ctx, fz_font *font);
/**
Query whether the font flags say that this font is bold.
*/
int fz_font_is_bold(fz_context *ctx, fz_font *font);
/**
Query whether the font flags say that this font is italic.
*/
int fz_font_is_italic(fz_context *ctx, fz_font *font);
/**
Query whether the font flags say that this font is serif.
*/
int fz_font_is_serif(fz_context *ctx, fz_font *font);
/**
Query whether the font flags say that this font is monospaced.
*/
int fz_font_is_monospaced(fz_context *ctx, fz_font *font);
/**
Retrieve the font bbox.
font: The font to query.
Returns the font bbox by value; it is valid only if
fz_font_flags(font)->invalid_bbox is zero.
*/
fz_rect fz_font_bbox(fz_context *ctx, fz_font *font);
/**
Type for user supplied system font loading hook.
name: The name of the font to load.
bold: 1 if a bold font desired, 0 otherwise.
italic: 1 if an italic font desired, 0 otherwise.
needs_exact_metrics: 1 if an exact metric match is required for
the font requested.
Returns a new font handle, or NULL if no font found (or on error).
*/
typedef fz_font *(fz_load_system_font_fn)(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics);
/**
Type for user supplied cjk font loading hook.
name: The name of the font to load.
ordering: The ordering for which to load the font (e.g.
FZ_ADOBE_KOREA)
serif: 1 if a serif font is desired, 0 otherwise.
Returns a new font handle, or NULL if no font found (or on error).
*/
typedef fz_font *(fz_load_system_cjk_font_fn)(fz_context *ctx, const char *name, int ordering, int serif);
/**
Type for user supplied fallback font loading hook.
name: The name of the font to load.
script: UCDN script enum.
language: FZ_LANG enum.
serif, bold, italic: boolean style flags.
Returns a new font handle, or NULL if no font found (or on error).
*/
typedef fz_font *(fz_load_system_fallback_font_fn)(fz_context *ctx, int script, int language, int serif, int bold, int italic);
/**
Install functions to allow MuPDF to request fonts from the
system.
Only one set of hooks can be in use at a time.
*/
void fz_install_load_system_font_funcs(fz_context *ctx,
fz_load_system_font_fn *f,
fz_load_system_cjk_font_fn *f_cjk,
fz_load_system_fallback_font_fn *f_fallback);
/**
Attempt to load a given font from the system.
name: The name of the desired font.
bold: 1 if bold desired, 0 otherwise.
italic: 1 if italic desired, 0 otherwise.
needs_exact_metrics: 1 if an exact metrical match is required,
0 otherwise.
Returns a new font handle, or NULL if no matching font was found
(or on error).
*/
fz_font *fz_load_system_font(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics);
/**
Attempt to load a given font from
the system.
name: The name of the desired font.
ordering: The ordering to load the font from (e.g. FZ_ADOBE_KOREA)
serif: 1 if serif desired, 0 otherwise.
Returns a new font handle, or NULL if no matching font was found
(or on error).
*/
fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ordering, int serif);
/**
Search the builtin fonts for a match.
Whether a given font is present or not will depend on the
configuration in which MuPDF is built.
name: The name of the font desired.
bold: 1 if bold desired, 0 otherwise.
italic: 1 if italic desired, 0 otherwise.
len: Pointer to a place to receive the length of the discovered
font buffer.
Returns a pointer to the font file data, or NULL if not present.
*/
const unsigned char *fz_lookup_builtin_font(fz_context *ctx, const char *name, int bold, int italic, int *len);
/**
Search the builtin base14 fonts for a match.
Whether a given font is present or not will depend on the
configuration in which MuPDF is built.
name: The name of the font desired.
len: Pointer to a place to receive the length of the discovered
font buffer.
Returns a pointer to the font file data, or NULL if not present.
*/
const unsigned char *fz_lookup_base14_font(fz_context *ctx, const char *name, int *len);
/**
Search the builtin cjk fonts for a match.
Whether a font is present or not will depend on the
configuration in which MuPDF is built.
ordering: The desired ordering of the font (e.g. FZ_ADOBE_KOREA).
len: Pointer to a place to receive the length of the discovered
font buffer.
Returns a pointer to the font file data, or NULL if not present.
*/
const unsigned char *fz_lookup_cjk_font(fz_context *ctx, int ordering, int *len, int *index);
/**
Search the builtin cjk fonts for a match for a given language.
Whether a font is present or not will depend on the
configuration in which MuPDF is built.
lang: Pointer to a (case sensitive) language string (e.g.
"ja", "ko", "zh-Hant" etc).
len: Pointer to a place to receive the length of the discovered
font buffer.
subfont: Pointer to a place to store the subfont index of the
discovered font.
Returns a pointer to the font file data, or NULL if not present.
*/
const unsigned char *fz_lookup_cjk_font_by_language(fz_context *ctx, const char *lang, int *len, int *subfont);
/**
Return the matching FZ_ADOBE_* ordering
for the given language tag, such as "zh-Hant", "zh-Hans", "ja", or "ko".
*/
int fz_lookup_cjk_ordering_by_language(const char *name);
/**
Search the builtin noto fonts for a match.
Whether a font is present or not will depend on the
configuration in which MuPDF is built.
script: The script desired (e.g. UCDN_SCRIPT_KATAKANA).
lang: The language desired (e.g. FZ_LANG_ja).
len: Pointer to a place to receive the length of the discovered
font buffer.
Returns a pointer to the font file data, or NULL if not present.
*/
const unsigned char *fz_lookup_noto_font(fz_context *ctx, int script, int lang, int *len, int *subfont);
/**
Search the builtin noto fonts specific symbol fonts.
Whether a font is present or not will depend on the
configuration in which MuPDF is built.
*/
const unsigned char *fz_lookup_noto_math_font(fz_context *ctx, int *len);
const unsigned char *fz_lookup_noto_music_font(fz_context *ctx, int *len);
const unsigned char *fz_lookup_noto_symbol1_font(fz_context *ctx, int *len);
const unsigned char *fz_lookup_noto_symbol2_font(fz_context *ctx, int *len);
const unsigned char *fz_lookup_noto_emoji_font(fz_context *ctx, int *len);
/**
Try to load a fallback font for the
given combination of font attributes. Whether a font is
present or not will depend on the configuration in which
MuPDF is built.
script: The script desired (e.g. UCDN_SCRIPT_KATAKANA).
language: The language desired (e.g. FZ_LANG_ja).
serif: 1 if serif desired, 0 otherwise.
bold: 1 if bold desired, 0 otherwise.
italic: 1 if italic desired, 0 otherwise.
Returns a new font handle, or NULL if not available.
*/
fz_font *fz_load_fallback_font(fz_context *ctx, int script, int language, int serif, int bold, int italic);
/**
Create a new (empty) type3 font.
name: Name of font (or NULL).
matrix: Font matrix.
Returns a new font handle, or throws exception on
allocation failure.
*/
fz_font *fz_new_type3_font(fz_context *ctx, const char *name, fz_matrix matrix);
/**
Create a new font from a font file in memory.
Fonts created in this way, will be eligible for embedding by default.
name: Name of font (leave NULL to use name from font).
data: Pointer to the font file data.
len: Length of the font file data.
index: Which font from the file to load (0 for default).
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
Returns new font handle, or throws exception on error.
*/
fz_font *fz_new_font_from_memory(fz_context *ctx, const char *name, const unsigned char *data, int len, int index, int use_glyph_bbox);
/**
Create a new font from a font file in a fz_buffer.
Fonts created in this way, will be eligible for embedding by default.
name: Name of font (leave NULL to use name from font).
buffer: Buffer to load from.
index: Which font from the file to load (0 for default).
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
Returns new font handle, or throws exception on error.
*/
fz_font *fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox);
/**
Create a new font from a font file.
Fonts created in this way, will be eligible for embedding by default.
name: Name of font (leave NULL to use name from font).
path: File path to load from.
index: Which font from the file to load (0 for default).
use_glyph_box: 1 if we should use the glyph bbox, 0 otherwise.
Returns new font handle, or throws exception on error.
*/
fz_font *fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox);
/**
Create a new font from one of the built-in fonts.
*/
fz_font *fz_new_base14_font(fz_context *ctx, const char *name);
fz_font *fz_new_cjk_font(fz_context *ctx, int ordering);
fz_font *fz_new_builtin_font(fz_context *ctx, const char *name, int is_bold, int is_italic);
/**
Control whether a given font should be embedded or not when writing.
*/
void fz_set_font_embedding(fz_context *ctx, fz_font *font, int embed);
/**
Add a reference to an existing fz_font.
font: The font to add a reference to.
Returns the same font.
*/
fz_font *fz_keep_font(fz_context *ctx, fz_font *font);
/**
Drop a reference to a fz_font, destroying the
font when the last reference is dropped.
font: The font to drop a reference to.
*/
void fz_drop_font(fz_context *ctx, fz_font *font);
/**
Set the font bbox.
font: The font to set the bbox for.
xmin, ymin, xmax, ymax: The bounding box.
*/
void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax);
/**
Return a bbox for a given glyph in a font.
font: The font to look for the glyph in.
gid: The glyph to bound.
trm: The matrix to apply to the glyph before bounding.
Returns rectangle by value containing the bounds of the given
glyph.
*/
fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
/**
Determine if a given glyph in a font
is cacheable. Certain glyphs in a type 3 font cannot safely
be cached, as their appearance depends on the enclosing
graphic state.
font: The font to look for the glyph in.
gif: The glyph to query.
Returns non-zero if cacheable, 0 if not.
*/
int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid);
/**
Run a glyph from a Type3 font to
a given device.
font: The font to find the glyph in.
gid: The glyph to run.
trm: The transform to apply.
dev: The device to render onto.
*/
void fz_run_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, struct fz_device *dev);
/**
Return the advance for a given glyph.
font: The font to look for the glyph in.
glyph: The glyph to find the advance for.
wmode: 1 for vertical mode, 0 for horizontal.
Returns the advance for the glyph.
*/
float fz_advance_glyph(fz_context *ctx, fz_font *font, int glyph, int wmode);
/**
Find the glyph id for a given unicode
character within a font.
font: The font to look for the unicode character in.
unicode: The unicode character to encode.
Returns the glyph id for the given unicode value, or 0 if
unknown.
*/
int fz_encode_character(fz_context *ctx, fz_font *font, int unicode);
/**
Encode character, preferring small-caps variant if available.
font: The font to look for the unicode character in.
unicode: The unicode character to encode.
Returns the glyph id for the given unicode value, or 0 if
unknown.
*/
int fz_encode_character_sc(fz_context *ctx, fz_font *font, int unicode);
/**
Encode character.
Either by direct lookup of glyphname within a font, or, failing
that, by mapping glyphname to unicode and thence to the glyph
index within the given font.
Returns zero for type3 fonts.
*/
int fz_encode_character_by_glyph_name(fz_context *ctx, fz_font *font, const char *glyphname);
/**
Find the glyph id for
a given unicode character within a font, falling back to
an alternative if not found.
font: The font to look for the unicode character in.
unicode: The unicode character to encode.
script: The script in use.
language: The language in use.
out_font: The font handle in which the given glyph represents
the requested unicode character. The caller does not own the
reference it is passed, so should call fz_keep_font if it is
not simply to be used immediately.
Returns the glyph id for the given unicode value in the supplied
font (and sets *out_font to font) if it is present. Otherwise
an alternative fallback font (based on script/language) is
searched for. If the glyph is found therein, *out_font is set
to this reference, and the glyph reference is returned. If it
cannot be found anywhere, the function returns 0.
*/
int fz_encode_character_with_fallback(fz_context *ctx, fz_font *font, int unicode, int script, int language, fz_font **out_font);
/**
Find the name of a glyph
font: The font to look for the glyph in.
glyph: The glyph id to look for.
buf: Pointer to a buffer for the name to be inserted into.
size: The size of the buffer.
If a font contains a name table, then the name of the glyph
will be returned in the supplied buffer. Otherwise a name
is synthesised. The name will be truncated to fit in
the buffer.
*/
void fz_get_glyph_name(fz_context *ctx, fz_font *font, int glyph, char *buf, int size);
/**
Retrieve font ascender in ems.
*/
float fz_font_ascender(fz_context *ctx, fz_font *font);
/**
Retrieve font descender in ems.
*/
float fz_font_descender(fz_context *ctx, fz_font *font);
/**
Retrieve the MD5 digest for the font's data.
*/
void fz_font_digest(fz_context *ctx, fz_font *font, unsigned char digest[16]);
/* Implementation details: subject to change. */
void fz_decouple_type3_font(fz_context *ctx, fz_font *font, void *t3doc);
/**
map an FT error number to a
static string.
err: The error number to lookup.
Returns a pointer to a static textual representation
of a freetype error.
*/
const char *ft_error_string(int err);
int ft_char_index(void *face, int cid);
int ft_name_index(void *face, const char *name);
/**
Internal functions for our Harfbuzz integration
to work around the lack of thread safety.
*/
/**
Lock against Harfbuzz being called
simultaneously in several threads. This reuses
FZ_LOCK_FREETYPE.
*/
void fz_hb_lock(fz_context *ctx);
/**
Unlock after a Harfbuzz call. This reuses
FZ_LOCK_FREETYPE.
*/
void fz_hb_unlock(fz_context *ctx);
struct fz_font
{
int refs;
char name[32];
fz_buffer *buffer;
fz_font_flags_t flags;
void *ft_face; /* has an FT_Face if used */
fz_shaper_data_t shaper_data;
fz_matrix t3matrix;
void *t3resources;
fz_buffer **t3procs; /* has 256 entries if used */
struct fz_display_list **t3lists; /* has 256 entries if used */
float *t3widths; /* has 256 entries if used */
unsigned short *t3flags; /* has 256 entries if used */
void *t3doc; /* a pdf_document for the callback */
void (*t3run)(fz_context *ctx, void *doc, void *resources, fz_buffer *contents, struct fz_device *dev, fz_matrix ctm, void *gstate, fz_default_colorspaces *default_cs);
void (*t3freeres)(fz_context *ctx, void *doc, void *resources);
fz_rect bbox; /* font bbox is used only for t3 fonts */
int glyph_count;
/* per glyph bounding box cache. */
fz_rect **bbox_table;
int use_glyph_bbox;
/* substitute metrics */
int width_count;
short width_default; /* in 1000 units */
short *width_table; /* in 1000 units */
/* cached glyph metrics */
float **advance_cache;
/* cached encoding lookup */
uint16_t *encoding_cache[256];
/* cached md5sum for caching */
int has_digest;
unsigned char digest[16];
/* Which font to use in a collection. */
int subfont;
};
#endif

View File

@ -0,0 +1,818 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_MATH_H
#define MUPDF_FITZ_MATH_H
#include "mupdf/fitz/system.h"
#include <assert.h>
/**
Multiply scaled two integers in the 0..255 range
*/
static inline int fz_mul255(int a, int b)
{
/* see Jim Blinn's book "Dirty Pixels" for how this works */
int x = a * b + 128;
x += x >> 8;
return x >> 8;
}
/**
Undo alpha premultiplication.
*/
static inline int fz_div255(int c, int a)
{
return a ? c * (255 * 256 / a) >> 8 : 0;
}
/**
Expand a value A from the 0...255 range to the 0..256 range
*/
#define FZ_EXPAND(A) ((A)+((A)>>7))
/**
Combine values A (in any range) and B (in the 0..256 range),
to give a single value in the same range as A was.
*/
#define FZ_COMBINE(A,B) (((A)*(B))>>8)
/**
Combine values A and C (in the same (any) range) and B and D (in
the 0..256 range), to give a single value in the same range as A
and C were.
*/
#define FZ_COMBINE2(A,B,C,D) (((A) * (B) + (C) * (D))>>8)
/**
Blend SRC and DST (in the same range) together according to
AMOUNT (in the 0...256 range).
*/
#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8)
/**
Range checking atof
*/
float fz_atof(const char *s);
/**
atoi that copes with NULL
*/
int fz_atoi(const char *s);
/**
64bit atoi that copes with NULL
*/
int64_t fz_atoi64(const char *s);
/**
Some standard math functions, done as static inlines for speed.
People with compilers that do not adequately implement inline
may like to reimplement these using macros.
*/
static inline float fz_abs(float f)
{
return (f < 0 ? -f : f);
}
static inline int fz_absi(int i)
{
return (i < 0 ? -i : i);
}
static inline float fz_min(float a, float b)
{
return (a < b ? a : b);
}
static inline int fz_mini(int a, int b)
{
return (a < b ? a : b);
}
static inline size_t fz_minz(size_t a, size_t b)
{
return (a < b ? a : b);
}
static inline int64_t fz_mini64(int64_t a, int64_t b)
{
return (a < b ? a : b);
}
static inline float fz_max(float a, float b)
{
return (a > b ? a : b);
}
static inline int fz_maxi(int a, int b)
{
return (a > b ? a : b);
}
static inline size_t fz_maxz(size_t a, size_t b)
{
return (a > b ? a : b);
}
static inline int64_t fz_maxi64(int64_t a, int64_t b)
{
return (a > b ? a : b);
}
static inline float fz_clamp(float x, float min, float max)
{
return x < min ? min : x > max ? max : x;
}
static inline int fz_clampi(int x, int min, int max)
{
return x < min ? min : x > max ? max : x;
}
static inline int64_t fz_clamp64(int64_t x, int64_t min, int64_t max)
{
return x < min ? min : x > max ? max : x;
}
static inline double fz_clampd(double x, double min, double max)
{
return x < min ? min : x > max ? max : x;
}
static inline void *fz_clampp(void *x, void *min, void *max)
{
return x < min ? min : x > max ? max : x;
}
#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max))
/**
fz_point is a point in a two-dimensional space.
*/
typedef struct
{
float x, y;
} fz_point;
static inline fz_point fz_make_point(float x, float y)
{
fz_point p = { x, y };
return p;
}
/**
fz_rect is a rectangle represented by two diagonally opposite
corners at arbitrary coordinates.
Rectangles are always axis-aligned with the X- and Y- axes. We
wish to distinguish rectangles in 3 categories; infinite, finite,
and invalid. Zero area rectangles are a sub-category of finite
ones.
For all valid rectangles, x0 <= x1 and y0 <= y1 in all cases.
Infinite rectangles have x0 = y0 = FZ_MIN_INF_RECT,
x1 = y1 = FZ_MAX_INF_RECT. For any non infinite valid rectangle,
the area is defined as (x1 - x0) * (y1 - y0).
To check for empty or infinite rectangles use fz_is_empty_rect
and fz_is_infinite_rect. To check for valid rectangles use
fz_is_valid_rect.
We choose this representation, so that we can easily distinguish
the difference between intersecting 2 valid rectangles and
getting an invalid one, as opposed to getting a zero area one
(which nonetheless has valid bounds within the plane).
x0, y0: The top left corner.
x1, y1: The bottom right corner.
We choose FZ_{MIN,MAX}_INF_RECT to be the largest 32bit signed
integer values that survive roundtripping to floats.
*/
#define FZ_MIN_INF_RECT ((int)0x80000000)
#define FZ_MAX_INF_RECT ((int)0x7fffff80)
typedef struct
{
float x0, y0;
float x1, y1;
} fz_rect;
static inline fz_rect fz_make_rect(float x0, float y0, float x1, float y1)
{
fz_rect r = { x0, y0, x1, y1 };
return r;
}
/**
fz_irect is a rectangle using integers instead of floats.
It's used in the draw device and for pixmap dimensions.
*/
typedef struct
{
int x0, y0;
int x1, y1;
} fz_irect;
static inline fz_irect fz_make_irect(int x0, int y0, int x1, int y1)
{
fz_irect r = { x0, y0, x1, y1 };
return r;
}
/**
A rectangle with sides of length one.
The bottom left corner is at (0, 0) and the top right corner
is at (1, 1).
*/
FZ_DATA extern const fz_rect fz_unit_rect;
/**
An empty rectangle with an area equal to zero.
*/
FZ_DATA extern const fz_rect fz_empty_rect;
FZ_DATA extern const fz_irect fz_empty_irect;
/**
An infinite rectangle.
*/
FZ_DATA extern const fz_rect fz_infinite_rect;
FZ_DATA extern const fz_irect fz_infinite_irect;
/**
Check if rectangle is empty.
An empty rectangle is defined as one whose area is zero.
All invalid rectangles are empty.
*/
static inline int fz_is_empty_rect(fz_rect r)
{
return (r.x0 >= r.x1 || r.y0 >= r.y1);
}
static inline int fz_is_empty_irect(fz_irect r)
{
return (r.x0 >= r.x1 || r.y0 >= r.y1);
}
/**
Check if rectangle is infinite.
*/
static inline int fz_is_infinite_rect(fz_rect r)
{
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
}
/**
Check if an integer rectangle
is infinite.
*/
static inline int fz_is_infinite_irect(fz_irect r)
{
return (r.x0 == FZ_MIN_INF_RECT && r.x1 == FZ_MAX_INF_RECT &&
r.y0 == FZ_MIN_INF_RECT && r.y1 == FZ_MAX_INF_RECT);
}
/**
Check if rectangle is valid.
*/
static inline int fz_is_valid_rect(fz_rect r)
{
return (r.x0 <= r.x1 && r.y0 <= r.y1);
}
/**
Check if an integer rectangle is valid.
*/
static inline int fz_is_valid_irect(fz_irect r)
{
return (r.x0 <= r.x1 && r.y0 <= r.y1);
}
/**
Return the width of an irect. Invalid irects return 0.
*/
static inline unsigned int
fz_irect_width(fz_irect r)
{
unsigned int w;
if (r.x0 >= r.x1)
return 0;
/* Check for w overflowing. This should never happen, but
* if it does, it's pretty likely an indication of a severe
* problem. */
w = (unsigned int)r.x1 - r.x0;
assert((int)w >= 0);
if ((int)w < 0)
return 0;
return (int)w;
}
/**
Return the height of an irect. Invalid irects return 0.
*/
static inline int
fz_irect_height(fz_irect r)
{
unsigned int h;
if (r.y0 >= r.y1)
return 0;
/* Check for h overflowing. This should never happen, but
* if it does, it's pretty likely an indication of a severe
* problem. */
h = (unsigned int)(r.y1 - r.y0);
assert((int)h >= 0);
if ((int)h < 0)
return 0;
return (int)h;
}
/**
fz_matrix is a row-major 3x3 matrix used for representing
transformations of coordinates throughout MuPDF.
Since all points reside in a two-dimensional space, one vector
is always a constant unit vector; hence only some elements may
vary in a matrix. Below is how the elements map between
different representations.
/ a b 0 \
| c d 0 | normally represented as [ a b c d e f ].
\ e f 1 /
*/
typedef struct
{
float a, b, c, d, e, f;
} fz_matrix;
/**
Identity transform matrix.
*/
FZ_DATA extern const fz_matrix fz_identity;
static inline fz_matrix fz_make_matrix(float a, float b, float c, float d, float e, float f)
{
fz_matrix m = { a, b, c, d, e, f };
return m;
}
static inline int fz_is_identity(fz_matrix m)
{
return m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0;
}
/**
Multiply two matrices.
The order of the two matrices are important since matrix
multiplication is not commutative.
Returns result.
*/
fz_matrix fz_concat(fz_matrix left, fz_matrix right);
/**
Create a scaling matrix.
The returned matrix is of the form [ sx 0 0 sy 0 0 ].
m: Pointer to the matrix to populate
sx, sy: Scaling factors along the X- and Y-axes. A scaling
factor of 1.0 will not cause any scaling along the relevant
axis.
Returns m.
*/
fz_matrix fz_scale(float sx, float sy);
/**
Scale a matrix by premultiplication.
m: Pointer to the matrix to scale
sx, sy: Scaling factors along the X- and Y-axes. A scaling
factor of 1.0 will not cause any scaling along the relevant
axis.
Returns m (updated).
*/
fz_matrix fz_pre_scale(fz_matrix m, float sx, float sy);
/**
Scale a matrix by postmultiplication.
m: Pointer to the matrix to scale
sx, sy: Scaling factors along the X- and Y-axes. A scaling
factor of 1.0 will not cause any scaling along the relevant
axis.
Returns m (updated).
*/
fz_matrix fz_post_scale(fz_matrix m, float sx, float sy);
/**
Create a shearing matrix.
The returned matrix is of the form [ 1 sy sx 1 0 0 ].
m: pointer to place to store returned matrix
sx, sy: Shearing factors. A shearing factor of 0.0 will not
cause any shearing along the relevant axis.
Returns m.
*/
fz_matrix fz_shear(float sx, float sy);
/**
Premultiply a matrix with a shearing matrix.
The shearing matrix is of the form [ 1 sy sx 1 0 0 ].
m: pointer to matrix to premultiply
sx, sy: Shearing factors. A shearing factor of 0.0 will not
cause any shearing along the relevant axis.
Returns m (updated).
*/
fz_matrix fz_pre_shear(fz_matrix m, float sx, float sy);
/**
Create a rotation matrix.
The returned matrix is of the form
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
m: Pointer to place to store matrix
degrees: Degrees of counter clockwise rotation. Values less
than zero and greater than 360 are handled as expected.
Returns m.
*/
fz_matrix fz_rotate(float degrees);
/**
Rotate a transformation by premultiplying.
The premultiplied matrix is of the form
[ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
m: Pointer to matrix to premultiply.
degrees: Degrees of counter clockwise rotation. Values less
than zero and greater than 360 are handled as expected.
Returns m (updated).
*/
fz_matrix fz_pre_rotate(fz_matrix m, float degrees);
/**
Create a translation matrix.
The returned matrix is of the form [ 1 0 0 1 tx ty ].
m: A place to store the created matrix.
tx, ty: Translation distances along the X- and Y-axes. A
translation of 0 will not cause any translation along the
relevant axis.
Returns m.
*/
fz_matrix fz_translate(float tx, float ty);
/**
Translate a matrix by premultiplication.
m: The matrix to translate
tx, ty: Translation distances along the X- and Y-axes. A
translation of 0 will not cause any translation along the
relevant axis.
Returns m.
*/
fz_matrix fz_pre_translate(fz_matrix m, float tx, float ty);
/**
Create transform matrix to draw page
at a given resolution and rotation. Adjusts the scaling
factors so that the page covers whole number of
pixels and adjust the page origin to be at 0,0.
*/
fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate);
/**
Create an inverse matrix.
inverse: Place to store inverse matrix.
matrix: Matrix to invert. A degenerate matrix, where the
determinant is equal to zero, can not be inverted and the
original matrix is returned instead.
Returns inverse.
*/
fz_matrix fz_invert_matrix(fz_matrix matrix);
/**
Attempt to create an inverse matrix.
inverse: Place to store inverse matrix.
matrix: Matrix to invert. A degenerate matrix, where the
determinant is equal to zero, can not be inverted.
Returns 1 if matrix is degenerate (singular), or 0 otherwise.
*/
int fz_try_invert_matrix(fz_matrix *inv, fz_matrix src);
/**
Check if a transformation is rectilinear.
Rectilinear means that no shearing is present and that any
rotations present are a multiple of 90 degrees. Usually this
is used to make sure that axis-aligned rectangles before the
transformation are still axis-aligned rectangles afterwards.
*/
int fz_is_rectilinear(fz_matrix m);
/**
Calculate average scaling factor of matrix.
*/
float fz_matrix_expansion(fz_matrix m);
/**
Compute intersection of two rectangles.
Given two rectangles, update the first to be the smallest
axis-aligned rectangle that covers the area covered by both
given rectangles. If either rectangle is empty then the
intersection is also empty. If either rectangle is infinite
then the intersection is simply the non-infinite rectangle.
Should both rectangles be infinite, then the intersection is
also infinite.
*/
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
/**
Compute intersection of two bounding boxes.
Similar to fz_intersect_rect but operates on two bounding
boxes instead of two rectangles.
*/
fz_irect fz_intersect_irect(fz_irect a, fz_irect b);
/**
Compute union of two rectangles.
Given two rectangles, update the first to be the smallest
axis-aligned rectangle that encompasses both given rectangles.
If either rectangle is infinite then the union is also infinite.
If either rectangle is empty then the union is simply the
non-empty rectangle. Should both rectangles be empty, then the
union is also empty.
*/
fz_rect fz_union_rect(fz_rect a, fz_rect b);
/**
Convert a rect into the minimal bounding box
that covers the rectangle.
Coordinates in a bounding box are integers, so rounding of the
rects coordinates takes place. The top left corner is rounded
upwards and left while the bottom right corner is rounded
downwards and to the right.
*/
fz_irect fz_irect_from_rect(fz_rect rect);
/**
Round rectangle coordinates.
Coordinates in a bounding box are integers, so rounding of the
rects coordinates takes place. The top left corner is rounded
upwards and left while the bottom right corner is rounded
downwards and to the right.
This differs from fz_irect_from_rect, in that fz_irect_from_rect
slavishly follows the numbers (i.e any slight over/under
calculations can cause whole extra pixels to be added).
fz_round_rect allows for a small amount of rounding error when
calculating the bbox.
*/
fz_irect fz_round_rect(fz_rect rect);
/**
Convert a bbox into a rect.
For our purposes, a rect can represent all the values we meet in
a bbox, so nothing can go wrong.
rect: A place to store the generated rectangle.
bbox: The bbox to convert.
Returns rect (updated).
*/
fz_rect fz_rect_from_irect(fz_irect bbox);
/**
Expand a bbox by a given amount in all directions.
*/
fz_rect fz_expand_rect(fz_rect b, float expand);
fz_irect fz_expand_irect(fz_irect a, int expand);
/**
Expand a bbox to include a given point.
To create a rectangle that encompasses a sequence of points, the
rectangle must first be set to be the empty rectangle at one of
the points before including the others.
*/
fz_rect fz_include_point_in_rect(fz_rect r, fz_point p);
/**
Translate bounding box.
Translate a bbox by a given x and y offset. Allows for overflow.
*/
fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff);
fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff);
/**
Test rectangle inclusion.
Return true if a entirely contains b.
*/
int fz_contains_rect(fz_rect a, fz_rect b);
/**
Apply a transformation to a point.
transform: Transformation matrix to apply. See fz_concat,
fz_scale, fz_rotate and fz_translate for how to create a
matrix.
point: Pointer to point to update.
Returns transform (unchanged).
*/
fz_point fz_transform_point(fz_point point, fz_matrix m);
fz_point fz_transform_point_xy(float x, float y, fz_matrix m);
/**
Apply a transformation to a vector.
transform: Transformation matrix to apply. See fz_concat,
fz_scale and fz_rotate for how to create a matrix. Any
translation will be ignored.
vector: Pointer to vector to update.
*/
fz_point fz_transform_vector(fz_point vector, fz_matrix m);
/**
Apply a transform to a rectangle.
After the four corner points of the axis-aligned rectangle
have been transformed it may not longer be axis-aligned. So a
new axis-aligned rectangle is created covering at least the
area of the transformed rectangle.
transform: Transformation matrix to apply. See fz_concat,
fz_scale and fz_rotate for how to create a matrix.
rect: Rectangle to be transformed. The two special cases
fz_empty_rect and fz_infinite_rect, may be used but are
returned unchanged as expected.
*/
fz_rect fz_transform_rect(fz_rect rect, fz_matrix m);
/**
Normalize a vector to length one.
*/
fz_point fz_normalize_vector(fz_point p);
/**
Grid fit a matrix.
as_tiled = 0 => adjust the matrix so that the image of the unit
square completely covers any pixel that was touched by the
image of the unit square under the original matrix.
as_tiled = 1 => adjust the matrix so that the corners of the
image of the unit square align with the closest integer corner
of the image of the unit square under the original matrix.
*/
fz_matrix fz_gridfit_matrix(int as_tiled, fz_matrix m);
/**
Find the largest expansion performed by this matrix.
(i.e. max(abs(m.a),abs(m.b),abs(m.c),abs(m.d))
*/
float fz_matrix_max_expansion(fz_matrix m);
/**
A representation for a region defined by 4 points.
The significant difference between quads and rects is that
the edges of quads are not axis aligned.
*/
typedef struct
{
fz_point ul, ur, ll, lr;
} fz_quad;
/**
Inline convenience construction function.
*/
static inline fz_quad fz_make_quad(
float ul_x, float ul_y,
float ur_x, float ur_y,
float ll_x, float ll_y,
float lr_x, float lr_y)
{
fz_quad q = {
{ ul_x, ul_y },
{ ur_x, ur_y },
{ ll_x, ll_y },
{ lr_x, lr_y },
};
return q;
}
/**
Convert a rect to a quad (losslessly).
*/
fz_quad fz_quad_from_rect(fz_rect r);
/**
Convert a quad to the smallest rect that covers it.
*/
fz_rect fz_rect_from_quad(fz_quad q);
/**
Transform a quad by a matrix.
*/
fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
/**
Inclusion test for quads.
*/
int fz_is_point_inside_quad(fz_point p, fz_quad q);
/**
Inclusion test for rects. (Rect is assumed to be open, i.e.
top right corner is not included).
*/
int fz_is_point_inside_rect(fz_point p, fz_rect r);
/**
Inclusion test for irects. (Rect is assumed to be open, i.e.
top right corner is not included).
*/
int fz_is_point_inside_irect(int x, int y, fz_irect r);
/**
Inclusion test for quad in quad.
This may break down if quads are not 'well formed'.
*/
int fz_is_quad_inside_quad(fz_quad needle, fz_quad haystack);
/**
Intersection test for quads.
This may break down if quads are not 'well formed'.
*/
int fz_is_quad_intersecting_quad(fz_quad a, fz_quad b);
#endif

View File

@ -0,0 +1,35 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_GETOPT_H
#define MUPDF_FITZ_GETOPT_H
#include "export.h"
/**
Simple functions/variables for use in tools.
*/
extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
FZ_DATA extern int fz_optind;
FZ_DATA extern char *fz_optarg;
#endif

View File

@ -0,0 +1,96 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_GLYPH_CACHE_H
#define MUPDF_FITZ_GLYPH_CACHE_H
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/device.h"
/**
Purge all the glyphs from the cache.
*/
void fz_purge_glyph_cache(fz_context *ctx);
/**
Create a pixmap containing a rendered glyph.
Lookup gid from font, clip it with scissor, and rendering it
with aa bits of antialiasing into a new pixmap.
The caller takes ownership of the pixmap and so must free it.
Note: This function is no longer used for normal rendering
operations, and is kept around just because we use it in the
app. It should be considered "at risk" of removal from the API.
*/
fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, const fz_irect *scissor, int aa);
/**
Nasty PDF interpreter specific hernia, required to allow the
interpreter to replay glyphs from a type3 font directly into
the target device.
This is only used in exceptional circumstances (such as type3
glyphs that inherit current graphics state, or nested type3
glyphs).
*/
void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate, fz_default_colorspaces *def_cs);
/**
Force a type3 font to cache the displaylist for a given glyph
id.
This caching can involve reading the underlying file, so must
happen ahead of time, so we aren't suddenly forced to read the
file while playing a displaylist back.
*/
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid);
/**
Dump debug statistics for the glyph cache.
*/
void fz_dump_glyph_cache_stats(fz_context *ctx, fz_output *out);
/**
Perform subpixel quantisation and adjustment on a glyph matrix.
ctm: On entry, the desired 'ideal' transformation for a glyph.
On exit, adjusted to a (very similar) transformation quantised
for subpixel caching.
subpix_ctm: Initialised by the routine to the transform that
should be used to render the glyph.
qe, qf: which subpixel position we quantised to.
Returns: the size of the glyph.
Note: This is currently only exposed for use in our app. It
should be considered "at risk" of removal from the API.
*/
float fz_subpixel_adjust(fz_context *ctx, fz_matrix *ctm, fz_matrix *subpix_ctm, unsigned char *qe, unsigned char *qf);
#endif

View File

@ -0,0 +1,81 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_GLYPH_H
#define MUPDF_FITZ_GLYPH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/path.h"
/**
Glyphs represent a run length encoded set of pixels for a 2
dimensional region of a plane.
*/
typedef struct fz_glyph fz_glyph;
/**
Return the bounding box of the glyph in pixels.
*/
fz_irect fz_glyph_bbox(fz_context *ctx, fz_glyph *glyph);
fz_irect fz_glyph_bbox_no_ctx(fz_glyph *src);
/**
Return the width of the glyph in pixels.
*/
int fz_glyph_width(fz_context *ctx, fz_glyph *glyph);
/**
Return the height of the glyph in pixels.
*/
int fz_glyph_height(fz_context *ctx, fz_glyph *glyph);
/**
Take a reference to a glyph.
pix: The glyph to increment the reference for.
Returns pix.
*/
fz_glyph *fz_keep_glyph(fz_context *ctx, fz_glyph *pix);
/**
Drop a reference and free a glyph.
Decrement the reference count for the glyph. When no
references remain the glyph will be freed.
*/
void fz_drop_glyph(fz_context *ctx, fz_glyph *pix);
/**
Look a glyph up from a font, and return the outline of the
glyph using the given transform.
The caller owns the returned path, and so is responsible for
ensuring that it eventually gets dropped.
*/
fz_path *fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm);
#endif

126
include/mupdf/fitz/hash.h Normal file
View File

@ -0,0 +1,126 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_HASH_H
#define MUPDF_FITZ_HASH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#define FZ_HASH_TABLE_KEY_LENGTH 48
/**
Generic hash-table with fixed-length keys.
The keys and values are NOT reference counted by the hash table.
Callers are responsible for taking care the reference counts are
correct. Inserting a duplicate entry will NOT overwrite the old
value, and will return the old value.
The drop_val callback function is only used to release values
when the hash table is destroyed.
*/
typedef struct fz_hash_table fz_hash_table;
/**
Function type called when a hash table entry is dropped.
Only used when the entire hash table is dropped.
*/
typedef void (fz_hash_table_drop_fn)(fz_context *ctx, void *val);
/**
Create a new hash table.
initialsize: The initial size of the hashtable. The hashtable
may grow (double in size) if it starts to get crowded (80%
full).
keylen: byte length for each key.
lock: -1 for no lock, otherwise the FZ_LOCK to use to protect
this table.
drop_val: Function to use to destroy values on table drop.
*/
fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_hash_table_drop_fn *drop_val);
/**
Destroy the hash table.
Values are dropped using the drop function.
*/
void fz_drop_hash_table(fz_context *ctx, fz_hash_table *table);
/**
Search for a matching hash within the table, and return the
associated value.
*/
void *fz_hash_find(fz_context *ctx, fz_hash_table *table, const void *key);
/**
Insert a new key/value pair into the hash table.
If an existing entry with the same key is found, no change is
made to the hash table, and a pointer to the existing value is
returned.
If no existing entry with the same key is found, ownership of
val passes in, key is copied, and NULL is returned.
*/
void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val);
/**
Remove the entry for a given key.
The value is NOT freed, so the caller is expected to take care
of this.
*/
void fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key);
/**
Callback function called on each key/value pair in the hash
table, when fz_hash_for_each is run.
*/
typedef void (fz_hash_table_for_each_fn)(fz_context *ctx, void *state, void *key, int keylen, void *val);
/**
Iterate over the entries in a hash table.
*/
void fz_hash_for_each(fz_context *ctx, fz_hash_table *table, void *state, fz_hash_table_for_each_fn *callback);
/**
Callback function called on each key/value pair in the hash
table, when fz_hash_filter is run to remove entries where the
callback returns true.
*/
typedef int (fz_hash_table_filter_fn)(fz_context *ctx, void *state, void *key, int keylen, void *val);
/**
Iterate over the entries in a hash table, removing all the ones where callback returns true.
Does NOT free the value of the entry, so the caller is expected to take care of this.
*/
void fz_hash_filter(fz_context *ctx, fz_hash_table *table, void *state, fz_hash_table_filter_fn *callback);
#endif

428
include/mupdf/fitz/image.h Normal file
View File

@ -0,0 +1,428 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_IMAGE_H
#define MUPDF_FITZ_IMAGE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/compressed-buffer.h"
/**
Images are storable objects from which we can obtain fz_pixmaps.
These may be implemented as simple wrappers around a pixmap, or
as more complex things that decode at different subsample
settings on demand.
*/
typedef struct fz_image fz_image;
typedef struct fz_compressed_image fz_compressed_image;
typedef struct fz_pixmap_image fz_pixmap_image;
/**
Called to get a handle to a pixmap from an image.
image: The image to retrieve a pixmap from.
subarea: The subarea of the image that we actually care about
(or NULL to indicate the whole image).
ctm: Optional, unless subarea is given. If given, then on
entry this is the transform that will be applied to the complete
image. It should be updated on exit to the transform to apply to
the given subarea of the image. This is used to calculate the
desired width/height for subsampling.
w: If non-NULL, a pointer to an int to be updated on exit to the
width (in pixels) that the scaled output will cover.
h: If non-NULL, a pointer to an int to be updated on exit to the
height (in pixels) that the scaled output will cover.
Returns a non NULL kept pixmap pointer. May throw exceptions.
*/
fz_pixmap *fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *ctm, int *w, int *h);
/**
Calls fz_get_pixmap_from_image() with ctm, subarea, w and h all set to NULL.
*/
fz_pixmap *fz_get_unscaled_pixmap_from_image(fz_context *ctx, fz_image *image);
/**
Increment the (normal) reference count for an image. Returns the
same pointer.
Never throws exceptions.
*/
fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
/**
Decrement the (normal) reference count for an image. When the
total (normal + key) reference count reaches zero, the image and
its resources are freed.
Never throws exceptions.
*/
void fz_drop_image(fz_context *ctx, fz_image *image);
/**
Increment the store key reference for an image. Returns the same
pointer. (This is the count of references for an image held by
keys in the image store).
Never throws exceptions.
*/
fz_image *fz_keep_image_store_key(fz_context *ctx, fz_image *image);
/**
Decrement the store key reference count for an image. When the
total (normal + key) reference count reaches zero, the image and
its resources are freed.
Never throws exceptions.
*/
void fz_drop_image_store_key(fz_context *ctx, fz_image *image);
/**
Function type to destroy an images data
when it's reference count reaches zero.
*/
typedef void (fz_drop_image_fn)(fz_context *ctx, fz_image *image);
/**
Function type to get a decoded pixmap for an image.
im: The image to decode.
subarea: NULL, or the subarea of the image required. Expressed
in terms of a rectangle in the original width/height of the
image. If non NULL, this should be updated by the function to
the actual subarea decoded - which must include the requested
area!
w, h: The actual width and height that the whole image would
need to be decoded to.
l2factor: On entry, the log 2 subsample factor required. If
possible the decode process can take care of (all or some) of
this subsampling, and must then update the value so the caller
knows what remains to be done.
Returns a reference to a decoded pixmap that satisfies the
requirements of the request. The caller owns the returned
reference.
*/
typedef fz_pixmap *(fz_image_get_pixmap_fn)(fz_context *ctx, fz_image *im, fz_irect *subarea, int w, int h, int *l2factor);
/**
Function type to get the given storage
size for an image.
Returns the size in bytes used for a given image.
*/
typedef size_t (fz_image_get_size_fn)(fz_context *, fz_image *);
/**
Internal function to make a new fz_image structure
for a derived class.
w,h: Width and height of the created image.
bpc: Bits per component.
colorspace: The colorspace (determines the number of components,
and any color conversions required while decoding).
xres, yres: The X and Y resolutions respectively.
interpolate: 1 if interpolation should be used when decoding
this image, 0 otherwise.
imagemask: 1 if this is an imagemask (i.e. transparent), 0
otherwise.
decode: NULL, or a pointer to to a decode array. The default
decode array is [0 1] (repeated n times, for n color components).
colorkey: NULL, or a pointer to a colorkey array. The default
colorkey array is [0 255] (repeated n times, for n color
components).
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
size: The size of the required allocated structure (the size of
the derived structure).
get: The function to be called to obtain a decoded pixmap.
get_size: The function to be called to return the storage size
used by this image.
drop: The function to be called to dispose of this image once
the last reference is dropped.
Returns a pointer to an allocated structure of the required size,
with the first sizeof(fz_image) bytes initialised as appropriate
given the supplied parameters, and the other bytes set to zero.
*/
fz_image *fz_new_image_of_size(fz_context *ctx,
int w,
int h,
int bpc,
fz_colorspace *colorspace,
int xres,
int yres,
int interpolate,
int imagemask,
float *decode,
int *colorkey,
fz_image *mask,
size_t size,
fz_image_get_pixmap_fn *get_pixmap,
fz_image_get_size_fn *get_size,
fz_drop_image_fn *drop);
#define fz_new_derived_image(CTX,W,H,B,CS,X,Y,I,IM,D,C,M,T,G,S,Z) \
((T*)Memento_label(fz_new_image_of_size(CTX,W,H,B,CS,X,Y,I,IM,D,C,M,sizeof(T),G,S,Z),#T))
/**
Create an image based on
the data in the supplied compressed buffer.
w,h: Width and height of the created image.
bpc: Bits per component.
colorspace: The colorspace (determines the number of components,
and any color conversions required while decoding).
xres, yres: The X and Y resolutions respectively.
interpolate: 1 if interpolation should be used when decoding
this image, 0 otherwise.
imagemask: 1 if this is an imagemask (i.e. transparency bitmap
mask), 0 otherwise.
decode: NULL, or a pointer to to a decode array. The default
decode array is [0 1] (repeated n times, for n color components).
colorkey: NULL, or a pointer to a colorkey array. The default
colorkey array is [0 255] (repeated n times, for n color
components).
buffer: Buffer of compressed data and compression parameters.
Ownership of this reference is passed in.
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
*/
fz_image *fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask);
/**
Create an image from the given
pixmap.
pixmap: The pixmap to base the image upon. A new reference
to this is taken.
mask: NULL, or another image to use as a mask for this one.
A new reference is taken to this image. Supplying a masked
image as a mask to another image is illegal!
*/
fz_image *fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask);
/**
Create a new image from a
buffer of data, inferring its type from the format
of the data.
*/
fz_image *fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer);
/**
Create a new image from the contents
of a file, inferring its type from the format of the
data.
*/
fz_image *fz_new_image_from_file(fz_context *ctx, const char *path);
/**
Internal destructor exposed for fz_store integration.
*/
void fz_drop_image_imp(fz_context *ctx, fz_storable *image);
/**
Internal destructor for the base image class members.
Exposed to allow derived image classes to be written.
*/
void fz_drop_image_base(fz_context *ctx, fz_image *image);
/**
Decode a subarea of a compressed image. l2factor is the amount
of subsampling inbuilt to the stream (i.e. performed by the
decoder). If non NULL, l2extra is the extra amount of
subsampling that should be performed by this routine. This will
be updated on exit to the amount of subsampling that is still
required to be done.
Returns a kept reference.
*/
fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *image, fz_irect *subarea, int indexed, int l2factor, int *l2extra);
/**
Convert pixmap from indexed to base colorspace.
This creates a new bitmap containing the converted pixmap data.
*/
fz_pixmap *fz_convert_indexed_pixmap_to_base(fz_context *ctx, const fz_pixmap *src);
/**
Convert pixmap from DeviceN/Separation to base colorspace.
This creates a new bitmap containing the converted pixmap data.
*/
fz_pixmap *fz_convert_separation_pixmap_to_base(fz_context *ctx, const fz_pixmap *src);
/**
Return the size of the storage used by an image.
*/
size_t fz_image_size(fz_context *ctx, fz_image *im);
/**
Structure is public to allow other structures to
be derived from it. Do not access members directly.
*/
struct fz_image
{
fz_key_storable key_storable;
int w, h;
uint8_t n;
uint8_t bpc;
unsigned int imagemask:1;
unsigned int interpolate:1;
unsigned int use_colorkey:1;
unsigned int use_decode:1;
unsigned int decoded:1;
unsigned int scalable:1;
uint8_t orientation;
fz_image *mask;
int xres; /* As given in the image, not necessarily as rendered */
int yres; /* As given in the image, not necessarily as rendered */
fz_colorspace *colorspace;
fz_drop_image_fn *drop_image;
fz_image_get_pixmap_fn *get_pixmap;
fz_image_get_size_fn *get_size;
int colorkey[FZ_MAX_COLORS * 2];
float decode[FZ_MAX_COLORS * 2];
};
/**
Request the natural resolution
of an image.
xres, yres: Pointers to ints to be updated with the
natural resolution of an image (or a sensible default
if not encoded).
*/
void fz_image_resolution(fz_image *image, int *xres, int *yres);
/**
Request the natural orientation of an image.
This is for images (such as JPEG) that can contain internal
specifications of rotation/flips. This is ignored by all the
internal decode/rendering routines, but can be used by callers
(such as the image document handler) to respect such
specifications.
The values used by MuPDF are as follows, with the equivalent
Exif specifications given for information:
0: Undefined
1: 0 degree ccw rotation. (Exif = 1)
2: 90 degree ccw rotation. (Exif = 8)
3: 180 degree ccw rotation. (Exif = 3)
4: 270 degree ccw rotation. (Exif = 6)
5: flip on X. (Exif = 2)
6: flip on X, then rotate ccw by 90 degrees. (Exif = 5)
7: flip on X, then rotate ccw by 180 degrees. (Exif = 4)
8: flip on X, then rotate ccw by 270 degrees. (Exif = 7)
*/
uint8_t fz_image_orientation(fz_context *ctx, fz_image *image);
fz_matrix
fz_image_orientation_matrix(fz_context *ctx, fz_image *image);
/**
Retrieve the underlying compressed data for an image.
Returns a pointer to the underlying data buffer for an image,
or NULL if this image is not based upon a compressed data
buffer.
This is not a reference counted structure, so no reference is
returned. Lifespan is limited to that of the image itself.
*/
fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *image);
void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *cimg, fz_compressed_buffer *buf);
/**
Retrieve the underlying fz_pixmap for an image.
Returns a pointer to the underlying fz_pixmap for an image,
or NULL if this image is not based upon an fz_pixmap.
No reference is returned. Lifespan is limited to that of
the image itself. If required, use fz_keep_pixmap to take
a reference to keep it longer.
*/
fz_pixmap *fz_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *cimg);
void fz_set_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *cimg, fz_pixmap *pix);
/* Implementation details: subject to change. */
/**
Exposed for PDF.
*/
fz_pixmap *fz_load_jpx(fz_context *ctx, const unsigned char *data, size_t size, fz_colorspace *cs);
/**
Exposed for CBZ.
*/
int fz_load_tiff_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len);
fz_pixmap *fz_load_tiff_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage);
int fz_load_pnm_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len);
fz_pixmap *fz_load_pnm_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage);
int fz_load_jbig2_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len);
fz_pixmap *fz_load_jbig2_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage);
int fz_load_bmp_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len);
fz_pixmap *fz_load_bmp_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage);
#endif

130
include/mupdf/fitz/link.h Normal file
View File

@ -0,0 +1,130 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_LINK_H
#define MUPDF_FITZ_LINK_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/types.h"
typedef struct fz_link fz_link;
typedef void (fz_link_set_rect_fn)(fz_context *ctx, fz_link *link, fz_rect rect);
typedef void (fz_link_set_uri_fn)(fz_context *ctx, fz_link *link, const char *uri);
typedef void (fz_link_drop_link_fn)(fz_context *ctx, fz_link *link);
/**
fz_link is a list of interactive links on a page.
There is no relation between the order of the links in the
list and the order they appear on the page. The list of links
for a given page can be obtained from fz_load_links.
A link is reference counted. Dropping a reference to a link is
done by calling fz_drop_link.
rect: The hot zone. The area that can be clicked in
untransformed coordinates.
uri: Link destinations come in two forms: internal and external.
Internal links refer to other pages in the same document.
External links are URLs to other documents.
next: A pointer to the next link on the same page.
*/
typedef struct fz_link
{
int refs;
struct fz_link *next;
fz_rect rect;
char *uri;
fz_link_set_rect_fn *set_rect_fn;
fz_link_set_uri_fn *set_uri_fn;
fz_link_drop_link_fn *drop;
} fz_link;
typedef enum
{
FZ_LINK_DEST_FIT,
FZ_LINK_DEST_FIT_B,
FZ_LINK_DEST_FIT_H,
FZ_LINK_DEST_FIT_BH,
FZ_LINK_DEST_FIT_V,
FZ_LINK_DEST_FIT_BV,
FZ_LINK_DEST_FIT_R,
FZ_LINK_DEST_XYZ
} fz_link_dest_type;
typedef struct
{
fz_location loc;
fz_link_dest_type type;
float x, y, w, h, zoom;
} fz_link_dest;
fz_link_dest fz_make_link_dest_none(void);
fz_link_dest fz_make_link_dest_xyz(int chapter, int page, float x, float y, float z);
/**
Create a new link record.
next is set to NULL with the expectation that the caller will
handle the linked list setup. Internal function.
Different document types will be implemented by deriving from
fz_link. This macro allocates such derived structures, and
initialises the base sections.
*/
fz_link *fz_new_link_of_size(fz_context *ctx, int size, fz_rect rect, const char *uri);
#define fz_new_derived_link(CTX,TYPE,RECT,URI) \
((TYPE *)Memento_label(fz_new_link_of_size(CTX,sizeof(TYPE),RECT,URI),#TYPE))
/**
Increment the reference count for a link. The same pointer is
returned.
Never throws exceptions.
*/
fz_link *fz_keep_link(fz_context *ctx, fz_link *link);
/**
Decrement the reference count for a link. When the reference
count reaches zero, the link is destroyed.
When a link is freed, the reference for any linked link (next)
is dropped too, thus an entire linked list of fz_link's can be
freed by just dropping the head.
*/
void fz_drop_link(fz_context *ctx, fz_link *link);
/**
Query whether a link is external to a document (determined by
uri containing a ':', intended to match with '://' which
separates the scheme from the scheme specific parts in URIs).
*/
int fz_is_external_link(fz_context *ctx, const char *uri);
void fz_set_link_rect(fz_context *ctx, fz_link *link, fz_rect rect);
void fz_set_link_uri(fz_context *ctx, fz_link *link, const char *uri);
#endif

61
include/mupdf/fitz/log.h Normal file
View File

@ -0,0 +1,61 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_LOG_H
#define MUPDF_FITZ_LOG_H
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
/**
The functions in this file offer simple logging abilities.
The default logfile is "fitz_log.txt". This can overridden by
defining an environment variable "FZ_LOG_FILE", or module
specific environment variables "FZ_LOG_FILE_<module>" (e.g.
"FZ_LOG_FILE_STORE").
Enable the following define(s) to enable built in debug logging
from within the appropriate module(s).
*/
/* #define ENABLE_STORE_LOGGING */
/**
Output a line to the log.
*/
void fz_log(fz_context *ctx, const char *fmt, ...);
/**
Output a line to the log for a given module.
*/
void fz_log_module(fz_context *ctx, const char *module, const char *fmt, ...);
/**
Internal function to actually do the opening of the logfile.
Caller should close/drop the output when finished with it.
*/
fz_output *fz_new_log_for_module(fz_context *ctx, const char *module);
#endif

View File

@ -0,0 +1,228 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_OUTLINE_H
#define MUPDF_FITZ_OUTLINE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/types.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/output.h"
/* Outline */
typedef struct {
char *title;
char *uri;
int is_open;
} fz_outline_item;
typedef struct fz_outline_iterator fz_outline_iterator;
/**
Call to get the current outline item.
Can return NULL. The item is only valid until the next call.
*/
fz_outline_item *fz_outline_iterator_item(fz_context *ctx, fz_outline_iterator *iter);
/**
Calls to move the iterator position.
A negative return value means we could not move as requested. Otherwise:
0 = the final position has a valid item.
1 = not a valid item, but we can insert an item here.
*/
int fz_outline_iterator_next(fz_context *ctx, fz_outline_iterator *iter);
int fz_outline_iterator_prev(fz_context *ctx, fz_outline_iterator *iter);
int fz_outline_iterator_up(fz_context *ctx, fz_outline_iterator *iter);
int fz_outline_iterator_down(fz_context *ctx, fz_outline_iterator *iter);
/**
Call to insert a new item BEFORE the current point.
Ownership of pointers are retained by the caller. The item data will be copied.
After an insert, we do not change where we are pointing.
The return code is the same as for next, it indicates the current iterator position.
*/
int fz_outline_iterator_insert(fz_context *ctx, fz_outline_iterator *iter, fz_outline_item *item);
/**
Delete the current item.
This implicitly moves us to the 'next' item, and the return code is as for fz_outline_iterator_next.
*/
int fz_outline_iterator_delete(fz_context *ctx, fz_outline_iterator *iter);
/**
Update the current item properties according to the given item.
*/
void fz_outline_iterator_update(fz_context *ctx, fz_outline_iterator *iter, fz_outline_item *item);
/**
Drop the current iterator.
*/
void fz_drop_outline_iterator(fz_context *ctx, fz_outline_iterator *iter);
/** Structure based API */
/**
fz_outline is a tree of the outline of a document (also known
as table of contents).
title: Title of outline item using UTF-8 encoding. May be NULL
if the outline item has no text string.
uri: Destination in the document to be displayed when this
outline item is activated. May be an internal or external
link, or NULL if the outline item does not have a destination.
page: The page number of an internal link, or -1 for external
links or links with no destination.
next: The next outline item at the same level as this outline
item. May be NULL if no more outline items exist at this level.
down: The outline items immediate children in the hierarchy.
May be NULL if no children exist.
*/
typedef struct fz_outline
{
int refs;
char *title;
char *uri;
fz_location page;
float x, y;
struct fz_outline *next;
struct fz_outline *down;
int is_open;
} fz_outline;
/**
Create a new outline entry with zeroed fields for the caller
to fill in.
*/
fz_outline *fz_new_outline(fz_context *ctx);
/**
Increment the reference count. Returns the same pointer.
Never throws exceptions.
*/
fz_outline *fz_keep_outline(fz_context *ctx, fz_outline *outline);
/**
Decrements the reference count. When the reference point
reaches zero, the outline is freed.
When freed, it will drop linked outline entries (next and down)
too, thus a whole outline structure can be dropped by dropping
the top entry.
Never throws exceptions.
*/
void fz_drop_outline(fz_context *ctx, fz_outline *outline);
/**
Routine to implement the old Structure based API from an iterator.
*/
fz_outline *
fz_load_outline_from_iterator(fz_context *ctx, fz_outline_iterator *iter);
/**
Implementation details.
Of use to people coding new document handlers.
*/
/**
Function type for getting the current item.
Can return NULL. The item is only valid until the next call.
*/
typedef fz_outline_item *(fz_outline_iterator_item_fn)(fz_context *ctx, fz_outline_iterator *iter);
/**
Function types for moving the iterator position.
A negative return value means we could not move as requested. Otherwise:
0 = the final position has a valid item.
1 = not a valid item, but we can insert an item here.
*/
typedef int (fz_outline_iterator_next_fn)(fz_context *ctx, fz_outline_iterator *iter);
typedef int (fz_outline_iterator_prev_fn)(fz_context *ctx, fz_outline_iterator *iter);
typedef int (fz_outline_iterator_up_fn)(fz_context *ctx, fz_outline_iterator *iter);
typedef int (fz_outline_iterator_down_fn)(fz_context *ctx, fz_outline_iterator *iter);
/**
Function type for inserting a new item BEFORE the current point.
Ownership of pointers are retained by the caller. The item data will be copied.
After an insert, we implicitly do a next, so that a successive insert operation
would insert after the item inserted here. The return code is therefore as for next.
*/
typedef int (fz_outline_iterator_insert_fn)(fz_context *ctx, fz_outline_iterator *iter, fz_outline_item *item);
/**
Function type for deleting the current item.
This implicitly moves us to the 'next' item, and the return code is as for fz_outline_iterator_next.
*/
typedef int (fz_outline_iterator_delete_fn)(fz_context *ctx, fz_outline_iterator *iter);
/**
Function type for updating the current item properties according to the given item.
*/
typedef void (fz_outline_iterator_update_fn)(fz_context *ctx, fz_outline_iterator *iter, fz_outline_item *item);
/**
Function type for dropping the current iterator.
*/
typedef void (fz_outline_iterator_drop_fn)(fz_context *ctx, fz_outline_iterator *iter);
#define fz_new_derived_outline_iter(CTX, TYPE, DOC)\
((TYPE *)Memento_label(fz_new_outline_iterator_of_size(ctx,sizeof(TYPE),DOC),#TYPE))
fz_outline_iterator *fz_new_outline_iterator_of_size(fz_context *ctx, size_t size, fz_document *doc);
fz_outline_iterator *fz_outline_iterator_from_outline(fz_context *ctx, fz_outline *outline);
struct fz_outline_iterator {
/* Functions */
fz_outline_iterator_drop_fn *drop;
fz_outline_iterator_item_fn *item;
fz_outline_iterator_next_fn *next;
fz_outline_iterator_prev_fn *prev;
fz_outline_iterator_up_fn *up;
fz_outline_iterator_down_fn *down;
fz_outline_iterator_insert_fn *insert;
fz_outline_iterator_update_fn *update;
fz_outline_iterator_delete_fn *del;
/* Common state */
fz_document *doc;
};
#endif

View File

@ -0,0 +1,64 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_OUTPUT_SVG_H
#define MUPDF_FITZ_OUTPUT_SVG_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/output.h"
enum {
FZ_SVG_TEXT_AS_PATH = 0,
FZ_SVG_TEXT_AS_TEXT = 1,
};
/**
Create a device that outputs (single page) SVG files to
the given output stream.
Equivalent to fz_new_svg_device_with_id passing id = NULL.
*/
fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format, int reuse_images);
/**
Create a device that outputs (single page) SVG files to
the given output stream.
output: The output stream to send the constructed SVG page to.
page_width, page_height: The page dimensions to use (in points).
text_format: How to emit text. One of the following values:
FZ_SVG_TEXT_AS_TEXT: As <text> elements with possible
layout errors and mismatching fonts.
FZ_SVG_TEXT_AS_PATH: As <path> elements with exact
visual appearance.
reuse_images: Share image resources using <symbol> definitions.
id: ID parameter to keep generated IDs unique across SVG files.
*/
fz_device *fz_new_svg_device_with_id(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format, int reuse_images, int *id);
#endif

383
include/mupdf/fitz/output.h Normal file
View File

@ -0,0 +1,383 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_OUTPUT_H
#define MUPDF_FITZ_OUTPUT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/string-util.h"
#include "mupdf/fitz/stream.h"
/**
Generic output streams - generalise between outputting to a
file, a buffer, etc.
*/
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called
whenever data is written to the output.
state: The state for the output stream.
data: a pointer to a buffer of data to write.
n: The number of bytes of data to write.
*/
typedef void (fz_output_write_fn)(fz_context *ctx, void *state, const void *data, size_t n);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called when
fz_seek_output is requested.
state: The output stream state to seek within.
offset, whence: as defined for fs_seek_output.
*/
typedef void (fz_output_seek_fn)(fz_context *ctx, void *state, int64_t offset, int whence);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called when
fz_tell_output is requested.
state: The output stream state to report on.
Returns the offset within the output stream.
*/
typedef int64_t (fz_output_tell_fn)(fz_context *ctx, void *state);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the output stream is closed, to flush any pending writes.
*/
typedef void (fz_output_close_fn)(fz_context *ctx, void *state);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the output stream is dropped, to release the stream
specific state information.
*/
typedef void (fz_output_drop_fn)(fz_context *ctx, void *state);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called
when the fz_stream_from_output is called.
*/
typedef fz_stream *(fz_stream_from_output_fn)(fz_context *ctx, void *state);
/**
A function type for use when implementing
fz_outputs. The supplied function of this type is called
when fz_truncate_output is called to truncate the file
at that point.
*/
typedef void (fz_truncate_fn)(fz_context *ctx, void *state);
struct fz_output
{
void *state;
fz_output_write_fn *write;
fz_output_seek_fn *seek;
fz_output_tell_fn *tell;
fz_output_close_fn *close;
fz_output_drop_fn *drop;
fz_stream_from_output_fn *as_stream;
fz_truncate_fn *truncate;
char *bp, *wp, *ep;
/* If buffered is non-zero, then we have that many
* bits (1-7) waiting to be written in bits. */
int buffered;
int bits;
};
/**
Create a new output object with the given
internal state and function pointers.
state: Internal state (opaque to everything but implementation).
write: Function to output a given buffer.
close: Cleanup function to destroy state when output closed.
May permissibly be null.
*/
fz_output *fz_new_output(fz_context *ctx, int bufsiz, void *state, fz_output_write_fn *write, fz_output_close_fn *close, fz_output_drop_fn *drop);
/**
Open an output stream that writes to a
given path.
filename: The filename to write to (specified in UTF-8).
append: non-zero if we should append to the file, rather than
overwriting it.
*/
fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append);
/**
Open an output stream that appends
to a buffer.
buf: The buffer to append to.
*/
fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf);
/**
Retrieve an fz_output that directs to stdout.
Optionally may be fz_dropped when finished with.
*/
fz_output *fz_stdout(fz_context *ctx);
/**
Retrieve an fz_output that directs to stdout.
Optionally may be fz_dropped when finished with.
*/
fz_output *fz_stderr(fz_context *ctx);
#ifdef _WIN32
/**
Retrieve an fz_output that directs to OutputDebugString.
Optionally may be fz_dropped when finished with.
*/
fz_output *fz_stdods(fz_context *ctx);
#endif
/**
Set the output stream to be used for fz_stddbg. Set to NULL to
reset to default (stderr).
*/
void fz_set_stddbg(fz_context *ctx, fz_output *out);
/**
Retrieve an fz_output for the default debugging stream. On
Windows this will be OutputDebugString for non-console apps.
Otherwise, it is always fz_stderr.
Optionally may be fz_dropped when finished with.
*/
fz_output *fz_stddbg(fz_context *ctx);
/**
Format and write data to an output stream.
See fz_format_string for formatting details.
*/
void fz_write_printf(fz_context *ctx, fz_output *out, const char *fmt, ...);
/**
va_list version of fz_write_printf.
*/
void fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap);
/**
Seek to the specified file position.
See fseek for arguments.
Throw an error on unseekable outputs.
*/
void fz_seek_output(fz_context *ctx, fz_output *out, int64_t off, int whence);
/**
Return the current file position.
Throw an error on untellable outputs.
*/
int64_t fz_tell_output(fz_context *ctx, fz_output *out);
/**
Flush unwritten data.
*/
void fz_flush_output(fz_context *ctx, fz_output *out);
/**
Flush pending output and close an output stream.
*/
void fz_close_output(fz_context *, fz_output *);
/**
Free an output stream. Don't forget to close it first!
*/
void fz_drop_output(fz_context *, fz_output *);
/**
Query whether a given fz_output supports fz_stream_from_output.
*/
int fz_output_supports_stream(fz_context *ctx, fz_output *out);
/**
Obtain the fz_output in the form of a fz_stream.
This allows data to be read back from some forms of fz_output
object. When finished reading, the fz_stream should be released
by calling fz_drop_stream. Until the fz_stream is dropped, no
further operations should be performed on the fz_output object.
*/
fz_stream *fz_stream_from_output(fz_context *, fz_output *);
/**
Truncate the output at the current position.
This allows output streams which have seeked back from the end
of their storage to be truncated at the current point.
*/
void fz_truncate_output(fz_context *, fz_output *);
/**
Write data to output.
data: Pointer to data to write.
size: Size of data to write in bytes.
*/
void fz_write_data(fz_context *ctx, fz_output *out, const void *data, size_t size);
void fz_write_buffer(fz_context *ctx, fz_output *out, fz_buffer *data);
/**
Write a string. Does not write zero terminator.
*/
void fz_write_string(fz_context *ctx, fz_output *out, const char *s);
/**
Write different sized data to an output stream.
*/
void fz_write_int32_be(fz_context *ctx, fz_output *out, int x);
void fz_write_int32_le(fz_context *ctx, fz_output *out, int x);
void fz_write_uint32_be(fz_context *ctx, fz_output *out, unsigned int x);
void fz_write_uint32_le(fz_context *ctx, fz_output *out, unsigned int x);
void fz_write_int16_be(fz_context *ctx, fz_output *out, int x);
void fz_write_int16_le(fz_context *ctx, fz_output *out, int x);
void fz_write_uint16_be(fz_context *ctx, fz_output *out, unsigned int x);
void fz_write_uint16_le(fz_context *ctx, fz_output *out, unsigned int x);
void fz_write_char(fz_context *ctx, fz_output *out, char x);
void fz_write_byte(fz_context *ctx, fz_output *out, unsigned char x);
void fz_write_float_be(fz_context *ctx, fz_output *out, float f);
void fz_write_float_le(fz_context *ctx, fz_output *out, float f);
/**
Write a UTF-8 encoded unicode character.
*/
void fz_write_rune(fz_context *ctx, fz_output *out, int rune);
/**
Write a base64 encoded data block, optionally with periodic
newlines.
*/
void fz_write_base64(fz_context *ctx, fz_output *out, const unsigned char *data, size_t size, int newline);
/**
Write a base64 encoded fz_buffer, optionally with periodic
newlines.
*/
void fz_write_base64_buffer(fz_context *ctx, fz_output *out, fz_buffer *data, int newline);
/**
Write num_bits of data to the end of the output stream, assumed to be packed
most significant bits first.
*/
void fz_write_bits(fz_context *ctx, fz_output *out, unsigned int data, int num_bits);
/**
Sync to byte boundary after writing bits.
*/
void fz_write_bits_sync(fz_context *ctx, fz_output *out);
/**
Our customised 'printf'-like string formatter.
Takes %c, %d, %s, %u, %x, as usual.
Modifiers are not supported except for zero-padding ints (e.g.
%02d, %03u, %04x, etc).
%g output in "as short as possible hopefully lossless
non-exponent" form, see fz_ftoa for specifics.
%f and %e output as usual.
%C outputs a utf8 encoded int.
%M outputs a fz_matrix*.
%R outputs a fz_rect*.
%P outputs a fz_point*.
%n outputs a PDF name (with appropriate escaping).
%q and %( output escaped strings in C/PDF syntax.
%l{d,u,x} indicates that the values are int64_t.
%z{d,u,x} indicates that the value is a size_t.
user: An opaque pointer that is passed to the emit function.
emit: A function pointer called to emit output bytes as the
string is being formatted.
*/
void fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, va_list args);
/**
A vsnprintf work-alike, using our custom formatter.
*/
size_t fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args);
/**
The non va_list equivalent of fz_vsnprintf.
*/
size_t fz_snprintf(char *buffer, size_t space, const char *fmt, ...);
/**
Allocated sprintf.
Returns a null terminated allocated block containing the
formatted version of the format string/args.
*/
char *fz_asprintf(fz_context *ctx, const char *fmt, ...);
/**
Save the contents of a buffer to a file.
*/
void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);
/**
Compression and other filtering outputs.
These outputs write encoded data to another output. Create a
filter output with the destination, write to the filter, then
close and drop it when you're done. These can also be chained
together, for example to write ASCII Hex encoded, Deflate
compressed, and RC4 encrypted data to a buffer output.
Output streams don't use reference counting, so make sure to
close all of the filters in the reverse order of creation so
that data is flushed properly.
Accordingly, ownership of 'chain' is never passed into the
following functions, but remains with the caller, whose
responsibility it is to ensure they exist at least until
the returned fz_output is dropped.
*/
fz_output *fz_new_asciihex_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_ascii85_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_rle_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_arc4_output(fz_context *ctx, fz_output *chain, unsigned char *key, size_t keylen);
fz_output *fz_new_deflate_output(fz_context *ctx, fz_output *chain, int effort, int raw);
#endif

447
include/mupdf/fitz/path.h Normal file
View File

@ -0,0 +1,447 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_PATH_H
#define MUPDF_FITZ_PATH_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
/**
* Vector path buffer.
* It can be stroked and dashed, or be filled.
* It has a fill rule (nonzero or even_odd).
*
* When rendering, they are flattened, stroked and dashed straight
* into the Global Edge List.
*/
typedef struct fz_path fz_path;
typedef enum
{
FZ_LINECAP_BUTT = 0,
FZ_LINECAP_ROUND = 1,
FZ_LINECAP_SQUARE = 2,
FZ_LINECAP_TRIANGLE = 3
} fz_linecap;
typedef enum
{
FZ_LINEJOIN_MITER = 0,
FZ_LINEJOIN_ROUND = 1,
FZ_LINEJOIN_BEVEL = 2,
FZ_LINEJOIN_MITER_XPS = 3
} fz_linejoin;
typedef struct
{
int refs;
fz_linecap start_cap, dash_cap, end_cap;
fz_linejoin linejoin;
float linewidth;
float miterlimit;
float dash_phase;
int dash_len;
float dash_list[32];
} fz_stroke_state;
typedef struct
{
/* Compulsory ones */
void (*moveto)(fz_context *ctx, void *arg, float x, float y);
void (*lineto)(fz_context *ctx, void *arg, float x, float y);
void (*curveto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3);
void (*closepath)(fz_context *ctx, void *arg);
/* Optional ones */
void (*quadto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
void (*curvetov)(fz_context *ctx, void *arg, float x2, float y2, float x3, float y3);
void (*curvetoy)(fz_context *ctx, void *arg, float x1, float y1, float x3, float y3);
void (*rectto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
} fz_path_walker;
/**
Walk the segments of a path, calling the
appropriate callback function from a given set for each
segment of the path.
path: The path to walk.
walker: The set of callback functions to use. The first
4 callback pointers in the set must be non-NULL. The
subsequent ones can either be supplied, or can be left
as NULL, in which case the top 4 functions will be
called as appropriate to simulate them.
arg: An opaque argument passed in to each callback.
Exceptions will only be thrown if the underlying callback
functions throw them.
*/
void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg);
/**
Create a new (empty) path structure.
*/
fz_path *fz_new_path(fz_context *ctx);
/**
Increment the reference count. Returns the same pointer.
All paths can be kept, regardless of their packing type.
Never throws exceptions.
*/
fz_path *fz_keep_path(fz_context *ctx, const fz_path *path);
/**
Decrement the reference count. When the reference count hits
zero, free the path.
All paths can be dropped, regardless of their packing type.
Packed paths do not own the blocks into which they are packed
so dropping them does not free those blocks.
Never throws exceptions.
*/
void fz_drop_path(fz_context *ctx, const fz_path *path);
/**
Minimise the internal storage used by a path.
As paths are constructed, the internal buffers
grow. To avoid repeated reallocations they
grow with some spare space. Once a path has
been fully constructed, this call allows the
excess space to be trimmed.
*/
void fz_trim_path(fz_context *ctx, fz_path *path);
/**
Return the number of bytes required to pack a path.
*/
int fz_packed_path_size(const fz_path *path);
/**
Pack a path into the given block.
To minimise the size of paths, this function allows them to be
packed into a buffer with other information. Paths can be used
interchangeably regardless of how they are packed.
pack: Pointer to a block of data to pack the path into. Should
be aligned by the caller to the same alignment as required for
a fz_path pointer.
path: The path to pack.
Returns the number of bytes within the block used. Callers can
access the packed path data by casting the value of pack on
entry to be a fz_path *.
Throws exceptions on failure to allocate.
Implementation details: Paths can be 'unpacked', 'flat', or
'open'. Standard paths, as created are 'unpacked'. Paths
will be packed as 'flat', unless they are too large
(where large indicates that they exceed some private
implementation defined limits, currently including having
more than 256 coordinates or commands).
Large paths are 'open' packed as a header into the given block,
plus pointers to other data blocks.
Users should not have to care about whether paths are 'open'
or 'flat' packed. Simply pack a path (if required), and then
forget about the details.
*/
size_t fz_pack_path(fz_context *ctx, uint8_t *pack, const fz_path *path);
/**
Clone the data for a path.
This is used in preference to fz_keep_path when a whole
new copy of a path is required, rather than just a shared
pointer. This probably indicates that the path is about to
be modified.
path: path to clone.
Throws exceptions on failure to allocate.
*/
fz_path *fz_clone_path(fz_context *ctx, fz_path *path);
/**
Return the current point that a path has
reached or (0,0) if empty.
path: path to return the current point of.
*/
fz_point fz_currentpoint(fz_context *ctx, fz_path *path);
/**
Append a 'moveto' command to a path.
This 'opens' a path.
path: The path to modify.
x, y: The coordinate to move to.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_moveto(fz_context *ctx, fz_path *path, float x, float y);
/**
Append a 'lineto' command to an open path.
path: The path to modify.
x, y: The coordinate to line to.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_lineto(fz_context *ctx, fz_path *path, float x, float y);
/**
Append a 'rectto' command to an open path.
The rectangle is equivalent to:
moveto x0 y0
lineto x1 y0
lineto x1 y1
lineto x0 y1
closepath
path: The path to modify.
x0, y0: First corner of the rectangle.
x1, y1: Second corner of the rectangle.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
/**
Append a 'quadto' command to an open path. (For a
quadratic bezier).
path: The path to modify.
x0, y0: The control coordinates for the quadratic curve.
x1, y1: The end coordinates for the quadratic curve.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
/**
Append a 'curveto' command to an open path. (For a
cubic bezier).
path: The path to modify.
x0, y0: The coordinates of the first control point for the
curve.
x1, y1: The coordinates of the second control point for the
curve.
x2, y2: The end coordinates for the curve.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2);
/**
Append a 'curvetov' command to an open path. (For a
cubic bezier with the first control coordinate equal to
the start point).
path: The path to modify.
x1, y1: The coordinates of the second control point for the
curve.
x2, y2: The end coordinates for the curve.
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2);
/**
Append a 'curvetoy' command to an open path. (For a
cubic bezier with the second control coordinate equal to
the end point).
path: The path to modify.
x0, y0: The coordinates of the first control point for the
curve.
x2, y2: The end coordinates for the curve (and the second
control coordinate).
Throws exceptions on failure to allocate, or attempting to
modify a packed path.
*/
void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2);
/**
Close the current subpath.
path: The path to modify.
Throws exceptions on failure to allocate, attempting to modify
a packed path, and illegal path closes (i.e. closing a non open
path).
*/
void fz_closepath(fz_context *ctx, fz_path *path);
/**
Transform a path by a given
matrix.
path: The path to modify (must not be a packed path).
transform: The transform to apply.
Throws exceptions if the path is packed, or on failure
to allocate.
*/
void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
/**
Return a bounding rectangle for a path.
path: The path to bound.
stroke: If NULL, the bounding rectangle given is for
the filled path. If non-NULL the bounding rectangle
given is for the path stroked with the given attributes.
ctm: The matrix to apply to the path during stroking.
r: Pointer to a fz_rect which will be used to hold
the result.
Returns r, updated to contain the bounding rectangle.
*/
fz_rect fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm);
/**
Given a rectangle (assumed to be the bounding box for a path),
expand it to allow for the expansion of the bbox that would be
seen by stroking the path with the given stroke state and
transform.
*/
fz_rect fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect rect, const fz_stroke_state *stroke, fz_matrix ctm);
/**
A sane 'default' stroke state.
*/
FZ_DATA extern const fz_stroke_state fz_default_stroke_state;
/**
Create a new (empty) stroke state structure (with no dash
data) and return a reference to it.
Throws exception on failure to allocate.
*/
fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
/**
Create a new (empty) stroke state structure, with room for
dash data of the given length, and return a reference to it.
len: The number of dash elements to allow room for.
Throws exception on failure to allocate.
*/
fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
/**
Take an additional reference to a stroke state structure.
No modifications should be carried out on a stroke
state to which more than one reference is held, as
this can cause race conditions.
*/
fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
/**
Drop a reference to a stroke state structure, destroying the
structure if it is the last reference.
*/
void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
/**
Given a reference to a (possibly) shared stroke_state structure,
return a reference to an equivalent stroke_state structure
that is guaranteed to be unshared (i.e. one that can
safely be modified).
shared: The reference to a (possibly) shared structure
to unshare. Ownership of this reference is passed in
to this function, even in the case of exceptions being
thrown.
Exceptions may be thrown in the event of failure to
allocate if required.
*/
fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
/**
Given a reference to a (possibly) shared stroke_state structure,
return a reference to a stroke_state structure (with room for a
given amount of dash data) that is guaranteed to be unshared
(i.e. one that can safely be modified).
shared: The reference to a (possibly) shared structure
to unshare. Ownership of this reference is passed in
to this function, even in the case of exceptions being
thrown.
Exceptions may be thrown in the event of failure to
allocate if required.
*/
fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
/**
Create an identical stroke_state structure and return a
reference to it.
stroke: The stroke state reference to clone.
Exceptions may be thrown in the event of a failure to
allocate.
*/
fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
#endif

474
include/mupdf/fitz/pixmap.h Normal file
View File

@ -0,0 +1,474 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_PIXMAP_H
#define MUPDF_FITZ_PIXMAP_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/separation.h"
/**
Pixmaps represent a set of pixels for a 2 dimensional region of
a plane. Each pixel has n components per pixel. The components
are in the order process-components, spot-colors, alpha, where
there can be 0 of any of those types. The data is in
premultiplied alpha when rendering, but non-premultiplied for
colorspace conversions and rescaling.
*/
typedef struct fz_overprint fz_overprint;
/**
Return the bounding box for a pixmap.
*/
fz_irect fz_pixmap_bbox(fz_context *ctx, const fz_pixmap *pix);
/**
Return the width of the pixmap in pixels.
*/
int fz_pixmap_width(fz_context *ctx, const fz_pixmap *pix);
/**
Return the height of the pixmap in pixels.
*/
int fz_pixmap_height(fz_context *ctx, const fz_pixmap *pix);
/**
Return the x value of the pixmap in pixels.
*/
int fz_pixmap_x(fz_context *ctx, const fz_pixmap *pix);
/**
Return the y value of the pixmap in pixels.
*/
int fz_pixmap_y(fz_context *ctx, const fz_pixmap *pix);
/**
Create a new pixmap, with its origin at (0,0)
cs: The colorspace to use for the pixmap, or NULL for an alpha
plane/mask.
w: The width of the pixmap (in pixels)
h: The height of the pixmap (in pixels)
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
Returns a pointer to the new pixmap. Throws exception on failure
to allocate.
*/
fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha);
/**
Create a pixmap of a given size, location and pixel format.
The bounding box specifies the size of the created pixmap and
where it will be located. The colorspace determines the number
of components per pixel. Alpha is always present. Pixmaps are
reference counted, so drop references using fz_drop_pixmap.
colorspace: Colorspace format used for the created pixmap. The
pixmap will keep a reference to the colorspace.
bbox: Bounding box specifying location/size of created pixmap.
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
Returns a pointer to the new pixmap. Throws exception on failure
to allocate.
*/
fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_irect bbox, fz_separations *seps, int alpha);
/**
Create a new pixmap, with its origin at
(0,0) using the supplied data block.
cs: The colorspace to use for the pixmap, or NULL for an alpha
plane/mask.
w: The width of the pixmap (in pixels)
h: The height of the pixmap (in pixels)
seps: Details of separations.
alpha: 0 for no alpha, 1 for alpha.
stride: The byte offset from the pixel data in a row to the
pixel data in the next row.
samples: The data block to keep the samples in.
Returns a pointer to the new pixmap. Throws exception on failure to
allocate.
*/
fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, fz_separations *seps, int alpha, int stride, unsigned char *samples);
/**
Create a pixmap of a given size, location and pixel format,
using the supplied data block.
The bounding box specifies the size of the created pixmap and
where it will be located. The colorspace determines the number
of components per pixel. Alpha is always present. Pixmaps are
reference counted, so drop references using fz_drop_pixmap.
colorspace: Colorspace format used for the created pixmap. The
pixmap will keep a reference to the colorspace.
rect: Bounding box specifying location/size of created pixmap.
seps: Details of separations.
alpha: Number of alpha planes (0 or 1).
samples: The data block to keep the samples in.
Returns a pointer to the new pixmap. Throws exception on failure
to allocate.
*/
fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_irect rect, fz_separations *seps, int alpha, unsigned char *samples);
/**
Create a new pixmap that represents a subarea of the specified
pixmap. A reference is taken to this pixmap that will be dropped
on destruction.
The supplied rectangle must be wholly contained within the
original pixmap.
Returns a pointer to the new pixmap. Throws exception on failure
to allocate.
*/
fz_pixmap *fz_new_pixmap_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, const fz_irect *rect);
/**
Clone a pixmap, copying the pixels and associated data to new
storage.
The reference count of 'old' is unchanged.
*/
fz_pixmap *fz_clone_pixmap(fz_context *ctx, const fz_pixmap *old);
/**
Increment the reference count for the pixmap. The same pointer
is returned.
Never throws exceptions.
*/
fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
/**
Decrement the reference count for the pixmap. When the
reference count hits 0, the pixmap is freed.
Never throws exceptions.
*/
void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
/**
Return the colorspace of a pixmap
Returns colorspace.
*/
fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, const fz_pixmap *pix);
/**
Return the number of components in a pixmap.
Returns the number of components (including spots and alpha).
*/
int fz_pixmap_components(fz_context *ctx, const fz_pixmap *pix);
/**
Return the number of colorants in a pixmap.
Returns the number of colorants (components, less any spots and
alpha).
*/
int fz_pixmap_colorants(fz_context *ctx, const fz_pixmap *pix);
/**
Return the number of spots in a pixmap.
Returns the number of spots (components, less colorants and
alpha). Does not throw exceptions.
*/
int fz_pixmap_spots(fz_context *ctx, const fz_pixmap *pix);
/**
Return the number of alpha planes in a pixmap.
Returns the number of alphas. Does not throw exceptions.
*/
int fz_pixmap_alpha(fz_context *ctx, const fz_pixmap *pix);
/**
Returns a pointer to the pixel data of a pixmap.
Returns the pointer.
*/
unsigned char *fz_pixmap_samples(fz_context *ctx, const fz_pixmap *pix);
/**
Return the number of bytes in a row in the pixmap.
*/
int fz_pixmap_stride(fz_context *ctx, const fz_pixmap *pix);
/**
Set the pixels per inch resolution of the pixmap.
*/
void fz_set_pixmap_resolution(fz_context *ctx, fz_pixmap *pix, int xres, int yres);
/**
Clears a pixmap with the given value.
pix: The pixmap to clear.
value: Values in the range 0 to 255 are valid. Each component
sample for each pixel in the pixmap will be set to this value,
while alpha will always be set to 255 (non-transparent).
This function is horrible, and should be removed from the
API and replaced with a less magic one.
*/
void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
/**
Fill pixmap with solid color.
*/
void fz_fill_pixmap_with_color(fz_context *ctx, fz_pixmap *pix, fz_colorspace *colorspace, float *color, fz_color_params color_params);
/**
Clears a subrect of a pixmap with the given value.
pix: The pixmap to clear.
value: Values in the range 0 to 255 are valid. Each component
sample for each pixel in the pixmap will be set to this value,
while alpha will always be set to 255 (non-transparent).
r: the rectangle.
*/
void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_irect r);
/**
Sets all components (including alpha) of
all pixels in a pixmap to 0.
pix: The pixmap to clear.
*/
void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
/**
Invert all the pixels in a pixmap. All components (process and
spots) of all pixels are inverted (except alpha, which is
unchanged).
*/
void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
/**
Invert the alpha fo all the pixels in a pixmap.
*/
void fz_invert_pixmap_alpha(fz_context *ctx, fz_pixmap *pix);
/**
Transform the pixels in a pixmap so that luminance of each
pixel is inverted, and the chrominance remains unchanged (as
much as accuracy allows).
All components of all pixels are inverted (except alpha, which
is unchanged). Only supports Grey and RGB bitmaps.
*/
void fz_invert_pixmap_luminance(fz_context *ctx, fz_pixmap *pix);
/**
Tint all the pixels in an RGB, BGR, or Gray pixmap.
black: Map black to this hexadecimal RGB color.
white: Map white to this hexadecimal RGB color.
*/
void fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int black, int white);
/**
Invert all the pixels in a given rectangle of a (premultiplied)
pixmap. All components of all pixels in the rectangle are
inverted (except alpha, which is unchanged).
*/
void fz_invert_pixmap_rect(fz_context *ctx, fz_pixmap *image, fz_irect rect);
/**
Invert all the pixels in a non-premultiplied pixmap in a
very naive manner.
*/
void fz_invert_pixmap_raw(fz_context *ctx, fz_pixmap *pix);
/**
Apply gamma correction to a pixmap. All components
of all pixels are modified (except alpha, which is unchanged).
gamma: The gamma value to apply; 1.0 for no change.
*/
void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
/**
Convert an existing pixmap to a desired
colorspace. Other properties of the pixmap, such as resolution
and position are copied to the converted pixmap.
pix: The pixmap to convert.
default_cs: If NULL pix->colorspace is used. It is possible that
the data may need to be interpreted as one of the color spaces
in default_cs.
cs_des: Desired colorspace, may be NULL to denote alpha-only.
prf: Proofing color space through which we need to convert.
color_params: Parameters that may be used in conversion (e.g.
ri).
keep_alpha: If 0 any alpha component is removed, otherwise
alpha is kept if present in the pixmap.
*/
fz_pixmap *fz_convert_pixmap(fz_context *ctx, const fz_pixmap *pix, fz_colorspace *cs_des, fz_colorspace *prf, fz_default_colorspaces *default_cs, fz_color_params color_params, int keep_alpha);
/**
Check if the pixmap is a 1-channel image containing samples with
only values 0 and 255
*/
int fz_is_pixmap_monochrome(fz_context *ctx, fz_pixmap *pixmap);
/* Implementation details: subject to change.*/
fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray);
void fz_decode_tile(fz_context *ctx, fz_pixmap *pix, const float *decode);
void fz_md5_pixmap(fz_context *ctx, fz_pixmap *pixmap, unsigned char digest[16]);
fz_stream *
fz_unpack_stream(fz_context *ctx, fz_stream *src, int depth, int w, int h, int n, int indexed, int pad, int skip);
/**
Pixmaps represent a set of pixels for a 2 dimensional region of
a plane. Each pixel has n components per pixel. The components
are in the order process-components, spot-colors, alpha, where
there can be 0 of any of those types. The data is in
premultiplied alpha when rendering, but non-premultiplied for
colorspace conversions and rescaling.
x, y: The minimum x and y coord of the region in pixels.
w, h: The width and height of the region in pixels.
n: The number of color components in the image.
n = num composite colors + num spots + num alphas
s: The number of spot channels in the image.
alpha: 0 for no alpha, 1 for alpha present.
flags: flag bits.
Bit 0: If set, draw the image with linear interpolation.
Bit 1: If set, free the samples buffer when the pixmap
is destroyed.
stride: The byte offset from the data for any given pixel
to the data for the same pixel on the row below.
seps: NULL, or a pointer to a separations structure. If NULL,
s should be 0.
xres, yres: Image resolution in dpi. Default is 96 dpi.
colorspace: Pointer to a colorspace object describing the
colorspace the pixmap is in. If NULL, the image is a mask.
samples: Pointer to the first byte of the pixmap sample data.
This is typically a simple block of memory w * h * n bytes of
memory in which the components are stored linearly, but with the
use of appropriate stride values, scanlines can be stored in
different orders, and have different amounts of padding. The
first n bytes are components 0 to n-1 for the pixel at (x,y).
Each successive n bytes gives another pixel in scanline order
as we move across the line. The start of each scanline is offset
the start of the previous one by stride bytes.
*/
struct fz_pixmap
{
fz_storable storable;
int x, y, w, h;
unsigned char n;
unsigned char s;
unsigned char alpha;
unsigned char flags;
ptrdiff_t stride;
fz_separations *seps;
int xres, yres;
fz_colorspace *colorspace;
unsigned char *samples;
fz_pixmap *underlying;
};
enum
{
FZ_PIXMAP_FLAG_INTERPOLATE = 1,
FZ_PIXMAP_FLAG_FREE_SAMPLES = 2
};
/* Create a new pixmap from a warped section of another.
*
* Colorspace, resolution etc are inherited from the original.
* points give the corner points within the original pixmap of a
* (convex) quadrilateral. These corner points will be 'warped' to be
* the corner points of the returned bitmap, which will have the given
* width/height.
*/
fz_pixmap *
fz_warp_pixmap(fz_context *ctx, fz_pixmap *src, const fz_point points[4], int width, int height);
/*
Convert between different separation results.
*/
fz_pixmap *fz_clone_pixmap_area_with_different_seps(fz_context *ctx, fz_pixmap *src, const fz_irect *bbox, fz_colorspace *dcs, fz_separations *seps, fz_color_params color_params, fz_default_colorspaces *default_cs);
/*
* Extract alpha channel as a separate pixmap.
* Returns NULL if there is no alpha channel in the source.
*/
fz_pixmap *fz_new_pixmap_from_alpha_channel(fz_context *ctx, fz_pixmap *src);
/*
* Combine a pixmap without an alpha channel with a soft mask.
*/
fz_pixmap *fz_new_pixmap_from_color_and_mask(fz_context *ctx, fz_pixmap *color, fz_pixmap *mask);
#endif

68
include/mupdf/fitz/pool.h Normal file
View File

@ -0,0 +1,68 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_POOL_H
#define MUPDF_FITZ_POOL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/**
Simple pool allocators.
Allocate from the pool, which can then be freed at once.
*/
typedef struct fz_pool fz_pool;
/**
Create a new pool to allocate from.
*/
fz_pool *fz_new_pool(fz_context *ctx);
/**
Allocate a block of size bytes from the pool.
*/
void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size);
/**
strdup equivalent allocating from the pool.
*/
char *fz_pool_strdup(fz_context *ctx, fz_pool *pool, const char *s);
/**
The current size of the pool.
The number of bytes of storage currently allocated to the pool.
This is the total of the storage used for the blocks making
up the pool, rather then total of the allocated blocks so far,
so it will increase in 'lumps'.
from the pool, then the pool size may still be X
*/
size_t fz_pool_size(fz_context *ctx, fz_pool *pool);
/**
Drop a pool, freeing and invalidating all storage returned from
the pool.
*/
void fz_drop_pool(fz_context *ctx, fz_pool *pool);
#endif

View File

@ -0,0 +1,138 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_SEPARATION_H
#define MUPDF_FITZ_SEPARATION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/color.h"
/**
A fz_separation structure holds details of a set of separations
(such as might be used on within a page of the document).
The app might control the separations by enabling/disabling them,
and subsequent renders would take this into account.
*/
enum
{
FZ_MAX_SEPARATIONS = 64
};
typedef struct fz_separations fz_separations;
typedef enum
{
/* "Composite" separations are rendered using process
* colors using the equivalent colors */
FZ_SEPARATION_COMPOSITE = 0,
/* Spot colors are rendered into their own spot plane. */
FZ_SEPARATION_SPOT = 1,
/* Disabled colors are not rendered at all in the final
* output. */
FZ_SEPARATION_DISABLED = 2
} fz_separation_behavior;
/**
Create a new separations structure (initially empty)
*/
fz_separations *fz_new_separations(fz_context *ctx, int controllable);
/**
Increment the reference count for a separations structure.
Returns the same pointer.
Never throws exceptions.
*/
fz_separations *fz_keep_separations(fz_context *ctx, fz_separations *sep);
/**
Decrement the reference count for a separations structure.
When the reference count hits zero, the separations structure
is freed.
Never throws exceptions.
*/
void fz_drop_separations(fz_context *ctx, fz_separations *sep);
/**
Add a separation (null terminated name, colorspace)
*/
void fz_add_separation(fz_context *ctx, fz_separations *sep, const char *name, fz_colorspace *cs, int cs_channel);
/**
Add a separation with equivalents (null terminated name,
colorspace)
(old, deprecated)
*/
void fz_add_separation_equivalents(fz_context *ctx, fz_separations *sep, uint32_t rgba, uint32_t cmyk, const char *name);
/**
Control the rendering of a given separation.
*/
void fz_set_separation_behavior(fz_context *ctx, fz_separations *sep, int separation, fz_separation_behavior behavior);
/**
Test for the current behavior of a separation.
*/
fz_separation_behavior fz_separation_current_behavior(fz_context *ctx, const fz_separations *sep, int separation);
const char *fz_separation_name(fz_context *ctx, const fz_separations *sep, int separation);
int fz_count_separations(fz_context *ctx, const fz_separations *sep);
/**
Return the number of active separations.
*/
int fz_count_active_separations(fz_context *ctx, const fz_separations *seps);
/**
Compare 2 separations structures (or NULLs).
Return 0 if identical, non-zero if not identical.
*/
int fz_compare_separations(fz_context *ctx, const fz_separations *sep1, const fz_separations *sep2);
/**
Return a separations object with all the spots in the input
separations object that are set to composite, reset to be
enabled. If there ARE no spots in the object, this returns
NULL. If the object already has all its spots enabled, then
just returns another handle on the same object.
*/
fz_separations *fz_clone_separations_for_overprint(fz_context *ctx, fz_separations *seps);
/**
Convert a color given in terms of one colorspace,
to a color in terms of another colorspace/separations.
*/
void fz_convert_separation_colors(fz_context *ctx, fz_colorspace *src_cs, const float *src_color, fz_separations *dst_seps, fz_colorspace *dst_cs, float *dst_color, fz_color_params color_params);
/**
Get the equivalent separation color in a given colorspace.
*/
void fz_separation_equivalent(fz_context *ctx, const fz_separations *seps, int idx, fz_colorspace *dst_cs, float *dst_color, fz_colorspace *prf, fz_color_params color_params);
#endif

231
include/mupdf/fitz/shade.h Normal file
View File

@ -0,0 +1,231 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_SHADE_H
#define MUPDF_FITZ_SHADE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/compressed-buffer.h"
/**
* The shading code uses gouraud shaded triangle meshes.
*/
enum
{
FZ_FUNCTION_BASED = 1,
FZ_LINEAR = 2,
FZ_RADIAL = 3,
FZ_MESH_TYPE4 = 4,
FZ_MESH_TYPE5 = 5,
FZ_MESH_TYPE6 = 6,
FZ_MESH_TYPE7 = 7
};
/**
Structure is public to allow derived classes. Do not
access the members directly.
*/
typedef struct
{
fz_storable storable;
fz_rect bbox; /* can be fz_infinite_rect */
fz_colorspace *colorspace;
fz_matrix matrix; /* matrix from pattern dict */
int use_background; /* background color for fills but not 'sh' */
float background[FZ_MAX_COLORS];
/* Just to be confusing, PDF Shadings of Type 1 (Function Based
* Shadings), do NOT use_function, but all the others do. This
* is because Type 1 shadings take 2 inputs, whereas all the
* others (when used with a function take 1 input. The type 1
* data is in the 'f' field of the union below. */
int use_function;
float function[256][FZ_MAX_COLORS + 1];
int type; /* function, linear, radial, mesh */
union
{
struct
{
int extend[2];
float coords[2][3]; /* (x,y,r) twice */
} l_or_r;
struct
{
int vprow;
int bpflag;
int bpcoord;
int bpcomp;
float x0, x1;
float y0, y1;
float c0[FZ_MAX_COLORS];
float c1[FZ_MAX_COLORS];
} m;
struct
{
fz_matrix matrix;
int xdivs;
int ydivs;
float domain[2][2];
float *fn_vals;
} f;
} u;
fz_compressed_buffer *buffer;
} fz_shade;
/**
Increment the reference count for the shade structure. The
same pointer is returned.
Never throws exceptions.
*/
fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade);
/**
Decrement the reference count for the shade structure. When
the reference count hits zero, the structure is freed.
Never throws exceptions.
*/
void fz_drop_shade(fz_context *ctx, fz_shade *shade);
/**
Bound a given shading.
shade: The shade to bound.
ctm: The transform to apply to the shade before bounding.
r: Pointer to storage to put the bounds in.
Returns r, updated to contain the bounds for the shading.
*/
fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm);
typedef struct fz_shade_color_cache fz_shade_color_cache;
void fz_drop_shade_color_cache(fz_context *ctx, fz_shade_color_cache *cache);
/**
Render a shade to a given pixmap.
shade: The shade to paint.
override_cs: NULL, or colorspace to override the shades
inbuilt colorspace.
ctm: The transform to apply.
dest: The pixmap to render into.
color_params: The color rendering settings
bbox: Pointer to a bounding box to limit the rendering
of the shade.
eop: NULL, or pointer to overprint bitmap.
cache: *cache is used to cache color information. If *cache is NULL it
is set to point to a new fz_shade_color_cache. If cache is NULL it is
ignored.
*/
void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_colorspace *override_cs, fz_matrix ctm, fz_pixmap *dest, fz_color_params color_params, fz_irect bbox, const fz_overprint *eop, fz_shade_color_cache **cache);
/**
* Handy routine for processing mesh based shades
*/
typedef struct
{
fz_point p;
float c[FZ_MAX_COLORS];
} fz_vertex;
/**
Callback function type for use with
fz_process_shade.
arg: Opaque pointer from fz_process_shade caller.
v: Pointer to a fz_vertex structure to populate.
c: Pointer to an array of floats used to populate v.
*/
typedef void (fz_shade_prepare_fn)(fz_context *ctx, void *arg, fz_vertex *v, const float *c);
/**
Callback function type for use with
fz_process_shade.
arg: Opaque pointer from fz_process_shade caller.
av, bv, cv: Pointers to a fz_vertex structure describing
the corner locations and colors of a triangle to be
filled.
*/
typedef void (fz_shade_process_fn)(fz_context *ctx, void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex *cv);
/**
Process a shade, using supplied callback functions. This
decomposes the shading to a mesh (even ones that are not
natively meshes, such as linear or radial shadings), and
processes triangles from those meshes.
shade: The shade to process.
ctm: The transform to use
prepare: Callback function to 'prepare' each vertex.
This function is passed an array of floats, and populates
a fz_vertex structure.
process: This function is passed 3 pointers to vertex
structures, and actually performs the processing (typically
filling the area between the vertexes).
process_arg: An opaque argument passed through from caller
to callback functions.
*/
void fz_process_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_rect scissor,
fz_shade_prepare_fn *prepare,
fz_shade_process_fn *process,
void *process_arg);
/* Implementation details: subject to change. */
/**
Internal function to destroy a
shade. Only exposed for use with the fz_store.
shade: The reference to destroy.
*/
void fz_drop_shade_imp(fz_context *ctx, fz_storable *shade);
#endif

442
include/mupdf/fitz/store.h Normal file
View File

@ -0,0 +1,442 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STORE_H
#define MUPDF_FITZ_STORE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/log.h"
/**
Resource store
MuPDF stores decoded "objects" into a store for potential reuse.
If the size of the store gets too big, objects stored within it
can be evicted and freed to recover space. When MuPDF comes to
decode such an object, it will check to see if a version of this
object is already in the store - if it is, it will simply reuse
it. If not, it will decode it and place it into the store.
All objects that can be placed into the store are derived from
the fz_storable type (i.e. this should be the first component of
the objects structure). This allows for consistent (thread safe)
reference counting, and includes a function that will be called
to free the object as soon as the reference count reaches zero.
Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived
from fz_keep_storable/fz_drop_storable. Creation of such objects
includes a call to FZ_INIT_STORABLE to set up the fz_storable
header.
*/
typedef struct fz_storable fz_storable;
/**
Function type for a function to drop a storable object.
Objects within the store are identified by type by comparing
their drop_fn pointers.
*/
typedef void (fz_store_drop_fn)(fz_context *, fz_storable *);
/**
Any storable object should include an fz_storable structure
at the start (by convention at least) of their structure.
(Unless it starts with an fz_key_storable, see below).
*/
struct fz_storable {
int refs;
fz_store_drop_fn *drop;
};
/**
Any storable object that can appear in the key of another
storable object should include an fz_key_storable structure
at the start (by convention at least) of their structure.
*/
typedef struct
{
fz_storable storable;
short store_key_refs;
} fz_key_storable;
/**
Macro to initialise a storable object.
*/
#define FZ_INIT_STORABLE(S_,RC,DROP) \
do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
S->drop = (DROP); \
} while (0)
/**
Macro to initialise a key storable object.
*/
#define FZ_INIT_KEY_STORABLE(KS_,RC,DROP) \
do { fz_key_storable *KS = &(KS_)->key_storable; KS->store_key_refs = 0;\
FZ_INIT_STORABLE(KS,RC,DROP); \
} while (0)
/**
Increment the reference count for a storable object.
Returns the same pointer.
Never throws exceptions.
*/
void *fz_keep_storable(fz_context *, const fz_storable *);
/**
Decrement the reference count for a storable object. When the
reference count hits zero, the drop function for that object
is called to free the object.
Never throws exceptions.
*/
void fz_drop_storable(fz_context *, const fz_storable *);
/**
Increment the (normal) reference count for a key storable
object. Returns the same pointer.
Never throws exceptions.
*/
void *fz_keep_key_storable(fz_context *, const fz_key_storable *);
/**
Decrement the (normal) reference count for a storable object.
When the total reference count hits zero, the drop function for
that object is called to free the object.
Never throws exceptions.
*/
void fz_drop_key_storable(fz_context *, const fz_key_storable *);
/**
Increment the (key) reference count for a key storable
object. Returns the same pointer.
Never throws exceptions.
*/
void *fz_keep_key_storable_key(fz_context *, const fz_key_storable *);
/**
Decrement the (key) reference count for a storable object.
When the total reference count hits zero, the drop function for
that object is called to free the object.
Never throws exceptions.
*/
void fz_drop_key_storable_key(fz_context *, const fz_key_storable *);
/**
The store can be seen as a dictionary that maps keys to
fz_storable values. In order to allow keys of different types to
be stored, we have a structure full of functions for each key
'type'; this fz_store_type pointer is stored with each key, and
tells the store how to perform certain operations (like taking/
dropping a reference, comparing two keys, outputting details for
debugging etc).
The store uses a hash table internally for speed where possible.
In order for this to work, we need a mechanism for turning a
generic 'key' into 'a hashable string'. For this purpose the
type structure contains a make_hash_key function pointer that
maps from a void * to a fz_store_hash structure. If
make_hash_key function returns 0, then the key is determined not
to be hashable, and the value is not stored in the hash table.
Some objects can be used both as values within the store, and as
a component of keys within the store. We refer to these objects
as "key storable" objects. In this case, we need to take
additional care to ensure that we do not end up keeping an item
within the store, purely because its value is referred to by
another key in the store.
An example of this are fz_images in PDF files. Each fz_image is
placed into the store to enable it to be easily reused. When the
image is rendered, a pixmap is generated from the image, and the
pixmap is placed into the store so it can be reused on
subsequent renders. The image forms part of the key for the
pixmap.
When we close the pdf document (and any associated pages/display
lists etc), we drop the images from the store. This may leave us
in the position of the images having non-zero reference counts
purely because they are used as part of the keys for the
pixmaps.
We therefore use special reference counting functions to keep
track of these "key storable" items, and hence store the number
of references to these items that are used in keys.
When the number of references to an object == the number of
references to an object from keys in the store, we know that we
can remove all the items which have that object as part of the
key. This is done by running a pass over the store, 'reaping'
those items.
Reap passes are slower than we would like as they touch every
item in the store. We therefore provide a way to 'batch' such
reap passes together, using fz_defer_reap_start/
fz_defer_reap_end to bracket a region in which many may be
triggered.
*/
typedef struct
{
fz_store_drop_fn *drop;
union
{
struct
{
const void *ptr;
int i;
} pi; /* 8 or 12 bytes */
struct
{
const void *ptr;
int i;
fz_irect r;
} pir; /* 24 or 28 bytes */
struct
{
int id;
char has_shape;
char has_group_alpha;
float m[4];
void *ptr;
} im; /* 28 or 32 bytes */
struct
{
unsigned char src_md5[16];
unsigned char dst_md5[16];
unsigned int ri:2;
unsigned int bp:1;
unsigned int format:1;
unsigned int proof:1;
unsigned int src_extras:5;
unsigned int dst_extras:5;
unsigned int copy_spots:1;
unsigned int bgr:1;
} link; /* 36 bytes */
} u;
} fz_store_hash; /* 40 or 44 bytes */
/**
Every type of object to be placed into the store defines an
fz_store_type. This contains the pointers to functions to
make hashes, manipulate keys, and check for needing reaping.
*/
typedef struct
{
const char *name;
int (*make_hash_key)(fz_context *ctx, fz_store_hash *hash, void *key);
void *(*keep_key)(fz_context *ctx, void *key);
void (*drop_key)(fz_context *ctx, void *key);
int (*cmp_key)(fz_context *ctx, void *a, void *b);
void (*format_key)(fz_context *ctx, char *buf, size_t size, void *key);
int (*needs_reap)(fz_context *ctx, void *key);
} fz_store_type;
/**
Create a new store inside the context
max: The maximum size (in bytes) that the store is allowed to
grow to. FZ_STORE_UNLIMITED means no limit.
*/
void fz_new_store_context(fz_context *ctx, size_t max);
/**
Increment the reference count for the store context. Returns
the same pointer.
Never throws exceptions.
*/
fz_store *fz_keep_store_context(fz_context *ctx);
/**
Decrement the reference count for the store context. When the
reference count hits zero, the store context is freed.
Never throws exceptions.
*/
void fz_drop_store_context(fz_context *ctx);
/**
Add an item to the store.
Add an item into the store, returning NULL for success. If an
item with the same key is found in the store, then our item will
not be inserted, and the function will return a pointer to that
value instead. This function takes its own reference to val, as
required (i.e. the caller maintains ownership of its own
reference).
key: The key used to index the item.
val: The value to store.
itemsize: The size in bytes of the value (as counted towards the
store size).
type: Functions used to manipulate the key.
*/
void *fz_store_item(fz_context *ctx, void *key, void *val, size_t itemsize, const fz_store_type *type);
/**
Find an item within the store.
drop: The function used to free the value (to ensure we get a
value of the correct type).
key: The key used to index the item.
type: Functions used to manipulate the key.
Returns NULL for not found, otherwise returns a pointer to the
value indexed by key to which a reference has been taken.
*/
void *fz_find_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
/**
Remove an item from the store.
If an item indexed by the given key exists in the store, remove
it.
drop: The function used to free the value (to ensure we get a
value of the correct type).
key: The key used to find the item to remove.
type: Functions used to manipulate the key.
*/
void fz_remove_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
/**
Evict every item from the store.
*/
void fz_empty_store(fz_context *ctx);
/**
Internal function used as part of the scavenging
allocator; when we fail to allocate memory, before returning a
failure to the caller, we try to scavenge space within the store
by evicting at least 'size' bytes. The allocator then retries.
size: The number of bytes we are trying to have free.
phase: What phase of the scavenge we are in. Updated on exit.
Returns non zero if we managed to free any memory.
*/
int fz_store_scavenge(fz_context *ctx, size_t size, int *phase);
/**
External function for callers to use
to scavenge while trying allocations.
size: The number of bytes we are trying to have free.
phase: What phase of the scavenge we are in. Updated on exit.
Returns non zero if we managed to free any memory.
*/
int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase);
/**
Evict items from the store until the total size of
the objects in the store is reduced to a given percentage of its
current size.
percent: %age of current size to reduce the store to.
Returns non zero if we managed to free enough memory, zero
otherwise.
*/
int fz_shrink_store(fz_context *ctx, unsigned int percent);
/**
Callback function called by fz_filter_store on every item within
the store.
Return 1 to drop the item from the store, 0 to retain.
*/
typedef int (fz_store_filter_fn)(fz_context *ctx, void *arg, void *key);
/**
Filter every element in the store with a matching type with the
given function.
If the function returns 1 for an element, drop the element.
*/
void fz_filter_store(fz_context *ctx, fz_store_filter_fn *fn, void *arg, const fz_store_type *type);
/**
Output debugging information for the current state of the store
to the given output channel.
*/
void fz_debug_store(fz_context *ctx, fz_output *out);
/**
Increment the defer reap count.
No reap operations will take place (except for those
triggered by an immediate failed malloc) until the
defer reap count returns to 0.
Call this at the start of a process during which you
potentially might drop many reapable objects.
It is vital that every fz_defer_reap_start is matched
by a fz_defer_reap_end call.
*/
void fz_defer_reap_start(fz_context *ctx);
/**
Decrement the defer reap count.
If the defer reap count returns to 0, and the store
has reapable objects in, a reap pass will begin.
Call this at the end of a process during which you
potentially might drop many reapable objects.
It is vital that every fz_defer_reap_start is matched
by a fz_defer_reap_end call.
*/
void fz_defer_reap_end(fz_context *ctx);
#ifdef ENABLE_STORE_LOGGING
void fz_log_dump_store(fz_context *ctx, const char *fmt, ...);
#define FZ_LOG_STORE(CTX, ...) fz_log_module(CTX, "STORE", __VA_ARGS__)
#define FZ_LOG_DUMP_STORE(...) fz_log_dump_store(__VA_ARGS__)
#else
#define FZ_LOG_STORE(...) do {} while (0)
#define FZ_LOG_DUMP_STORE(...) do {} while (0)
#endif
#endif

View File

@ -0,0 +1,209 @@
// Copyright (C) 2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STORY_WRITER_H
#define MUPDF_FITZ_STORY_WRITER_H
#include "mupdf/fitz/story.h"
#include "mupdf/fitz/writer.h"
/*
* A fz_story_element_position plus page number information; used with
* fz_write_story() and fz_write_stabilized_story().
*/
typedef struct
{
fz_story_element_position element;
int page_num;
} fz_write_story_position;
/*
* A set of fz_write_story_position items; used with
* fz_write_stabilized_story().
*/
typedef struct
{
fz_write_story_position *positions;
int num;
} fz_write_story_positions;
/*
* Callback type used by fz_write_story() and fz_write_stabilized_story().
*
* Should set *rect to rect number <num>. If this is on a new page should also
* set *mediabox and return 1, otherwise return 0.
*
* ref:
* As passed to fz_write_story() or fz_write_stabilized_story().
* num:
* The rect number. Will typically increment by one each time, being reset
* to zero when fz_write_stabilized_story() starts a new iteration.
* filled:
* From earlier internal call to fz_place_story().
* rect:
* Out param.
* ctm:
* Out param, defaults to fz_identity.
* mediabox:
* Out param, only used if we return 1.
*/
typedef int (fz_write_story_rectfn)(fz_context *ctx, void *ref, int num, fz_rect filled, fz_rect *rect, fz_matrix *ctm, fz_rect *mediabox);
/*
* Callback used by fz_write_story() to report information about element
* positions. Slightly different from fz_story_position_callback() because
* <position> also includes the page number.
*
* ref:
* As passed to fz_write_story() or fz_write_stabilized_story().
* position:
* Called via internal call to fz_story_position_callback().
*/
typedef void (fz_write_story_positionfn)(fz_context *ctx, void *ref, const fz_write_story_position *position);
/*
* Callback for fz_write_story(), called twice for each page, before (after=0)
* and after (after=1) the story is written.
*
* ref:
* As passed to fz_write_story() or fz_write_stabilized_story().
* page_num:
* Page number, starting from 1.
* mediabox:
* As returned from fz_write_story_rectfn().
* dev:
* Created from the fz_writer passed to fz_write_story() or
* fz_write_stabilized_story().
* after:
* 0 - before writing the story.
* 1 - after writing the story.
*/
typedef void (fz_write_story_pagefn)(fz_context *ctx, void *ref, int page_num, fz_rect mediabox, fz_device *dev, int after);
/*
* Callback type for fz_write_stabilized_story().
*
* Should populate the supplied buffer with html content for use with internal
* calls to fz_new_story(). This may include extra content derived from
* information in <positions>, for example a table of contents.
*
* ref:
* As passed to fz_write_stabilized_story().
* positions:
* Information from previous iteration.
* buffer:
* Where to write the new content. Will be initially empty.
*/
typedef void (fz_write_story_contentfn)(fz_context *ctx, void *ref, const fz_write_story_positions *positions, fz_buffer *buffer);
/*
* Places and writes a story to a fz_document_writer. Avoids the need
* for calling code to implement a loop that calls fz_place_story()
* and fz_draw_story() etc, at the expense of having to provide a
* fz_write_story_rectfn() callback.
*
* story:
* The story to place and write.
* writer:
* Where to write the story; can be NULL.
* rectfn:
* Should return information about the rect to be used in the next
* internal call to fz_place_story().
* rectfn_ref:
* Passed to rectfn().
* positionfn:
* If not NULL, is called via internal calls to fz_story_positions().
* positionfn_ref:
* Passed to positionfn().
* pagefn:
* If not NULL, called at start and end of each page (before and after all
* story content has been written to the device).
* pagefn_ref:
* Passed to pagefn().
*/
void fz_write_story(
fz_context *ctx,
fz_document_writer *writer,
fz_story *story,
fz_write_story_rectfn rectfn,
void *rectfn_ref,
fz_write_story_positionfn positionfn,
void *positionfn_ref,
fz_write_story_pagefn pagefn,
void *pagefn_ref
);
/*
* Does iterative layout of html content to a fz_document_writer. For example
* this allows one to add a table of contents section while ensuring that page
* numbers are patched up until stable.
*
* Repeatedly creates new story from (contentfn(), contentfn_ref, user_css, em)
* and lays it out with internal call to fz_write_story(); uses a NULL writer
* and populates a fz_write_story_positions which is passed to the next call of
* contentfn().
*
* When the html from contentfn() becomes unchanged, we do a final iteration
* using <writer>.
*
* writer:
* Where to write in the final iteration.
* user_css:
* Used in internal calls to fz_new_story().
* em:
* Used in internal calls to fz_new_story().
* contentfn:
* Should return html content for use with fz_new_story(), possibly
* including extra content such as a table-of-contents.
* contentfn_ref:
* Passed to contentfn().
* rectfn:
* Should return information about the rect to be used in the next
* internal call to fz_place_story().
* rectfn_ref:
* Passed to rectfn().
* fz_write_story_pagefn:
* If not NULL, called at start and end of each page (before and after all
* story content has been written to the device).
* pagefn_ref:
* Passed to pagefn().
* archive:
* NULL, or an archive to load images etc from.
*/
void fz_write_stabilized_story(
fz_context *ctx,
fz_document_writer *writer,
const char *user_css,
float em,
fz_write_story_contentfn contentfn,
void *contentfn_ref,
fz_write_story_rectfn rectfn,
void *rectfn_ref,
fz_write_story_pagefn pagefn,
void *pagefn_ref,
fz_archive *archive
);
#endif

206
include/mupdf/fitz/story.h Normal file
View File

@ -0,0 +1,206 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STORY_H
#define MUPDF_FITZ_STORY_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/xml.h"
#include "mupdf/fitz/archive.h"
/*
This header file provides an API for laying out and placing styled
text on a page, or pages.
First a text story is created from some styled HTML.
Next, this story can be laid out into a given rectangle (possibly
retrying several times with updated rectangles as required).
Next, the laid out story can be drawn to a given device.
In the case where the text story cannot be fitted into the given
areas all at once, these two steps can be repeated multiple
times until the text story is completely consumed.
Finally, the text story can be dropped in the usual fashion.
*/
typedef struct fz_story fz_story;
/*
Create a text story using styled html.
Passing a NULL buffer will be treated as an empty document.
Passing a NULL user_css will be treated as an empty CSS string.
A non-NULL archive will allow images etc to be loaded. The
story keeps its own reference, so the caller can drop its
reference after this call.
*/
fz_story *fz_new_story(fz_context *ctx, fz_buffer *buf, const char *user_css, float em, fz_archive *archive);
/*
Retrieve the warnings given from parsing this story.
If there are warnings, this will be returned as a NULL terminated
C string. If there are no warnings, this will return NULL.
These warnings will not be complete until AFTER any DOM manipulations
have been completed.
This function does not need to be called, but once it has been
the DOM is no longer accessible, and any fz_xml pointer
retrieved from fz_story_docment is no longer valid.
*/
const char *fz_story_warnings(fz_context *ctx, fz_story *story);
/*
Place (or continue placing) a story into the supplied rectangle
'where', updating 'filled' with the actual area that was used.
Returns zero if all the content fitted, non-zero if there is
more to fit.
Note, that filled may not be returned as a strict subset of
where, due to padding/margins at the bottom of pages, and
non-wrapping content extending to the right.
Subsequent calls will attempt to place the same section of story
again and again, until the placed story is drawn using fz_draw_story,
whereupon subsequent calls to fz_place_story will attempt to place
the unused remainder of the story.
After this function is called, the DOM is no longer accessible,
and any fz_xml pointer retrieved from fz_story_document is no
longer valid.
*/
int fz_place_story(fz_context *ctx, fz_story *story, fz_rect where, fz_rect *filled);
/*
Draw the placed story to the given device.
This moves the point at which subsequent calls to fz_place_story
will restart placing to the end of what has just been output.
*/
void fz_draw_story(fz_context *ctx, fz_story *story, fz_device *dev, fz_matrix ctm);
/*
Reset the position within the story at which the next layout call
will continue to the start of the story.
*/
void fz_reset_story(fz_context *ctx, fz_story *story);
/*
Drop the html story.
*/
void fz_drop_story(fz_context *ctx, fz_story *story);
/*
Get a borrowed reference to the DOM document pointer for this
story. Do not destroy this reference, it will be destroyed
when the story is laid out.
This only makes sense before the first placement of the story
or retrieval of the warnings. Once either of those things happen
the DOM representation is destroyed.
*/
fz_xml *fz_story_document(fz_context *ctx, fz_story *story);
typedef struct
{
/* The overall depth of this element in the box structure.
* This can be used to compare the relative depths of different
* elements, but shouldn't be relied upon not to change between
* different versions of MuPDF. */
int depth;
/* The heading level of this element. 0 if not a header, or 1-6 for h1-h6. */
int heading;
/* The id for this element. */
const char *id;
/* The href for this element. */
const char *href;
/* The rectangle for this element. */
fz_rect rect;
/* The immediate text for this element. */
const char *text;
/* This indicates whether this opens and/or closes this element.
*
* As we traverse the tree we do a depth first search. In order for
* the caller of fz_story_positions to know whether a given element
* is inside another element, we therefore announce 'start' and 'stop'
* for each element. For instance, with:
*
* <div id="part1">
* <h1>Chapter 1</h1>...
* <h1>Chapter 2</h1>...
* ...
* </div>
* <div id="part2">
* <h1>Chapter 10</h1>...
* <h1>Chapter 11</h1>...
* ...
* </div>
*
* We would announce:
* + id='part1' (open)
* + header=1 "Chapter 1" (open/close)
* + header=1 "Chapter 2" (open/close)
* ...
* + id='part1' (close)
* + id='part2' (open)
* + header=1 "Chapter 10" (open/close)
* + header=1 "Chapter 11" (open/close)
* ...
* + id='part2' (close)
*
* If bit 0 is set, then this 'opens' the element.
* If bit 1 is set, then this 'closes' the element.
*/
int open_close;
/* A count of the number of rectangles that the layout code has split the
* story into so far. After the first layout, this will be 1. If a
* layout is repeated, this number is not incremented. */
int rectangle_num;
} fz_story_element_position;
typedef void (fz_story_position_callback)(fz_context *ctx, void *arg, const fz_story_element_position *);
/*
Enumerate the positions for key blocks in the story.
This will cause the supplied function to be called with details of each
element in the story that is either a header, or has an id.
*/
void fz_story_positions(fz_context *ctx, fz_story *story, fz_story_position_callback *cb, void *arg);
#endif

605
include/mupdf/fitz/stream.h Normal file
View File

@ -0,0 +1,605 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STREAM_H
#define MUPDF_FITZ_STREAM_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
/**
Return true if the named file exists and is readable.
*/
int fz_file_exists(fz_context *ctx, const char *path);
/**
fz_stream is a buffered reader capable of seeking in both
directions.
Streams are reference counted, so references must be dropped
by a call to fz_drop_stream.
Only the data between rp and wp is valid.
*/
typedef struct fz_stream fz_stream;
/**
Open the named file and wrap it in a stream.
filename: Path to a file. On non-Windows machines the filename
should be exactly as it would be passed to fopen(2). On Windows
machines, the path should be UTF-8 encoded so that non-ASCII
characters can be represented. Other platforms do the encoding
as standard anyway (and in most cases, particularly for MacOS
and Linux, the encoding they use is UTF-8 anyway).
*/
fz_stream *fz_open_file(fz_context *ctx, const char *filename);
/**
Open the named file and wrap it in a stream.
Does the same as fz_open_file, but in the event the file
does not open, it will return NULL rather than throw an
exception.
*/
fz_stream *fz_try_open_file(fz_context *ctx, const char *name);
#ifdef _WIN32
/**
Open the named file and wrap it in a stream.
This function is only available when compiling for Win32.
filename: Wide character path to the file as it would be given
to _wfopen().
*/
fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename);
#endif /* _WIN32 */
/**
Open a block of memory as a stream.
data: Pointer to start of data block. Ownership of the data
block is NOT passed in.
len: Number of bytes in data block.
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len);
/**
Open a buffer as a stream.
buf: The buffer to open. Ownership of the buffer is NOT passed
in (this function takes its own reference).
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
/**
Attach a filter to a stream that will store any
characters read from the stream into the supplied buffer.
chain: The underlying stream to leech from.
buf: The buffer into which the read data should be appended.
The buffer will be resized as required.
Returns pointer to newly created stream. May throw exceptions on
failure to allocate.
*/
fz_stream *fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buf);
/**
Increments the reference count for a stream. Returns the same
pointer.
Never throws exceptions.
*/
fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm);
/**
Decrements the reference count for a stream.
When the reference count for the stream hits zero, frees the
storage used for the fz_stream itself, and (usually)
releases the underlying resources that the stream is based upon
(depends on the method used to open the stream initially).
*/
void fz_drop_stream(fz_context *ctx, fz_stream *stm);
/**
return the current reading position within a stream
*/
int64_t fz_tell(fz_context *ctx, fz_stream *stm);
/**
Seek within a stream.
stm: The stream to seek within.
offset: The offset to seek to.
whence: From where the offset is measured (see fseek).
*/
void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
/**
Read from a stream into a given data block.
stm: The stream to read from.
data: The data block to read into.
len: The length of the data block (in bytes).
Returns the number of bytes read. May throw exceptions.
*/
size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len);
/**
Read from a stream discarding data.
stm: The stream to read from.
len: The number of bytes to read.
Returns the number of bytes read. May throw exceptions.
*/
size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len);
/**
Read all of a stream into a buffer.
stm: The stream to read from
initial: Suggested initial size for the buffer.
Returns a buffer created from reading from the stream. May throw
exceptions on failure to allocate.
*/
fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial);
/**
Read all the contents of a file into a buffer.
*/
fz_buffer *fz_read_file(fz_context *ctx, const char *filename);
/**
Read all the contents of a file into a buffer.
Returns NULL if the file does not exist, otherwise
behaves exactly as fz_read_file.
*/
fz_buffer *fz_try_read_file(fz_context *ctx, const char *filename);
/**
fz_read_[u]int(16|24|32|64)(_le)?
Read a 16/32/64 bit signed/unsigned integer from stream,
in big or little-endian byte orders.
Throws an exception if EOF is encountered.
*/
uint16_t fz_read_uint16(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint24(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint32(fz_context *ctx, fz_stream *stm);
uint64_t fz_read_uint64(fz_context *ctx, fz_stream *stm);
uint16_t fz_read_uint16_le(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint24_le(fz_context *ctx, fz_stream *stm);
uint32_t fz_read_uint32_le(fz_context *ctx, fz_stream *stm);
uint64_t fz_read_uint64_le(fz_context *ctx, fz_stream *stm);
int16_t fz_read_int16(fz_context *ctx, fz_stream *stm);
int32_t fz_read_int32(fz_context *ctx, fz_stream *stm);
int64_t fz_read_int64(fz_context *ctx, fz_stream *stm);
int16_t fz_read_int16_le(fz_context *ctx, fz_stream *stm);
int32_t fz_read_int32_le(fz_context *ctx, fz_stream *stm);
int64_t fz_read_int64_le(fz_context *ctx, fz_stream *stm);
float fz_read_float_le(fz_context *ctx, fz_stream *stm);
float fz_read_float(fz_context *ctx, fz_stream *stm);
/**
Read a null terminated string from the stream into
a buffer of a given length. The buffer will be null terminated.
Throws on failure (including the failure to fit the entire
string including the terminator into the buffer).
*/
void fz_read_string(fz_context *ctx, fz_stream *stm, char *buffer, int len);
/**
A function type for use when implementing
fz_streams. The supplied function of this type is called
whenever data is required, and the current buffer is empty.
stm: The stream to operate on.
max: a hint as to the maximum number of bytes that the caller
needs to be ready immediately. Can safely be ignored.
Returns -1 if there is no more data in the stream. Otherwise,
the function should find its internal state using stm->state,
refill its buffer, update stm->rp and stm->wp to point to the
start and end of the new data respectively, and then
"return *stm->rp++".
*/
typedef int (fz_stream_next_fn)(fz_context *ctx, fz_stream *stm, size_t max);
/**
A function type for use when implementing
fz_streams. The supplied function of this type is called
when the stream is dropped, to release the stream specific
state information.
state: The stream state to release.
*/
typedef void (fz_stream_drop_fn)(fz_context *ctx, void *state);
/**
A function type for use when implementing
fz_streams. The supplied function of this type is called when
fz_seek is requested, and the arguments are as defined for
fz_seek.
The stream can find it's private state in stm->state.
*/
typedef void (fz_stream_seek_fn)(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
struct fz_stream
{
int refs;
int error;
int eof;
int progressive;
int64_t pos;
int avail;
int bits;
unsigned char *rp, *wp;
void *state;
fz_stream_next_fn *next;
fz_stream_drop_fn *drop;
fz_stream_seek_fn *seek;
};
/**
Create a new stream object with the given
internal state and function pointers.
state: Internal state (opaque to everything but implementation).
next: Should provide the next set of bytes (up to max) of stream
data. Return the number of bytes read, or EOF when there is no
more data.
drop: Should clean up and free the internal state. May not
throw exceptions.
*/
fz_stream *fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_drop_fn *drop);
/**
Attempt to read a stream into a buffer. If truncated
is NULL behaves as fz_read_all, sets a truncated flag in case of
error.
stm: The stream to read from.
initial: Suggested initial size for the buffer.
truncated: Flag to store success/failure indication in.
worst_case: 0 for unknown, otherwise an upper bound for the
size of the stream.
Returns a buffer created from reading from the stream.
*/
fz_buffer *fz_read_best(fz_context *ctx, fz_stream *stm, size_t initial, int *truncated, size_t worst_case);
/**
Read a line from stream into the buffer until either a
terminating newline or EOF, which it replaces with a null byte
('\0').
Returns buf on success, and NULL when end of file occurs while
no characters have been read.
*/
char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t max);
/**
Skip over a given string in a stream. Return 0 if successfully
skipped, non-zero otherwise. As many characters will be skipped
over as matched in the string.
*/
int fz_skip_string(fz_context *ctx, fz_stream *stm, const char *str);
/**
Skip over whitespace (bytes <= 32) in a stream.
*/
void fz_skip_space(fz_context *ctx, fz_stream *stm);
/**
Ask how many bytes are available immediately from
a given stream.
stm: The stream to read from.
max: A hint for the underlying stream; the maximum number of
bytes that we are sure we will want to read. If you do not know
this number, give 1.
Returns the number of bytes immediately available between the
read and write pointers. This number is guaranteed only to be 0
if we have hit EOF. The number of bytes returned here need have
no relation to max (could be larger, could be smaller).
*/
static inline size_t fz_available(fz_context *ctx, fz_stream *stm, size_t max)
{
size_t len = stm->wp - stm->rp;
int c = EOF;
if (len)
return len;
if (stm->eof)
return 0;
fz_try(ctx)
c = stm->next(ctx, stm, max);
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
{
stm->eof = 1;
return 0;
}
stm->rp--;
return stm->wp - stm->rp;
}
/**
Read the next byte from a stream.
stm: The stream t read from.
Returns -1 for end of stream, or the next byte. May
throw exceptions.
*/
static inline int fz_read_byte(fz_context *ctx, fz_stream *stm)
{
int c = EOF;
if (stm->rp != stm->wp)
return *stm->rp++;
if (stm->eof)
return EOF;
fz_try(ctx)
c = stm->next(ctx, stm, 1);
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
stm->eof = 1;
return c;
}
/**
Peek at the next byte in a stream.
stm: The stream to peek at.
Returns -1 for EOF, or the next byte that will be read.
*/
static inline int fz_peek_byte(fz_context *ctx, fz_stream *stm)
{
int c = EOF;
if (stm->rp != stm->wp)
return *stm->rp;
if (stm->eof)
return EOF;
fz_try(ctx)
{
c = stm->next(ctx, stm, 1);
if (c != EOF)
stm->rp--;
}
fz_catch(ctx)
{
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "read error; treating as end of file");
stm->error = 1;
c = EOF;
}
if (c == EOF)
stm->eof = 1;
return c;
}
/**
Unread the single last byte successfully
read from a stream. Do not call this without having
successfully read a byte.
stm: The stream to operate upon.
*/
static inline void fz_unread_byte(fz_context *ctx FZ_UNUSED, fz_stream *stm)
{
stm->rp--;
}
/**
Query if the stream has reached EOF (during normal bytewise
reading).
See fz_is_eof_bits for the equivalent function for bitwise
reading.
*/
static inline int fz_is_eof(fz_context *ctx, fz_stream *stm)
{
if (stm->rp == stm->wp)
{
if (stm->eof)
return 1;
return fz_peek_byte(ctx, stm) == EOF;
}
return 0;
}
/**
Read the next n bits from a stream (assumed to
be packed most significant bit first).
stm: The stream to read from.
n: The number of bits to read, between 1 and 8*sizeof(int)
inclusive.
Returns -1 for EOF, or the required number of bits.
*/
static inline unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n)
{
int x;
if (n <= stm->avail)
{
stm->avail -= n;
x = (stm->bits >> stm->avail) & ((1 << n) - 1);
}
else
{
x = stm->bits & ((1 << stm->avail) - 1);
n -= stm->avail;
stm->avail = 0;
while (n > 8)
{
x = (x << 8) | fz_read_byte(ctx, stm);
n -= 8;
}
if (n > 0)
{
stm->bits = fz_read_byte(ctx, stm);
stm->avail = 8 - n;
x = (x << n) | (stm->bits >> stm->avail);
}
}
return x;
}
/**
Read the next n bits from a stream (assumed to
be packed least significant bit first).
stm: The stream to read from.
n: The number of bits to read, between 1 and 8*sizeof(int)
inclusive.
Returns (unsigned int)-1 for EOF, or the required number of bits.
*/
static inline unsigned int fz_read_rbits(fz_context *ctx, fz_stream *stm, int n)
{
int x;
if (n <= stm->avail)
{
x = stm->bits & ((1 << n) - 1);
stm->avail -= n;
stm->bits = stm->bits >> n;
}
else
{
unsigned int used = 0;
x = stm->bits & ((1 << stm->avail) - 1);
n -= stm->avail;
used = stm->avail;
stm->avail = 0;
while (n > 8)
{
x = (fz_read_byte(ctx, stm) << used) | x;
n -= 8;
used += 8;
}
if (n > 0)
{
stm->bits = fz_read_byte(ctx, stm);
x = ((stm->bits & ((1 << n) - 1)) << used) | x;
stm->avail = 8 - n;
stm->bits = stm->bits >> n;
}
}
return x;
}
/**
Called after reading bits to tell the stream
that we are about to return to reading bytewise. Resyncs
the stream to whole byte boundaries.
*/
static inline void fz_sync_bits(fz_context *ctx FZ_UNUSED, fz_stream *stm)
{
stm->avail = 0;
}
/**
Query if the stream has reached EOF (during bitwise
reading).
See fz_is_eof for the equivalent function for bytewise
reading.
*/
static inline int fz_is_eof_bits(fz_context *ctx, fz_stream *stm)
{
return fz_is_eof(ctx, stm) && (stm->avail == 0 || stm->bits == EOF);
}
/* Implementation details: subject to change. */
/**
Create a stream from a FILE * that will not be closed
when the stream is dropped.
*/
fz_stream *fz_open_file_ptr_no_close(fz_context *ctx, FILE *file);
#endif

View File

@ -0,0 +1,267 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STRING_H
#define MUPDF_FITZ_STRING_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/* The Unicode character used to incoming character whose value is
* unknown or unrepresentable. */
#define FZ_REPLACEMENT_CHARACTER 0xFFFD
/**
Safe string functions
*/
/**
Return strlen(s), if that is less than maxlen, or maxlen if
there is no null byte ('\0') among the first maxlen bytes.
*/
size_t fz_strnlen(const char *s, size_t maxlen);
/**
Given a pointer to a C string (or a pointer to NULL) break
it at the first occurrence of a delimiter char (from a given
set).
stringp: Pointer to a C string pointer (or NULL). Updated on
exit to point to the first char of the string after the
delimiter that was found. The string pointed to by stringp will
be corrupted by this call (as the found delimiter will be
overwritten by 0).
delim: A C string of acceptable delimiter characters.
Returns a pointer to a C string containing the chars of stringp
up to the first delimiter char (or the end of the string), or
NULL.
*/
char *fz_strsep(char **stringp, const char *delim);
/**
Copy at most n-1 chars of a string into a destination
buffer with null termination, returning the real length of the
initial string (excluding terminator).
dst: Destination buffer, at least n bytes long.
src: C string (non-NULL).
n: Size of dst buffer in bytes.
Returns the length (excluding terminator) of src.
*/
size_t fz_strlcpy(char *dst, const char *src, size_t n);
/**
Concatenate 2 strings, with a maximum length.
dst: pointer to first string in a buffer of n bytes.
src: pointer to string to concatenate.
n: Size (in bytes) of buffer that dst is in.
Returns the real length that a concatenated dst + src would have
been (not including terminator).
*/
size_t fz_strlcat(char *dst, const char *src, size_t n);
/**
Find the start of the first occurrence of the substring needle in haystack.
*/
void *fz_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
/**
extract the directory component from a path.
*/
void fz_dirname(char *dir, const char *path, size_t dirsize);
/**
Find the filename component in a path.
*/
const char *fz_basename(const char *path);
/**
Like fz_decode_uri_component but in-place.
*/
char *fz_urldecode(char *url);
/**
* Return a new string representing the unencoded version of the given URI.
* This decodes all escape sequences except those that would result in a reserved
* character that are part of the URI syntax (; / ? : @ & = + $ , #).
*/
char *fz_decode_uri(fz_context *ctx, const char *s);
/**
* Return a new string representing the unencoded version of the given URI component.
* This decodes all escape sequences!
*/
char *fz_decode_uri_component(fz_context *ctx, const char *s);
/**
* Return a new string representing the provided string encoded as a URI.
*/
char *fz_encode_uri(fz_context *ctx, const char *s);
/**
* Return a new string representing the provided string encoded as an URI component.
* This also encodes the special reserved characters (; / ? : @ & = + $ , #).
*/
char *fz_encode_uri_component(fz_context *ctx, const char *s);
/**
* Return a new string representing the provided string encoded as an URI path name.
* This also encodes the special reserved characters except /.
*/
char *fz_encode_uri_pathname(fz_context *ctx, const char *s);
/**
create output file name using a template.
If the path contains %[0-9]*d, the first such pattern will be
replaced with the page number. If the template does not contain
such a pattern, the page number will be inserted before the
filename extension. If the template does not have a filename
extension, the page number will be added to the end.
*/
void fz_format_output_path(fz_context *ctx, char *path, size_t size, const char *fmt, int page);
/**
rewrite path to the shortest string that names the same path.
Eliminates multiple and trailing slashes, interprets "." and
"..". Overwrites the string in place.
*/
char *fz_cleanname(char *name);
/**
Resolve a path to an absolute file name.
The resolved path buffer must be of at least PATH_MAX size.
*/
char *fz_realpath(const char *path, char *resolved_path);
/**
Case insensitive (ASCII only) string comparison.
*/
int fz_strcasecmp(const char *a, const char *b);
int fz_strncasecmp(const char *a, const char *b, size_t n);
/**
FZ_UTFMAX: Maximum number of bytes in a decoded rune (maximum
length returned by fz_chartorune).
*/
enum { FZ_UTFMAX = 4 };
/**
UTF8 decode a single rune from a sequence of chars.
rune: Pointer to an int to assign the decoded 'rune' to.
str: Pointer to a UTF8 encoded string.
Returns the number of bytes consumed.
*/
int fz_chartorune(int *rune, const char *str);
/**
UTF8 encode a rune to a sequence of chars.
str: Pointer to a place to put the UTF8 encoded character.
rune: Pointer to a 'rune'.
Returns the number of bytes the rune took to output.
*/
int fz_runetochar(char *str, int rune);
/**
Count how many chars are required to represent a rune.
rune: The rune to encode.
Returns the number of bytes required to represent this run in
UTF8.
*/
int fz_runelen(int rune);
/**
Compute the index of a rune in a string.
str: Pointer to beginning of a string.
p: Pointer to a char in str.
Returns the index of the rune pointed to by p in str.
*/
int fz_runeidx(const char *str, const char *p);
/**
Obtain a pointer to the char representing the rune
at a given index.
str: Pointer to beginning of a string.
idx: Index of a rune to return a char pointer to.
Returns a pointer to the char where the desired rune starts,
or NULL if the string ends before the index is reached.
*/
const char *fz_runeptr(const char *str, int idx);
/**
Count how many runes the UTF-8 encoded string
consists of.
s: The UTF-8 encoded, NUL-terminated text string.
Returns the number of runes in the string.
*/
int fz_utflen(const char *s);
/**
Locale-independent decimal to binary conversion. On overflow
return (-)INFINITY and set errno to ERANGE. On underflow return
0 and set errno to ERANGE. Special inputs (case insensitive):
"NAN", "INF" or "INFINITY".
*/
float fz_strtof(const char *s, char **es);
int fz_grisu(float f, char *s, int *exp);
/**
Check and parse string into page ranges:
/,?(-?\d+|N)(-(-?\d+|N))?/
*/
int fz_is_page_range(fz_context *ctx, const char *s);
const char *fz_parse_page_range(fz_context *ctx, const char *s, int *a, int *b, int n);
/**
Unicode aware tolower and toupper functions.
*/
int fz_tolower(int c);
int fz_toupper(int c);
#endif

View File

@ -0,0 +1,363 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_STRUCTURED_TEXT_H
#define MUPDF_FITZ_STRUCTURED_TEXT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/types.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/pool.h"
/**
Simple text layout (for use with annotation editing primarily).
*/
typedef struct fz_layout_char
{
float x, advance;
const char *p; /* location in source text of character */
struct fz_layout_char *next;
} fz_layout_char;
typedef struct fz_layout_line
{
float x, y, font_size;
const char *p; /* location in source text of start of line */
fz_layout_char *text;
struct fz_layout_line *next;
} fz_layout_line;
typedef struct
{
fz_pool *pool;
fz_matrix matrix;
fz_matrix inv_matrix;
fz_layout_line *head, **tailp;
fz_layout_char **text_tailp;
} fz_layout_block;
/**
Create a new layout block, with new allocation pool, zero
matrices, and initialise linked pointers.
*/
fz_layout_block *fz_new_layout(fz_context *ctx);
/**
Drop layout block. Free the pool, and linked blocks.
Never throws exceptions.
*/
void fz_drop_layout(fz_context *ctx, fz_layout_block *block);
/**
Add a new line to the end of the layout block.
*/
void fz_add_layout_line(fz_context *ctx, fz_layout_block *block, float x, float y, float h, const char *p);
/**
Add a new char to the line at the end of the layout block.
*/
void fz_add_layout_char(fz_context *ctx, fz_layout_block *block, float x, float w, const char *p);
/**
Text extraction device: Used for searching, format conversion etc.
(In development - Subject to change in future versions)
*/
typedef struct fz_stext_char fz_stext_char;
typedef struct fz_stext_line fz_stext_line;
typedef struct fz_stext_block fz_stext_block;
/**
FZ_STEXT_PRESERVE_LIGATURES: If this option is activated
ligatures are passed through to the application in their
original form. If this option is deactivated ligatures are
expanded into their constituent parts, e.g. the ligature ffi is
expanded into three separate characters f, f and i.
FZ_STEXT_PRESERVE_WHITESPACE: If this option is activated
whitespace is passed through to the application in its original
form. If this option is deactivated any type of horizontal
whitespace (including horizontal tabs) will be replaced with
space characters of variable width.
FZ_STEXT_PRESERVE_IMAGES: If this option is set, then images
will be stored in the structured text structure. The default is
to ignore all images.
FZ_STEXT_INHIBIT_SPACES: If this option is set, we will not try
to add missing space characters where there are large gaps
between characters.
FZ_STEXT_DEHYPHENATE: If this option is set, hyphens at the
end of a line will be removed and the lines will be merged.
FZ_STEXT_PRESERVE_SPANS: If this option is set, spans on the same line
will not be merged. Each line will thus be a span of text with the same
font, colour, and size.
FZ_STEXT_MEDIABOX_CLIP: If this option is set, characters entirely
outside each page's mediabox will be ignored.
*/
enum
{
FZ_STEXT_PRESERVE_LIGATURES = 1,
FZ_STEXT_PRESERVE_WHITESPACE = 2,
FZ_STEXT_PRESERVE_IMAGES = 4,
FZ_STEXT_INHIBIT_SPACES = 8,
FZ_STEXT_DEHYPHENATE = 16,
FZ_STEXT_PRESERVE_SPANS = 32,
FZ_STEXT_MEDIABOX_CLIP = 64,
};
/**
A text page is a list of blocks, together with an overall
bounding box.
*/
typedef struct
{
fz_pool *pool;
fz_rect mediabox;
fz_stext_block *first_block, *last_block;
} fz_stext_page;
enum
{
FZ_STEXT_BLOCK_TEXT = 0,
FZ_STEXT_BLOCK_IMAGE = 1
};
/**
A text block is a list of lines of text (typically a paragraph),
or an image.
*/
struct fz_stext_block
{
int type;
fz_rect bbox;
union {
struct { fz_stext_line *first_line, *last_line; } t;
struct { fz_matrix transform; fz_image *image; } i;
} u;
fz_stext_block *prev, *next;
};
/**
A text line is a list of characters that share a common baseline.
*/
struct fz_stext_line
{
int wmode; /* 0 for horizontal, 1 for vertical */
fz_point dir; /* normalized direction of baseline */
fz_rect bbox;
fz_stext_char *first_char, *last_char;
fz_stext_line *prev, *next;
};
/**
A text char is a unicode character, the style in which is
appears, and the point at which it is positioned.
*/
struct fz_stext_char
{
int c;
int color; /* sRGB hex color */
fz_point origin;
fz_quad quad;
float size;
fz_font *font;
fz_stext_char *next;
};
FZ_DATA extern const char *fz_stext_options_usage;
/**
Create an empty text page.
The text page is filled out by the text device to contain the
blocks and lines of text on the page.
mediabox: optional mediabox information.
*/
fz_stext_page *fz_new_stext_page(fz_context *ctx, fz_rect mediabox);
void fz_drop_stext_page(fz_context *ctx, fz_stext_page *page);
/**
Output structured text to a file in HTML (visual) format.
*/
void fz_print_stext_page_as_html(fz_context *ctx, fz_output *out, fz_stext_page *page, int id);
void fz_print_stext_header_as_html(fz_context *ctx, fz_output *out);
void fz_print_stext_trailer_as_html(fz_context *ctx, fz_output *out);
/**
Output structured text to a file in XHTML (semantic) format.
*/
void fz_print_stext_page_as_xhtml(fz_context *ctx, fz_output *out, fz_stext_page *page, int id);
void fz_print_stext_header_as_xhtml(fz_context *ctx, fz_output *out);
void fz_print_stext_trailer_as_xhtml(fz_context *ctx, fz_output *out);
/**
Output structured text to a file in XML format.
*/
void fz_print_stext_page_as_xml(fz_context *ctx, fz_output *out, fz_stext_page *page, int id);
/**
Output structured text to a file in JSON format.
*/
void fz_print_stext_page_as_json(fz_context *ctx, fz_output *out, fz_stext_page *page, float scale);
/**
Output structured text to a file in plain-text UTF-8 format.
*/
void fz_print_stext_page_as_text(fz_context *ctx, fz_output *out, fz_stext_page *page);
/**
Search for occurrence of 'needle' in text page.
Return the number of hits and store hit quads in the passed in
array.
NOTE: This is an experimental interface and subject to change
without notice.
*/
int fz_search_stext_page(fz_context *ctx, fz_stext_page *text, const char *needle, int *hit_mark, fz_quad *hit_bbox, int hit_max);
/**
Return a list of quads to highlight lines inside the selection
points.
*/
int fz_highlight_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, fz_quad *quads, int max_quads);
enum
{
FZ_SELECT_CHARS,
FZ_SELECT_WORDS,
FZ_SELECT_LINES,
};
fz_quad fz_snap_selection(fz_context *ctx, fz_stext_page *page, fz_point *ap, fz_point *bp, int mode);
/**
Return a newly allocated UTF-8 string with the text for a given
selection.
crlf: If true, write "\r\n" style line endings (otherwise "\n"
only).
*/
char *fz_copy_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, int crlf);
/**
Return a newly allocated UTF-8 string with the text for a given
selection rectangle.
crlf: If true, write "\r\n" style line endings (otherwise "\n"
only).
*/
char *fz_copy_rectangle(fz_context *ctx, fz_stext_page *page, fz_rect area, int crlf);
/**
Options for creating a pixmap and draw device.
*/
typedef struct
{
int flags;
float scale;
} fz_stext_options;
/**
Parse stext device options from a comma separated key-value
string.
*/
fz_stext_options *fz_parse_stext_options(fz_context *ctx, fz_stext_options *opts, const char *string);
/**
Create a device to extract the text on a page.
Gather the text on a page into blocks and lines.
The reading order is taken from the order the text is drawn in
the source file, so may not be accurate.
page: The text page to which content should be added. This will
usually be a newly created (empty) text page, but it can be one
containing data already (for example when merging multiple
pages, or watermarking).
options: Options to configure the stext device.
*/
fz_device *fz_new_stext_device(fz_context *ctx, fz_stext_page *page, const fz_stext_options *options);
/**
Create a device to OCR the text on the page.
Renders the page internally to a bitmap that is then OCRd. Text
is then forwarded onto the target device.
target: The target device to receive the OCRd text.
ctm: The transform to apply to the mediabox to get the size for
the rendered page image. Also used to calculate the resolution
for the page image. In general, this will be the same as the CTM
that you pass to fz_run_page (or fz_run_display_list) to feed
this device.
mediabox: The mediabox (in points). Combined with the CTM to get
the bounds of the pixmap used internally for the rendered page
image.
with_list: If with_list is false, then all non-text operations
are forwarded instantly to the target device. This results in
the target device seeing all NON-text operations, followed by
all the text operations (derived from OCR).
If with_list is true, then all the marking operations are
collated into a display list which is then replayed to the
target device at the end.
language: NULL (for "eng"), or a pointer to a string to describe
the languages/scripts that should be used for OCR (e.g.
"eng,ara").
datadir: NULL (for ""), or a pointer to a path string otherwise
provided to Tesseract in the TESSDATA_PREFIX environment variable.
progress: NULL, or function to be called periodically to indicate
progress. Return 0 to continue, or 1 to cancel. progress_arg is
returned as the void *. The int is a value between 0 and 100 to
indicate progress.
progress_arg: A void * value to be parrotted back to the progress
function.
*/
fz_device *fz_new_ocr_device(fz_context *ctx, fz_device *target, fz_matrix ctm, fz_rect mediabox, int with_list, const char *language,
const char *datadir, int (*progress)(fz_context *, void *, int), void *progress_arg);
fz_document *fz_open_reflowed_document(fz_context *ctx, fz_document *underdoc, const fz_stext_options *opts);
#endif

460
include/mupdf/fitz/system.h Normal file
View File

@ -0,0 +1,460 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_SYSTEM_H
#define MUPDF_FITZ_SYSTEM_H
/* Turn on valgrind pacification in debug builds. */
#ifndef NDEBUG
#ifndef PACIFY_VALGRIND
#define PACIFY_VALGRIND
#endif
#endif
/**
Include the standard libc headers.
*/
#include <stddef.h> /* needed for size_t */
#include <stdarg.h> /* needed for va_list vararg functions */
#include <setjmp.h> /* needed for the try/catch macros */
#include <stdio.h> /* useful for debug printfs */
#include "export.h"
#if defined(_MSC_VER) && (_MSC_VER < 1700) /* MSVC older than VS2012 */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807i64
#endif
#else
#include <stdint.h> /* needed for int64_t */
#endif
#include "mupdf/memento.h"
#include "mupdf/fitz/track-usage.h"
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
#define FZ_PI 3.14159265f
#define FZ_RADIAN 57.2957795f
#define FZ_DEGREE 0.017453292f
#define FZ_SQRT2 1.41421356f
#define FZ_LN2 0.69314718f
/**
Spot architectures where we have optimisations.
*/
#if defined(__arm__) || defined(__thumb__)
#ifndef ARCH_ARM
#define ARCH_ARM
#endif
#endif
/**
Some differences in libc can be smoothed over
*/
#ifndef __STRICT_ANSI__
#if defined(__APPLE__)
#ifndef HAVE_SIGSETJMP
#define HAVE_SIGSETJMP 1
#endif
#elif defined(__unix)
#ifndef __EMSCRIPTEN__
#ifndef HAVE_SIGSETJMP
#define HAVE_SIGSETJMP 1
#endif
#endif
#endif
#endif
#ifndef HAVE_SIGSETJMP
#define HAVE_SIGSETJMP 0
#endif
/**
Where possible (i.e. on platforms on which they are provided),
use sigsetjmp/siglongjmp in preference to setjmp/longjmp. We
don't alter signal handlers within mupdf, so there is no need
for us to store/restore them - hence we use the non-restoring
variants. This makes a large speed difference on MacOSX (and
probably other platforms too.
*/
#if HAVE_SIGSETJMP
#define fz_setjmp(BUF) sigsetjmp(BUF, 0)
#define fz_longjmp(BUF,VAL) siglongjmp(BUF, VAL)
typedef sigjmp_buf fz_jmp_buf;
#else
#define fz_setjmp(BUF) setjmp(BUF)
#define fz_longjmp(BUF,VAL) longjmp(BUF,VAL)
typedef jmp_buf fz_jmp_buf;
#endif
/* these constants mirror the corresponding macros in stdio.h */
#ifndef EOF
#define EOF (-1)
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifdef _MSC_VER /* Microsoft Visual C */
/* MSVC up to VS2012 */
#if _MSC_VER < 1800
static __inline int signbit(double x)
{
union
{
double d;
__int64 i;
} u;
u.d = x;
return (int)(u.i>>63);
}
#endif
#pragma warning( disable: 4244 ) /* conversion from X to Y, possible loss of data */
#pragma warning( disable: 4701 ) /* Potentially uninitialized local variable 'name' used */
#pragma warning( disable: 4996 ) /* 'function': was declared deprecated */
#if _MSC_VER <= 1700 /* MSVC 2012 */
#define isnan(x) _isnan(x)
#define isinf(x) (!_finite(x))
#endif
#if _MSC_VER <= 1920 /* MSVC 2019 */
#define hypotf _hypotf
#endif
#define atoll _atoi64
#endif
#ifdef _WIN32
char *fz_utf8_from_wchar(const wchar_t *s);
wchar_t *fz_wchar_from_utf8(const char *s);
/* really a FILE* but we don't want to include stdio.h here */
void *fz_fopen_utf8(const char *name, const char *mode);
int fz_remove_utf8(const char *name);
char **fz_argv_from_wargv(int argc, wchar_t **wargv);
void fz_free_argv(int argc, char **argv);
#endif
/* Cope with systems (such as Windows) with no S_ISDIR */
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode) & S_IFDIR)
#endif
int64_t fz_stat_ctime(const char *path);
int64_t fz_stat_mtime(const char *path);
/* inline is standard in C++. For some compilers we can enable it within
* C too. Some compilers think they know better than we do about when
* to actually honour inline (particularly for large functions); use
* fz_forceinline to kick them into really inlining. */
#ifndef __cplusplus
#if defined (__STDC_VERSION_) && (__STDC_VERSION__ >= 199901L) /* C99 */
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) /* MSVC 9 or newer */
#define inline __inline
#define fz_forceinline __forceinline
#elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC 3 or newer */
#define inline __inline
#else /* Unknown or ancient */
#define inline
#endif
#endif
#ifndef fz_forceinline
#define fz_forceinline inline
#endif
/* restrict is standard in C99, but not in all C++ compilers. */
#if defined (__STDC_VERSION_) && (__STDC_VERSION__ >= 199901L) /* C99 */
#define FZ_RESTRICT restrict
#elif defined(_MSC_VER) && (_MSC_VER >= 1600) /* MSVC 10 or newer */
#define FZ_RESTRICT __restrict
#elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC 3 or newer */
#define FZ_RESTRICT __restrict
#else /* Unknown or ancient */
#define FZ_RESTRICT
#endif
/* noreturn is a GCC extension */
#ifdef __GNUC__
#define FZ_NORETURN __attribute__((noreturn))
#else
#ifdef _MSC_VER
#define FZ_NORETURN __declspec(noreturn)
#else
#define FZ_NORETURN
#endif
#endif
/* Flag unused parameters, for use with 'static inline' functions in
* headers. */
#if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define FZ_UNUSED __attribute__((__unused__))
#else
#define FZ_UNUSED
#endif
/* GCC can do type checking of printf strings */
#ifdef __printflike
#define FZ_PRINTFLIKE(F,V) __printflike(F,V)
#else
#if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define FZ_PRINTFLIKE(F,V) __attribute__((__format__ (__printf__, F, V)))
#else
#define FZ_PRINTFLIKE(F,V)
#endif
#endif
/* ARM assembly specific defines */
#ifdef ARCH_ARM
/* If we're compiling as thumb code, then we need to tell the compiler
* to enter and exit ARM mode around our assembly sections. If we move
* the ARM functions to a separate file and arrange for it to be
* compiled without thumb mode, we can save some time on entry.
*/
/* This is slightly suboptimal; __thumb__ and __thumb2__ become defined
* and undefined by #pragma arm/#pragma thumb - but we can't define a
* macro to track that. */
#if defined(__thumb__) || defined(__thumb2__)
#define ENTER_ARM ".balign 4\nmov r12,pc\nbx r12\n0:.arm\n"
#define ENTER_THUMB "9:.thumb\n"
#else
#define ENTER_ARM
#define ENTER_THUMB
#endif
#endif
/* Memory block alignment */
/* Most architectures are happy with blocks being aligned to the size
* of void *'s. Some (notably sparc) are not.
*
* Some architectures (notably amd64) are happy for pointers to be 32bit
* aligned even on 64bit systems. By making use of this we can save lots
* of memory in data structures (notably the display list).
*
* We attempt to cope with these vagaries via the following definitions.
*/
/* All blocks allocated by mupdf's allocators are expected to be
* returned aligned to FZ_MEMORY_BLOCK_ALIGN_MOD. This is sizeof(void *)
* unless overwritten by a predefinition, or by a specific architecture
* being detected. */
#ifndef FZ_MEMORY_BLOCK_ALIGN_MOD
#if defined(sparc) || defined(__sparc) || defined(__sparc__)
#define FZ_MEMORY_BLOCK_ALIGN_MOD 8
#else
#define FZ_MEMORY_BLOCK_ALIGN_MOD sizeof(void *)
#endif
#endif
/* MuPDF will ensure that its use of pointers in packed structures
* (such as the display list) will be aligned to FZ_POINTER_ALIGN_MOD.
* This is the same as FZ_MEMORY_BLOCK_ALIGN_MOD unless overridden by
* a predefinition, or by a specific architecture being detected. */
#ifndef FZ_POINTER_ALIGN_MOD
#if defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__)
#define FZ_POINTER_ALIGN_MOD 4
#else
#define FZ_POINTER_ALIGN_MOD FZ_MEMORY_BLOCK_ALIGN_MOD
#endif
#endif
#ifdef CLUSTER
/* Include this first so our defines don't clash with the system
* definitions */
#include <math.h>
/**
* Trig functions
*/
static float
my_atan_table[258] =
{
0.0000000000f, 0.00390623013f,0.00781234106f,0.0117182136f,
0.0156237286f, 0.0195287670f, 0.0234332099f, 0.0273369383f,
0.0312398334f, 0.0351417768f, 0.0390426500f, 0.0429423347f,
0.0468407129f, 0.0507376669f, 0.0546330792f, 0.0585268326f,
0.0624188100f, 0.0663088949f, 0.0701969711f, 0.0740829225f,
0.0779666338f, 0.0818479898f, 0.0857268758f, 0.0896031775f,
0.0934767812f, 0.0973475735f, 0.1012154420f, 0.1050802730f,
0.1089419570f, 0.1128003810f, 0.1166554350f, 0.1205070100f,
0.1243549950f, 0.1281992810f, 0.1320397620f, 0.1358763280f,
0.1397088740f, 0.1435372940f, 0.1473614810f, 0.1511813320f,
0.1549967420f, 0.1588076080f, 0.1626138290f, 0.1664153010f,
0.1702119250f, 0.1740036010f, 0.1777902290f, 0.1815717110f,
0.1853479500f, 0.1891188490f, 0.1928843120f, 0.1966442450f,
0.2003985540f, 0.2041471450f, 0.2078899270f, 0.2116268090f,
0.2153577000f, 0.2190825110f, 0.2228011540f, 0.2265135410f,
0.2302195870f, 0.2339192060f, 0.2376123140f, 0.2412988270f,
0.2449786630f, 0.2486517410f, 0.2523179810f, 0.2559773030f,
0.2596296290f, 0.2632748830f, 0.2669129880f, 0.2705438680f,
0.2741674510f, 0.2777836630f, 0.2813924330f, 0.2849936890f,
0.2885873620f, 0.2921733830f, 0.2957516860f, 0.2993222020f,
0.3028848680f, 0.3064396190f, 0.3099863910f, 0.3135251230f,
0.3170557530f, 0.3205782220f, 0.3240924700f, 0.3275984410f,
0.3310960770f, 0.3345853220f, 0.3380661230f, 0.3415384250f,
0.3450021770f, 0.3484573270f, 0.3519038250f, 0.3553416220f,
0.3587706700f, 0.3621909220f, 0.3656023320f, 0.3690048540f,
0.3723984470f, 0.3757830650f, 0.3791586690f, 0.3825252170f,
0.3858826690f, 0.3892309880f, 0.3925701350f, 0.3959000740f,
0.3992207700f, 0.4025321870f, 0.4058342930f, 0.4091270550f,
0.4124104420f, 0.4156844220f, 0.4189489670f, 0.4222040480f,
0.4254496370f, 0.4286857080f, 0.4319122350f, 0.4351291940f,
0.4383365600f, 0.4415343100f, 0.4447224240f, 0.4479008790f,
0.4510696560f, 0.4542287350f, 0.4573780990f, 0.4605177290f,
0.4636476090f, 0.4667677240f, 0.4698780580f, 0.4729785980f,
0.4760693300f, 0.4791502430f, 0.4822213240f, 0.4852825630f,
0.4883339510f, 0.4913754780f, 0.4944071350f, 0.4974289160f,
0.5004408130f, 0.5034428210f, 0.5064349340f, 0.5094171490f,
0.5123894600f, 0.5153518660f, 0.5183043630f, 0.5212469510f,
0.5241796290f, 0.5271023950f, 0.5300152510f, 0.5329181980f,
0.5358112380f, 0.5386943730f, 0.5415676050f, 0.5444309400f,
0.5472843810f, 0.5501279330f, 0.5529616020f, 0.5557853940f,
0.5585993150f, 0.5614033740f, 0.5641975770f, 0.5669819340f,
0.5697564530f, 0.5725211450f, 0.5752760180f, 0.5780210840f,
0.5807563530f, 0.5834818390f, 0.5861975510f, 0.5889035040f,
0.5915997100f, 0.5942861830f, 0.5969629370f, 0.5996299860f,
0.6022873460f, 0.6049350310f, 0.6075730580f, 0.6102014430f,
0.6128202020f, 0.6154293530f, 0.6180289120f, 0.6206188990f,
0.6231993300f, 0.6257702250f, 0.6283316020f, 0.6308834820f,
0.6334258830f, 0.6359588250f, 0.6384823300f, 0.6409964180f,
0.6435011090f, 0.6459964250f, 0.6484823880f, 0.6509590190f,
0.6534263410f, 0.6558843770f, 0.6583331480f, 0.6607726790f,
0.6632029930f, 0.6656241120f, 0.6680360620f, 0.6704388650f,
0.6728325470f, 0.6752171330f, 0.6775926450f, 0.6799591110f,
0.6823165550f, 0.6846650020f, 0.6870044780f, 0.6893350100f,
0.6916566220f, 0.6939693410f, 0.6962731940f, 0.6985682070f,
0.7008544080f, 0.7031318220f, 0.7054004770f, 0.7076604000f,
0.7099116190f, 0.7121541600f, 0.7143880520f, 0.7166133230f,
0.7188300000f, 0.7210381110f, 0.7232376840f, 0.7254287490f,
0.7276113330f, 0.7297854640f, 0.7319511710f, 0.7341084830f,
0.7362574290f, 0.7383980370f, 0.7405303370f, 0.7426543560f,
0.7447701260f, 0.7468776740f, 0.7489770290f, 0.7510682220f,
0.7531512810f, 0.7552262360f, 0.7572931160f, 0.7593519510f,
0.7614027700f, 0.7634456020f, 0.7654804790f, 0.7675074280f,
0.7695264800f, 0.7715376650f, 0.7735410110f, 0.7755365500f,
0.7775243100f, 0.7795043220f, 0.7814766150f, 0.7834412190f,
0.7853981630f, 0.7853981630f /* Extended by 1 for interpolation */
};
static inline float my_sinf(float x)
{
float x2, xn;
int i;
/* Map x into the -PI to PI range. We could do this using:
* x = fmodf(x, 2.0f * FZ_PI);
* but that's C99, and seems to misbehave with negative numbers
* on some platforms. */
x -= FZ_PI;
i = x / (2.0f * FZ_PI);
x -= i * 2.0f * FZ_PI;
if (x < 0.0f)
x += 2.0f * FZ_PI;
x -= FZ_PI;
if (x <= -FZ_PI / 2.0f)
x = -FZ_PI - x;
else if (x >= FZ_PI / 2.0f)
x = FZ_PI-x;
x2 = x * x;
xn = x * x2 / 6.0f;
x -= xn;
xn *= x2 / 20.0f;
x += xn;
xn *= x2 / 42.0f;
x -= xn;
xn *= x2 / 72.0f;
x += xn;
if (x > 1)
x = 1;
else if (x < -1)
x = -1;
return x;
}
static inline float my_atan2f(float o, float a)
{
int negate = 0, flip = 0, i;
float r, s;
if (o == 0.0f)
{
if (a > 0)
return 0.0f;
else
return FZ_PI;
}
if (o < 0)
o = -o, negate = 1;
if (a < 0)
a = -a, flip = 1;
if (o < a)
i = 65536.0f * o / a + 0.5f;
else
i = 65536.0f * a / o + 0.5f;
r = my_atan_table[i >> 8];
s = my_atan_table[(i >> 8) + 1];
r += (s - r) * (i & 255) / 256.0f;
if (o >= a)
r = FZ_PI / 2.0f - r;
if (flip)
r = FZ_PI - r;
if (negate)
r = -r;
return r;
}
#define sinf(x) my_sinf(x)
#define cosf(x) my_sinf(FZ_PI / 2.0f + (x))
#define atan2f(x,y) my_atan2f((x),(y))
#endif
static inline int fz_is_pow2(int a)
{
return (a != 0) && (a & (a-1)) == 0;
}
#endif

205
include/mupdf/fitz/text.h Normal file
View File

@ -0,0 +1,205 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_TEXT_H
#define MUPDF_FITZ_TEXT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/path.h"
#include "mupdf/fitz/bidi.h"
/**
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
{
float x, y;
int gid; /* -1 for one gid to many ucs mappings */
int ucs; /* -1 for one ucs to many gid mappings */
} fz_text_item;
#define FZ_LANG_TAG2(c1,c2) ((c1-'a'+1) + ((c2-'a'+1)*27))
#define FZ_LANG_TAG3(c1,c2,c3) ((c1-'a'+1) + ((c2-'a'+1)*27) + ((c3-'a'+1)*27*27))
typedef enum
{
FZ_LANG_UNSET = 0,
FZ_LANG_ur = FZ_LANG_TAG2('u','r'),
FZ_LANG_urd = FZ_LANG_TAG3('u','r','d'),
FZ_LANG_ko = FZ_LANG_TAG2('k','o'),
FZ_LANG_ja = FZ_LANG_TAG2('j','a'),
FZ_LANG_zh = FZ_LANG_TAG2('z','h'),
FZ_LANG_zh_Hans = FZ_LANG_TAG3('z','h','s'),
FZ_LANG_zh_Hant = FZ_LANG_TAG3('z','h','t'),
} fz_text_language;
typedef struct fz_text_span
{
fz_font *font;
fz_matrix trm;
unsigned wmode : 1; /* 0 horizontal, 1 vertical */
unsigned bidi_level : 7; /* The bidirectional level of text */
unsigned markup_dir : 2; /* The direction of text as marked in the original document */
unsigned language : 15; /* The language as marked in the original document */
int len, cap;
fz_text_item *items;
struct fz_text_span *next;
} fz_text_span;
typedef struct
{
int refs;
fz_text_span *head, *tail;
} fz_text;
/**
Create a new empty fz_text object.
Throws exception on failure to allocate.
*/
fz_text *fz_new_text(fz_context *ctx);
/**
Increment the reference count for the text object. The same
pointer is returned.
Never throws exceptions.
*/
fz_text *fz_keep_text(fz_context *ctx, const fz_text *text);
/**
Decrement the reference count for the text object. When the
reference count hits zero, the text object is freed.
Never throws exceptions.
*/
void fz_drop_text(fz_context *ctx, const fz_text *text);
/**
Add a glyph/unicode value to a text object.
text: Text object to add to.
font: The font the glyph should be added in.
trm: The transform to use for the glyph.
glyph: The glyph id to add.
unicode: The unicode character for the glyph.
wmode: 1 for vertical mode, 0 for horizontal.
bidi_level: The bidirectional level for this glyph.
markup_dir: The direction of the text as specified in the
markup.
language: The language in use (if known, 0 otherwise)
(e.g. FZ_LANG_zh_Hans).
Throws exception on failure to allocate.
*/
void fz_show_glyph(fz_context *ctx, fz_text *text, fz_font *font, fz_matrix trm, int glyph, int unicode, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language);
/**
Add a UTF8 string to a text object.
text: Text object to add to.
font: The font the string should be added in.
trm: The transform to use.
s: The utf-8 string to add.
wmode: 1 for vertical mode, 0 for horizontal.
bidi_level: The bidirectional level for this glyph.
markup_dir: The direction of the text as specified in the markup.
language: The language in use (if known, 0 otherwise)
(e.g. FZ_LANG_zh_Hans).
Returns the transform updated with the advance width of the
string.
*/
fz_matrix fz_show_string(fz_context *ctx, fz_text *text, fz_font *font, fz_matrix trm, const char *s, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language);
/**
Measure the advance width of a UTF8 string should it be added to a text object.
This uses the same layout algorithms as fz_show_string, and can be used
to calculate text alignment adjustments.
*/
fz_matrix
fz_measure_string(fz_context *ctx, fz_font *user_font, fz_matrix trm, const char *s, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language);
/**
Find the bounds of a given text object.
text: The text object to find the bounds of.
stroke: Pointer to the stroke attributes (for stroked
text), or NULL (for filled text).
ctm: The matrix in use.
r: pointer to storage for the bounds.
Returns a pointer to r, which is updated to contain the
bounding box for the text object.
*/
fz_rect fz_bound_text(fz_context *ctx, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm);
/**
Convert ISO 639 (639-{1,2,3,5}) language specification
strings losslessly to a 15 bit fz_text_language code.
No validation is carried out. Obviously invalid (out
of spec) codes will be mapped to FZ_LANG_UNSET, but
well-formed (but undefined) codes will be blithely
accepted.
*/
fz_text_language fz_text_language_from_string(const char *str);
/**
Recover ISO 639 (639-{1,2,3,5}) language specification
strings losslessly from a 15 bit fz_text_language code.
No validation is carried out. See note above.
*/
char *fz_string_from_text_language(char str[8], fz_text_language lang);
#endif

View File

@ -0,0 +1,57 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef TRACK_USAGE_H
#define TRACK_USAGE_H
#ifdef TRACK_USAGE
typedef struct track_usage_data {
int count;
const char *function;
int line;
const char *desc;
struct track_usage_data *next;
} track_usage_data;
#define TRACK_LABEL(A) \
do { \
static track_usage_data USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, A);\
} while (0)
#define TRACK_FN() \
do { \
static track_usage_data USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, __FUNCTION__);\
} while (0)
void track_usage(track_usage_data *data, const char *function, int line, const char *desc);
#else
#define TRACK_LABEL(A) do { } while (0)
#define TRACK_FN() do { } while (0)
#endif
#endif

View File

@ -0,0 +1,76 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_TRANSITION_H
#define MUPDF_FITZ_TRANSITION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/pixmap.h"
/* Transition support */
enum {
FZ_TRANSITION_NONE = 0, /* aka 'R' or 'REPLACE' */
FZ_TRANSITION_SPLIT,
FZ_TRANSITION_BLINDS,
FZ_TRANSITION_BOX,
FZ_TRANSITION_WIPE,
FZ_TRANSITION_DISSOLVE,
FZ_TRANSITION_GLITTER,
FZ_TRANSITION_FLY,
FZ_TRANSITION_PUSH,
FZ_TRANSITION_COVER,
FZ_TRANSITION_UNCOVER,
FZ_TRANSITION_FADE
};
typedef struct
{
int type;
float duration; /* Effect duration (seconds) */
/* Parameters controlling the effect */
int vertical; /* 0 or 1 */
int outwards; /* 0 or 1 */
int direction; /* Degrees */
/* Potentially more to come */
/* State variables for use of the transition code */
int state0;
int state1;
} fz_transition;
/**
Generate a frame of a transition.
tpix: Target pixmap
opix: Old pixmap
npix: New pixmap
time: Position within the transition (0 to 256)
trans: Transition details
Returns 1 if successfully generated a frame.
Note: Pixmaps must include alpha.
*/
int fz_generate_transition(fz_context *ctx, fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time, fz_transition *trans);
#endif

62
include/mupdf/fitz/tree.h Normal file
View File

@ -0,0 +1,62 @@
// Copyright (C) 2004-2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_TREE_H
#define MUPDF_FITZ_TREE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
/**
AA-tree to look up things by strings.
*/
typedef struct fz_tree fz_tree;
/**
Look for the value of a node in the tree with the given key.
Simple pointer equivalence is used for key.
Returns NULL for no match.
*/
void *fz_tree_lookup(fz_context *ctx, fz_tree *node, const char *key);
/**
Insert a new key/value pair and rebalance the tree.
Return the new root of the tree after inserting and rebalancing.
May be called with a NULL root to create a new tree.
No data is copied into the tree structure; key and value are
merely kept as pointers.
*/
fz_tree *fz_tree_insert(fz_context *ctx, fz_tree *root, const char *key, void *value);
/**
Drop the tree.
The storage used by the tree is freed, and each value has
dropfunc called on it.
*/
void fz_drop_tree(fz_context *ctx, fz_tree *node, void (*dropfunc)(fz_context *ctx, void *value));
#endif

View File

@ -0,0 +1,41 @@
// Copyright (C) 2021 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_TYPES_H
#define MUPDF_FITZ_TYPES_H
typedef struct fz_document fz_document;
/**
Locations within the document are referred to in terms of
chapter and page, rather than just a page number. For some
documents (such as epub documents with large numbers of pages
broken into many chapters) this can make navigation much faster
as only the required chapter needs to be decoded at a time.
*/
typedef struct
{
int chapter;
int page;
} fz_location;
#endif

151
include/mupdf/fitz/util.h Normal file
View File

@ -0,0 +1,151 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_UTIL_H
#define MUPDF_FITZ_UTIL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/structured-text.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/xml.h"
#include "mupdf/fitz/archive.h"
#include "mupdf/fitz/display-list.h"
/**
Create a display list.
Ownership of the display list is returned to the caller.
*/
fz_display_list *fz_new_display_list_from_page(fz_context *ctx, fz_page *page);
fz_display_list *fz_new_display_list_from_page_number(fz_context *ctx, fz_document *doc, int number);
/**
Create a display list from page contents (no annotations).
Ownership of the display list is returned to the caller.
*/
fz_display_list *fz_new_display_list_from_page_contents(fz_context *ctx, fz_page *page);
/**
Render the page to a pixmap using the transform and colorspace.
Ownership of the pixmap is returned to the caller.
*/
fz_pixmap *fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, fz_matrix ctm, fz_colorspace *cs, int alpha);
fz_pixmap *fz_new_pixmap_from_page(fz_context *ctx, fz_page *page, fz_matrix ctm, fz_colorspace *cs, int alpha);
fz_pixmap *fz_new_pixmap_from_page_number(fz_context *ctx, fz_document *doc, int number, fz_matrix ctm, fz_colorspace *cs, int alpha);
/**
Render the page contents without annotations.
Ownership of the pixmap is returned to the caller.
*/
fz_pixmap *fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, fz_matrix ctm, fz_colorspace *cs, int alpha);
/**
Render the page contents with control over spot colors.
Ownership of the pixmap is returned to the caller.
*/
fz_pixmap *fz_new_pixmap_from_display_list_with_separations(fz_context *ctx, fz_display_list *list, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha);
fz_pixmap *fz_new_pixmap_from_page_with_separations(fz_context *ctx, fz_page *page, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha);
fz_pixmap *fz_new_pixmap_from_page_number_with_separations(fz_context *ctx, fz_document *doc, int number, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha);
fz_pixmap *fz_new_pixmap_from_page_contents_with_separations(fz_context *ctx, fz_page *page, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha);
fz_pixmap *fz_fill_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, fz_matrix ctm, fz_pixmap *pix);
/**
Extract text from page.
Ownership of the fz_stext_page is returned to the caller.
*/
fz_stext_page *fz_new_stext_page_from_page(fz_context *ctx, fz_page *page, const fz_stext_options *options);
fz_stext_page *fz_new_stext_page_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_stext_options *options);
fz_stext_page *fz_new_stext_page_from_chapter_page_number(fz_context *ctx, fz_document *doc, int chapter, int number, const fz_stext_options *options);
fz_stext_page *fz_new_stext_page_from_display_list(fz_context *ctx, fz_display_list *list, const fz_stext_options *options);
/**
Convert structured text into plain text.
*/
fz_buffer *fz_new_buffer_from_stext_page(fz_context *ctx, fz_stext_page *text);
fz_buffer *fz_new_buffer_from_page(fz_context *ctx, fz_page *page, const fz_stext_options *options);
fz_buffer *fz_new_buffer_from_page_number(fz_context *ctx, fz_document *doc, int number, const fz_stext_options *options);
fz_buffer *fz_new_buffer_from_display_list(fz_context *ctx, fz_display_list *list, const fz_stext_options *options);
/**
Search for the 'needle' text on the page.
Record the hits in the hit_bbox array and return the number of
hits. Will stop looking once it has filled hit_max rectangles.
*/
int fz_search_page(fz_context *ctx, fz_page *page, const char *needle, int *hit_mark, fz_quad *hit_bbox, int hit_max);
int fz_search_page_number(fz_context *ctx, fz_document *doc, int number, const char *needle, int *hit_mark, fz_quad *hit_bbox, int hit_max);
int fz_search_chapter_page_number(fz_context *ctx, fz_document *doc, int chapter, int page, const char *needle, int *hit_mark, fz_quad *hit_bbox, int hit_max);
int fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *needle, int *hit_mark, fz_quad *hit_bbox, int hit_max);
/**
Parse an SVG document into a display-list.
*/
fz_display_list *fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *zip, float *w, float *h);
/**
Create a scalable image from an SVG document.
*/
fz_image *fz_new_image_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *zip);
/**
Parse an SVG document into a display-list.
*/
fz_display_list *fz_new_display_list_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *zip, float *w, float *h);
/**
Create a scalable image from an SVG document.
*/
fz_image *fz_new_image_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *zip);
/**
Write image as a data URI (for HTML and SVG output).
*/
void fz_write_image_as_data_uri(fz_context *ctx, fz_output *out, fz_image *image);
void fz_write_pixmap_as_data_uri(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
void fz_append_image_as_data_uri(fz_context *ctx, fz_buffer *out, fz_image *image);
void fz_append_pixmap_as_data_uri(fz_context *ctx, fz_buffer *out, fz_pixmap *pixmap);
/**
Use text extraction to convert the input document into XHTML,
then open the result as a new document that can be reflowed.
*/
fz_document *fz_new_xhtml_document_from_document(fz_context *ctx, fz_document *old_doc, const fz_stext_options *opts);
/**
Returns an fz_buffer containing a page after conversion to specified format.
page: The page to convert.
format, options: Passed to fz_new_document_writer_with_output() internally.
transform, cookie: Passed to fz_run_page() internally.
*/
fz_buffer *fz_new_buffer_from_page_with_format(fz_context *ctx, fz_page *page, const char *format, const char *options, fz_matrix transform, fz_cookie *cookie);
#endif

View File

@ -0,0 +1,31 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_VERSION_H
#define MUPDF_FITZ_VERSION_H
#ifndef FZ_VERSION
#define FZ_VERSION "1.23.0"
#define FZ_VERSION_MAJOR 1
#define FZ_VERSION_MINOR 23
#define FZ_VERSION_PATCH 0
#endif
#endif

View File

@ -0,0 +1,476 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_WRITE_PIXMAP_H
#define MUPDF_FITZ_WRITE_PIXMAP_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/writer.h"
/**
PCL output
*/
typedef struct
{
/* Features of a particular printer */
int features;
const char *odd_page_init;
const char *even_page_init;
/* Options for this job */
int tumble;
int duplex_set;
int duplex;
int paper_size;
int manual_feed_set;
int manual_feed;
int media_position_set;
int media_position;
int orientation;
/* Updated as we move through the job */
int page_count;
} fz_pcl_options;
/**
Initialize PCL option struct for a given preset.
Currently defined presets include:
generic Generic PCL printer
ljet4 HP DeskJet
dj500 HP DeskJet 500
fs600 Kyocera FS-600
lj HP LaserJet, HP LaserJet Plus
lj2 HP LaserJet IIp, HP LaserJet IId
lj3 HP LaserJet III
lj3d HP LaserJet IIId
lj4 HP LaserJet 4
lj4pl HP LaserJet 4 PL
lj4d HP LaserJet 4d
lp2563b HP 2563B line printer
oce9050 Oce 9050 Line printer
*/
void fz_pcl_preset(fz_context *ctx, fz_pcl_options *opts, const char *preset);
/**
Parse PCL options.
Currently defined options and values are as follows:
preset=X Either "generic" or one of the presets as for fz_pcl_preset.
spacing=0 No vertical spacing capability
spacing=1 PCL 3 spacing (<ESC>*p+<n>Y)
spacing=2 PCL 4 spacing (<ESC>*b<n>Y)
spacing=3 PCL 5 spacing (<ESC>*b<n>Y and clear seed row)
mode2 Disable/Enable mode 2 graphics compression
mode3 Disable/Enable mode 3 graphics compression
eog_reset End of graphics (<ESC>*rB) resets all parameters
has_duplex Duplex supported (<ESC>&l<duplex>S)
has_papersize Papersize setting supported (<ESC>&l<sizecode>A)
has_copies Number of copies supported (<ESC>&l<copies>X)
is_ljet4pjl Disable/Enable HP 4PJL model-specific output
is_oce9050 Disable/Enable Oce 9050 model-specific output
*/
fz_pcl_options *fz_parse_pcl_options(fz_context *ctx, fz_pcl_options *opts, const char *args);
/**
Create a new band writer, outputing monochrome pcl.
*/
fz_band_writer *fz_new_mono_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options);
/**
Write a bitmap as mono PCL.
*/
void fz_write_bitmap_as_pcl(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pcl_options *pcl);
/**
Save a bitmap as mono PCL.
*/
void fz_save_bitmap_as_pcl(fz_context *ctx, fz_bitmap *bitmap, char *filename, int append, const fz_pcl_options *pcl);
/**
Create a new band writer, outputing color pcl.
*/
fz_band_writer *fz_new_color_pcl_band_writer(fz_context *ctx, fz_output *out, const fz_pcl_options *options);
/**
Write an (RGB) pixmap as color PCL.
*/
void fz_write_pixmap_as_pcl(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pcl_options *pcl);
/**
Save an (RGB) pixmap as color PCL.
*/
void fz_save_pixmap_as_pcl(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pcl_options *pcl);
/**
PCLm output
*/
typedef struct
{
int compress;
int strip_height;
/* Updated as we move through the job */
int page_count;
} fz_pclm_options;
/**
Parse PCLm options.
Currently defined options and values are as follows:
compression=none: No compression
compression=flate: Flate compression
strip-height=n: Strip height (default 16)
*/
fz_pclm_options *fz_parse_pclm_options(fz_context *ctx, fz_pclm_options *opts, const char *args);
/**
Create a new band writer, outputing pclm
*/
fz_band_writer *fz_new_pclm_band_writer(fz_context *ctx, fz_output *out, const fz_pclm_options *options);
/**
Write a (Greyscale or RGB) pixmap as pclm.
*/
void fz_write_pixmap_as_pclm(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pclm_options *options);
/**
Save a (Greyscale or RGB) pixmap as pclm.
*/
void fz_save_pixmap_as_pclm(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pclm_options *options);
/**
PDFOCR output
*/
typedef struct
{
int compress;
int strip_height;
char language[256];
char datadir[1024];
/* Updated as we move through the job */
int page_count;
} fz_pdfocr_options;
/**
Parse PDFOCR options.
Currently defined options and values are as follows:
compression=none: No compression
compression=flate: Flate compression
strip-height=n: Strip height (default 16)
ocr-language=<lang>: OCR Language (default eng)
ocr-datadir=<datadir>: OCR data path (default rely on TESSDATA_PREFIX)
*/
fz_pdfocr_options *fz_parse_pdfocr_options(fz_context *ctx, fz_pdfocr_options *opts, const char *args);
/**
Create a new band writer, outputing pdfocr.
Ownership of output stays with the caller, the band writer
borrows the reference. The caller must keep the output around
for the duration of the band writer, and then close/drop as
appropriate.
*/
fz_band_writer *fz_new_pdfocr_band_writer(fz_context *ctx, fz_output *out, const fz_pdfocr_options *options);
/**
Set the progress callback for a pdfocr bandwriter.
*/
void fz_pdfocr_band_writer_set_progress(fz_context *ctx, fz_band_writer *writer, fz_pdfocr_progress_fn *progress_fn, void *progress_arg);
/**
Write a (Greyscale or RGB) pixmap as pdfocr.
*/
void fz_write_pixmap_as_pdfocr(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pdfocr_options *options);
/**
Save a (Greyscale or RGB) pixmap as pdfocr.
*/
void fz_save_pixmap_as_pdfocr(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pdfocr_options *options);
/**
Save a (Greyscale or RGB) pixmap as a png.
*/
void fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Save a pixmap as a JPEG.
*/
void fz_save_pixmap_as_jpeg(fz_context *ctx, fz_pixmap *pixmap, const char *filename, int quality);
/**
Write a (Greyscale or RGB) pixmap as a png.
*/
void fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
/**
Create a new png band writer (greyscale or RGB, with or without
alpha).
*/
fz_band_writer *fz_new_png_band_writer(fz_context *ctx, fz_output *out);
/**
Reencode a given image as a PNG into a buffer.
Ownership of the buffer is returned.
*/
fz_buffer *fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_image_as_pnm(fz_context *ctx, fz_image *image, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_image_as_pam(fz_context *ctx, fz_image *image, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_image_as_psd(fz_context *ctx, fz_image *image, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_image_as_jpeg(fz_context *ctx, fz_image *image, fz_color_params color_params, int quality);
/**
Reencode a given pixmap as a PNG into a buffer.
Ownership of the buffer is returned.
*/
fz_buffer *fz_new_buffer_from_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_pixmap_as_psd(fz_context *ctx, fz_pixmap *pix, fz_color_params color_params);
fz_buffer *fz_new_buffer_from_pixmap_as_jpeg(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params, int quality);
/**
Save a pixmap as a pnm (greyscale or rgb, no alpha).
*/
void fz_save_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Write a pixmap as a pnm (greyscale or rgb, no alpha).
*/
void fz_write_pixmap_as_pnm(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
/**
Create a band writer targetting pnm (greyscale or rgb, no
alpha).
*/
fz_band_writer *fz_new_pnm_band_writer(fz_context *ctx, fz_output *out);
/**
Save a pixmap as a pnm (greyscale, rgb or cmyk, with or without
alpha).
*/
void fz_save_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Write a pixmap as a pnm (greyscale, rgb or cmyk, with or without
alpha).
*/
void fz_write_pixmap_as_pam(fz_context *ctx, fz_output *out, fz_pixmap *pixmap);
/**
Create a band writer targetting pnm (greyscale, rgb or cmyk,
with or without alpha).
*/
fz_band_writer *fz_new_pam_band_writer(fz_context *ctx, fz_output *out);
/**
Save a bitmap as a pbm.
*/
void fz_save_bitmap_as_pbm(fz_context *ctx, fz_bitmap *bitmap, const char *filename);
/**
Write a bitmap as a pbm.
*/
void fz_write_bitmap_as_pbm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap);
/**
Create a new band writer, targetting pbm.
*/
fz_band_writer *fz_new_pbm_band_writer(fz_context *ctx, fz_output *out);
/**
Save a pixmap as a pbm. (Performing halftoning).
*/
void fz_save_pixmap_as_pbm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Save a CMYK bitmap as a pkm.
*/
void fz_save_bitmap_as_pkm(fz_context *ctx, fz_bitmap *bitmap, const char *filename);
/**
Write a CMYK bitmap as a pkm.
*/
void fz_write_bitmap_as_pkm(fz_context *ctx, fz_output *out, fz_bitmap *bitmap);
/**
Create a new pkm band writer for CMYK pixmaps.
*/
fz_band_writer *fz_new_pkm_band_writer(fz_context *ctx, fz_output *out);
/**
Save a CMYK pixmap as a pkm. (Performing halftoning).
*/
void fz_save_pixmap_as_pkm(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Write a (gray, rgb, or cmyk, no alpha) pixmap out as postscript.
*/
void fz_write_pixmap_as_ps(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
/**
Save a (gray, rgb, or cmyk, no alpha) pixmap out as postscript.
*/
void fz_save_pixmap_as_ps(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append);
/**
Create a postscript band writer for gray, rgb, or cmyk, no
alpha.
*/
fz_band_writer *fz_new_ps_band_writer(fz_context *ctx, fz_output *out);
/**
Write the file level header for ps band writer output.
*/
void fz_write_ps_file_header(fz_context *ctx, fz_output *out);
/**
Write the file level trailer for ps band writer output.
*/
void fz_write_ps_file_trailer(fz_context *ctx, fz_output *out, int pages);
/**
Save a pixmap as a PSD file.
*/
void fz_save_pixmap_as_psd(fz_context *ctx, fz_pixmap *pixmap, const char *filename);
/**
Write a pixmap as a PSD file.
*/
void fz_write_pixmap_as_psd(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap);
/**
Open a PSD band writer.
*/
fz_band_writer *fz_new_psd_band_writer(fz_context *ctx, fz_output *out);
typedef struct
{
/* These are not interpreted as CStrings by the writing code,
* but are rather copied directly out. */
char media_class[64];
char media_color[64];
char media_type[64];
char output_type[64];
unsigned int advance_distance;
int advance_media;
int collate;
int cut_media;
int duplex;
int insert_sheet;
int jog;
int leading_edge;
int manual_feed;
unsigned int media_position;
unsigned int media_weight;
int mirror_print;
int negative_print;
unsigned int num_copies;
int orientation;
int output_face_up;
unsigned int PageSize[2];
int separations;
int tray_switch;
int tumble;
int media_type_num;
int compression;
unsigned int row_count;
unsigned int row_feed;
unsigned int row_step;
/* These are not interpreted as CStrings by the writing code, but
* are rather copied directly out. */
char rendering_intent[64];
char page_size_name[64];
} fz_pwg_options;
/**
Save a pixmap as a PWG.
*/
void fz_save_pixmap_as_pwg(fz_context *ctx, fz_pixmap *pixmap, char *filename, int append, const fz_pwg_options *pwg);
/**
Save a bitmap as a PWG.
*/
void fz_save_bitmap_as_pwg(fz_context *ctx, fz_bitmap *bitmap, char *filename, int append, const fz_pwg_options *pwg);
/**
Write a pixmap as a PWG.
*/
void fz_write_pixmap_as_pwg(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pwg_options *pwg);
/**
Write a bitmap as a PWG.
*/
void fz_write_bitmap_as_pwg(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pwg_options *pwg);
/**
Write a pixmap as a PWG page.
Caller should provide a file header by calling
fz_write_pwg_file_header, but can then write several pages to
the same file.
*/
void fz_write_pixmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap, const fz_pwg_options *pwg);
/**
Write a bitmap as a PWG page.
Caller should provide a file header by calling
fz_write_pwg_file_header, but can then write several pages to
the same file.
*/
void fz_write_bitmap_as_pwg_page(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pwg_options *pwg);
/**
Create a new monochrome pwg band writer.
*/
fz_band_writer *fz_new_mono_pwg_band_writer(fz_context *ctx, fz_output *out, const fz_pwg_options *pwg);
/**
Create a new color pwg band writer.
*/
fz_band_writer *fz_new_pwg_band_writer(fz_context *ctx, fz_output *out, const fz_pwg_options *pwg);
/**
Output the file header to a pwg stream, ready for pages to follow it.
*/
void fz_write_pwg_file_header(fz_context *ctx, fz_output *out); /* for use by mudraw.c */
#endif

265
include/mupdf/fitz/writer.h Normal file
View File

@ -0,0 +1,265 @@
// Copyright (C) 2004-2023 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_WRITER_H
#define MUPDF_FITZ_WRITER_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/device.h"
typedef struct fz_document_writer fz_document_writer;
/**
Function type to start
the process of writing a page to a document.
mediabox: page size rectangle in points.
Returns a fz_device to write page contents to.
*/
typedef fz_device *(fz_document_writer_begin_page_fn)(fz_context *ctx, fz_document_writer *wri, fz_rect mediabox);
/**
Function type to end the
process of writing a page to a document.
dev: The device created by the begin_page function.
*/
typedef void (fz_document_writer_end_page_fn)(fz_context *ctx, fz_document_writer *wri, fz_device *dev);
/**
Function type to end
the process of writing pages to a document.
This writes any file level trailers required. After this
completes successfully the file is up to date and complete.
*/
typedef void (fz_document_writer_close_writer_fn)(fz_context *ctx, fz_document_writer *wri);
/**
Function type to discard
an fz_document_writer. This may be called at any time during
the process to release all the resources owned by the writer.
Calling drop without having previously called close may leave
the file in an inconsistent state and the user of the
fz_document_writer would need to do any cleanup required.
*/
typedef void (fz_document_writer_drop_writer_fn)(fz_context *ctx, fz_document_writer *wri);
#define fz_new_derived_document_writer(CTX,TYPE,BEGIN_PAGE,END_PAGE,CLOSE,DROP) \
((TYPE *)Memento_label(fz_new_document_writer_of_size(CTX,sizeof(TYPE),BEGIN_PAGE,END_PAGE,CLOSE,DROP),#TYPE))
/**
Look for a given option (key) in the opts string. Return 1 if
it has it, and update *val to point to the value within opts.
*/
int fz_has_option(fz_context *ctx, const char *opts, const char *key, const char **val);
/**
Check to see if an option, a, from a string matches a reference
option, b.
(i.e. a could be 'foo' or 'foo,bar...' etc, but b can only be
'foo'.)
*/
int fz_option_eq(const char *a, const char *b);
/**
Copy an option (val) into a destination buffer (dest), of maxlen
bytes.
Returns the number of bytes (including terminator) that did not
fit. If val is maxlen or greater bytes in size, it will be left
unterminated.
*/
size_t fz_copy_option(fz_context *ctx, const char *val, char *dest, size_t maxlen);
/**
Create a new fz_document_writer, for a
file of the given type.
path: The document name to write (or NULL for default)
format: Which format to write (currently cbz, html, pdf, pam,
pbm, pgm, pkm, png, ppm, pnm, svg, text, xhtml, docx, odt)
options: NULL, or pointer to comma separated string to control
file generation.
*/
fz_document_writer *fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options);
/**
Like fz_new_document_writer but takes a fz_output for writing
the result. Only works for multi-page formats.
*/
fz_document_writer *
fz_new_document_writer_with_output(fz_context *ctx, fz_output *out, const char *format, const char *options);
fz_document_writer *
fz_new_document_writer_with_buffer(fz_context *ctx, fz_buffer *buf, const char *format, const char *options);
/**
Document writers for various possible output formats.
All of the "_with_output" variants pass the ownership of out in
immediately upon calling. The writers are responsible for
dropping the fz_output when they are finished with it (even
if they throw an exception during creation).
*/
fz_document_writer *fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pdf_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_svg_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_text_writer(fz_context *ctx, const char *format, const char *path, const char *options);
fz_document_writer *fz_new_text_writer_with_output(fz_context *ctx, const char *format, fz_output *out, const char *options);
fz_document_writer *fz_new_odt_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_odt_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_docx_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_docx_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_ps_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_ps_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_pcl_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pcl_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_pclm_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pclm_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_pwg_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pwg_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
fz_document_writer *fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_cbz_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
/**
Used to report progress of the OCR operation.
page: Current page being processed.
percent: Progress of the OCR operation for the
current page in percent. Whether it reaches 100
once a page is finished, depends on the OCR engine.
Return 0 to continue progress, return 1 to cancel the
operation.
*/
typedef int (fz_pdfocr_progress_fn)(fz_context *ctx, void *progress_arg, int page, int percent);
fz_document_writer *fz_new_pdfocr_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pdfocr_writer_with_output(fz_context *ctx, fz_output *out, const char *options);
void fz_pdfocr_writer_set_progress(fz_context *ctx, fz_document_writer *writer, fz_pdfocr_progress_fn *progress, void *);
fz_document_writer *fz_new_jpeg_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_png_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pam_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pnm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pgm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_ppm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pbm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
fz_document_writer *fz_new_pkm_pixmap_writer(fz_context *ctx, const char *path, const char *options);
/**
Called to start the process of writing a page to
a document.
mediabox: page size rectangle in points.
Returns a borrowed fz_device to write page contents to. This
should be kept if required, and only dropped if it was kept.
*/
fz_device *fz_begin_page(fz_context *ctx, fz_document_writer *wri, fz_rect mediabox);
/**
Called to end the process of writing a page to a
document.
*/
void fz_end_page(fz_context *ctx, fz_document_writer *wri);
/**
Convenience function to feed all the pages of a document to
fz_begin_page/fz_run_page/fz_end_page.
*/
void fz_write_document(fz_context *ctx, fz_document_writer *wri, fz_document *doc);
/**
Called to end the process of writing
pages to a document.
This writes any file level trailers required. After this
completes successfully the file is up to date and complete.
*/
void fz_close_document_writer(fz_context *ctx, fz_document_writer *wri);
/**
Called to discard a fz_document_writer.
This may be called at any time during the process to release all
the resources owned by the writer.
Calling drop without having previously called close may leave
the file in an inconsistent state.
*/
void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri);
fz_document_writer *fz_new_pixmap_writer(fz_context *ctx, const char *path, const char *options, const char *default_path, int n,
void (*save)(fz_context *ctx, fz_pixmap *pix, const char *filename));
FZ_DATA extern const char *fz_pdf_write_options_usage;
FZ_DATA extern const char *fz_svg_write_options_usage;
FZ_DATA extern const char *fz_pcl_write_options_usage;
FZ_DATA extern const char *fz_pclm_write_options_usage;
FZ_DATA extern const char *fz_pwg_write_options_usage;
FZ_DATA extern const char *fz_pdfocr_write_options_usage;
/* Implementation details: subject to change. */
/**
Structure is public to allow other structures to
be derived from it. Do not access members directly.
*/
struct fz_document_writer
{
fz_document_writer_begin_page_fn *begin_page;
fz_document_writer_end_page_fn *end_page;
fz_document_writer_close_writer_fn *close_writer;
fz_document_writer_drop_writer_fn *drop_writer;
fz_device *dev;
};
/**
Internal function to allocate a
block for a derived document_writer structure, with the base
structure's function pointers populated correctly, and the extra
space zero initialised.
*/
fz_document_writer *fz_new_document_writer_of_size(fz_context *ctx, size_t size,
fz_document_writer_begin_page_fn *begin_page,
fz_document_writer_end_page_fn *end_page,
fz_document_writer_close_writer_fn *close,
fz_document_writer_drop_writer_fn *drop);
#endif

391
include/mupdf/fitz/xml.h Normal file
View File

@ -0,0 +1,391 @@
// Copyright (C) 2004-2022 Artifex Software, Inc.
//
// This file is part of MuPDF.
//
// MuPDF is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
//
// Alternative licensing terms are available from the licensor.
// For commercial licensing, see <https://www.artifex.com/> or contact
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
// CA 94129, USA, for further information.
#ifndef MUPDF_FITZ_XML_H
#define MUPDF_FITZ_XML_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/pool.h"
#include "mupdf/fitz/archive.h"
/**
XML document model
*/
typedef struct fz_xml fz_xml;
/* For backwards compatibility */
typedef fz_xml fz_xml_doc;
/**
Parse the contents of buffer into a tree of xml nodes.
preserve_white: whether to keep or delete all-whitespace nodes.
*/
fz_xml *fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white);
/**
Parse the contents of buffer into a tree of xml nodes.
preserve_white: whether to keep or delete all-whitespace nodes.
*/
fz_xml *fz_parse_xml_stream(fz_context *ctx, fz_stream *stream, int preserve_white);
/**
Parse the contents of an archive entry into a tree of xml nodes.
preserve_white: whether to keep or delete all-whitespace nodes.
*/
fz_xml *fz_parse_xml_archive_entry(fz_context *ctx, fz_archive *arch, const char *filename, int preserve_white);
/**
Try and parse the contents of an archive entry into a tree of xml nodes.
preserve_white: whether to keep or delete all-whitespace nodes.
Will return NULL if the archive entry can't be found. Otherwise behaves
the same as fz_parse_xml_archive_entry. May throw exceptions.
*/
fz_xml *fz_try_parse_xml_archive_entry(fz_context *ctx, fz_archive *arch, const char *filename, int preserve_white);
/**
Parse the contents of a buffer into a tree of XML nodes,
using the HTML5 parsing algorithm.
*/
fz_xml *fz_parse_xml_from_html5(fz_context *ctx, fz_buffer *buf);
/**
Add a reference to the XML.
*/
fz_xml *fz_keep_xml(fz_context *ctx, fz_xml *xml);
/**
Drop a reference to the XML. When the last reference is
dropped, the node and all its children and siblings will
be freed.
*/
void fz_drop_xml(fz_context *ctx, fz_xml *xml);
/**
Detach a node from the tree, unlinking it from its parent,
and setting the document root to the node.
*/
void fz_detach_xml(fz_context *ctx, fz_xml *node);
/**
Return the topmost XML node of a document.
*/
fz_xml *fz_xml_root(fz_xml_doc *xml);
/**
Return previous sibling of XML node.
*/
fz_xml *fz_xml_prev(fz_xml *item);
/**
Return next sibling of XML node.
*/
fz_xml *fz_xml_next(fz_xml *item);
/**
Return parent of XML node.
*/
fz_xml *fz_xml_up(fz_xml *item);
/**
Return first child of XML node.
*/
fz_xml *fz_xml_down(fz_xml *item);
/**
Return true if the tag name matches.
*/
int fz_xml_is_tag(fz_xml *item, const char *name);
/**
Return tag of XML node. Return NULL for text nodes.
*/
char *fz_xml_tag(fz_xml *item);
/**
Return the value of an attribute of an XML node.
NULL if the attribute doesn't exist.
*/
char *fz_xml_att(fz_xml *item, const char *att);
/**
Return the value of an attribute of an XML node.
If the first attribute doesn't exist, try the second.
NULL if neither attribute exists.
*/
char *fz_xml_att_alt(fz_xml *item, const char *one, const char *two);
/**
Check for a matching attribute on an XML node.
If the node has the requested attribute (name), and the value
matches (match) then return 1. Otherwise, 0.
*/
int fz_xml_att_eq(fz_xml *item, const char *name, const char *match);
/**
Add an attribute to an XML node.
*/
void fz_xml_add_att(fz_context *ctx, fz_pool *pool, fz_xml *node, const char *key, const char *val);
/**
Return the text content of an XML node.
Return NULL if the node is a tag.
*/
char *fz_xml_text(fz_xml *item);
/**
Pretty-print an XML tree to stdout.
*/
void fz_debug_xml(fz_xml *item, int level);
/**
Search the siblings of XML nodes starting with item looking for
the first with the given tag.
Return NULL if none found.
*/
fz_xml *fz_xml_find(fz_xml *item, const char *tag);
/**
Search the siblings of XML nodes starting with the first sibling
of item looking for the first with the given tag.
Return NULL if none found.
*/
fz_xml *fz_xml_find_next(fz_xml *item, const char *tag);
/**
Search the siblings of XML nodes starting with the first child
of item looking for the first with the given tag.
Return NULL if none found.
*/
fz_xml *fz_xml_find_down(fz_xml *item, const char *tag);
/**
Search the siblings of XML nodes starting with item looking for
the first with the given tag (or any tag if tag is NULL), and
with a matching attribute.
Return NULL if none found.
*/
fz_xml *fz_xml_find_match(fz_xml *item, const char *tag, const char *att, const char *match);
/**
Search the siblings of XML nodes starting with the first sibling
of item looking for the first with the given tag (or any tag if tag
is NULL), and with a matching attribute.
Return NULL if none found.
*/
fz_xml *fz_xml_find_next_match(fz_xml *item, const char *tag, const char *att, const char *match);
/**
Search the siblings of XML nodes starting with the first child
of item looking for the first with the given tag (or any tag if
tag is NULL), and with a matching attribute.
Return NULL if none found.
*/
fz_xml *fz_xml_find_down_match(fz_xml *item, const char *tag, const char *att, const char *match);
/**
Perform a depth first search from item, returning the first
child that matches the given tag (or any tag if tag is NULL),
with the given attribute (if att is non NULL), that matches
match (if match is non NULL).
*/
fz_xml *fz_xml_find_dfs(fz_xml *item, const char *tag, const char *att, const char *match);
/**
Perform a depth first search from item, returning the first
child that matches the given tag (or any tag if tag is NULL),
with the given attribute (if att is non NULL), that matches
match (if match is non NULL). The search stops if it ever
reaches the top of the tree, or the declared 'top' item.
*/
fz_xml *fz_xml_find_dfs_top(fz_xml *item, const char *tag, const char *att, const char *match, fz_xml *top);
/**
Perform a depth first search onwards from item, returning the first
child that matches the given tag (or any tag if tag is NULL),
with the given attribute (if att is non NULL), that matches
match (if match is non NULL).
*/
fz_xml *fz_xml_find_next_dfs(fz_xml *item, const char *tag, const char *att, const char *match);
/**
Perform a depth first search onwards from item, returning the first
child that matches the given tag (or any tag if tag is NULL),
with the given attribute (if att is non NULL), that matches
match (if match is non NULL). The search stops if it ever reaches
the top of the tree, or the declared 'top' item.
*/
fz_xml *fz_xml_find_next_dfs_top(fz_xml *item, const char *tag, const char *att, const char *match, fz_xml *top);
/**
DOM-like functions for html in xml.
*/
/**
Return a borrowed reference for the 'body' element of
the given DOM.
*/
fz_xml *fz_dom_body(fz_context *ctx, fz_xml *dom);
/**
Return a borrowed reference for the document (the top
level element) of the DOM.
*/
fz_xml *fz_dom_document_element(fz_context *ctx, fz_xml *dom);
/**
Create an element of a given tag type for the given DOM.
The element is not linked into the DOM yet.
*/
fz_xml *fz_dom_create_element(fz_context *ctx, fz_xml *dom, const char *tag);
/**
Create a text node for the given DOM.
The element is not linked into the DOM yet.
*/
fz_xml *fz_dom_create_text_node(fz_context *ctx, fz_xml *dom, const char *text);
/**
Find the first element matching the requirements in a depth first traversal from elt.
The tagname must match tag, unless tag is NULL, when all tag names are considered to match.
If att is NULL, then all tags match.
Otherwise:
If match is NULL, then only nodes that have an att attribute match.
If match is non-NULL, then only nodes that have an att attribute that matches match match.
Returns NULL (if no match found), or a borrowed reference to the first matching element.
*/
fz_xml *fz_dom_find(fz_context *ctx, fz_xml *elt, const char *tag, const char *att, const char *match);
/**
Find the next element matching the requirements.
*/
fz_xml *fz_dom_find_next(fz_context *ctx, fz_xml *elt, const char *tag, const char *att, const char *match);
/**
Insert an element as the last child of a parent, unlinking the
child from its current position if required.
*/
void fz_dom_append_child(fz_context *ctx, fz_xml *parent, fz_xml *child);
/**
Insert an element (new_elt), before another element (node),
unlinking the new_elt from its current position if required.
*/
void fz_dom_insert_before(fz_context *ctx, fz_xml *node, fz_xml *new_elt);
/**
Insert an element (new_elt), after another element (node),
unlinking the new_elt from its current position if required.
*/
void fz_dom_insert_after(fz_context *ctx, fz_xml *node, fz_xml *new_elt);
/**
Remove an element from the DOM. The element can be added back elsewhere
if required.
No reference counting changes for the element.
*/
void fz_dom_remove(fz_context *ctx, fz_xml *elt);
/**
Clone an element (and its children).
A borrowed reference to the clone is returned. The clone is not
yet linked into the DOM.
*/
fz_xml *fz_dom_clone(fz_context *ctx, fz_xml *elt);
/**
Return a borrowed reference to the first child of a node,
or NULL if there isn't one.
*/
fz_xml *fz_dom_first_child(fz_context *ctx, fz_xml *elt);
/**
Return a borrowed reference to the parent of a node,
or NULL if there isn't one.
*/
fz_xml *fz_dom_parent(fz_context *ctx, fz_xml *elt);
/**
Return a borrowed reference to the next sibling of a node,
or NULL if there isn't one.
*/
fz_xml *fz_dom_next(fz_context *ctx, fz_xml *elt);
/**
Return a borrowed reference to the previous sibling of a node,
or NULL if there isn't one.
*/
fz_xml *fz_dom_previous(fz_context *ctx, fz_xml *elt);
/**
Add an attribute to an element.
Ownership of att and value remain with the caller.
*/
void fz_dom_add_attribute(fz_context *ctx, fz_xml *elt, const char *att, const char *value);
/**
Remove an attribute from an element.
*/
void fz_dom_remove_attribute(fz_context *ctx, fz_xml *elt, const char *att);
/**
Retrieve the value of a given attribute from a given element.
Returns a borrowed pointer to the value or NULL if not found.
*/
const char *fz_dom_attribute(fz_context *ctx, fz_xml *elt, const char *att);
/**
Enumerate through the attributes of an element.
Call with i=0,1,2,3... to enumerate attributes.
On return *att and the return value will be NULL if there are not
that many attributes to read. Otherwise, *att will be filled in
with a borrowed pointer to the attribute name, and the return
value will be a borrowed pointer to the value.
*/
const char *fz_dom_get_attribute(fz_context *ctx, fz_xml *elt, int i, const char **att);
#endif