summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-06-19 15:29:44 +0200
committerTor Andersson <tor.andersson@artifex.com>2013-06-20 16:45:35 +0200
commit0a927854a10e1e6b9770a81e2e1d9f3093631757 (patch)
tree3d65d820d9fdba2d0d394d99c36290c851b78ca0 /doc
parent1ae8f19179c5f0f8c6352b3c7855465325d5449a (diff)
downloadmupdf-0a927854a10e1e6b9770a81e2e1d9f3093631757.tar.xz
Rearrange source files.
Diffstat (limited to 'doc')
-rw-r--r--doc/example.c100
-rw-r--r--doc/multi-threaded.c266
-rw-r--r--doc/naming.txt30
-rw-r--r--doc/overview.txt268
-rw-r--r--doc/refcount.txt17
-rw-r--r--doc/thirdparty.txt38
6 files changed, 0 insertions, 719 deletions
diff --git a/doc/example.c b/doc/example.c
deleted file mode 100644
index 1a21c200..00000000
--- a/doc/example.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// Rendering a page of a PDF document to a PNG image in less than 100 lines.
-
-// Compile a debug build of mupdf, then compile and run this example:
-//
-// gcc -g -o build/debug/example -Iinclude doc/example.c build/debug/lib*.a -lm
-//
-// build/debug/example /path/to/document.pdf 1 200 25
-
-// Include the MuPDF header file.
-#include <mupdf/fitz.h>
-
-void
-render(char *filename, int pagenumber, int zoom, int rotation)
-{
- // Create a context to hold the exception stack and various caches.
-
- fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
-
- // Open the PDF, XPS or CBZ document.
-
- fz_document *doc = fz_open_document(ctx, filename);
-
- // Retrieve the number of pages (not used in this example).
-
- int pagecount = fz_count_pages(doc);
-
- // Load the page we want. Page numbering starts from zero.
-
- fz_page *page = fz_load_page(doc, pagenumber - 1);
-
- // Calculate a transform to use when rendering. This transform
- // contains the scale and rotation. Convert zoom percentage to a
- // scaling factor. Without scaling the resolution is 72 dpi.
-
- fz_matrix transform;
- fz_rotate(&transform, rotation);
- fz_pre_scale(&transform, zoom / 100.0f, zoom / 100.0f);
-
- // Take the page bounds and transform them by the same matrix that
- // we will use to render the page.
-
- fz_rect bounds;
- fz_bound_page(doc, page, &bounds);
- fz_transform_rect(&bounds, &transform);
-
- // Create a blank pixmap to hold the result of rendering. The
- // pixmap bounds used here are the same as the transformed page
- // bounds, so it will contain the entire page. The page coordinate
- // space has the origin at the top left corner and the x axis
- // extends to the right and the y axis extends down.
-
- fz_irect bbox;
- fz_round_rect(&bbox, &bounds);
- fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);
- fz_clear_pixmap_with_value(ctx, pix, 0xff);
-
- // A page consists of a series of objects (text, line art, images,
- // gradients). These objects are passed to a device when the
- // interpreter runs the page. There are several devices, used for
- // different purposes:
- //
- // draw device -- renders objects to a target pixmap.
- //
- // text device -- extracts the text in reading order with styling
- // information. This text can be used to provide text search.
- //
- // list device -- records the graphic objects in a list that can
- // be played back through another device. This is useful if you
- // need to run the same page through multiple devices, without
- // the overhead of parsing the page each time.
-
- // Create a draw device with the pixmap as its target.
- // Run the page with the transform.
-
- fz_device *dev = fz_new_draw_device(ctx, pix);
- fz_run_page(doc, page, dev, &transform, NULL);
- fz_free_device(dev);
-
- // Save the pixmap to a file.
-
- fz_write_png(ctx, pix, "out.png", 0);
-
- // Clean up.
-
- fz_drop_pixmap(ctx, pix);
- fz_free_page(doc, page);
- fz_close_document(doc);
- fz_free_context(ctx);
-}
-
-int main(int argc, char **argv)
-{
- char *filename = argv[1];
- int pagenumber = argc > 2 ? atoi(argv[2]) : 1;
- int zoom = argc > 3 ? atoi(argv[3]) : 100;
- int rotation = argc > 4 ? atoi(argv[4]) : 0;
-
- render(filename, pagenumber, zoom, rotation);
- return 0;
-}
diff --git a/doc/multi-threaded.c b/doc/multi-threaded.c
deleted file mode 100644
index 3141e3c4..00000000
--- a/doc/multi-threaded.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// Multi-threaded rendering of all pages in a document to PNG images.
-
-// First look at doc/example.c and make sure you understand it.
-// Then read the multi-threading section in doc/overview.txt,
-// before coming back here to see an example of multi-threading.
-
-// This example will create one main thread for reading pages from the
-// document, and one thread per page for rendering. After rendering
-// the main thread will wait for each rendering thread to complete before
-// writing that thread's rendered image to a PNG image. There is
-// nothing in MuPDF requiring a rendering thread to only render a
-// single page, this is just a design decision taken for this example.
-
-// Compile a debug build of mupdf, then compile and run this example:
-//
-// gcc -g -o build/debug/example-mt -Iinclude doc/multi-threading.c \
-// build/debug/lib*.a -lpthread -lm
-//
-// build/debug/example-mt /path/to/document.pdf
-//
-// Caution! As all pages are rendered simultaneously, please choose a
-// file with just a few pages to avoid stressing your machine too
-// much. Also you may run in to a limitation on the number of threads
-// depending on your environment.
-
-// Include the MuPDF header file, and pthread's header file.
-#include <mupdf/fitz.h>
-#include <pthread.h>
-
-// A convenience function for dying abruptly on pthread errors.
-
-void
-fail(char *msg)
-{
- fprintf(stderr, "%s", msg);
- abort();
-}
-
-// The data structure passed between the requesting main thread and
-// each rendering thread.
-
-struct data {
- // A pointer to the original context in the main thread sent
- // from main to rendering thread. It will be used to create
- // each rendering thread's context clone.
- fz_context *ctx;
-
- // Page number sent from main to rendering thread for printing
- int pagenumber;
-
- // The display list as obtained by the main thread and sent
- // from main to rendering thread. This contains the drawing
- // commands (text, images, etc.) for the page that should be
- // rendered.
- fz_display_list *list;
-
- // The area of the page to render as obtained by the main
- // thread and sent from main to rendering thread.
- fz_rect bbox;
-
- // This is the result, a pixmap containing the rendered page.
- // It is passed first from main thread to the rendering
- // thread, then its samples are changed by the rendering
- // thread, and then back from the rendering thread to the main
- // thread.
- fz_pixmap *pix;
-};
-
-// This is the function run by each rendering function. It takes
-// pointer to an instance of the data structure described above and
-// renders the display list into the pixmap before exiting.
-
-void *
-renderer(void *data)
-{
- int pagenumber = ((struct data *) data)->pagenumber;
- fz_context *ctx = ((struct data *) data)->ctx;
- fz_display_list *list = ((struct data *) data)->list;
- fz_rect bbox = ((struct data *) data)->bbox;
- fz_pixmap *pix = ((struct data *) data)->pix;
-
- fprintf(stderr, "thread at page %d loading!\n", pagenumber);
-
- // The context pointer is pointing to the main thread's
- // context, so here we create a new context based on it for
- // use in this thread.
-
- ctx = fz_clone_context(ctx);
-
- // Next we run the display list through the draw device which
- // will render the request area of the page to the pixmap.
-
- fprintf(stderr, "thread at page %d rendering!\n", pagenumber);
- fz_device *dev = fz_new_draw_device(ctx, pix);
- fz_run_display_list(list, dev, &fz_identity, &bbox, NULL);
- fz_free_device(dev);
-
- // This threads context is freed.
-
- fz_free_context(ctx);
-
- fprintf(stderr, "thread at page %d done!\n", pagenumber);
-
- return data;
-}
-
-// These are the two locking functions required by MuPDF when
-// operating in a multi-threaded environment. They each take a user
-// argument that can be used to transfer some state, in this case a
-// pointer to the array of mutexes.
-
-void lock_mutex(void *user, int lock)
-{
- pthread_mutex_t *mutex = (pthread_mutex_t *) user;
-
- if (pthread_mutex_lock(&mutex[lock]) != 0)
- fail("pthread_mutex_lock()");
-}
-
-void unlock_mutex(void *user, int lock)
-{
- pthread_mutex_t *mutex = (pthread_mutex_t *) user;
-
- if (pthread_mutex_unlock(&mutex[lock]) != 0)
- fail("pthread_mutex_unlock()");
-}
-
-int main(int argc, char **argv)
-{
- char *filename = argv[1];
- pthread_t *thread = NULL;
- fz_locks_context locks;
- pthread_mutex_t mutex[FZ_LOCK_MAX];
- int i;
-
- // Initialize FZ_LOCK_MAX number of non-recursive mutexes.
-
- for (i = 0; i < FZ_LOCK_MAX; i++)
- {
- if (pthread_mutex_init(&mutex[i], NULL) != 0)
- fail("pthread_mutex_init()");
- }
-
- // Initialize the locking structure with function pointers to
- // the locking functions and to the user data. In this case
- // the user data is a pointer to the array of mutexes so the
- // locking functions can find the relevant lock to change when
- // they are called. This way we avoid global variables.
-
- locks.user = mutex;
- locks.lock = lock_mutex;
- locks.unlock = unlock_mutex;
-
- // This is the main threads context function, so supply the
- // locking structure. This context will be used to parse all
- // the pages from the document.
-
- fz_context *ctx = fz_new_context(NULL, &locks, FZ_STORE_UNLIMITED);
-
- // Open the PDF, XPS or CBZ document.
-
- fz_document *doc = fz_open_document(ctx, filename);
-
- // Retrieve the number of pages, which translates to the
- // number of threads used for rendering pages.
-
- int threads = fz_count_pages(doc);
- fprintf(stderr, "spawning %d threads, one per page...\n", threads);
-
- thread = malloc(threads * sizeof (pthread_t));
-
- for (i = 0; i < threads; i++)
- {
- // Load the relevant page for each thread.
-
- fz_page *page = fz_load_page(doc, i);
-
- // Compute the bounding box for each page.
-
- fz_rect bbox;
- fz_irect rbox;
- fz_bound_page(doc, page, &bbox);
-
- // Create a display list that will hold the drawing
- // commands for the page.
-
- fz_display_list *list = fz_new_display_list(ctx);
-
- // Run the loaded page through a display list device
- // to populate the page's display list.
-
- fz_device *dev = fz_new_list_device(ctx, list);
- fz_run_page(doc, page, dev, &fz_identity, NULL);
- fz_free_device(dev);
-
- // The page is no longer needed, all drawing commands
- // are now in the display list.
-
- fz_free_page(doc, page);
-
- // Create a white pixmap using the correct dimensions.
-
- fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), fz_round_rect(&rbox, &bbox));
- fz_clear_pixmap_with_value(ctx, pix, 0xff);
-
- // Populate the data structure to be sent to the
- // rendering thread for this page.
-
- struct data *data = malloc(sizeof (struct data));
-
- data->pagenumber = i + 1;
- data->ctx = ctx;
- data->list = list;
- data->bbox = bbox;
- data->pix = pix;
-
- // Create the thread and pass it the data structure.
-
- if (pthread_create(&thread[i], NULL, renderer, data) != 0)
- fail("pthread_create()");
- }
-
- // Now each thread is rendering pages, so wait for each thread
- // to complete its rendering.
-
- fprintf(stderr, "joining %d threads...\n", threads);
- for (i = threads - 1; i >= 0; i--)
- {
- char filename[42];
- struct data *data;
-
- if (pthread_join(thread[i], (void **) &data) != 0)
- fail("pthread_join");
-
- sprintf(filename, "out%04d.png", i);
- fprintf(stderr, "\tSaving %s...\n", filename);
-
- // Write the rendered image to a PNG file
-
- fz_write_png(ctx, data->pix, filename, 0);
-
- // Free the thread's pixmap and display list since
- // they were allocated by the main thread above.
-
- fz_drop_pixmap(ctx, data->pix);
- fz_free_display_list(ctx, data->list);
-
- // Free the data structured passed back and forth
- // between the main thread and rendering thread.
-
- free(data);
- }
-
- fprintf(stderr, "finally!\n");
- fflush(NULL);
-
- free(thread);
-
- // Finally the document is closed and the main thread's
- // context is freed.
-
- fz_close_document(doc);
- fz_free_context(ctx);
-
- return 0;
-}
diff --git a/doc/naming.txt b/doc/naming.txt
deleted file mode 100644
index 6c641c33..00000000
--- a/doc/naming.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Functions should be named according to one of the following schemes:
-
- verb_noun
- verb_noun_with_noun
-
- noun_attribute
- get_noun_attribute -- when the 'noun_attribute' name conflicts with a type
- set_noun_attribute
-
-Prefixes are mandatory for exported functions, macros, enums, globals and types.
-
- fz for common code
- pdf, xps, etc., for interpreter specific code
-
-Prefixes are optional (but encouraged) for private functions and types.
-
-Avoid using 'get' as this is a meaningless and redundant filler word.
-
-These words are reserved for reference counting schemes:
-
- new, find, load, open, keep -- return objects that you are responsible for freeing.
-
- drop, free, close -- relinquish ownership of the object passed in.
-
-When searching for an object or value, the name used depends on whether
-returning the value is passing ownership:
-
- lookup -- return a value or borrowed pointer
-
- find -- return an object that the caller is responsible for freeing
diff --git a/doc/overview.txt b/doc/overview.txt
deleted file mode 100644
index 2d4e25d7..00000000
--- a/doc/overview.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-Contents
-========
-
-* Basic MuPDF usage example
-* Common function arguments
-* Error Handling
-* Multi-threading
-
-Basic MuPDF usage example
-=========================
-
-For an example of how to use MuPDF in the most basic way, see
-doc/example.c. To limit the complexity and give an easier introduction
-this code has no error handling at all, but any serious piece of code
-using MuPDF should use the error handling strategies described below.
-
-Common function arguments
-=========================
-
-Many functions in MuPDFs interface take a context argument.
-
-A context contains global state used by MuPDF inside functions when
-parsing or rendering pages of the document. It contains for example:
-
- an exception stack (see error handling below),
-
- a memory allocator (allowing for custom allocators)
-
- a resource store (for caching of images, fonts, etc.)
-
- a set of locks and (un-)locking functions (for multi-threading)
-
-Other functions in MuPDF's interface take arguments such as document,
-stream and device which contain state for each type of object. Those
-arguments each have a reference to a context and therefore act as
-proxies for a context.
-
-Without the set of locks and accompanying functions the context and
-its proxies may only be used in a single-threaded application.
-
-Error handling
-==============
-
-MuPDF uses a set of exception handling macros to simplify error return
-and cleanup. Conceptually, they work a lot like C++'s try/catch
-system, but do not require any special compiler support.
-
-The basic formulation is as follows:
-
- fz_try(ctx)
- {
- // Try to perform a task. Never 'return', 'goto' or
- // 'longjmp' out of here. 'break' may be used to
- // safely exit (just) the try block scope.
- }
- fz_always(ctx)
- {
- // Any code here is always executed, regardless of
- // whether an exception was thrown within the try or
- // not. Never 'return', 'goto' or longjmp out from
- // here. 'break' may be used to safely exit (just) the
- // always block scope.
- }
- fz_catch(ctx)
- {
- // This code is called (after any always block) only
- // if something within the fz_try block (including any
- // functions it called) threw an exception. The code
- // here is expected to handle the exception (maybe
- // record/report the error, cleanup any stray state
- // etc) and can then either exit the block, or pass on
- // the exception to a higher level (enclosing) fz_try
- // block (using fz_throw, or fz_rethrow).
- }
-
-The fz_always block is optional, and can safely be omitted.
-
-The macro based nature of this system has 3 main limitations:
-
-1) Never return from within try (or 'goto' or longjmp out of it).
- This upsets the internal housekeeping of the macros and will
- cause problems later on. The code will detect such things
- happening, but by then it is too late to give a helpful error
- report as to where the original infraction occurred.
-
-2) The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... }
- is not one atomic C statement. That is to say, if you do:
-
- if (condition)
- fz_try(ctx) { ... }
- fz_catch(ctx) { ... }
-
- then you will not get what you want. Use the following instead:
-
- if (condition) {
- fz_try(ctx) { ... }
- fz_catch(ctx) { ... }
- }
-
-3) The macros are implemented using setjmp and longjmp, and so
- the standard C restrictions on the use of those functions
- apply to fz_try/fz_catch too. In particular, any "truly local"
- variable that is set between the start of fz_try and something
- in fz_try throwing an exception may become undefined as part
- of the process of throwing that exception.
-
- As a way of mitigating this problem, we provide an fz_var()
- macro that tells the compiler to ensure that that variable is
- not unset by the act of throwing the exception.
-
-A model piece of code using these macros then might be:
-
- house build_house(plans *p)
- {
- material m = NULL;
- walls w = NULL;
- roof r = NULL;
- house h = NULL;
- tiles t = make_tiles();
-
- fz_var(w);
- fz_var(r);
- fz_var(h);
-
- fz_try(ctx)
- {
- fz_try(ctx)
- {
- m = make_bricks();
- }
- fz_catch(ctx)
- {
- // No bricks available, make do with straw?
- m = make_straw();
- }
- w = make_walls(m, p);
- r = make_roof(m, t);
- // Note, NOT: return combine(w,r);
- h = combine(w, r);
- }
- fz_always(ctx)
- {
- drop_walls(w);
- drop_roof(r);
- drop_material(m);
- drop_tiles(t);
- }
- fz_catch(ctx)
- {
- fz_throw(ctx, "build_house failed");
- }
- return h;
- }
-
-Things to note about this:
-
-a) If make_tiles throws an exception, this will immediately be
- handled by some higher level exception handler. If it
- succeeds, t will be set before fz_try starts, so there is no
- need to fz_var(t);
-
-b) We try first off to make some bricks as our building material.
- If this fails, we fall back to straw. If this fails, we'll end
- up in the fz_catch, and the process will fail neatly.
-
-c) We assume in this code that combine takes new reference to
- both the walls and the roof it uses, and therefore that w and
- r need to be cleaned up in all cases.
-
-d) We assume the standard C convention that it is safe to destroy
- NULL things.
-
-Multi-threading
-===============
-
-First off, study the basic usage example in doc/example.c and make
-sure you understand how it works as the data structures manipulated
-there will be refered to in this section too.
-
-MuPDF can usefully be built into a multi-threaded application without
-the library needing to know anything threading at all. If the library
-opens a document in one thread, and then sits there as a 'server'
-requesting pages and rendering them for other threads that need them,
-then the library is only ever being called from this one thread.
-
-Other threads can still be used to handle UI requests etc, but as far
-as MuPDF is concerned it is only being used in a single threaded way.
-In this instance, there are no threading issues with MuPDF at all,
-and it can safely be used without any locking, as described in the
-previous sections.
-
-This section will attempt to explain how to use MuPDF in the more
-complex case; where we genuinely want to call the MuPDF library
-concurrently from multiple threads within a single application.
-
-MuPDF can be invoked with a user supplied set of locking functions.
-It uses these to take mutexes around operations that would conflict
-if performed concurrently in multiple threads. By leaving the
-exact implementation of locks to the caller MuPDF remains threading
-library agnostic.
-
-The following simple rules should be followed to ensure that
-multi-threaded operations run smoothly:
-
-1) "No simultaneous calls to MuPDF in different threads are
- allowed to use the same context."
-
- Most of the time it is simplest to just use a different
- context for every thread; just create a new context at the
- same time as you create the thread.
-
-2) "The document is bound to the context with which it is created."
-
- All subsequent accesses to the document implicitly use the same
- context; this means that only 1 thread can ever be accessing
- the document at once. This does not mean that the document can
- only ever be used from one thread, though in many cases this
- is the simplest structure overall.
-
-3) "Any device is bound to the context with which it is created."
-
- All subsequent uses of a device implicitly use the context with
- which it was created; this means that if a device is used with
- a document, it should be created with the same context as that
- document was. This does not mean that the device can only ever
- be used from one thread, though in many cases this is the
- simplest structure overall.
-
-So, how does a multi-threaded example differ from a non-multithreaded
-one?
-
-Firstly, when we create the first context, we call fz_new_context
-as before, but the second argument should be a pointer to a set
-of locking functions.
-
-The calling code should provide FZ_LOCK_MAX mutexes, which will be
-locked/unlocked by MuPDF calling the lock/unlock function pointers
-in the supplied structure with the user pointer from the structure
-and the lock number, i (0 <= i < FZ_LOCK_MAX). These mutexes can
-safely be recursive or non-recursive as MuPDF only calls in a non-
-recursive style.
-
-To make subsequent contexts, the user should NOT call fz_new_context
-again (as this will fail to share important resources such as the
-store and glyphcache), but should rather call fz_clone_context.
-Each of these cloned contexts can be freed by fz_free_context as
-usual.
-
-To open a document, call fz_open_document as usual, passing a context
-and a filename; this context is bound to the document. All future
-calls to access the document will use this context internally.
-
-Only one thread at a time can therefore perform operations such as
-fetching a page, or rendering that page to a display list. Once a
-display list has been obtained however, it can be rendered from any
-other thread (or even from several threads simultaneously, giving
-banded rendering).
-
-This means that an implementer has 2 basic choices when constructing
-an application to use MuPDF in multi-threaded mode. Either he can
-construct it so that a single nominated thread opens the document
-and then acts as a 'server' creating display lists for other threads
-to render, or he can add his own mutex around calls to mupdf that
-use the document. The former is likely to be far more efficient in
-the long run.
-
-For an example of how to do multi-threading see doc/multi-threaded.c
-which has a main thread and one rendering thread per page.
diff --git a/doc/refcount.txt b/doc/refcount.txt
deleted file mode 100644
index e575142a..00000000
--- a/doc/refcount.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Reference counting uses special words in functions to make it easy to remember
-and follow the rules.
-
-Words that take ownership: new, find, load, open, keep.
-
-Words that release ownership: drop, free, close.
-
-If an object is returned by a function with one of the special words that take
-ownership, you are responsible for freeing it by calling "drop" or "free", or
-"close" before you return. You may pass ownership of an owned object by return
-it only if you name the function using one of the special words.
-
-Any objects returned by functions that do not have any of these special words,
-are borrowed and have a limited life time. Do not hold on to them past the
-duration of the current function, or stow them away inside structs. If you need
-to keep the object for longer than that, you have to either "keep" it or make
-your own copy.
diff --git a/doc/thirdparty.txt b/doc/thirdparty.txt
deleted file mode 100644
index 2233b634..00000000
--- a/doc/thirdparty.txt
+++ /dev/null
@@ -1,38 +0,0 @@
- Third Party Libraries Used by MuPDF
- ===================================
-
-
-Library Version Function License URL
-
-
-
-freetype 2.4.11 Font scaling Freetype http://www.freetype.org/
- and rendering License
-
-
-
-jpeg 9.0 JPEG decoding "Free", with
- acknowledgement http://www.ijg.org/
-
-
-
-openjpeg 2.0.0 JPEG 2000 BSD-style http://www.openjpeg.org/
- (with patches) decoding
-
-
-zlib 1.2.7 (De)Flate zlib License http://www.zlib.net/
- compression
-
-
-
-(Optional)
-v8 3.9 JavaScript BSD http://code.google.com/p/v8/
- interpreter
-
-
-
-
-
-NOTE: jbig2dec is included in "thirdparty" but is copyright Artifex Software Inc.
-
-