Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
Remove fz_free_display_list from the API; instead use fz_drop_display_list.
|
|
It seems that the code for begin_tile currently assumes that area
is passed in untransformed. Maybe this is something we should
look at, but for now commit it to revert the rendering problems.
|
|
|
|
Pass stroke state into fz_bound_text to allow for stroked text.
Simplifies some calling code.
Add consts to clarify the meanings of the calls.
|
|
Add configuration functions to control the hints set on a given device.
Use this to set whether image data is captured or not in the text
extraction process.
Also update the display list device to respect the device hints during
playback.
|
|
fz_bound_path already takes care of stroke expansion - don't apply
it twice.
|
|
When we calculate the bbox to store in display list nodes, we had been
forgetting to allow for the stroke state.
|
|
This requires a slight change to the device interface.
Callers that use fz_begin_tile will see no change (and no caching
will be done). We add a new fz_begin_tile_id function that takes an
extra 'id' parameter, and returns 0 or 1. If the id is 0 then the
function behaves exactly as fz_being_tile does, and always returns 0.
The PDF and XPS code continues to call the old (uncached) version.
The display list code however generates a unique id for every
BEGIN_TILE node, and passes this in.
If the id is non zero, then it is taken to be a unique identifier
for this tile; the implementer of the fz_begin_tile_id entry point
can choose to use this to implement caching. If it chooses to ignore
the id (and do no caching), it returns 0.
If the device implements caching, then it can check on entry for a
previously rendered tile with the appropriate matrix and a matching id.
If it finds one, then it returns 1. It is the callers responsibility
to then skip over all the device calls that would usually happen to
render the tiles (i.e. to skip forward to the matching 'END_TILE'
operation).
|
|
Thanks to zeniko.
|
|
This is faster on ARM in particular. The primary changes involve
fz_matrix, fz_rect and fz_bbox.
Rather than passing 'fz_rect r' into a function, we now consistently
pass 'const fz_rect *r'. Where a rect is passed in and modified, we
miss the 'const' off. Where possible, we return the pointer to the
modified structure to allow 'chaining' of expressions.
The basic upshot of this work is that we do far fewer copies of
rectangle/matrix structures, and all the copies we do are explicit.
This has opened the way to other optimisations, also performed in
this commit.
Rather than using expressions like:
fz_concat(fz_scale(sx, sy), fz_translate(tx, ty))
we now have fz_pre_{scale,translate,rotate} functions. These
can be implemented much more efficiently than doing the fully
fledged matrix multiplication that fz_concat requires.
We add fz_rect_{min,max} functions to return pointers to the
min/max points of a rect. These can be used to in transformations
to directly manipulate values.
With a little casting in the path transformation code we can avoid
more needless copying.
We rename fz_widget_bbox to the more consistent fz_bound_widget.
|
|
|
|
|
|
|
|
As zeniko points out, pointer arithmetic is pointless on a linked
list. Keep a count of the length in the list header.
|
|
When calculating the displaylist node rectangles, we were failing
to adjust for linewidth/mitrewidth etc. This could result in glyphs
being clipped; see normal_130.pdf for example.
|
|
The file supplied with the bug contains corrupt jpeg data on page
61. This causes an error to be thrown which results in mudraw
exiting.
Previously, when image decode was done at loading time, the error
would have been thrown under the pdf interpreter rather than under
the display list renderer. This error would have been caught, a
warning given, and the program would have continued. This is not
ideal behaviour, as there is no way for a caller to know that there
was a problem, and that the image is potentially incomplete.
The solution adopted here, solves both these problems. The fz_cookie
structure is expanded to include a 'errors' count. Whenever we meet
an error during rendering, we increment the 'errors' count, and
continue.
This enables applications to spot the errors count being non-zero on
exit and to display a warning.
mupdf is updated here to pass a cookie in and to check the error count
at the end; if it is found to be non zero, then a warning is given (just
once per visit to each page) to say that the page may have errors on it.
|
|
Currently all conversions from rect to bbox are done using a single
function, fz_round_rect. This causes problems, as sometimes we want
'round, allowing for slight calculation errors' and sometimes we
want 'round slavishly to ensure we have a bbox that covers the rect'.
We therefore split these 2 cases into 2 separate functions;
fz_round_rect is kept, meaning "round outwards allowing for slight
errors", and fz_bbox_covering_rect is added to mean "give us the
smallest bbox that is guaranteed to cover rect".
No regressions seen.
|
|
Move fz_stroke_state from being a simple structure whose contents
are copied repeatedly to being a dynamically allocated reference
counted object so we can cope with large numbers of entries in
the dash array.
|
|
Attempt to separate public API from internal functions.
|
|
Introduce a new 'fz_image' type; this type contains rudimentary
information about images (such as native, size, colorspace etc)
and a function to call to get a pixmap of that image (with a
size hint).
Instead of passing pixmaps through the device interface (and
holding pixmaps in the display list) we now pass images instead.
The rendering routines therefore call fz_image_to_pixmap to get
pixmaps to render, and fz_pixmap_drop those afterwards.
The file format handling routines therefore need to produce
images rather than pixmaps; xps and cbz currently just wrap
pixmaps as images. PDF is more involved.
The stream handling routines in PDF have been altered so that
they can recognise when the last stream entry in a filter
dictionary is an image decoding filter. Rather than applying
this filter, they read and store the parameters into a
pdf_image_params structure, and stop decoding at that point.
This allows us to read the compressed data for an image into
memory as a block. We can then restart the image decode process
later.
pdf_images therefore consist of the compressed image data for
images. When a pixmap is requested for such an image, the code
checks to see if we have one (of an appropriate size), and if
not, decodes it.
The size hint is used to determine whether it is possible to
subsample the image; currently this is only supported for
JPEGs, but we could add generic subsampling code later.
In order to handle caching the produced images, various changes
have been made to the store and the underlying hash table.
Previously the store was indexed purely by fz_obj keys; we don't
have an fz_obj key any more, so have extended the store by adding
a concept of a key 'type'. A key type is a pointer to a set of
functions that keep/drop/compare and make a hashable key from
a key pointer.
We make a pdf_store.c file that contains functions to offer the
existing fz_obj based functions, and add a new 'type' for keys
(based on the fz_image handle, and the subsample factor) in the
pdf_image.c file.
While working on this, a problem became apparent in the existing
store codel; fz_obj objects had no protection on their reference
counts, hence an interpreter thread could try to alter a ref count
at the same time as a malloc caused an eviction from the store.
This has been solved by using the alloc lock as protection. This in
turn requires some tweaks to the code to make sure we don't try
and keep/drop fz_obj's from the store code while the alloc lock is
held.
A side effect of this work is that when a hash table is created, we
inform it what lock should be used to protect its innards (if any).
If the alloc lock is used, the insert method knows to drop/retake it
to allow it to safely expand the hash table. Callers to the hash
functions have the responsibility of taking/dropping the appropriate
lock, and ensuring that they cope with the possibility that insert
might drop the alloc lock, causing race conditions.
|
|
|
|
|
|
When we moved over to a context based system, we laid the foundation
for a thread-safe mupdf. This commit should complete that process.
Firstly, fz_clone_context is properly implemented so that it
makes a new context, but shares certain sections (currently
just the allocator, and the store).
Secondly, we add locking (to parts of the code that have
previously just had placeholder LOCK/UNLOCK comments). Functions
to lock and unlock a mutex are added to the allocator structure;
omit these (as is the case today) and no multithreading is
(safely) possible. The context will refuse to clone if these are
not provided.
Finally we flesh out the LOCK/UNLOCK comments to be real calls of
the functions - unfortunately this requires us to plumb fz_context
into the fz_keep_storable function (and all the fz_keep_xxx
functions that call it). This is the largest section of the patch.
No changes expected to any test files.
|
|
Thanks to Zeniko for spotting these problems.
|
|
|
|
Keep the fuzz in just one place. Hopefully will be rendered
unnecessary by changes to make fz_bound_text accurate.
|
|
A new 'cookie' parameter is added to page rendering/interpretation
functions. Supply this as NULL to get existing behaviour.
If you supply a non-NULL cookie, then this is taken as a pointer to
a struct that can be used for simple, non-thread locked communication
between caller and library.
The entire struct should be memset to zero before entry, except for
specific flags (thus coping with future extensions to this struct).
The abort flag should be zero on entry. It will be checked periodically
by the library - if the caller sets it non-zero (via another thread)
then the current operation will be aborted. No guarantees are given as
to how often this will be checked, or how fast it will be responded to.
The progress_max field will be set to an integer (-1 for unknown)
representing the number of 'things' to do. The progress field will
count up from 0 to this number as time goes by. No guarantees are
made as to the accuracy of this information, but it should be
useful for offering some sort of progress bar etc. Note that
progress_max may increase during the job.
In general, callers should be careful to accept out of range or
invalid data in this structure as this is deliberately
accessed 'unlocked'.
|
|
|
|
The new fz_malloc_struct(A,B) macro allocates sizeof(B) bytes using
fz_malloc, and then passes the resultant pointer to Memento_label
to label it with "B".
This costs nothing in non-memento builds, but gives much nicer
listings of leaked blocks when memento is enabled.
|
|
|
|
Also: use 'cannot' instead of 'failed to' in error messages.
|
|
Huge pervasive change to lots of files, adding a context for exception
handling and allocation.
In time we'll move more statics into there.
Also fix some for(i = 0; i < function(...); i++) calls.
|
|
|
|
When playing back from a list, previously flags would just be 0 or
non-zero. This makes no real difference, but looks odd when traced.
|
|
Firstly, this takes on some of Zenikos patch to correct the clip
stack handling that was broken by the fix to bug 692287 (in commit
2c3bbbf). This bug should now be solved.
We add a new 'shape' field to the draw device structure (and clip
stack). When we are inside non-isolated groups, this is set to be
a pixmap where we accumulate the 'shape' of the objects drawn.
When we come to blend back, if we are blending a non-isolated group
back, we have to use a different blending function that takes account
of the shape.
Various internal groups (the page group, and groups used to force
blending) are set to be isolated to avoid carrying shape planes
around when this is not required.
All our rendering code now has to know how to maintain the shape
plane as well as doing the basic rendering.
|
|
First, we add clipping rects to clipping functions. Various functions
(the ones that handle clipping) are now additionally passed a rectangle
that represents an additional bound for this clip in device space
(i.e. it has already been mapped through the current ctm).
Next, when constructing the displaylist, keep track of the bounding box
for the contents of each clip.
While writing the list, on every node we add, we add the bbox for that
node to the enclosing clips content bbox (if there is an enclosing clip).
When we pop a clip, write back to the corresponding push to update
the bbox.
This means if we get large clip regions, with only small areas used within
them, we will only do the slow blending for those small areas.
Finally, we fix a calculation in fz_bound_path which was incorrectly
accounting for mitrelimits. This was showing up in testing on page 630
of the PDF reference v1.7.
|
|
|
|
|
|
|
|
|
|
|
|
The run-together words are dead! Long live the underscores!
The postscript inspired naming convention of using all run-together
words has served us well, but it is now time for more readable code.
In this commit I have also added the sed script, rename.sed, that I used
to convert the source. Use it on your patches and application code.
|
|
|
|
The node bbox was not transformed to device space before the
visibility test.
|
|
|
|
|
|
|