Merge pull request #4 from moronigranja/format-fix-pr

Format fix pr
This commit is contained in:
SeanOMik 2019-10-30 12:43:47 -05:00 committed by GitHub
commit 1fcd013c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6759 changed files with 2010100 additions and 5 deletions

View File

@ -74,7 +74,7 @@ LIBS := -lstdc++fs -lSDL2_ttf -lSDL2_image -lpng -ljpeg `sdl2-config --libs`
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX) LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/mupdf
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
@ -163,7 +163,7 @@ ifneq ($(ROMFS),)
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
endif endif
.PHONY: $(BUILD) clean all .PHONY: $(BUILD) clean all mupdf
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all: $(BUILD) all: $(BUILD)
@ -181,6 +181,14 @@ else
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
endif endif
#---------------------------------------------------------------------------------
mupdf-clean:
@echo cleaning mupdf ...
@$(MAKE) -C $(CURDIR)/mupdf clean
#---------------------------------------------------------------------------------
mupdf:
@$(MAKE) -f $(CURDIR)/Makefile.mupdf
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
else else

64
Makefile.mupdf Normal file
View File

@ -0,0 +1,64 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
TOOL_PREFIX ?= aarch64-none-elf-
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -O2 -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += -D__SWITCH__ $(INCLUDE) `sdl2-config --cflags`
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -DDEBUG=1 -DTOFU_NOTO= -DTOFU_CJK=
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
.PHONY: mupdf
#---------------------------------------------------------------------------------
mupdf:
@echo Building mupdf ...
@$(shell ./opt/devkitpro/switchvars.sh $<)
$(MAKE) -e -C mupdf \
CC=${TOOL_PREFIX}gcc \
CXX=${TOOL_PREFIX}g++ \
LD=${TOOL_PREFIX}ld \
AR=${TOOL_PREFIX}ar \
RANLIB=${TOOL_PREFIX}ranlib \
XCFLAGS="${CPPFLAGS} ${CFLAGS}" \
USE_SYSTEM_FREETYPE=yes \
USE_SYSTEM_HARFBUZZ=no \
USE_SYSTEM_JBIG2DEC=no \
USE_SYSTEM_JPEGXR=no \
USE_SYSTEM_LCMS2=no \
USE_SYSTEM_LIBJPEG=yes \
USE_SYSTEM_MUJS=no \
USE_SYSTEM_OPENJPEG=no \
USE_SYSTEM_ZLIB=no \
libs
@mkdir -p mupdf/lib
@cp -f mupdf/build/release/*.a mupdf/lib

View File

@ -10,13 +10,14 @@ This is a project I've recently just started working on again. Currently its usi
* Portrait reading view * Portrait reading view
### Current State: ### Current State:
* So far, only **MOST** of the PDF files I've tested works. * Most PDF files work, and all epub, cbz and xps files I've tested work.
### TODO: ### TODO:
* Fix some PDF crashes and all the other file extentions. * Do some extra testing on file compatibility.
* 2 pages side by side in landscape. * 2 pages side by side in landscape.
* Touch screen for going to next page. * Touch screen for going to next page.
* Hardware lock to prevent accidental touches (maybe Vol- ?) (?). * Hardware lock to prevent accidental touches (maybe Vol- ?) (?).
* Save orientation, and dark mode settings.
### Screen Shots: ### Screen Shots:
@ -43,3 +44,16 @@ Dark Mode Book Selection:
Light Mode Landscape Reading: Light Mode Landscape Reading:
<br></br> <br></br>
<img src="screenshots/lightModeLandscape.jpg" width="512" height="288"> <img src="screenshots/lightModeLandscape.jpg" width="512" height="288">
### Building
* Release built with [libnx release v2.4.0](https://github.com/switchbrew/libnx).
* Uses `freetype` and other libs which comes with `switch-portlibs` via `devkitPro pacman`:
```
pacman -S libnx switch-portlibs
```
then run:
```
make mupdf
make
```
to build.

13
mupdf/.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# editorconfig.org settings for mupdf project
root = true
[*]
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
[memento.*]
indent_style = space
indent_size = 4

24
mupdf/.gitattributes vendored Normal file
View File

@ -0,0 +1,24 @@
# Macros:
[attr]tabs whitespace=trailing-space,space-before-tab,indent-with-non-tab,tabwidth=4
[attr]spaces whitespace=trailing-space,space-before-tab,tabs-in-indent
[attr]makefile whitespace=trailing-space,space-before-tab,indent-with-non-tab,tabwidth=8
# Source files:
* text=auto
Make* makefile
*.mk makefile
*.make makefile
*.[chm] tabs
*.java tabs
*.xml tabs
# Documentation files:
*.txt spaces
# Legacy source files:
memento.* spaces
# iOS project files:
*.xib spaces
*.xcscheme spaces
*.json spaces

63
mupdf/.gitignore vendored Normal file
View File

@ -0,0 +1,63 @@
# Optional thirdparty libraryes
thirdparty/luratech
thirdparty/jpegxr
thirdparty/mapping-resources-pdf
thirdparty/cmap-resources
# Generated files:
build
generated
tags
cscope.*
lib
# Editor and file browser turds:
*~
.*.swp
.DS_Store
\#*\#
# Editor settings:
.vimrc
.gradle
*.xcworkspace
*.xcuserdatad
user.make
# Test files:
*.pdf
*.xps
*.epub
*.fb2
*.svg
*.pam
*.pbm
*.pgm
*.ppm
*.jpg
*.jpeg
*.pcl
*.ps
# Temporary and build files:
*.class
*.jar
*.o
*.so
*.zip
*.dll
DerivedData
platform/java/obj
platform/java/libs
platform/java/local.properties
platform/win32/*.user
platform/win32/*.ncb
platform/win32/*.suo
platform/win32/Debug
platform/win32/DebugOpenssl
platform/win32/Profile
platform/win32/Release
platform/win32/ReleaseOpenssl
platform/win32/Memento
platform/win32/x64

503
mupdf/CHANGES Normal file
View File

@ -0,0 +1,503 @@
List of changes since the last release
api: Improved accessors for markup/ink/polygon annotation data.
mutool run: Edit Markup, Ink, and Polygon annotation data.
mutool run: Fill out form fields.
List of changes in MuPDF 1.16.1
mupdf-x11: Changed key bindings to match mupdf-gl.
mupdf-x11: Invert by luminance for dark mode.
android: Fix compilation error.
List of changes in MuPDF 1.16.0
api: Major overhaul of color management architecture.
api: Improved functions to verify/sign PDF documents.
api: Number tree accessor function pdf_lookup_number.
api: Parse and handle more options for PWG output.
api: Removed obsolete gproof document type.
api: User callbacks for warning and error messages.
epub: Changed default page size to A5.
epub: Draw embedded SVG documents in EPUB/XHTML.
epub: New Noto fonts covering more unicode scripts.
epub: Support small-caps font-variant.
pdf: Add Redact annotation type and function to apply redactions.
pdf: Add/remove/change encryption and password when saving PDF files.
pdf: Improvements to text handling in PDF filter processor.
pdf: MP and DP operators now call begin/end_layer device methods.
pdf: New and improved progressive loading.
svg: Draw external images in SVG documents.
mutool show: Add 'form' selector to list PDF form fields.
mutool sign: Sign PDF documents from the command line.
mutool sign: Verify signatures in PDF documents from the command line.
viewer: Option to save a script of user actions for replay with mutool run.
viewer: Runtime toggle for ICC and spot rendering.
viewer: Tooltip when hovering over a link in mupdf-gl.
List of changes in MuPDF 1.15.0
General improvements:
* WebAssembly build target and examples.
* Improved forms API in both C and Java bindings.
* Improved forms JavaScript support.
* Create appearance streams for more form field types.
* Fixed many bugs in ICC color management.
* Fixed many memory leaks in error cleanup.
* Fixed bugs in pdfwrite output.
* Improved text extraction from LaTeX documents with math symbols.
* Improved trace device formatting.
* Support CBZ and CBT files larger than 2Gb.
* Show table of contents for FB2 and XHTML documents.
* Show embedded raster images in SVG and XHTML documents.
* Show FB2 cover page.
* Add option to save PDF files without encryption.
* Add inhibit-spaces option to stext device to turn off missing space detection.
* Simplified fz_try/fz_always/fz_catch macros.
mupdf-gl improvements:
* Automatically open annotation editor when selecting an annotation.
* Full page color tinting option in mupdf-gl.
* Show/hide table of contents sections.
* Trigger a reload with sighup.
* Toggle spot color mode with 'e'.
mutool improvements:
mutool show $PDF outline -- show outline with open/closed state indicator.
mutool show $PDF js -- show document level javascript.
mutool clean -A -- create appearance streams when missing.
mutool clean -AA -- recreate all appearance streams.
mutool run docs/examples/portfolio.js -- extract embedded files from PDF document.
mutool run docs/examples/pdf-dejpx.js -- decompress JPEG2000 images in PDF document.
mutool run docs/examples/fix-s22pdf.js -- fix fonts in documents generated by S22PDF.
Significant API changes:
* New and improved forms API.
* Renamed -DNO_ICC to -DFZ_ENABLE_ICC=0
* Removed fz_annot superclass. Use pdf_annot and pdf_widget directly instead.
* Annotations and Widgets now have separate enumerators.
* Added optional separations argument to pixmap rendering utility functions.
Various cleanups:
Per-function documentation comments moved to the source file.
Hopefully they will stay up to date more often than when they
were hidden away in the header file.
Removed unused internal testing tools: mjsgen and jstest.
Removed TGA output support. Use one of the more common and useful PAM,
PNM, PNG, or TIFF formats instead.
Removed support for PDF portfolios. This work-in-progress feature was
never completed, and only worked for a small subset of files.
Removed support for progressive loading. This rarely used feature added
a lot of complexity and was an unending source of bugs and strange
behaviour. Removing this feature has allowed us to clean up and
simplify large amounts of code, and fix dozens of bugs in one fell
swoop.
List of changes in MuPDF 1.14.0
* New features:
* Added "Source Han Serif" CJK fallback font.
* Added more scripts to the Noto fallback fonts.
* Multi-page PNM support.
* "mutool show" now supports a path syntax for selecting objects to show.
* Build system simplifications:
* Auto-generated CMap, ICC, and JS source files are checked in to git.
* Embedded CMap resources are now generated by a python script.
* Embedded font resources are linked directly if using GNU ld or windows.
* Namegen tool replaced by use of C macros.
* Simplified Makefile.
* Annotation editing:
* New annotation editing mode in mupdf-gl.
* Can create, edit, and delete most annotation types.
* Can create appearance streams for most annotation types.
* Can create appearance streams for Tx form fields.
* Can create appearance streams for Ch form fields.
* Form filling in mupdf-gl:
* Can click buttons, checkboxes, and radioboxes.
* Can fill out text fields using dialog box.
* Can select choice options using dialog box.
* Can verify and sign digital signatures.
* Improved UI for mupdf-gl:
* Password dialog.
* Error dialog.
* Open/save file dialog.
* Snap selection to words or lines by holding control or control+shift.
* Save and restore current location, bookmarks, and navigation history.
* Bug fixes:
* Improved CJK character fallback handling in EPUB.
* API changes:
* Pass rectangle and matrix structs by value.
* Replaced PDF_NAME_Xxx macros with PDF_NAME(Xxx).
* Added PDF_TRUE, PDF_FALSE, and PDF_NULL constant pdf_obj* macros.
* Added helper functions: pdf_dict_get_int, etc.
* Removed 'doc' argument in pdf_new_int, etc.
* Quads instead of rects when highlighting and searching text.
* mutool run: Pass arguments to script in scriptArgs global.
List of changes in MuPDF 1.13.0
* This is primarily a bugfix release.
* New "mutool sign" tool for showing and verifying digital signatures.
* Chinese, Japanese, Korean, Cyrillic, and Greek font support in mutool create.
* Improvements to annotation editing API.
List of changes in MuPDF 1.12.0
* New Android SDK:
New git repositories for the SDK projects:
* mupdf-android-fitz.git has the JNI bindings in a library.
* mupdf-android-viewer.git has the viewer as an activity in a library.
* mupdf-android-viewer-mini.git has the minimalist viewer as an activity in a library.
Binary packages in our Maven repository at http://maven.ghostscript.com:
* com.artifex.mupdf:fitz:1.12.+
* com.artifex.mupdf:viewer:1.12.+
* com.artifex.mupdf:mini:1.12.+
* Color management:
* LCMS2 library for color management.
* CMYK rendering with overprint simulation.
* Spot color rendering.
* Transparency rendering fixes.
* Structured text output improvements:
* Reworked structured text API.
* Faster text searching.
* Highlight and copy text by selecting lines instead of by area.
* New semantic XHTML output format.
* New layout preserving HTML output format.
* Features and improvements:
* Improved non-AA rendering with new scan converter.
* Improved LARGEFILE support.
* Improved TIFF support.
* Improved documentation.
* PCLm output.
* PSD output.
* New "mutool trace" tool.
* New "mutool sign" tool (work in progress).
* Text redaction (work in progress).
* Lots of bug fixes.
List of changes in MuPDF 1.11
* This is primarily a bug fix release.
* Split Android and iOS viewers into separate projects:
* mupdf-viewer-ios.git has the iOS viewer.
* mupdf-viewer-android-old.git has the Android viewer.
* mupdf-viewer-android-nui.git has a new advanced Android viewer.
* mupdf-viewer-android-mini.git has a new minimalist Android viewer.
* PDF portfolio support with command line tool "mutool portfolio".
* Add callbacks to load fallback fonts from the system.
* Use system fonts in Android to reduce install size.
* Flag to disable publisher styles in EPUB layout.
* Improved SVG output.
List of changes in MuPDF 1.10
* Headline changes:
* FictionBook (FB2) e-book support.
* Simple SVG parser (a small subset of SVG only).
* mutool convert: a new document conversion tool and interface.
* Multi-threaded rendering in mudraw.
* Luratech decoders for JBIG2 and JPEG2000 (commercial releases only).
* Optional JPEG-XR support (not included by default for security reasons).
* Updated base 14 fonts from URW.
* New CJK font with language specific variants.
* Hyperlink support in EPUB.
* Reduced memory use:
* New tool muraster: example printer driver with limited RAM usage and automatic banding.
* Alpha channel is now optional in pixmaps.
* More aggressive purging of cached objects.
* Partial image decoding for lower memory use when banding.
* Reduced code size when building with a subset of features:
* Reduced default set of built-in CMap tables to the minimum required.
* FZ_ENABLE_PDF, _XPS, _JS, to disable features at compile time.
* Function level linking.
* Interface changes and cleanups:
* Dropped pdf object generation numbers from public interfaces.
* Simplified PDF page, xobject, and annotation internals.
* Closing and freeing devices and writers are now separate steps.
* Improved PDF annotation editing interface (still a work in progress).
* Document writer interface.
* Banded image writer interface.
* Mobile viewers:
* New JNI interfaces to match capabilities of 'mutool run' javascript.
* New android and desktop java examples using new JNI interface.
List of changes in MuPDF 1.9
* Headline changes:
* New command line tools: create and run.
* New low-level Java interface for desktop and android.
* Bidirectional layout for Arabic and Hebrew scripts.
* Shaping complex scripts for EPUB text layout.
* Noto fallback fonts for EPUB layout.
* mutool create
Create new PDF files from scratch.
Read an annotated content stream in a text file and write a PDF file,
automatically embedding font and image resources.
* mutool run
Run javascript scripts with MuPDF bindings.
The interface is similar to the new Java interface.
* mutool draw
Optional multi-threaded operation (Windows and pthreads).
Optional low memory mode (primarily for testing).
List of changes in MuPDF 1.8
* Headline changes:
* New OpenGL-based barebones desktop viewer.
* New URW fonts with greek and cyrillic.
* 64-bit file support.
* Ghostscript proofing mode (source only; not in shipped binaries).
* EPUB improvements:
* User style sheets.
* GIF images (also for CBZ).
* Table of contents.
* CJK text.
* Page margins.
* Many bug fixes.
* Bug fixes:
* Updated FreeType to version 2.6.1.
* Various font substitution bug fixes.
* Fix setjmp/longjmp behaviour which could cause optimizing compilers to misbehave.
List of changes in MuPDF 1.7a
* Bugfixes
* Fixed bug that allocated too much memory when packing paths.
* Fixed EPUB font scaling bug.
* Fixed EPUB file type handling in viewers.
* Improved tolerance for broken and unsupported CSS.
* Features
* Added mudraw -z option to compress output streams.
List of changes in MuPDF 1.7
* Headline changes:
* New 'Indie dev' licensing options - contact sales@artifex.com for more details.
* New HTML layout engine, and (DRM-free) EPUB viewer.
* Reduced memory usage - displaylists and internal PDF representation take much less memory, reducing total memory use on some files by over 60%.
* Important API changes:
* Bound contexts have been removed; we now pass fz_contexts explicitly.
* Reference counting of paths and text structures.
* Features:
* Add mutool pages option.
* Tweaked rendering to prevent feature dropout in common cases.
* Viewer tweaks
* Better mouse wheel handling
* Shift-space support
* Mouse button control of presentation mode
* Internal changes:
* Removal of bound contexts; fz_contexts now passed explicitly everywhere.
* PDF filter revamp - simpler interface.
* Devices use derived structures rather than user pointer.
* Sparse PDF xrefs held in more compact form.
* New gsview viewer split out to its own repository.
* Bug fixes
* Improved handling of broken files.
* Fix BBoxes of Type 3 fonts.
* Updated fonts (including greek and cyrillic).
* Various memory leaks and crashes.
* And many more.
List of changes in MuPDF 1.6
* Features:
* Color detection device (mudraw -T).
* Sepia mode full-page color tinting in X11 and win32 viewer (keybinding: shift-C).
* Re-implement printf and strtod due to portability issue with locales and number formatting.
* Add 'gsview' project: a Windows Modern UI viewer.
* Improve XML parser interface.
* Bug fixes:
* CBZ page ordering
* ZIP64 support
* iOS and Android bug fixes
* Miscellaneous minor fixes
List of changes in MuPDF 1.5
* Bug fixes.
List of changes in MuPDF 1.4
* Headline changes:
* CMYK rendering (mudraw PWG and PAM formats)
* TIFF viewer (with multi-page support).
* Added MuJS Javascript interpreter.
* MuJS is the default, V8 and JavaScriptCore are compile time options.
* Javascript support has to be explicitly enabled with pdf_enable_js.
* All viewers now have JavaScript enabled in the default builds.
* Viewers:
* X11: Horizontal scroll wheel support.
* X11: Status bar display with warnings.
* Android: Digital signatures.
* iOS: Links, form filling, annotation editing, and javascript.
* iOS: Reflow mode.
* WinRT: Printing.
* WinRT: Improved zooming behaviour.
* Tools:
* mudraw: Banded rendering with -B /band-height/.
* mudraw: Select output format with -F /format/.
* mudraw: Write to stdout if you use '-' as the output file name.
* mudraw: Add TGA output format.
* mudraw: Improved SVG output.
* mutool show: Write output to file instead of stdout with -o /filename/.
* mutool clean: Clean content streams with -s option.
* Annotations:
* Improved font handling.
* Form fields.
* Free text.
* Sticky notes.
* Optimizations:
* glyph cache: Partial eviction.
* glyph cache: Run-length compressed glyphs.
* Smarter handling of subpixel metrics in text rendering.
* Optimized blitting functions.
* Optimized gradient mesh drawing.
* API changes and additions:
* fz_stream API reworked: replace "read" function with "next".
* "Rebind" functions to associate context bound objects with another context:
fz_output, fz_stream, fz_device and fz_document.
* Introduce "document handlers" to detect and open different file types.
* Must now call fz_register_document_handlers() to register the defaults.
* May register your own handlers as well to work with fz_open_document.
* Hook to load system fonts: fz_install_load_system_font_funcs.
* PDF xref cache flushing functions (mark/clear/clear-to-mark).
* Add our own "printf" set of functions to format strings and write to fz_output:
* Format %f as short as possible while preserving precision.
* Has %C for formatting a unicode character as UTF-8.
* Has %M to format fz_matrix.
* Has %R to format fz_rect.
* Has %q and %( to format strings with escaped characters.
* PDF process interface: allow PDF interpreter to do more than just draw!
* Content stream state cleaning filter.
* Content stream rewriting filter.
* PDF digital signatures.
* Stroke states may now be stored on the stack.
* Improved fz_path internals.
* Gradient mesh drawing interface has been improved.
* Save files with incremental updates.
List of changes in MuPDF 1.3
* Windows RT viewer app for MuPDF.
* Library changes to support progressive loading (display PDF files as
they download). Windows/Linux/MacOS viewer supports this using curl.
* Incremental updates to PDF files are now (optionally) preserved on
loading/saving.
* Prototype support for checking PDF Digital Signatures.
* Initial annotation support (strike-out, underline, highlight and ink)
(library and android builds only).
* Fix operation on Android API level 8.
* Android redraw optimisations.
* Android app now supports Google Cloud Print.
* Android app translated into many languages.
* Android support for more architectures.
* Improvements to store (avoid collisions causing unnecessary evictions).
* Windows apps use Unicode filenames now.
* PDF function handling improved; functions can now be passed to devices
without 'sampling'.
* PDF image handling improved; images can now be passed to devices
without decompression.
* Indexed images are no longer uncompressed at load time, saving memory.
* Caching of rendered tiles for speed.
* Improved text analysis mode, capable of spotting columns/indents,
right-to-left text etc.
* HTML output mode now includes image output.
* PDF password encoding handling improved.
* MuPDF now opens Jpeg, Tiff and PNG files directly.
* Bug preventing OpenXPS files from being opened fixed.
* Initial (feature incomplete) SVG and PDF output devices.
* PWG raster (mono/grey/RGB) and PCL (mono) output devices.
* Various performance improvements (including tilings and mesh based
shadings).
* Revamped directory structure to reflect recent changes.
* Various potential SEGV, SoftMask and rendering fixes.
* Many potential crashes in Jpeg2000 and JBIG2 images fixed.
List of changes in MuPDF 1.2
* Important API changes:
* fz_bbox is now fz_irect.
* APIs (including fz_device) now pass fz_rect/fz_matrix by reference.
* fz_device API is now more consistent with regards to use of
fz_rect rather than fz_bbox.
* Add support for Javascript and forms handling.
* Fix many SEGVs with out of spec files. Many thanks to Mateusz "j00ru"
Jurczyk and Gynvael Coldwind of the Google Security team, zeniko,
Sebastian Rasmussen and all other contributors.
* Add fz_open_document_with_stream to allow non-file based operation.
* Move to using git submodules for third party libraries.
* Much enhanced Android application. Now on Google Play!
* Oversized and stroke text clipping implemented.
* Change shadings to decompose at render times; massive memory savings.
* Renamed 'mubusy' to 'mutool'.
* PDF 1.7 Extension Level 8 encryption implemented.
* Added consts to various parts of the API to help C++ interworking.
* Prototype transition support.
* Text searching API moved to fitz.
* Highlight and copy text selections.
* Performance enhancements for color conversion and fax decompression.
* ARM optimisations for color conversion and bitmap scaling.
* Bitmap subsampling stage introduced, with ARM optimisations.
* Type 3 fonts; glyphs are now handled as display lists.
* Scan converter performance improvements.
* Various rendering fixes.
List of changes in MuPDF 1.1
* Rendering bugs fixed (text clipping, stroked text etc).
* Better handling of 'large' (uncachable) glyphs.
* Added a delete button to the library view on the iOS port.
* Minor speed optimisations.
* Shading bug fixes.
* Move to using dynamically allocated parsing buffers (more resilient).
* Support for UserUnits.
* Fix bugs with image predictors (including with 16 bit images).
* More resilient to out of spec files.
* Extract pdf writing capability into the library from pdfclean, and
expand on it to allow for linearisation. Bug fixes in the garbage
collection of unused objects.
* Improve pdf writing recognition of images.
* Improved font matching.
* Start to move away from macros to inline functions (helpful for
applications requiring certification).
* Many bugs fixed.

12
mupdf/CONTRIBUTORS Normal file
View File

@ -0,0 +1,12 @@
MuPDF was developed by Artifex Software, who own the copyright.
Along the way various patches for bug fixes and features were
contributed by many outside developers. We are grateful for
these contributions, and while privacy/brevity/confidentiality
prevent us from listing everyone here, we would like to thank
the following in particular:
* Simon Bünzli (zeniko, of the SumatraPDF project).
* Krzysztof Kowalczyk (of the SumatraPDF project).
* Sebastian Rasmussen (Sebras).

661
mupdf/COPYING Normal file
View File

@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

396
mupdf/Makefile Normal file
View File

@ -0,0 +1,396 @@
# GNU Makefile
-include user.make
ifndef build
build := release
endif
ifndef OUT
OUT := build/$(build)
endif
default: all
# --- Configuration ---
include Makerules
include Makethird
# Do not specify CFLAGS or LIBS on the make invocation line - specify
# XCFLAGS or XLIBS instead. Make ignores any lines in the makefile that
# set a variable that was set on the command line.
CFLAGS += $(XCFLAGS) -Iinclude
LIBS += $(XLIBS) -lm
ifneq ($(threading),no)
ifeq ($(HAVE_PTHREAD),yes)
THREADING_CFLAGS := $(PTHREAD_CFLAGS) -DHAVE_PTHREAD
THREADING_LIBS := $(PTHREAD_LIBS)
endif
endif
ifeq ($(HAVE_WIN32),yes)
WIN32_LIBS := -lcomdlg32 -lgdi32
WIN32_LDFLAGS := -Wl,-subsystem,windows
endif
# --- Commands ---
ifneq ($(verbose),yes)
QUIET_AR = @ echo " AR $@" ;
QUIET_RANLIB = @ echo " RANLIB $@" ;
QUIET_CC = @ echo " CC $@" ;
QUIET_CXX = @ echo " CXX $@" ;
QUIET_GEN = @ echo " GEN $@" ;
QUIET_LINK = @ echo " LINK $@" ;
QUIET_RM = @ echo " RM $@" ;
QUIET_TAGS = @ echo " TAGS $@" ;
QUIET_WINDRES = @ echo " WINDRES $@" ;
QUIET_OBJCOPY = @ echo " OBJCOPY $@" ;
endif
MKTGTDIR = mkdir -p $(dir $@)
CC_CMD = $(QUIET_CC) $(MKTGTDIR) ; $(CC) $(CFLAGS) -MMD -MP -o $@ -c $<
CXX_CMD = $(QUIET_CXX) $(MKTGTDIR) ; $(CXX) $(CFLAGS) -MMD -MP -o $@ -c $<
AR_CMD = $(QUIET_AR) $(MKTGTDIR) ; $(AR) cr $@ $^
ifdef RANLIB
RANLIB_CMD = $(QUIET_RANLIB) $(RANLIB) $@
endif
LINK_CMD = $(QUIET_LINK) $(MKTGTDIR) ; $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
TAGS_CMD = $(QUIET_TAGS) ctags -R
WINDRES_CMD = $(QUIET_WINDRES) $(MKTGTDIR) ; $(WINDRES) $< $@
OBJCOPY_CMD = $(QUIET_OBJCOPY) $(MKTGTDIR) ; $(LD) -r -b binary -o $@ $<
# --- Rules ---
$(OUT)/%.a :
$(AR_CMD)
$(RANLIB_CMD)
$(OUT)/%.exe: %.c
$(LINK_CMD)
$(OUT)/source/helpers/mu-threads/%.o : source/helpers/mu-threads/%.c
$(CC_CMD) $(THREADING_CFLAGS)
$(OUT)/source/helpers/pkcs7/%.o : source/helpers/pkcs7/%.c
$(CC_CMD) $(LIBCRYPTO_CFLAGS)
$(OUT)/source/tools/%.o : source/tools/%.c
$(CC_CMD) -Wall $(THIRD_CFLAGS) $(THREADING_CFLAGS)
$(OUT)/generated/%.o : generated/%.c
$(CC_CMD) -O0
$(OUT)/platform/x11/%.o : platform/x11/%.c
$(CC_CMD) -Wall $(X11_CFLAGS)
$(OUT)/platform/x11/curl/%.o : platform/x11/%.c
$(CC_CMD) -Wall $(X11_CFLAGS) $(CURL_CFLAGS) -DHAVE_CURL
$(OUT)/platform/gl/%.o : platform/gl/%.c
$(CC_CMD) -Wall $(THIRD_CFLAGS) $(GLUT_CFLAGS)
ifeq ($(HAVE_OBJCOPY),yes)
$(OUT)/source/fitz/noto.o : source/fitz/noto.c
$(CC_CMD) -Wall -Wdeclaration-after-statement -DHAVE_OBJCOPY $(THIRD_CFLAGS)
endif
$(OUT)/source/%.o : source/%.c
$(CC_CMD) -Wall -Wdeclaration-after-statement $(THIRD_CFLAGS)
$(OUT)/platform/%.o : platform/%.c
$(CC_CMD) -Wall
$(OUT)/%.o: %.rc
$(WINDRES_CMD)
.PRECIOUS : $(OUT)/%.o # Keep intermediates from chained rules
.PRECIOUS : $(OUT)/%.exe # Keep intermediates from chained rules
# --- File lists ---
THIRD_OBJ := $(THIRD_SRC:%.c=$(OUT)/%.o)
THIRD_OBJ := $(THIRD_OBJ:%.cc=$(OUT)/%.o)
MUPDF_SRC := $(sort $(wildcard source/fitz/*.c))
MUPDF_SRC += $(sort $(wildcard source/pdf/*.c))
MUPDF_SRC += $(sort $(wildcard source/xps/*.c))
MUPDF_SRC += $(sort $(wildcard source/svg/*.c))
MUPDF_SRC += $(sort $(wildcard source/html/*.c))
MUPDF_SRC += $(sort $(wildcard source/cbz/*.c))
MUPDF_OBJ := $(MUPDF_SRC:%.c=$(OUT)/%.o)
THREAD_SRC := source/helpers/mu-threads/mu-threads.c
THREAD_OBJ := $(THREAD_SRC:%.c=$(OUT)/%.o)
PKCS7_SRC := source/helpers/pkcs7/pkcs7-check.c
PKCS7_SRC += source/helpers/pkcs7/pkcs7-openssl.c
PKCS7_OBJ := $(PKCS7_SRC:%.c=$(OUT)/%.o)
# --- Generated embedded font files ---
HEXDUMP_EXE := $(OUT)/scripts/hexdump.exe
FONT_BIN := $(sort $(wildcard resources/fonts/urw/*.cff))
FONT_BIN += $(sort $(wildcard resources/fonts/han/*.ttc))
FONT_BIN += $(sort $(wildcard resources/fonts/droid/*.ttf))
FONT_BIN += $(sort $(wildcard resources/fonts/noto/*.otf))
FONT_BIN += $(sort $(wildcard resources/fonts/noto/*.ttf))
FONT_BIN += $(sort $(wildcard resources/fonts/sil/*.cff))
FONT_GEN := $(FONT_BIN:%=generated/%.c)
generated/%.cff.c : %.cff $(HEXDUMP_EXE) ; $(QUIET_GEN) $(MKTGTDIR) ; $(HEXDUMP_EXE) -s $@ $<
generated/%.otf.c : %.otf $(HEXDUMP_EXE) ; $(QUIET_GEN) $(MKTGTDIR) ; $(HEXDUMP_EXE) -s $@ $<
generated/%.ttf.c : %.ttf $(HEXDUMP_EXE) ; $(QUIET_GEN) $(MKTGTDIR) ; $(HEXDUMP_EXE) -s $@ $<
generated/%.ttc.c : %.ttc $(HEXDUMP_EXE) ; $(QUIET_GEN) $(MKTGTDIR) ; $(HEXDUMP_EXE) -s $@ $<
ifeq ($(HAVE_OBJCOPY),yes)
MUPDF_OBJ += $(FONT_BIN:%=$(OUT)/%.o)
$(OUT)/%.cff.o : %.cff ; $(OBJCOPY_CMD)
$(OUT)/%.otf.o : %.otf ; $(OBJCOPY_CMD)
$(OUT)/%.ttf.o : %.ttf ; $(OBJCOPY_CMD)
$(OUT)/%.ttc.o : %.ttc ; $(OBJCOPY_CMD)
else
MUPDF_OBJ += $(FONT_GEN:%.c=$(OUT)/%.o)
endif
generate: $(FONT_GEN)
# --- Generated ICC profiles ---
source/fitz/icc/%.icc.h: resources/icc/%.icc
$(QUIET_GEN) xxd -i $< | sed 's/unsigned/static const unsigned/' > $@
generate: source/fitz/icc/gray.icc.h
generate: source/fitz/icc/rgb.icc.h
generate: source/fitz/icc/cmyk.icc.h
generate: source/fitz/icc/lab.icc.h
# --- Generated CMap files ---
CMAP_GEN := $(notdir $(sort $(wildcard resources/cmaps/*)))
CMAP_GEN := $(CMAP_GEN:%=source/pdf/cmaps/%.h)
source/pdf/cmaps/%.h: resources/cmaps/% scripts/cmapdump.py
$(QUIET_GEN) python3 scripts/cmapdump.py > $@ $<
generate: $(CMAP_GEN)
# --- Generated embedded javascript files ---
source/pdf/js/%.js.h: source/pdf/js/%.js scripts/jsdump.sed
$(QUIET_GEN) sed -f scripts/jsdump.sed < $< > $@
generate: source/pdf/js/util.js.h
# --- Library ---
MUPDF_LIB = $(OUT)/libmupdf.a
THIRD_LIB = $(OUT)/libmupdf-third.a
THREAD_LIB = $(OUT)/libmupdf-threads.a
PKCS7_LIB = $(OUT)/libmupdf-pkcs7.a
$(MUPDF_LIB) : $(MUPDF_OBJ)
$(THIRD_LIB) : $(THIRD_OBJ)
$(THREAD_LIB) : $(THREAD_OBJ)
$(PKCS7_LIB) : $(PKCS7_OBJ)
INSTALL_LIBS := $(MUPDF_LIB) $(THIRD_LIB)
# --- Main tools and viewers ---
MUTOOL_SRC := source/tools/mutool.c
MUTOOL_SRC += source/tools/muconvert.c
MUTOOL_SRC += source/tools/mudraw.c
MUTOOL_SRC += source/tools/murun.c
MUTOOL_SRC += source/tools/mutrace.c
MUTOOL_SRC += source/tools/cmapdump.c
MUTOOL_SRC += $(sort $(wildcard source/tools/pdf*.c))
MUTOOL_OBJ := $(MUTOOL_SRC:%.c=$(OUT)/%.o)
MUTOOL_EXE := $(OUT)/mutool
$(MUTOOL_EXE) : $(MUTOOL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB) $(THREAD_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(THREADING_LIBS) $(LIBCRYPTO_LIBS)
TOOL_APPS += $(MUTOOL_EXE)
MURASTER_OBJ := $(OUT)/source/tools/muraster.o
MURASTER_EXE := $(OUT)/muraster
$(MURASTER_EXE) : $(MURASTER_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(THREADING_LIBS)
TOOL_APPS += $(MURASTER_EXE)
ifeq ($(HAVE_GLUT),yes)
MUVIEW_GLUT_SRC += $(sort $(wildcard platform/gl/*.c))
MUVIEW_GLUT_OBJ := $(MUVIEW_GLUT_SRC:%.c=$(OUT)/%.o)
MUVIEW_GLUT_EXE := $(OUT)/mupdf-gl
$(MUVIEW_GLUT_EXE) : $(MUVIEW_GLUT_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB) $(GLUT_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(LIBCRYPTO_LIBS) $(WIN32_LDFLAGS) $(GLUT_LIBS)
VIEW_APPS += $(MUVIEW_GLUT_EXE)
endif
ifeq ($(HAVE_X11),yes)
MUVIEW_X11_EXE := $(OUT)/mupdf-x11
MUVIEW_X11_OBJ += $(OUT)/platform/x11/pdfapp.o
MUVIEW_X11_OBJ += $(OUT)/platform/x11/x11_main.o
MUVIEW_X11_OBJ += $(OUT)/platform/x11/x11_image.o
$(MUVIEW_X11_EXE) : $(MUVIEW_X11_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(X11_LIBS) $(LIBCRYPTO_LIBS)
VIEW_APPS += $(MUVIEW_X11_EXE)
endif
ifeq ($(HAVE_WIN32),yes)
MUVIEW_WIN32_EXE := $(OUT)/mupdf-w32
MUVIEW_WIN32_OBJ += $(OUT)/platform/x11/pdfapp.o
MUVIEW_WIN32_OBJ += $(OUT)/platform/x11/win_main.o
MUVIEW_WIN32_OBJ += $(OUT)/platform/x11/win_res.o
$(MUVIEW_WIN32_EXE) : $(MUVIEW_WIN32_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(WIN32_LDFLAGS) $(WIN32_LIBS) $(LIBCRYPTO_LIBS)
VIEW_APPS += $(MUVIEW_WIN32_EXE)
endif
ifeq ($(HAVE_X11),yes)
ifeq ($(HAVE_CURL),yes)
ifeq ($(HAVE_PTHREAD),yes)
MUVIEW_X11_CURL_EXE := $(OUT)/mupdf-x11-curl
MUVIEW_X11_CURL_OBJ += $(OUT)/platform/x11/curl/pdfapp.o
MUVIEW_X11_CURL_OBJ += $(OUT)/platform/x11/curl/x11_main.o
MUVIEW_X11_CURL_OBJ += $(OUT)/platform/x11/curl/x11_image.o
MUVIEW_X11_CURL_OBJ += $(OUT)/platform/x11/curl/curl_stream.o
MUVIEW_X11_CURL_OBJ += $(OUT)/platform/x11/curl/prog_stream.o
$(MUVIEW_X11_CURL_EXE) : $(MUVIEW_X11_CURL_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(PKCS7_LIB) $(CURL_LIB)
$(LINK_CMD) $(THIRD_LIBS) $(X11_LIBS) $(LIBCRYPTO_LIBS) $(CURL_LIBS) $(PTHREAD_LIBS)
VIEW_APPS += $(MUVIEW_X11_CURL_EXE)
endif
endif
endif
# --- Generated dependencies ---
-include $(MUPDF_OBJ:%.o=%.d)
-include $(PKCS7_OBJ:%.o=%.d)
-include $(THREAD_OBJ:%.o=%.d)
-include $(THIRD_OBJ:%.o=%.d)
-include $(GLUT_OBJ:%.o=%.d)
-include $(MUTOOL_OBJ:%.o=%.d)
-include $(MUVIEW_GLUT_OBJ:%.o=%.d)
-include $(MUVIEW_X11_OBJ:%.o=%.d)
-include $(MUVIEW_WIN32_OBJ:%.o=%.d)
-include $(MURASTER_OBJ:%.o=%.d)
-include $(MUVIEW_X11_CURL_OBJ:%.o=%.d)
# --- Examples ---
$(OUT)/example: docs/examples/example.c $(MUPDF_LIB) $(THIRD_LIB)
$(LINK_CMD) $(CFLAGS) $(THIRD_LIBS)
$(OUT)/multi-threaded: docs/examples/multi-threaded.c $(MUPDF_LIB) $(THIRD_LIB)
$(LINK_CMD) $(CFLAGS) $(THIRD_LIBS) -lpthread
# --- Update version string header ---
VERSION = $(shell git describe --tags)
version:
sed -i~ -e '/FZ_VERSION /s/".*"/"'$(VERSION)'"/' include/mupdf/fitz/version.h
# --- Format man pages ---
%.txt: %.1
nroff -man $< | col -b | expand > $@
MAN_FILES := $(sort $(wildcard docs/man/*.1))
TXT_FILES := $(MAN_FILES:%.1=%.txt)
catman: $(TXT_FILES)
# --- Install ---
prefix ?= /usr/local
bindir ?= $(prefix)/bin
libdir ?= $(prefix)/lib
incdir ?= $(prefix)/include
mandir ?= $(prefix)/share/man
docdir ?= $(prefix)/share/doc/mupdf
third: $(THIRD_LIB)
extra-libs: $(GLUT_LIB)
libs: $(INSTALL_LIBS)
tools: $(TOOL_APPS)
apps: $(TOOL_APPS) $(VIEW_APPS)
install: libs apps
install -d $(DESTDIR)$(incdir)/mupdf
install -d $(DESTDIR)$(incdir)/mupdf/fitz
install -d $(DESTDIR)$(incdir)/mupdf/pdf
install -m 644 include/mupdf/*.h $(DESTDIR)$(incdir)/mupdf
install -m 644 include/mupdf/fitz/*.h $(DESTDIR)$(incdir)/mupdf/fitz
install -m 644 include/mupdf/pdf/*.h $(DESTDIR)$(incdir)/mupdf/pdf
install -d $(DESTDIR)$(libdir)
install -m 644 $(INSTALL_LIBS) $(DESTDIR)$(libdir)
install -d $(DESTDIR)$(bindir)
install -m 755 $(TOOL_APPS) $(VIEW_APPS) $(DESTDIR)$(bindir)
install -d $(DESTDIR)$(mandir)/man1
install -m 644 docs/man/*.1 $(DESTDIR)$(mandir)/man1
install -d $(DESTDIR)$(docdir)
install -d $(DESTDIR)$(docdir)/examples
install -m 644 README COPYING CHANGES $(DESTDIR)$(docdir)
install -m 644 docs/*.html docs/*.css docs/*.png $(DESTDIR)$(docdir)
install -m 644 docs/examples/* $(DESTDIR)$(docdir)/examples
tarball:
bash scripts/archive.sh
# --- Clean and Default ---
WATCH_SRCS = $(shell find include source platform -type f -name '*.[ch]')
watch:
@ inotifywait -q -e modify $(WATCH_SRCS)
watch-recompile:
@ while ! inotifywait -q -e modify $(WATCH_SRCS) ; do time -p $(MAKE) ; done
java:
$(MAKE) -C platform/java
wasm:
$(MAKE) -C platform/wasm
tags:
$(TAGS_CMD)
cscope.files: $(shell find include source platform -name '*.[ch]')
@ echo $^ | tr ' ' '\n' > $@
cscope.out: cscope.files
cscope -b
all: libs apps
clean:
rm -rf $(OUT)
nuke:
rm -rf build/* generated
release:
$(MAKE) build=release
debug:
$(MAKE) build=debug
sanitize:
$(MAKE) build=sanitize
android: generate
ndk-build -j8 \
APP_BUILD_SCRIPT=platform/java/Android.mk \
APP_PROJECT_PATH=build/android \
APP_PLATFORM=android-16 \
APP_OPTIM=$(build)
.PHONY: all clean nuke install third libs apps generate tags wasm

199
mupdf/Makerules Normal file
View File

@ -0,0 +1,199 @@
# Configuration for the Makefile
OS := $(shell uname)
OS := $(OS:MINGW%=MINGW)
OS := $(OS:MSYS%=MINGW)
OS := $(OS:Windows_NT=MINGW)
OS := $(OS:Darwin=MACOS)
ifeq ($(findstring -fembed-bitcode,$(XCFLAGS)),)
# clang does not support these in combination with -fembed-bitcode
CFLAGS += -ffunction-sections -fdata-sections
endif
ifeq ($(OS),MACOS)
LDREMOVEUNREACH := -Wl,-dead_strip
else
LDREMOVEUNREACH := -Wl,--gc-sections
endif
CFLAGS += -Wsign-compare
SANITIZE_FLAGS += -fsanitize=address
SANITIZE_FLAGS += -fsanitize=leak
ifeq ($(build),debug)
CFLAGS += -pipe -g
LDFLAGS += -g
else ifeq ($(build),release)
CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer
LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),small)
CFLAGS += -pipe -Os -DNDEBUG -fomit-frame-pointer
LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),valgrind)
CFLAGS += -pipe -O2 -DNDEBUG -DPACIFY_VALGRIND -fno-omit-frame-pointer
LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),sanitize)
CFLAGS += -pipe -g -fno-omit-frame-pointer $(SANITIZE_FLAGS)
LDFLAGS += -g $(SANITIZE_FLAGS)
else ifeq ($(build),sanitize-release)
CFLAGS += -pipe -O2 -DNDEBUG -fno-omit-frame-pointer $(SANITIZE_FLAGS)
LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s $(SANITIZE_FLAGS)
else ifeq ($(build),profile)
CFLAGS += -pipe -O2 -DNDEBUG -pg
LDFLAGS += -pg
else ifeq ($(build),coverage)
CFLAGS += -pipe -g -pg -fprofile-arcs -ftest-coverage
LIBS += -lgcov
else ifeq ($(build),native)
CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer -march=native
LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),memento)
CFLAGS += -pipe -g -DMEMENTO
LDFLAGS += -g -rdynamic
ifneq ($(HAVE_LIBDL),no)
CFLAGS += -DHAVE_LIBDL
LIBS += -ldl
endif
else ifeq ($(build),gperf)
CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer -DGPERF
LIBS += -lprofiler
else
$(error unknown build setting: '$(build)')
endif
# Default system libraries
SYS_FREETYPE_LIBS := -lfreetype2
SYS_HARFBUZZ_LIBS := -lharfbuzz
SYS_JBIG2DEC_LIBS := -ljbig2dec
SYS_JPEGXR_LIBS := -ljpegxr
SYS_LCMS2_LIBS := -llcms2-art
SYS_LIBJPEG_LIBS := -ljpeg
SYS_MUJS_LIBS := -lmujs
SYS_OPENJPEG_LIBS := -lopenjp2
SYS_ZLIB_LIBS := -lz
ifeq ($(OS),MINGW)
WINDRES := windres
HAVE_WIN32 := yes
else ifeq ($(OS),MACOS)
HAVE_GLUT := yes
SYS_GLUT_CFLAGS := -Wno-deprecated-declarations
SYS_GLUT_LIBS := -framework GLUT -framework OpenGL
CC = xcrun cc
AR = xcrun ar
LD = xcrun ld
RANLIB = xcrun ranlib
else ifeq ($(OS),Linux)
HAVE_OBJCOPY := yes
ifeq ($(shell pkg-config --exists freetype2 && echo yes),yes)
SYS_FREETYPE_CFLAGS := $(shell pkg-config --cflags freetype2)
SYS_FREETYPE_LIBS := $(shell pkg-config --libs freetype2)
endif
ifeq ($(shell pkg-config --exists harfbuzz && echo yes),yes)
SYS_HARFBUZZ_CFLAGS := $(shell pkg-config --cflags harfbuzz)
SYS_HARFBUZZ_LIBS := $(shell pkg-config --libs harfbuzz)
endif
ifeq ($(shell pkg-config --exists lcms2 && echo yes),yes)
SYS_LCMS2_CFLAGS := $(shell pkg-config --cflags lcms2)
SYS_LCMS2_LIBS := $(shell pkg-config --libs lcms2)
endif
ifeq ($(shell pkg-config --exists libjpeg && echo yes),yes)
SYS_LIBJPEG_CFLAGS := $(shell pkg-config --cflags libjpeg)
SYS_LIBJPEG_LIBS := $(shell pkg-config --libs libjpeg)
endif
ifeq ($(shell pkg-config --exists libopenjp2 && echo yes),yes)
SYS_OPENJPEG_CFLAGS := $(shell pkg-config --cflags libopenjp2)
SYS_OPENJPEG_LIBS := $(shell pkg-config --libs libopenjp2)
endif
ifeq ($(shell pkg-config --exists zlib && echo yes),yes)
SYS_ZLIB_CFLAGS := $(shell pkg-config --cflags zlib)
SYS_ZLIB_LIBS := $(shell pkg-config --libs zlib)
endif
HAVE_SYS_CURL := $(shell pkg-config --exists libcurl && echo yes)
ifeq ($(HAVE_SYS_CURL),yes)
SYS_CURL_CFLAGS := $(shell pkg-config --cflags libcurl)
SYS_CURL_LIBS := $(shell pkg-config --libs libcurl)
endif
HAVE_GLUT := yes
ifeq ($(HAVE_GLUT),yes)
SYS_GLUT_CFLAGS :=
SYS_GLUT_LIBS := -lglut -lGL
endif
HAVE_X11 := $(shell pkg-config --exists x11 xext && echo yes)
ifeq ($(HAVE_X11),yes)
X11_CFLAGS := $(shell pkg-config --cflags x11 xext)
X11_LIBS := $(shell pkg-config --libs x11 xext)
endif
HAVE_LIBCRYPTO := $(shell pkg-config --exists 'libcrypto >= 1.1.0' && echo yes)
ifeq ($(HAVE_LIBCRYPTO),yes)
LIBCRYPTO_CFLAGS := $(shell pkg-config --cflags libcrypto) -DHAVE_LIBCRYPTO
LIBCRYPTO_LIBS := $(shell pkg-config --libs libcrypto)
endif
HAVE_PTHREAD := yes
ifeq ($(HAVE_PTHREAD),yes)
PTHREAD_CFLAGS :=
PTHREAD_LIBS := -lpthread
endif
endif
# The following section has various cross compilation configurations.
#
# Invoke these as:
# make OS=mingw32-cross
#
# This does rely on the generated directory being populated with the font files.
# On a unix-like system, run 'make generate' before doing the cross compile.
# On Windows, run 'nmake -f scripts\fontdump.nmake' in a Visual Studio command prompt.
ifeq "$(OS)" "wasm"
OUT := build/wasm/$(build)
CC = emcc
CXX = em++
AR = emar
HAVE_GLUT=no
HAVE_X11=no
HAVE_OBJCOPY=no
HAVE_LIBCRYPTO=no
endif
ifeq "$(OS)" "mingw32-cross"
OUT := build/$(OS)/$(build)
CC = i686-w64-mingw32-gcc
CXX = i686-w64-mingw32-g++
LD = i686-w64-mingw32-gcc
AR = i686-w64-mingw32-ar
WINDRES = i686-w64-mingw32-windres
HAVE_WIN32=yes
endif
ifeq "$(OS)" "mingw64-cross"
OUT := build/$(OS)/$(build)
CC = x86_64-w64-mingw32-gcc
CXX = x86_64-w64-mingw32-g++
LD = x86_64-w64-mingw32-gcc
AR = x86_64-w64-mingw32-ar
WINDRES = x86_64-w64-mingw32-windres
HAVE_WIN32=yes
endif
# Most variables when building for iOS are set up in ios/build_libs.sh,
# which is called from the Xcode project as a "Run Script" build step.
# The following section works for both device and simulator builds.
ifeq "$(OS)" "ios"
CC = xcrun cc
CXX = xcrun c++
AR = xcrun ar
LD = xcrun ld
RANLIB = xcrun ranlib
endif

391
mupdf/Makethird Normal file
View File

@ -0,0 +1,391 @@
# GNU Makefile for third party libraries used by MuPDF
ifeq ($(USE_SYSTEM_LIBS),yes)
USE_SYSTEM_FREETYPE := yes
USE_SYSTEM_HARFBUZZ := yes
USE_SYSTEM_JBIG2DEC := yes
USE_SYSTEM_JPEGXR := no # not available
USE_SYSTEM_LCMS2 := no # lcms2mt is strongly preferred
USE_SYSTEM_LIBJPEG := yes
USE_SYSTEM_MUJS := no # not available
USE_SYSTEM_OPENJPEG := yes
USE_SYSTEM_ZLIB := yes
USE_SYSTEM_GLUT := yes
USE_SYSTEM_CURL := yes
endif
ifeq ($(OS),MACOS)
USE_SYSTEM_GLUT := yes
endif
ifeq ($(OS),Linux)
USE_SYSTEM_CURL := yes
endif
# --- FREETYPE 2 ---
ifeq ($(USE_SYSTEM_FREETYPE),yes)
FREETYPE_CFLAGS += $(SYS_FREETYPE_CFLAGS)
THIRD_CFLAGS += $(FREETYPE_CFLAGS)
THIRD_LIBS += $(SYS_FREETYPE_LIBS)
else
FREETYPE_CFLAGS += -Iscripts/freetype -Ithirdparty/freetype/include
THIRD_SRC += thirdparty/freetype/src/base/ftbase.c
THIRD_SRC += thirdparty/freetype/src/base/ftbbox.c
THIRD_SRC += thirdparty/freetype/src/base/ftbitmap.c
THIRD_SRC += thirdparty/freetype/src/base/ftdebug.c
THIRD_SRC += thirdparty/freetype/src/base/ftgasp.c
THIRD_SRC += thirdparty/freetype/src/base/ftglyph.c
THIRD_SRC += thirdparty/freetype/src/base/ftinit.c
THIRD_SRC += thirdparty/freetype/src/base/ftstroke.c
THIRD_SRC += thirdparty/freetype/src/base/ftsynth.c
THIRD_SRC += thirdparty/freetype/src/base/ftsystem.c
THIRD_SRC += thirdparty/freetype/src/base/fttype1.c
THIRD_SRC += thirdparty/freetype/src/cff/cff.c
THIRD_SRC += thirdparty/freetype/src/cid/type1cid.c
THIRD_SRC += thirdparty/freetype/src/psaux/psaux.c
THIRD_SRC += thirdparty/freetype/src/pshinter/pshinter.c
THIRD_SRC += thirdparty/freetype/src/psnames/psnames.c
THIRD_SRC += thirdparty/freetype/src/raster/raster.c
THIRD_SRC += thirdparty/freetype/src/sfnt/sfnt.c
THIRD_SRC += thirdparty/freetype/src/smooth/smooth.c
THIRD_SRC += thirdparty/freetype/src/truetype/truetype.c
THIRD_SRC += thirdparty/freetype/src/type1/type1.c
THIRD_CFLAGS += $(FREETYPE_CFLAGS)
$(OUT)/thirdparty/freetype/%.o: thirdparty/freetype/%.c
$(CC_CMD) $(FREETYPE_CFLAGS) \
-DFT_CONFIG_MODULES_H=\"slimftmodules.h\" \
-DFT_CONFIG_OPTIONS_H=\"slimftoptions.h\" \
-DFT2_BUILD_LIBRARY
endif
# --- HARFBUZZ ---
ifeq ($(USE_SYSTEM_HARFBUZZ),yes)
THIRD_CFLAGS += $(SYS_HARFBUZZ_CFLAGS)
THIRD_LIBS += $(SYS_HARFBUZZ_LIBS)
else
THIRD_SRC += thirdparty/harfbuzz/src/hb-aat-layout.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-blob.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-buffer-serialize.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-buffer.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-common.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-face.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-fallback-shape.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-font.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ft.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-color.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-face.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-font.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-layout.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-map.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-math.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-default.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-tibetan.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-shape.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-tag.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ot-var.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-set.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-shape-plan.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-shape.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-shaper.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-static.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-ucdn.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-unicode.cc
THIRD_SRC += thirdparty/harfbuzz/src/hb-warning.cc
THIRD_CFLAGS += -Ithirdparty/harfbuzz/src
$(OUT)/thirdparty/harfbuzz/%.o: thirdparty/harfbuzz/%.cc
$(CXX_CMD) $(FREETYPE_CFLAGS) -Iinclude/mupdf \
-DHAVE_FALLBACK=1 \
-DHAVE_OT \
-DHAVE_ROUND \
-DHAVE_UCDN \
-DHB_NO_MT \
-Dhb_malloc_impl=fz_hb_malloc \
-Dhb_calloc_impl=fz_hb_calloc \
-Dhb_free_impl=fz_hb_free \
-Dhb_realloc_impl=fz_hb_realloc \
-fno-exceptions \
-fno-rtti \
-fvisibility-inlines-hidden
endif
# --- JPEG-XR ---
ifeq ($(HAVE_JPEGXR),yes)
ifeq ($(USE_SYSTEM_JPEGXR),yes)
THIRD_CFLAGS += $(SYS_JPEGXR_CFLAGS) -DHAVE_JPEGXR
THIRD_LIBS += $(SYS_JPEGXR_LIBS)
else
THIRD_SRC += thirdparty/jpegxr/Software/algo.c
THIRD_SRC += thirdparty/jpegxr/Software/api.c
THIRD_SRC += thirdparty/jpegxr/Software/cr_parse.c
THIRD_SRC += thirdparty/jpegxr/Software/flags.c
THIRD_SRC += thirdparty/jpegxr/Software/init.c
THIRD_SRC += thirdparty/jpegxr/Software/io.c
THIRD_SRC += thirdparty/jpegxr/Software/jpegxr_pixelformat.c
THIRD_SRC += thirdparty/jpegxr/Software/r_parse.c
THIRD_SRC += thirdparty/jpegxr/Software/r_strip.c
THIRD_SRC += thirdparty/jpegxr/Software/r_tile_frequency.c
THIRD_SRC += thirdparty/jpegxr/Software/r_tile_spatial.c
THIRD_SRC += thirdparty/jpegxr/Software/x_strip.c
THIRD_CFLAGS += -Ithirdparty/jpegxr
THIRD_CFLAGS += -Ithirdparty/jpegxr/Software
THIRD_CFLAGS += -DHAVE_JPEGXR
$(OUT)/thirdparty/jpegxr/%.o: thirdparty/jpegxr/%.c
$(CC_CMD) -Ithirdparty/jpegxr -Ithirdparty/jpegxr/Software -Wno-tautological-compare
endif
endif
# --- LIBJPEG ---
ifeq ($(USE_SYSTEM_LIBJPEG),yes)
THIRD_CFLAGS += $(SYS_LIBJPEG_CFLAGS) -DSHARE_JPEG
THIRD_LIBS += $(SYS_LIBJPEG_LIBS)
else
THIRD_SRC += thirdparty/libjpeg/jaricom.c
THIRD_SRC += thirdparty/libjpeg/jcomapi.c
THIRD_SRC += thirdparty/libjpeg/jdapimin.c
THIRD_SRC += thirdparty/libjpeg/jdapistd.c
THIRD_SRC += thirdparty/libjpeg/jdarith.c
THIRD_SRC += thirdparty/libjpeg/jdatadst.c
THIRD_SRC += thirdparty/libjpeg/jdatasrc.c
THIRD_SRC += thirdparty/libjpeg/jdcoefct.c
THIRD_SRC += thirdparty/libjpeg/jdcolor.c
THIRD_SRC += thirdparty/libjpeg/jddctmgr.c
THIRD_SRC += thirdparty/libjpeg/jdhuff.c
THIRD_SRC += thirdparty/libjpeg/jdinput.c
THIRD_SRC += thirdparty/libjpeg/jdmainct.c
THIRD_SRC += thirdparty/libjpeg/jdmarker.c
THIRD_SRC += thirdparty/libjpeg/jdmaster.c
THIRD_SRC += thirdparty/libjpeg/jdmerge.c
THIRD_SRC += thirdparty/libjpeg/jdpostct.c
THIRD_SRC += thirdparty/libjpeg/jdsample.c
THIRD_SRC += thirdparty/libjpeg/jdtrans.c
THIRD_SRC += thirdparty/libjpeg/jerror.c
THIRD_SRC += thirdparty/libjpeg/jfdctflt.c
THIRD_SRC += thirdparty/libjpeg/jfdctfst.c
THIRD_SRC += thirdparty/libjpeg/jfdctint.c
THIRD_SRC += thirdparty/libjpeg/jidctflt.c
THIRD_SRC += thirdparty/libjpeg/jidctfst.c
THIRD_SRC += thirdparty/libjpeg/jidctint.c
THIRD_SRC += thirdparty/libjpeg/jmemmgr.c
THIRD_SRC += thirdparty/libjpeg/jquant1.c
THIRD_SRC += thirdparty/libjpeg/jquant2.c
THIRD_SRC += thirdparty/libjpeg/jutils.c
THIRD_CFLAGS += -Iscripts/libjpeg -Ithirdparty/libjpeg
$(OUT)/thirdparty/libjpeg/%.o: thirdparty/libjpeg/%.c
$(CC_CMD) -Iscripts/libjpeg
endif
# --- LCMS2 ---
ifeq ($(USE_SYSTEM_LCMS2),yes)
THIRD_CFLAGS += $(SYS_LCMS2_CFLAGS)
THIRD_LIBS += $(SYS_LCMS2_LIBS)
else
THIRD_SRC += $(sort $(wildcard thirdparty/lcms2/src/cms*.c))
THIRD_CFLAGS += -Ithirdparty/lcms2/include -DHAVE_LCMS2MT
$(OUT)/thirdparty/lcms2/%.o: thirdparty/lcms2/%.c
$(CC_CMD) -Ithirdparty/lcms2/include
endif
# --- MuJS ---
ifeq ($(USE_SYSTEM_MUJS),yes)
THIRD_CFLAGS += $(SYS_MUJS_CFLAGS)
THIRD_LIBS += $(SYS_MUJS_LIBS)
else
THIRD_SRC += thirdparty/mujs/one.c
THIRD_CFLAGS += -Ithirdparty/mujs
$(OUT)/thirdparty/mujs/%.o: thirdparty/mujs/%.c
$(CC_CMD)
endif
# --- ZLIB ---
ifeq ($(USE_SYSTEM_ZLIB),yes)
THIRD_CFLAGS += $(SYS_ZLIB_CFLAGS)
THIRD_LIBS += $(SYS_ZLIB_LIBS)
else
THIRD_SRC += thirdparty/zlib/adler32.c
THIRD_SRC += thirdparty/zlib/compress.c
THIRD_SRC += thirdparty/zlib/crc32.c
THIRD_SRC += thirdparty/zlib/deflate.c
THIRD_SRC += thirdparty/zlib/inffast.c
THIRD_SRC += thirdparty/zlib/inflate.c
THIRD_SRC += thirdparty/zlib/inftrees.c
THIRD_SRC += thirdparty/zlib/trees.c
THIRD_SRC += thirdparty/zlib/uncompr.c
THIRD_SRC += thirdparty/zlib/zutil.c
THIRD_CFLAGS += -Ithirdparty/zlib
$(OUT)/thirdparty/zlib/%.o: thirdparty/zlib/%.c
$(CC_CMD) -DHAVE_UNISTD_H -DHAVE_STDARG_H
endif
# --- LURATECH ---
ifeq ($(HAVE_LURATECH),yes)
THIRD_SRC += $(sort $(wildcard thirdparty/luratech/ldf_jb2/source/common/*.c))
THIRD_SRC += $(sort $(wildcard thirdparty/luratech/ldf_jb2/source/compress/*.c))
THIRD_SRC += $(sort $(wildcard thirdparty/luratech/lwf_jp2/library/source/*.c))
LURATECH_CFLAGS += -Ithirdparty/luratech/ldf_jb2/source/libraries
LURATECH_CFLAGS += -Ithirdparty/luratech/ldf_jb2/source/compress
LURATECH_CFLAGS += -Ithirdparty/luratech/ldf_jb2/source/common
LURATECH_CFLAGS += -Ithirdparty/luratech/lwf_jp2/library/source
THIRD_CFLAGS += $(LURATECH_CFLAGS) -DHAVE_LURATECH
$(OUT)/thirdparty/luratech/%.o: thirdparty/luratech/%.c
$(CC_CMD) -DLINUX $(LURATECH_CFLAGS) -Wno-tautological-compare -Wno-absolute-value -Wno-sign-compare
else # HAVE_LURATECH
# --- JBIG2DEC ---
ifeq ($(USE_SYSTEM_JBIG2DEC),yes)
THIRD_CFLAGS += $(SYS_JBIG2DEC_CFLAGS)
THIRD_LIBS += $(SYS_JBIG2DEC_LIBS)
else
THIRD_SRC += thirdparty/jbig2dec/jbig2.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_arith.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_arith_iaid.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_arith_int.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_generic.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_halftone.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_huffman.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_image.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_mmr.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_page.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_refinement.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_segment.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_symbol_dict.c
THIRD_SRC += thirdparty/jbig2dec/jbig2_text.c
THIRD_CFLAGS += -Ithirdparty/jbig2dec
$(OUT)/thirdparty/jbig2dec/%.o: thirdparty/jbig2dec/%.c
$(CC_CMD) -DHAVE_STDINT_H -DJBIG_EXTERNAL_MEMENTO_H=\"mupdf/memento.h\" -Wno-sign-compare
endif
# --- OPENJPEG ---
ifeq ($(USE_SYSTEM_OPENJPEG),yes)
THIRD_CFLAGS += $(SYS_OPENJPEG_CFLAGS)
THIRD_LIBS += $(SYS_OPENJPEG_LIBS)
else
OPENJPEG_CFLAGS += -Ithirdparty/openjpeg/src/lib/openjp2
OPENJPEG_CFLAGS += -DOPJ_STATIC
OPENJPEG_CFLAGS += -DOPJ_HAVE_STDINT_H -DOPJ_HAVE_INTTYPES_H
OPENJPEG_CFLAGS += -DMUTEX_pthread=0
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/bio.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/cio.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/dwt.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/event.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/function_list.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/image.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/invert.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/j2k.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/jp2.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/mct.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/mqc.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/openjpeg.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/pi.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/sparse_array.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/t1.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/t2.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/tcd.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/tgt.c
THIRD_SRC += thirdparty/openjpeg/src/lib/openjp2/thread.c
THIRD_CFLAGS += $(OPENJPEG_CFLAGS)
$(OUT)/thirdparty/openjpeg/%.o: thirdparty/openjpeg/%.c
$(CC_CMD) $(OPENJPEG_CFLAGS)
endif
endif # HAVE_LURATECH
# --- FreeGLUT ---
ifeq ($(USE_SYSTEM_GLUT),yes)
GLUT_CFLAGS := $(SYS_GLUT_CFLAGS)
GLUT_LIBS := $(SYS_GLUT_LIBS)
else
GLUT_SRC += $(sort $(wildcard thirdparty/freeglut/src/fg_*.c))
GLUT_SRC += $(sort $(wildcard thirdparty/freeglut/src/x11/*.c))
GLUT_OBJ := $(GLUT_SRC:%.c=$(OUT)/%.o)
LOCAL_GLUT_CFLAGS += -Ithirdparty/freeglut/include
LOCAL_GLUT_CFLAGS += -Ithirdparty/freeglut/src
LOCAL_GLUT_CFLAGS += -DHAVE_UNISTD_H -DHAVE_STDINT_H -DHAVE_X11_EXTENSIONS_XRANDR_H
LOCAL_GLUT_CFLAGS += -Wno-sign-compare
GLUT_LIB := $(OUT)/libfreeglut.a
$(GLUT_LIB): $(GLUT_OBJ)
$(OUT)/thirdparty/freeglut/%.o: thirdparty/freeglut/%.c
$(CC_CMD) $(LOCAL_GLUT_CFLAGS)
GLUT_CFLAGS := -Ithirdparty/freeglut/include
GLUT_LIBS := -lGL -lX11 -lXrandr
endif
# --- cURL ---
ifeq ($(USE_SYSTEM_CURL),yes)
HAVE_CURL := $(HAVE_SYS_CURL)
CURL_CFLAGS := $(SYS_CURL_CFLAGS)
CURL_LIBS := $(SYS_CURL_LIBS)
endif

59
mupdf/PKGBUILD Normal file
View File

@ -0,0 +1,59 @@
# Contributor: Ezekiel Bethel <zek@9net.org>
pkgname=('switch-mupdf')
pkgver=1.16.1
pkgrel=1
pkgdesc="A lightweight PDF, XPS, and E-book viewer."
arch=('any')
license=('AGPL')
url="https://mupdf.com/"
options=(!strip libtool staticlibs)
source=(https://mupdf.com/downloads/archive/mupdf-$pkgver-source.tar.xz)
noextract=(mupdf-$pkgver-source.tar.xz)
sha256sums=('skip')
makedepends=('switch-pkg-config' 'devkitpro-pkgbuild-helpers')
depends=('switch-freetype' 'switch-libjpeg-turbo' 'switch-zlib')
groups=('switch-portlibs')
build() {
source /opt/devkitpro/switchvars.sh
# XCFLAGS here is intentional
# "Do not specify CFLAGS or LIBS on the make invocation line - specify
# XCFLAGS or XLIBS instead. Make ignores any lines in the makefile that
# set a variable that was set on the command line" - mupdf makefile
make -C "$srcdir/mupdf" \
CC=${TOOL_PREFIX}gcc \
CXX=${TOOL_PREFIX}g++ \
LD=${TOOL_PREFIX}ld \
AR=${TOOL_PREFIX}ar \
RANLIB=${TOOL_PREFIX}ranlib \
XCFLAGS="${CPPFLAGS} ${CFLAGS} -DTOFU_NOTO -DTOFU_CJK" \
USE_SYSTEM_FREETYPE=yes \
USE_SYSTEM_HARFBUZZ=no \
USE_SYSTEM_JBIG2DEC=no \
USE_SYSTEM_JPEGXR=no \
USE_SYSTEM_LCMS2=no \
USE_SYSTEM_LIBJPEG=yes \
USE_SYSTEM_MUJS=no \
USE_SYSTEM_OPENJPEG=no \
USE_SYSTEM_ZLIB=no \
libs
}
package() {
source /opt/devkitpro/switchvars.sh
export DESTDIR=..
install -d $DESTDIR/include/mupdf
install -d $DESTDIR/include/mupdf/fitz
install -d $DESTDIR/include/mupdf/pdf
install $srcdir/mupdf/include/mupdf/*.h $DESTDIR/include/mupdf
install $srcdir/mupdf/include/mupdf/fitz/*.h $DESTDIR/include/mupdf/fitz
install $srcdir/mupdf/include/mupdf/pdf/*.h $DESTDIR/include/mupdf/pdf
install -d $DESTDIR/lib
install $srcdir/mupdf/build/release/libmupdf.a $DESTDIR/lib
install $srcdir/mupdf/build/release/libmupdf-third.a $DESTDIR/lib
}

38
mupdf/README Normal file
View File

@ -0,0 +1,38 @@
ABOUT
MuPDF is a lightweight open source software framework for viewing and converting
PDF, XPS, and E-book documents.
See the documentation in docs/index.html for an overview.
Build instructions can be found in docs/building.html.
LICENSE
MuPDF is Copyright (c) 2006-2017 Artifex Software, Inc.
This program 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.
This program 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 General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
For commercial licensing, including our "Indie Dev" friendly options,
please contact sales@artifex.com.
REPORTING BUGS AND PROBLEMS
The MuPDF developers hang out on IRC in the #mupdf channel on irc.freenode.net.
Report bugs on the ghostscript bugzilla, with MuPDF as the selected component.
http://bugs.ghostscript.com/
If you are reporting a problem with a specific file, please include the file as
an attachment.

318
mupdf/docs/android-sdk.html Normal file
View File

@ -0,0 +1,318 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Android SDK</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF Android SDK</h1>
</header>
<article>
<style>
body {counter-reset: h2}
h2 {counter-reset: h3}
h3 {counter-reset: h4}
h4 {counter-reset: h5}
h5 {counter-reset: h6}
h2:before {counter-increment: h2; content: counter(h2) ". "}
h3:before {counter-increment: h3; content: counter(h2) "." counter(h3) ". "}
h4:before {counter-increment: h4; content: counter(h2) "." counter(h3) "." counter(h4) ". "}
h5:before {counter-increment: h5; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
h6:before {counter-increment: h6; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
</style>
<p>
This document outlines the steps necessary to use the MuPDF Android SDK in various ways.
<p>
First, we show you how to embed the SDK in your app. Then, we explain how to
customize the viewer if you need to change how it looks or behaves. Finally, we
tell you where to go if you need to do work on the SDK itself.
<p>
Embedding the viewer in your app provides an activity that you can start to
view PDF documents from within your app. This should be enough for most use
cases.
<h2 id="acquire-license">
Acquire a valid license
</h2>
<p>
Before using MuPDF, please make sure that you have a valid license to do so.
There are two available licenses; make sure you pick the one whose terms you can comply with.
<h3>
Open Source license
</h3>
<p>
If your software is open source, you may use MuPDF under the terms of the
<a href="https://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License</a>.
<p>
This means that <i>all of the source code</i> for your <i>complete</i> app must be
released under a compatible open source license!
<p>
It also means that you may <i>not</i> use any proprietary closed source libraries or
components in your app. This includes (but is not limited to)
Google Play Services,
Google Mobile Services,
AdMob by Google,
Crashlytics,
Answers,
etc.
<p>
Just because a library ships with Android or is made by Google does <i>not</i> make it AGPL compatible!
<p>
If you cannot or do not want to comply with these restrictions,
you <i><b>must</b></i> acquire a commercial license instead.
<h3>
Commercial license
</h3>
<p>
If your software is not open source, Artifex Software can sell you a license to use MuPDF in closed source software.
Go and fill out the <a href="https://www.artifex.com/contact-us/">product inquiry form</a>
for commercial licensing terms and pricing.
<h2 id="setup-build">
Add the MuPDF SDK to your project
</h2>
<p>
The MuPDF library uses the Gradle build system.
In order to include MuPDF in your app, you also need to use Gradle.
The Eclipse and Ant build systems are not supported.
<p>
The MuPDF library needs Android version 4.1 or newer.
Make sure that the minSdkVersion in your app's build.gradle is at least 16.
<pre>
android {
defaultConfig {
<b>minSdkVersion 16</b>
...
}
...
}
</pre>
<p>
The MuPDF library can be retrieved as a pre-built artifact from our Maven repository.
Add the maven repository to your project. In your project's top build.gradle, add the bolded line to
to the repositories section:
<pre>
allprojects {
repositories {
jcenter()
<b>maven { url 'http://maven.ghostscript.com' }</b>
...
}
}
</pre>
<p>
Then add the MuPDF viewer library to your app's dependencies.
In your app's build.gradle, add the bolded line to the dependencies section:
<pre>
dependencies {
<b>api 'com.artifex.mupdf:viewer:1.15.+'</b>
...
}
</pre>
<h2 id="use-activity">
Invoke the document viewer activity
</h2>
<p>
Once this has been done, you have access to the MuPDF viewer activity.
You can now open a document viewing activity by launching an intent,
passing the URI of the document you wish to view.
<pre>
import com.artifex.mupdf.viewer.DocumentActivity;
public void startMuPDFActivity(Uri documentUri) {
Intent intent = new Intent(this, DocumentActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(documentUri);
startActivity(intent);
}
</pre>
<p>
The activity supports viewing both file and content scheme URIs.
<p>
For example, to open the PDF file in ~/Download/example.pdf:
<pre>
public void startMuPDFActivityWithExampleFile() {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(dir, "example.pdf");
Uri uri = Uri.fromFile(file);
startMuPDFActivity(uri);
}
</pre>
<h2>
How to customize the viewer
</h2>
<p>
If you've already tried embedding the viewer in your app, but are unhappy with some
aspect of the look or behavior and want to modify it in some way, this document should
point you in the right direction.
<h3>
Decide which viewer to base your customizations on
</h3>
<p>
In order to customize the viewer UI, you will need to modify the existing android viewer activity.
There are two separate code bases you can start with:
<dl>
<dt>mupdf-android-viewer:
<dd>The main viewer app. This code is difficult to work with, but has the most
features and pre-renders neighboring pages into a page cache for faster page
turning performance.
<dt>mupdf-android-viewer-mini:
<dd>This is a minimalist viewer which has fewer features but is designed to be
easy to understand and modify. It does not (currently) have high-resolution
zooming, and it does not use the swipe gesture to flip pages (it requires the
user to tap on the side of the screen to flip pages).
</dl>
<p>
If all you want to do is brand the UI with your own colors and icons, you are
welcome to use whichever code base you prefer. However, if you want to do
extensive modifications, we suggest you base your code on the mini viewer.
<h3>
Check out the chosen project
</h3>
<p>
When you have decided which project to base your modifications on, you should check out
the corresponding git repository:
<pre>
$ git clone git://git.ghostscript.com/mupdf-android-viewer.git
$ git clone git://git.ghostscript.com/mupdf-android-viewer-mini.git
</pre>
<p>
Inside the checked out project you will find two modules: app and lib.
The app module is a file chooser activity that lets the user open files from the external storage.
The lib module is the viewer activity, which provides the "com.artifex.mupdf:viewer"
package that you're already using.
<p>
The lib module is the one you want; ignore everything else in this project.
<h3>
Copy the viewer library module into your project
</h3>
<p>
Copy the 'lib' directory to your project, renaming it to something appropriate.
The following instructions assume you called the directory 'mupdf-lib'.
Don't forget to include the module in the settings.gradle file:
<pre>
include ':app'
<b>include ':mupdf-lib'</b>
...
</pre>
<p>
You'll also want to change your app's dependencies to now depend on your local
copy rather than the official mupdf viewer package. In your app build.gradle:
<pre>
dependencies {
<strike>api 'com.artifex.mupdf:viewer:1.15.+'</strike>
<b>api project(':mupdf-lib')</b>
...
}
</pre>
<p>
The lib module depends on the JNI library "com.artifex.mupdf:fitz", so do
<i>not</i> remove the maven repository from your top build.gradle.
<h3>
Edit the viewer activity
</h3>
<p>
If all has gone well, you can now build your project with the local viewer library,
and access the mupdf viewer activity just as you used to.
<p>
You're now free to customize the resources in mupdf-lib/src/main/res and behavior in
mupdf-lib/src/main/java as you desire.
<h2>
Working on the MuPDF SDK
</h2>
<p>
If you want to work on the SDK itself, rather than just use it, you will need
to check out the following git repositories.
<dl>
<dt>mupdf.git
<dd>This repository contains the low-level "fitz" C library and the JNI bindings.
<dt>mupdf-android-fitz.git
<dd>This repository contains an Android project to build the C library and JNI bindings.
It uses mupdf.git as a git submodule.
<dt>mupdf-android-viewer.git
<dd>This repository contains the Android viewer library and app.
It uses mupdf-android-fitz.git as either a Maven artifact or git submodule.
<dt>mupdf-android-viewer-mini.git
<dd>This repository contains the minimalist Android viewer library and app.
It uses mupdf-android-fitz.git as either a Maven artifact or git submodule.
<dt>mupdf-android-viewer-old.git
<dd>This repository contains the old Android viewer. It has its own JNI
bindings and uses mupdf.git as a submodule directly. It is only listed here for
completeness sake, and is not part of the SDK.
</dl>
<p>
Since these repositories are set up as git submodules, if you're a Git expert,
you can clone one of the viewer repositories recursively and get all of them at
once. However, working with git submodules can be fraught with danger, so it
may be easier to check them out individually.
<p>
If you only want to work with one of the viewer repositories, you can use the
Maven artifact for the JNI bindings library and not worry about the mupdf.git
and mupdf-android-fitz.git repositories.
<p>
Good luck!
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2019 Artifex Software Inc.
</footer>
</body>
</html>

144
mupdf/docs/api/changes.html Normal file
View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html>
<head>
<title>API Changes</title>
<link rel="stylesheet" href="../style.css" type="text/css">
</head>
<body>
<header>
<h1>Changes in the public API</h1>
</header>
<article>
<h2>Why does the API change?</h2>
<p>
From time to time, during development, it becomes clear that the
public API needs to change; either because the existing API has
flaws in it, or to accommodate new functionality. Such changes
are not undertaken lightly, and they are kept as minimal as
possible.
<p>
The alternative would be to freeze the API and to introduce more
and more compatibility veneers, ultimately leading to a bloated
API and additional complexity. We have done this in the past, and
will do it again in future if circumstances demand it, but we
consider small changes in the API to be a price worth paying for
clarity and simplicity.
<p>
To minimise the impact of such changes, we undertake to list the
API changes between different versions of the library here, to
make it as simple as possible for integrators to make the small
changes that may be require to update between versions.
<p>
Note, that we only list changes in existing APIs here, not additions
to the API.
<h2>Changes from v1.16</h2>
<p>
The accessors for reading and creating QuadPoints, InkList and Vertices data
for Highlight, Underline, StrikeOut, Squiggle, Ink, Polygon, and PolyLine
annotation types have been simplified. They now take and return fz_quad and
fz_point structs instead of float arrays. We have also added functions to
construct the datastructures one piece at a time, removing the need to allocate
a temporary array to pass.
<h2>Changes from v1.15</h2>
<p>
There has been a major overhaul of the color management architecture. Unless
you're implementing custom devices or interpreters, this should only have a
minor impact.
<ul>
<li>Argument order when passing color and colorspace to functions regularized:
sourceColorspace, sourceColorArray,
destinationColorspace, destinationColorArray,
proofColorspace,
colorParams.
<li>Pass fz_color_params argument by value.
<li>Changed fz_default_parameters from a function to a global constant.
<li>Replaced fz_set_icc_engine with fz_enable_icc and fz_disable_icc to toggle color management at runtime.
<li>Replaced pixmap color converter struct with a single fz_convert_pixmap function call.
<li>Replaced fz_cal_colorspace struct with constructor to create an ICC-backed calibrated colorspace directly.
<li><b>Passing NULL is not a shortcut for DeviceGray any more!</b>
<li>Added public definitions for Indexed and Separation colorspaces.
<li>Changed colorspace constructors.
</ul>
<p>
The fz_set_stdout and fz_set_stderr functions have been removed.
If you were using these to capture warning and error messages,
use the new user callbacks for warning and error logging instead:
fz_set_warning_callback and fz_set_error_callback.
<p>
The structured text html and xhtml output formats take an additional argument:
the page number. This number is used to create an id attribute for each page to
use as a hyperlink target.
<h2>Changes from v1.14 to v1.15</h2>
<dl>
<dt>PDF Portfolios
<dd>This functionality has been removed. We do
not believe anyone was using this. If you were, please contact
us for assistance. This functionality can be achieved using
"mutool run" and docs/examples/pdf-portfolio.js.
<dt>FZ_ERROR_TRYLATER
<dd>This functionality has been removed. We do
not believe anyone was using this. If you were, please contact
us for assistance.
<dt>Annotations/Forms
<dd>We are undertaking a significant rework of this functionality
at the moment. We do not believe anyone is using this at the moment,
and would therefore encourage anyone who is to contact us for help
in upgrading.
<dt>Various functions involving fz_colorspace have lost consts.
<dd>fz_colorspaces are immutable once created, other than changes
due to reference counting. Passing a const fz_colorspace to a function
that might keep a reference to it either has to take a non const
fz_colorspace pointer, or take a const one, and 'break' the const.
Having some functions take const fz_colorspace and some not is
confusing, so therefore, for simplicity, all fz_colorspaces are now
passed as non const.
This should not affect any user code.
<dt>fz_process_shade()
<dd>This now takes an extra 'scissor' argument.
To upgrade old code, if you don't have an appropriate scissor rect available,
it is safe (but unwise) to pass fz_infinite_rect.
<dt>fz_tint_pixmap()
<dd>Rather than taking r, g and b, values to tint with, the
function now takes 8 bit hex rgb values for black and white,
enabling greater control, allowing "low contrast" and "night
view" effects.
<dt>pdf_add_image()
<dd>This no longer requires a mask flag. The image already knows if it is a mask.
<dt>pdf_processor.op_BI()
<dd>The op_BI callback is now passed an additional colorspace resource name.
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="../artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

522
mupdf/docs/api/core.html Normal file
View File

@ -0,0 +1,522 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Core API</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<style>
dl dt { font-family: monospace; margin-top: 0.5em; white-space: pre}
</style>
</head>
<body>
<header>
<h1>MuPDF Core API</h1>
</header>
<article>
<p>
Almost all functions in the MuPDF library take a fz_context structure as their
first argument. The context is used for many things; primarily it holds the
exception stack for our setjmp based exception handling. It also holds various
caches and auxiliary contexts for font rendering and color management.
<h2>The Fitz Context</h2>
<p>
<i>If you wonder where the prefix "fz" and name Fitz come from, MuPDF originally
started out as a prototype of a new rendering library architecture for Ghostscript.
It was to be the "bastard son" of libart and Ghostscript. History turned out
differently, and the project mutated into a standalone PDF renderer now called MuPDF.
The "fz" prefix for the graphics library and core modules remains to this day.
</i>
<p>
Here is the code to create a Fitz context. The first two arguments are used if
you need to use a custom memory allocator, and the third argument is a hint to
much memory the various caches should be allowed to grow. The limit is only a
soft limit. We may exceed it, but will start clearing out stale data to try to
stay below the limit when possible. Setting it to a lower value will prevent
the caches from growing out of hand if you are tight on memory.
<pre>
#include &lt;mupdf/fitz.h&gt;
main()
{
fz_context *ctx;
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
if (!ctx)
die("Failed to create a new Fitz context!");
<i>... do stuff ...</i>
fz_drop_context(ctx);
}
</pre>
<h2>Error Handling</h2>
<p>
MuPDF uses a setjmp based exception handling system. This is encapsulated
by the use of three macros: fz_try, fz_always, and fz_catch.
When an error is raised by fz_throw, or re-raised fz_rethrow, execution
will jump to the enclosing always/catch block.
<p>
All functions you call should be guarded by a fz_try block to catch the
errors, or the program will call abort() on errors. You don't want that.
<p>
The fz_always block is optional. It is typically used to free memory
or release resources unconditionally, in both the case when the execution
of the try block succeeds, and when an error occurs.
<pre>
fz_try(ctx) {
// Do stuff that may throw an exception.
}
fz_always(ctx) {
// This (optional) block is always executed.
}
fz_catch(ctx) {
// This block is only executed when recovering from an exception.
}
</pre>
<p>
Since the fz_try macro is based on setjmp, the same conditions that apply
to local variables in the presence of setjmp apply. Any locals written
to inside the try block may be restored to their pre-try state when an
error occurs. We provide a fz_var() macro to guard against this.
<p>
In the following example, if we don't guard 'buf' with fz_var, then
when an error occurs the 'buf' local variable might have be reset to
its pre-try value (NULL) and we would leak the memory.
<pre>
char *buf = NULL;
fz_var(buf);
fz_try(ctx) {
buf = fz_malloc(ctx, 100);
// Do stuff with buf that may throw an exception.
}
fz_always(ctx) {
fz_free(ctx, buf);
}
fz_catch(ctx) {
fz_rethrow(ctx);
}
</pre>
<p>
Carefully note that you should <i><b>NEVER</b></i> return from within a fz_try or fz_always block!
Doing so will unbalance the exception stack, and things will go catastrophically wrong.
Instead, it is possible to break out of the fz_try and fz_always block by using a break
statement if you want to exit the block early without throwing an exception.
<p>
Throwing a new exception can be done with fz_throw. Passing an exception along after having
cleaned up in the fz_catch block can be done with fz_rethrow. fz_throw takes a printf-like
formatting string.
<pre>
enum {
FZ_ERROR_MEMORY, // when malloc fails
FZ_ERROR_SYNTAX, // recoverable syntax errors
FZ_ERROR_GENERIC, // all other errors
};
void fz_throw(fz_context *ctx, int error_code, const char *fmt, ...);
void fz_rethrow(fz_context *ctx);
</pre>
<h2>Memory Allocation</h2>
<p>
You should not need to do raw memory allocation using the Fitz context, but if you do,
here are the functions you need. These work just like the regular C functions, but take
a Fitz context and throw an exception if the allocation fails. They will NOT return NULL;
either they will succeed or they will throw an exception.
<pre>
void *fz_malloc(fz_context *ctx, size_t size);
void *fz_realloc(fz_context *ctx, void *old, size_t size);
void *fz_calloc(fz_context *ctx, size_t count, size_t size);
void fz_free(fz_context *ctx, void *ptr);
</pre>
<p>
There are also some macros that allocate structures and arrays, together with a type cast
to catch typing errors.
<pre>
T *fz_malloc_struct(fz_context *ctx, T); // Allocate and zero the memory.
T *fz_malloc_array(fz_context *ctx, size_t count, T); // Allocate <i>uninitialized</i> memory!
T *fz_realloc_array(fz_context *ctx, T *old, size_t count, T);
</pre>
<p>
In the rare case that you need an allocation that returns NULL on failure,
there are variants for that too: fz_malloc_no_throw, etc.
<h2>Pool Allocator</h2>
<p>
The pool allocator is used for allocating many small objects that live and die together.
All objects allocated from the pool will be freed when the pool is freed.
<pre>
typedef struct { <i>opaque</i> } fz_pool;
fz_pool *fz_new_pool(fz_context *ctx);
void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size);
char *fz_pool_strdup(fz_context *ctx, fz_pool *pool, const char *s);
void fz_drop_pool(fz_context *ctx, fz_pool *pool);
</pre>
<h2>Reference Counting</h2>
<p>
Most objects in MuPDF use reference counting to keep track of when they are no longer
used and can be freed. We use the verbs "keep" and "drop" to increment and decrement
the reference count. For simplicity, we also use the word "drop" for non-reference
counted objects (so that in case we change our minds and decide to add reference counting
to an object, the code that uses it need not change).
<h2>Hash Table</h2>
<p>
We have a generic hash table structure with fixed length keys.
<p>
The keys and values are <i>not</i> reference counted by the hash table.
Callers are responsible for manually taking care of reference counting
when inserting and removing values from the table, should that be
desired.
<pre>
typedef struct { <i>opaque</i> } fz_hash_table;
</pre>
<dl>
<dt>fz_hash_table *fz_new_hash_table(fz_context *ctx,
int initial_size,
int key_length,
int lock,
void (*drop_value)(fz_context *ctx, void *value));
<dd>
The lock parameter should be zero, any other value will result in unpredictable behavior.
The drop_value callback function to the constructor is only used to
release values when the hash table is destroyed.
<dt>void fz_drop_hash_table(fz_context *ctx, fz_hash_table *table);
<dd>
Free the hash table and call the drop_value function on all the values in the table.
<dt>void *fz_hash_find(fz_context *ctx, fz_hash_table *table, const void *key);
<dd>
Find the value associated with the key. Returns NULL if not found.
<dt>void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *value);
<dd>Insert the value into the hash table.
Inserting a duplicate entry will NOT overwrite the old value, it will return the old value instead.
Return NULL if the value was inserted for the first time.
Does <i>not</i> reference count the value!
<dt>void fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key);
<dd>
Remove the associated value from the hash table. This will <i>not</i> reference count the value!
<dt>void fz_hash_for_each(fz_context *ctx,
fz_hash_table *table,
void *state,
void (*callback)(fz_context *ctx, void *state, void *key, int key_length, void *value);
<dd>
Iterate and call a function for each key-value pair in the table.
</dl>
<h2>Binary Tree</h2>
<p>
The fz_tree structure is a self-balancing binary tree that maps text strings to values.
<dl>
<dt>typedef struct { <i>opaque</i> } fz_tree;
<dt>void *fz_tree_lookup(fz_context *ctx, fz_tree *node, const char *key);
<dd>Look up an entry in the tree. Returns NULL if not found.
<dt>fz_tree *fz_tree_insert(fz_context *ctx, fz_tree *root, const char *key, void *value);
<dd>Insert a new entry into the tree. Do not insert duplicate entries. Returns the new root object.
<dt>void fz_drop_tree(fz_context *ctx, fz_tree *node, void (*dropfunc)(fz_context *ctx, void *value));
<dd>Free the tree and all the values in it.
</dl>
<p>
There is no constructor for this structure, since there is no containing root structure.
Instead, the insert function returns the new root node.
Use NULL for the initial empty tree.
<pre>
fz_tree *tree = NULL;
tree = fz_tree_insert(ctx, tree, "A", my_a_obj);
tree = fz_tree_insert(ctx, tree, "B", my_b_obj);
tree = fz_tree_insert(ctx, tree, "C", my_c_obj);
assert(fz_tree_lookup(ctx, tree, "B") == my_b_obj);
</pre>
<h2>XML Parser</h2>
<p>
We have a rudimentary XML parser that handles well formed XML. It does not do any namespace processing,
and it does not validate the XML syntax.
<p>
The parser supports UTF-8, UTF-16, iso-8859-1, iso-8859-7, koi8, windows-1250, windows-1251,
and windows-1252 encoded input.
<p>
If preserve_white is false, we will discard all whitespace-only text elements.
This is useful for parsing non-text documents such as XPS and SVG.
Preserving whitespace is useful for parsing XHTML.
<pre>
typedef struct { <i>opaque</i> } fz_xml_doc;
typedef struct { <i>opaque</i> } fz_xml;
fz_xml_doc *fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white);
void fz_drop_xml(fz_context *ctx, fz_xml_doc *xml);
fz_xml *fz_xml_root(fz_xml_doc *xml);
fz_xml *fz_xml_prev(fz_xml *item);
fz_xml *fz_xml_next(fz_xml *item);
fz_xml *fz_xml_up(fz_xml *item);
fz_xml *fz_xml_down(fz_xml *item);
</pre>
<dl>
<dt>int fz_xml_is_tag(fz_xml *item, const char *name);
<dd>Returns true if the element is a tag with the given name.
<dt>char *fz_xml_tag(fz_xml *item);
<dd>Returns the tag name if the element is a tag, otherwise NULL.
<dt>char *fz_xml_att(fz_xml *item, const char *att);
<dd>Returns the value of the tag element's attribute, or NULL if not a tag or missing.
<dt>char *fz_xml_text(fz_xml *item);
<dd>Returns the UTF-8 text of the text element, or NULL if not a text element.
<dt>fz_xml *fz_xml_find(fz_xml *item, const char *tag);
<dd>Find the next element with the given tag name. Returns the element itself if it matches, or the first sibling if it doesn't. Returns NULL if there is no sibling with that tag name.
<dt>fz_xml *fz_xml_find_next(fz_xml *item, const char *tag);
<dd>Find the next sibling element with the given tag name, or NULL if none.
<dt>fz_xml *fz_xml_find_down(fz_xml *item, const char *tag);
<dd>Find the first child element with the given tag name, or NULL if none.
</dl>
<h2>String Functions</h2>
<p>
All text strings in MuPDF use the UTF-8 encoding. The following functions encode and decode UTF-8 characters,
and return the number of bytes used by the UTF-8 character (at most FZ_UTFMAX).
<pre>
enum { FZ_UTFMAX=4 };
int fz_chartorune(int *rune, const char *str);
int fz_runetochar(char *str, int rune);
</pre>
<p>
Since many of the C string functions are locale dependent, we also provide
our own locale independent versions of these functions. We also have a couple
of semi-standard functions like strsep and strlcpy that we can't rely on
the system providing. These should be pretty self explanatory:
<pre>
char *fz_strdup(fz_context *ctx, const char *s);
float fz_strtof(const char *s, char **es);
char *fz_strsep(char **stringp, const char *delim);
size_t fz_strlcpy(char *dst, const char *src, size_t n);
size_t fz_strlcat(char *dst, const char *src, size_t n);
void *fz_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
int fz_strcasecmp(const char *a, const char *b);
</pre>
<p>
There are also a couple of functions to process filenames and URLs:
<dl>
<dt>char *fz_cleanname(char *path);
<dd>
Rewrite path in-place to the shortest string that names the same path.
Eliminates multiple and trailing slashes, and interprets "." and "..".
<dt>void fz_dirname(char *dir, const char *path, size_t dir_size);
<dd>Extract the directory component from a path.
<dt>char *fz_urldecode(char *url);
<dd>Decode URL escapes in-place.
</dl>
<h2>String formatting</h2>
<p>
Our printf family handles the common printf formatting characters, with a few minor differences.
We also support several non-standard formatting characters.
The same printf syntax is used in the printf functions in the I/O module as well.
<pre>
size_t fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args);
size_t fz_snprintf(char *buffer, size_t space, const char *fmt, ...);
char *fz_asprintf(fz_context *ctx, const char *fmt, ...);
</pre>
<dl>
<dt>%%, %c, %e, %f, %p, %x, %d, %u, %s
<dd>These behave as usual, but only take padding (+,0,space), width, and precision arguments.
<dt>%g float
<dd>Prints the float in the shortest possible format that won't lose precision,
except NaN to 0, +Inf to FLT_MAX, -Inf to -FLT_MAX.
<dt>%M fz_matrix*
<dd>Prints all 6 coefficients in the matrix as %g separated by spaces.
<dt>%R fz_rect*
<dd>Prints all x0, y0, x1, y1 in the rectangle as %g separated by spaces.
<dt>%P fz_point*
<dd>Prints x, y in the point as %g separated by spaces.
<dt>%C int
<dd>Formats character as UTF-8. Useful to print unicode text.
<dt>%q char*
<dd>Formats string using double quotes and C escapes.
<dt>%( char*
<dd>Formats string using parenthesis quotes and postscript escapes.
<dt>%n char*
<dd>Formats string using prefix / and PDF name hex-escapes.
</dl>
<h2>Math Functions</h2>
<p>
We obviously need to deal with lots of points, rectangles, and transformations in MuPDF.
<p>
Points are fairly self evident. The fz_make_point utility function is for use with
Visual Studio that doesn't yet support the C99 struct initializer syntax.
<pre>
typedef struct {
float x, y;
} fz_point;
fz_point fz_make_point(float x, float y);
</pre>
<p>
Rectangles are represented by two pairs of coordinates.
The x0, y0 pair have the smallest values, and in the normal
coordinate space used by MuPDF that is the upper left corner.
The x1, y1 pair have the largest values, typically the lower right corner.
<p>
In order to represent an infinite unbounded area, we use an x0 that
is larger than the x1.
<pre>
typedef struct {
float x0, y0;
float x1, y1;
} fz_rect;
const fz_rect fz_infinite_rect = { 1, 1, -1, -1 };
const fz_rect fz_empty_rect = { 0, 0, 0, 0 };
const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
fz_rect fz_make_rect(float x0, float y0, float x1, float y1);
</pre>
<p>
Our matrix structure is a row-major 3x3 matrix with the last column always [ 0 0 1 ].
This is represented as a struct with six fields, in the same order as in PDF and Postscript.
The identity matrix is a global constant, for easy access.
<pre>
/ a b 0 \
| c d 0 |
\ e f 1 /
typedef struct {
float a, b, c, d, e, f;
} fz_matrix;
const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
fz_matrix fz_make_matrix(float a, float b, float c, float d, float e, float f);
</pre>
<p>
Sometimes we need to represent a non-axis aligned rectangular-ish area, such
as the area covered by some rotated text. For this we use a quad representation,
using a points for each of the upper/lower/left/right corners as seen from
the reading direction of the text represented.
<pre>
typedef struct {
fz_point ul, ur, ll, lr;
} fz_quad;
</pre>
<p>
List of math functions. These are simple mathematical operations that can not
throw errors, so do not need a context argument.
<pre>
float fz_abs(float f);
float fz_min(float a, float b);
float fz_max(float a, float b);
float fz_clamp(float f, float min, float max);
int fz_absi(int i);
int fz_mini(int a, int b);
int fz_maxi(int a, int b);
int fz_clampi(int i, int min, int max);
</pre>
<pre>
int fz_is_empty_rect(fz_rect r);
int fz_is_infinite_rect(fz_rect r);
</pre>
<pre>
fz_matrix fz_concat(fz_matrix left, fz_matrix right);
fz_matrix fz_scale(float sx, float sy);
fz_matrix fz_shear(float sx, float sy);
fz_matrix fz_rotate(float degrees);
fz_matrix fz_translate(float tx, float ty);
fz_matrix fz_invert_matrix(fz_matrix matrix);
</pre>
<pre>
fz_point fz_transform_point(fz_point point, fz_matrix m);
fz_point fz_transform_vector(fz_point vector, fz_matrix m); // ignores translation
fz_rect fz_transform_rect(fz_rect rect, fz_matrix m);
fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
int fz_is_point_inside_rect(fz_point p, fz_rect r);
int fz_is_point_inside_quad(fz_point p, fz_quad q);
</pre>
<dl>
<dt>fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate);
<dd>
Create a transform matrix to draw a page at a given resolution and rotation.
The scaling factors are adjusted so that the page covers a whole number of pixels.
Resolution is given in dots per inch.
Rotation is expressed in degrees (0, 90, 180, and 270 are valid values).
</dl>
</article>
<footer>
<a href="https://www.artifex.com/"><img src="../artifex-logo.png" align="right"></a>
Copyright &copy; 2019 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,337 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Graphics API</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<style>
dl dt { font-family: monospace; margin-top: 0.5em; white-space: pre; }
</style>
</head>
<body>
<header>
<h1>MuPDF Graphics API</h1>
</header>
<article>
<p>
This module is a grab bag of various graphics related objects and functions.
<h2>Colors</h2>
<p>
Colors throughout MuPDF are represented as a float vector associated with
a colorspace object. Colorspaces come in many variants, the most common of
which are Gray, RGB, and CMYK. We also support Indexed (palette), L*a*b*,
Separation, DeviceN, and ICC based colorspaces.
<pre>
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,
};
struct fz_colorspace_s {
enum fz_colorspace_type type;
int n;
char *name;
<i>private internal fields</i>
};
fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
</pre>
<p>
Most colorspaces have color components between 0 and 1.
The number of components a color uses is given by the 'n' field
of the colorspace. This is at most FZ_MAX_COLORS.
<p>
L*a*b* colors have a range of 0..100 for the L* and -128..127 for a* and b*.
<p>
CMYK, Separation, and DeviceN colorspaces are subtractive colorspaces.
Separation and DeviceN colorspaces also have a tint transform function and
a base colorspace used to represent the colors when rendering to a device that
does not have these specific colorants.
<h3>Color management engine</h3>
<p>
MuPDF is usually built with a color management engine, but this can be turned
off at runtime if you need faster performance at the cost of much more
inaccurate color conversions.
<pre>
int fz_enable_icc(fz_context *ctx);
int fz_disable_icc(fz_context *ctx);
</pre>
<p>
The various color conversion functions also take certain parameters that
the color management engine uses, such as rendering intent and overprint
control.
<pre>
enum {
FZ_RI_PERCEPTUAL,
FZ_RI_RELATIVE_COLORIMETRIC,
FZ_RI_SATURATION,
FZ_RI_ABSOLUTE_COLORIMETRIC,
};
typedef struct {
int ri; // Rendering intent
int bp; // Black point compensation
int op;
int opm;
} fz_color_params;
const fz_color_params fz_default_color_params = { FZ_RI_RELATIVE_COLORIMETRIC, 1, 0, 0 };
</pre>
<h3>Device colorspaces</h3>
<p>
When you need to define a color, and don't care too much about the calibration,
you can use the Device colorspaces. When MuPDF is built with a color management
engine and ICC is enabled the Gray and RGB colorspaces use an sRGB ICC profile.
<pre>
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);
</pre>
<p>
BGR is present to allow you to render to pixmaps that have the RGB components
in a different order, so that the data can be passed directly to the operating
system for drawing without needing yet another conversion step.
<h3>Indexed colorspaces</h3>
<p>
Indexed colors have a range of 0..N where N is one less than the number of colors
in the palette. An indexed colorspace also has a base colorspace, which is used
to define the palette of colors used.
<pre>
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx,
fz_colorspace *base,
int high,
unsigned char *lookup);
</pre>
<p>
High is the maximum value in the palette; i.e. one less than the number of colors.
<p>
The lookup argument is a packed array of color values in the base colorspace,
represented as bytes mapped to the range of 0..255.
<h3>ICC colorspaces</h3>
<p>
You can create ICC colorspaces from a buffer containing the ICC profile.
<pre>
fz_colorspace *fz_new_icc_colorspace(fz_context *ctx,
enum fz_colorspace_type type,
int flags,
const char *name,
fz_buffer *buf);
</pre>
<p>
The 'type' argument can be NONE if you want to automatically infer the
colorspace type from the profile data. If the type is anything else, then an
error will be thrown if the profile does not match the type.
<h3>Color converters</h3>
<p>
There are several ways to convert colors. The easiest is to call a function,
but if you are converting many colors at once, it will be faster to use a
color converter object.
<pre>
void fz_convert_color(fz_context *ctx,
fz_colorspace *src_colorspace,
const float *src_color,
fz_colorspace *dst_colorspace,
float *dst_color,
fz_colorspace *proof_colorspace,
const fz_color_params params);
</pre>
<pre>
typedef struct {
void (*convert)(fz_context *ctx, fz_color_converter *cc, const float *src, float *dst);
<i>private internal fields</i>
} fz_color_converter;
void fz_find_color_converter(fz_context *ctx, fz_color_converter *cc,
fz_colorspace *src_colorspace,
fz_colorspace *dst_colorspace,
fz_colorspace *proof_colorspace,
fz_color_params params);
void fz_drop_color_converter(fz_context *ctx, fz_color_converter *cc);
</pre>
<p>
Here is some sample code to do a one-off CMYK to RGB color conversion.
<pre>
float cmyk[4] = { 1, 0, 0, 0 };
float rgb[3];
fz_convert_color(ctx, fz_device_cmyk(ctx), cmyk, fz_device_rgb(ctx), rgb, NULL, fz_default_color_params(ctx));
</pre>
<p>
Here is some sample code to do repeated CMYK to RGB color conversions on many colors
using a color converter object.
<pre>
float cmyk[100][4] = { {1,0,0,0}, ...
float rgb[100][3];
int i;
fz_color_converter cc;
fz_find_color_converter(ctx, &cc, fz_device_cmyk(ctx), fz_device_rgb(ctx), NULL, fz_default_color_params(ctx));
for (i = 0; i < 100; ++i)
cc.convert(ctx, &cc, cmyk[i], rgb[i]);
fz_drop_color_converter(ctx, &cc);
</pre>
<h2>Separations</h2>
<p>
TODO
<h2>Pixmaps</h2>
<p>
A pixmap is an 8-bit per component raster image.
Each pixel is packed with process colorants, spot colors, and alpha channel in that order.
If an alpha channel is present, the process colorants are pre-multiplied with the alpha value.
<pre>
typedef struct {
int w, h; // Width and height
int x, y; // X and Y offset
int n; // Number of components in total (colors + spots + alpha)
int s; // Number of components that are spot colors
int alpha; // True if alpha channel is present
int stride; // Number of bytes per row
int xres, yres; // Resolution in dots per inch.
fz_colorspace *colorspace; // Colorspace of samples, or NULL if alpha only pixmap.
unsigned char *samples;
<i>private internal fields</i>
} fz_pixmap;
fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
</pre>
<p>
There are too many pixmap constructors. Here is the only one you should need.
<pre>
fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha);
</pre>
<p>
A newly created pixmap has uninitialized data. The samples must either be
cleared or overwritten with existing data before the pixmap can be safely used.
<dl>
<dt>void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
<dd>Clear the pixmap to black.
<dt>void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
<dd>Clear the pixmap to a grayscale value 0..255, where 0 is black and 255 is white.
The value is automatically inverted for subtractive colorspaces.
<dt>void fz_fill_pixmap_with_color(fz_context *ctx,
fz_pixmap *pix,
fz_colorspace *colorspace, float *color,
fz_color_params color_params);
<dd>Fill the pixmap with a solid color.
<dt>void fz_unpack_tile(fz_context *ctx, fz_pixmap *dst,
unsigned char *src,
int n,
int depth,
size_t stride,
int scale);
<dd>Unpack pixel values from source data to fill in the pixmap samples. N is the number of samples per pixel, depth is the bit depth (1, 2, 4, 8, 16, 24, or 32), stride is the number of bytes per row. If scale is non-zero, it is the scaling factor to apply to the input samples to map them to the 8-bpc pixmap range. Pass 1 to the scale for indexed images, and 0 for everything else. If there are more components in the source data than the destination, they will be dropped. If there are fewer components in the source data, the pixmap will be padded with 255.
</dl>
<p>
Some functions can create a pixmap and initialize its samples in one go:
<pre>
TODO: should these be public? make grayscale?
fz_pixmap *fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *data, int stride);
fz_pixmap *fz_new_pixmap_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *data, int stride);
</pre>
<p>
Pixmaps can be tinted, inverted, scaled, gamma corrected, and converted to other colorspaces.
<dl>
<dt>void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
<dd>Invert the pixmap samples.
<dt>void fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int black, int white);
<dd>Map black to black and white to white. The black and white colors are represented as a packed RGB integer. 0xFFFFFF is white, 0xFF0000 is red, and 0x000000 is black.
<dt>void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
<dd>Apply a gamma correction curve on the samples. A typical use is to adjust the gamma curve on an inverted image by applying a correction factor of 1/1.4.
<dt>fz_pixmap *fz_convert_pixmap(fz_context *ctx,
fz_pixmap *source_pixmap,
fz_colorspace *destination_colorspace,
fz_colorspace *proof_colorspace,
fz_default_colorspaces *default_cs,
fz_color_params color_params,
int keep_alpha);
<dd>Convert the source pixmap into the destination colorspace. Pass NULL for the default_cs parameter.
<dt>fz_pixmap *fz_scale_pixmap(fz_context *ctx,
fz_pixmap *src,
float x,
float y,
float w,
float h,
const fz_irect *clip);
<dd>Scale the pixmap up or down in size to fit the rectangle. Will return NULL
if the scaling factors are out of whack. This applies fancy filtering and will
anti-alias the edges for subpixel positioning if using non-integer coordinates.
If the clip rectangle is set, the returned pixmap may be subset to
fit the clip rectangle. Pass NULL to the clip if you want the whole pixmap
scaled.
</dl>
<h2>Bitmaps</h2>
<h2>Images</h2>
<h2>Shadings</h2>
<h2>Fonts</h2>
<h2>Paths</h2>
<h2>Text</h2>
</article>
<footer>
<a href="https://www.artifex.com/"><img src="../artifex-logo.png" align="right"></a>
Copyright &copy; 2019 Artifex Software Inc.
</footer>
</body>
</html>

88
mupdf/docs/api/index.html Normal file
View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF C API</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<style>
dl dt { font-family: monospace; margin-top: 0.5em; }
</style>
</head>
<body>
<header>
<h1>MuPDF C API</h1>
</header>
<article>
<h2>Introduction</h2>
<p>
This is the MuPDF C API guide -- for developers.
In this document we will guide you through the public and stable bits of the MuPDF library.
This is intended to both provide an introduction to new developers wanting to use
low level features of MuPDF, and as a reference guide to the public interface.
<p>
We will be explaining the basics, enough to get you started on a single
threaded application. There are more functions and data structures used
internally, and there are also ways to use MuPDF from multiple threads,
but those are beyond the scope of this document.
<p>
The functions and structures documented in this document are what we consider
stable APIs. They will rarely change, and if they do, any such changes will be
noted in the "api-changes" document along with instructions for how to update
your code.
<h2>MuPDF modules</h2>
<p>
MuPDF is separated into several modules.
<dl>
<dt><a href="core.html">Core</a>
<dd>The core module contains the runtime context, exception handling, and
various string manipulation, math, hash table, binary tree, and other useful
functions.
<dt><a href="io.html">I/O</a>
<dd>The I/O module contains structures and functions for buffers of data,
reading and writing to streams, compression, and encryption.
<dt><a href="graphics.html">Graphics</a>
<dd>The graphics module contains graphic resource objects like colors, fonts, shadings, and images.
<dt>Device
<dd>The device interface is how we provide access to the contents of a document.
A device is a callback structure, that gets called for each piece of text,
line art, and image on a page.
There are several device implementations.
The most important one renders the contents to a raster image, and another
one gathers all the text into a structure that can be used to select
and copy and search the text content on a page.
<dt>Document
<dd>The document module handles reading and writing documents in various
formats, and ties together all the preceding modules to provide rendering,
format conversion, and search functionality for the document types we support.
<dt>PDF
<dd>The PDF module provides access to the low level PDF structure, letting you
query, modify, and create PDF objects and streams. It allows you to create new
documents, modify existing documents, or examine features, extract data, or do
almost anything you could want at the PDF object and stream level that we don't
provide with the higher level APIs.
</dl>
</article>
<footer>
<a href="https://www.artifex.com/"><img src="../artifex-logo.png" align="right"></a>
Copyright &copy; 2019 Artifex Software Inc.
</footer>
</body>
</html>

348
mupdf/docs/api/io.html Normal file
View File

@ -0,0 +1,348 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF I/O API</title>
<link rel="stylesheet" href="../style.css" type="text/css">
<style>
dl dt { font-family: monospace; margin-top: 0.5em; }
</style>
</head>
<body>
<header>
<h1>MuPDF I/O API</h1>
</header>
<article>
<h2>Buffers</h2>
<p>
In order to represent a generic chunks of data we use the fz_buffer structure.
<pre>
typedef struct {
unsigned char *data;
size_t len; // current length
size_t cap; // total capacity
<i>reserved internal fields</i>
} fz_buffer;
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
</pre>
<p>
There are many ways to create a buffer. Some create a buffer shared immutable data,
others with data you can edit, and others by copying or decoding other data.
<dl>
<dt>fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);
<dd>Create a new empty buffer, with the given initial capacity.
<dt>fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, const unsigned char *data, size_t size);
<dd>Create a new buffer wrapping the given data pointer. The data is only referenced, and will not
be freed when the buffer is destroyed. The data pointer must NOT change or disappear while the buffer lives.
<dt>fz_buffer *fz_new_buffer_from_copied_data(fz_context *ctx, const unsigned char *data, size_t size);
<dd>Create a buffer containing a copy of the data pointed to.
<dt>fz_buffer *fz_new_buffer_from_base64(fz_context *ctx, const char *data, size_t size);
<dd>Create a buffer containing the decoded BASE64 data.
</dl>
<p>
Sometimes you want to create buffers piece by piece by appending strings or other data to it,
while dynamically growing the underlying storage.
<pre>
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 *string);
void fz_append_byte(fz_context *ctx, fz_buffer *buf, int byte);
void fz_append_rune(fz_context *ctx, fz_buffer *buf, int rune);
void fz_append_int16_be(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_int32_le(fz_context *ctx, fz_buffer *buf, int x);
void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...);
void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
</pre>
<p>
You can also write a bit stream with the following functions.
The buffer length always covers all the bits in the buffer, including
any unused ones in the last byte, which will always be zero.
<dl>
<dt>void fz_append_bits(fz_context *ctx, fz_buffer *buf, int value, int count);
<dd>Write the lower count bits from value into the buffer.
<dt>void fz_append_bits_pad(fz_context *ctx, fz_buffer *buf);
<dd>Write enough zero bits to be byte aligned.
</dl>
<p>
You can use the buffer data as a zero-terminated C string by calling the following function.
This will ensure that there is a zero terminator after the last byte and return
a pointer to the first byte. This pointer is only borrowed, and should only be used
briefly, before the buffer is changed again (which may reallocate or free the data).
<pre>
const char *fz_string_from_buffer(fz_context *ctx, fz_buffer *buf);
</pre>
<p>
You can also read and write the contents of a buffer to file.
<dl>
<dt>fz_buffer *fz_read_file(fz_context *ctx, const char *filename);
<dd>Read the contents of a file into a buffer.
<dt>void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);
<dd>Save the contents of a buffer to a file.
</dl>
<h2>Input Streams and Filters</h2>
<p>
An input stream reads data from a source. Some stream types can decompress and decrypt data,
and these streams can be chained together in a pipeline.
<pre>
typedef struct { <i>internal</i> } fz_stream;
fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm);
void fz_drop_stream(fz_context *ctx, fz_stream *stm);
</pre>
<dl>
<dt>fz_stream *fz_open_file(fz_context *ctx, const char *filename);
<dd>Open a stream reading the contents of a file.
<dt>fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len);
<dd>Open a stream reading from the data pointer.
<dt>fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
<dd>Open a stream reading from a buffer.
</dl>
<p>
The basic stream operations you expect are available.
<pre>
int64_t fz_tell(fz_context *ctx, fz_stream *stm);
void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len);
size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len);
</pre>
<dl>
<dt>fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial);
<dd>Read the remaining data into a new buffer.
<dt>char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t n);
<dd>Behaves like fgets().
</dl>
<pre>
int fz_read_byte(fz_context *ctx, fz_stream *stm);
int fz_peek_byte(fz_context *ctx, fz_stream *stm);
int fz_is_eof(fz_context *ctx, fz_stream *stm);
</pre>
<p>
You can read binary data one integer at a time. The default is big endian, but LE versions are also
provided.
<pre>
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);
</pre>
<p>
Reading bit streams is also possible:
<pre>
unsigned int fz_read_bits(fz_context *ctx, fz_stream *stm, int n);
unsigned int fz_read_rbits(fz_context *ctx, fz_stream *stm, int n);
void fz_sync_bits(fz_context *ctx, fz_stream *stm);
int fz_is_eof_bits(fz_context *ctx, fz_stream *stm);
</pre>
<p>
Various decoding, decompression, and decryption filters can be chained together.
<pre>
fz_stream *fz_open_null_filter(fz_context *ctx, fz_stream *chain, int len, int64_t offset);
fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits);
fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain,
int color_transform,
int l2factor,
fz_stream *jpegtables);
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);
fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain,
int early_change,
int min_bits,
int reverse_bits,
int old_tiff);
fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain,
int predictor,
int columns,
int colors,
int bpc);
</pre>
<h2>Output Streams and Filters</h2>
<p>
Output streams let us write data to a sink, usually a file on disk or a buffer.
As with the input streams, output streams can be chained together to compress,
encrypt, and encode data.
<pre>
typedef struct { <i>internal</i> } fz_output;
</pre>
<p>
Because output may be buffered in the writer, we need a separate
close function to ensure that an output stream is properly flushed
and any end of data markers are written. This is separate to the
drop function, which just frees data. If a writing operation has
succeeded, you need to call close on the output stream before
dropping it.
If you encounter an error while writing data, you can just drop the stream directly, since
we couldn't finish writing it and closing it properly would be irrelevant.
<pre>
void fz_close_output(fz_context *ctx, fz_output *out);
void fz_drop_output(fz_context *ctx, fz_output *out);
</pre>
<p>
Outputs can be created to write to files or buffers.
You can also implement your own data sink by providing a state pointer
and callback functions.
<pre>
fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append);
fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf);
fz_output *fz_new_output(fz_context *ctx,
int buffer_size,
void *state,
void (*write)(fz_context *ctx, void *state, const void *data, size_t n),
void (*close)(fz_context *ctx, void *state),
void (*drop)(fz_context *ctx, void *state));
</pre>
<p>
The usual suspects are available, as well as functions to write
integers of various sizes and byte orders.
<dl>
<dt>void fz_seek_output(fz_context *ctx, fz_output *out, int64_t off, int whence);
<dd>Seek to a location in the output. This is not available for all output types.
<dt>int64_t fz_tell_output(fz_context *ctx, fz_output *out);
<dd>Tell the current write location of the output stream.
</dl>
<pre>
void fz_write_data(fz_context *ctx, fz_output *out, const void *data, size_t size);
void fz_write_string(fz_context *ctx, fz_output *out, const char *s);
void fz_write_byte(fz_context *ctx, fz_output *out, unsigned char x);
void fz_write_rune(fz_context *ctx, fz_output *out, int rune);
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_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_printf(fz_context *ctx, fz_output *out, const char *fmt, ...);
void fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap);
void fz_write_base64(fz_context *ctx, fz_output *out, const unsigned char *data, int size, int newline);
</pre>
<p>
Output streams can be chained together to add encryption, compression, and
encoding. Note that these do not take ownership of the chained stream, they
only write to it. For example, you can write a header, create a compression
filter stream, write some data to the filter to compress the data, close the
filter and then keep writing more data to the original stream.
<pre>
fz_output *fz_new_arc4_output(fz_context *ctx, fz_output *chain, unsigned char *key, size_t keylen);
fz_output *fz_new_ascii85_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_asciihex_output(fz_context *ctx, fz_output *chain);
fz_output *fz_new_deflate_output(fz_context *ctx, fz_output *chain, int effort, int no_header);
fz_output *fz_new_rle_output(fz_context *ctx, fz_output *chain);
</pre>
<h2>File Archives</h2>
<p>
The archive structure is a read-only collection of files. This is typically a
Zip file or directory on disk, but other formats are also supported.
<pre>
typedef struct { <i>internal</i> } fz_archive;
void fz_drop_archive(fz_context *ctx, fz_archive *arch);
int fz_is_directory(fz_context *ctx, const char *path);
fz_archive *fz_open_directory(fz_context *ctx, const char *path);
fz_archive *fz_open_archive(fz_context *ctx, const char *filename);
fz_archive *fz_open_archive_with_stream(fz_context *ctx, fz_stream *file);
int fz_count_archive_entries(fz_context *ctx, fz_archive *arch);
const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx);
int fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
</pre>
<p>
We can also create new Zip archives.
<pre>
typedef struct { <i>internal</i> } fz_zip_writer;
fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename);
fz_zip_writer *fz_new_zip_writer_with_output(fz_context *ctx, fz_output *out);
void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress);
void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip);
void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip);
</pre>
</article>
<footer>
<a href="https://www.artifex.com/"><img src="../artifex-logo.png" align="right"></a>
Copyright &copy; 2019 Artifex Software Inc.
</footer>
</body>
</html>

BIN
mupdf/docs/artifex-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

103
mupdf/docs/building.html Normal file
View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>How to build MuPDF</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>How to build MuPDF</h1>
</header>
<article>
<h2>License</h2>
<p>
MuPDF is Copyright (c) 2006-2019 Artifex Software, Inc.
<p>
This program 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.
<p>
This program 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 General Public License for more details.
<p>
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see
<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>
<p>
For commercial licensing, including our "Indie Dev" friendly options, please
contact <a href="https://artifex.com/contact-us/">Artifex Software</a>.
<h2>Download</h2>
<p>
The latest development source is available directly from the git repository:
<pre>
git clone --recursive git://git.ghostscript.com/mupdf.git
</pre>
<p>
In the mupdf directory, update the third party libraries:
<pre>
git submodule update --init
</pre>
<h2>Compiling on Windows</h2>
<p>
On Windows there is a Visual Studio project file in <tt>platform/win32/mupdf.vcproj</tt>.
<h2>Compiling on Linux</h2>
<p>
If you are compiling from source you will need several third party libraries:
freetype2, jbig2dec, libjpeg, openjpeg, and zlib. These libraries are contained
in the source archive. If you are using git, they are included as git
submodules.
<p>
You will also need the X11 headers and libraries if you're building on Linux.
These can typically be found in the xorg-dev package. Alternatively, if you
only want the command line tools, you can build with HAVE_X11=no.
<p>
The new OpenGL-based viewer also needs OpenGL headers and libraries. If you're
building on Linux, install the mesa-common-dev, libgl1-mesa-dev packages, and
libglu1-mesa-dev packages. You'll also need several X11 development packages:
xorg-dev, libxcursor-dev, libxrandr-dev, and libxinerama-dev. To skip building
the OpenGL viewer, build with HAVE_GLUT=no.
<p>
To install the viewer, command line tools, libraries, and header files on your system:
<pre>
make prefix=/usr/local install
</pre>
<p>
To install only the command line tools, libraries, and headers invoke make like this:
<pre>
make HAVE_X11=no HAVE_GLUT=no prefix=/usr/local install
</pre>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,370 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Overview</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF Overview</h1>
</header>
<article>
<h2>Contents</h2>
<ul>
<li><a href="#basic-mupdf-usage-example">Basic MuPDF usage example</a>
<li><a href="#common-function-arguments">Common function arguments</a>
<li><a href="#error-handling">Error Handling</a>
<li><a href="#multi-threading">Multi-threading</a>
<li><a href="#cloning-the-context">Cloning the context</a>
</ul>
<h2><a id="basic-mupdf-usage-example"></a>
Basic MuPDF usage example
</h2>
<p>
For an example of how to use MuPDF in the most basic way, see
<a href="examples/example.c">docs/examples/example.c</a>.
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.
<h2><a id="common-function-arguments"></a>
Common function arguments
</h2>
<p>
Most functions in MuPDF's interface take a context argument.
<p>
A context contains global state used by MuPDF inside functions when
parsing or rendering pages of the document. It contains for example:
<ul>
<li> an exception stack (see error handling below),
<li> a memory allocator (allowing for custom allocators)
<li> a resource store (for caching of images, fonts, etc.)
<li> a set of locks and (un-)locking functions (for multi-threading)
</ul>
<p>
Without the set of locks and accompanying functions the context and
its proxies may only be used in a single-threaded application.
<h2><a id="error-handling"></a>
Error handling
</h2>
<p>
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.
<p>
The basic formulation is as follows:
<pre>
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).
}
</pre>
<p>
The fz_always block is optional, and can safely be omitted.
<p>
The macro based nature of this system has 3 main limitations:
<ol>
<li> <p>
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.
<li> <p>
The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... }
is not one atomic C statement. That is to say, if you do:
<pre>
if (condition)
fz_try(ctx) { ... }
fz_catch(ctx) { ... }
</pre>
then you will not get what you want. Use the following instead:
<pre>
if (condition) {
fz_try(ctx) { ... }
fz_catch(ctx) { ... }
}
</pre>
<li> <p>
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.
<p>
As a way of mitigating this problem, we provide a fz_var()
macro that tells the compiler to ensure that that variable is
not unset by the act of throwing the exception.
</ol>
<p>
A model piece of code using these macros then might be:
<pre>
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;
}
</pre>
<p>
Things to note about this:
<ol>
<li> 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);
<li> 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.
<li> 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.
<li> We assume the standard C convention that it is safe to destroy
NULL things.
</ol>
<h2><a id="multi-threading"></a>
Multi-threading
</h2>
<p>
First off, study the basic usage example in
<a href="examples/example.c">docs/examples/example.c</a>
and make sure you understand how it works as the data structures manipulated
there will be referred to in this section too.
<p>
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.
<p>
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.
<p>
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.
<p>
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.
<p>
The following simple rules should be followed to ensure that
multi-threaded operations run smoothly:
<ol>
<li> <p>
"No simultaneous calls to MuPDF in different threads are
allowed to use the same context."
<p>
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. For more details see
"Cloning the context" below.
<li> <p>
"No simultaneous calls to MuPDF in different threads are
allowed to use the same document."
<p>
Only one thread can be accessing a document at a time, but
once display lists are created from that document, multiple
threads at a time can operate on them.
<p>
The document can be used from several different threads as
long as there are safeguards in place to prevent the usages
being simultaneous.
<li> <p>
"No simultaneous calls to MuPDF in different threads are
allowed to use the same device."
<p>
Calling a device simultaneously from different threads will
cause it to get confused and may crash. Calling a device from
several different threads is perfectly acceptable as long as
there are safeguards in place to prevent the calls being
simultaneous.
</ol>
<p>
So, how does a multi-threaded example differ from a non-multithreaded
one?
<p>
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.
<p>
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 &lt;= i &lt; FZ_LOCK_MAX). These mutexes can
safely be recursive or non-recursive as MuPDF only calls in a non-
recursive style.
<p>
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. They will share the important data structures (like store,
glyph cache etc) with the original context, but will have their
own exception stacks.
<p>
To open a document, call fz_open_document as usual, passing a context
and a filename. It is important to realise that only one thread at a
time can be accessing the documents itself.
<p>
This means that only one thread at a time can 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).
<p>
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.
<p>
For an example of how to do multi-threading see
<a href="examples/multi-threaded.c">docs/examples/multi-threaded.c</a>
which has a main thread and one rendering thread per page.
<h2><a id="cloning-the-context"></a>
Cloning the context
</h2>
<p>
As described above, every context contains an exception stack which is
manipulated during the course of nested fz_try/fz_catches. For obvious
reasons the same exception stack cannot be used from more than one
thread at a time.
<p>
If, however, we simply created a new context (using fz_new_context) for
every thread, we would end up with separate stores/glyph caches etc,
which is not (generally) what is desired. MuPDF therefore provides a
mechanism for "cloning" a context. This creates a new context that
shares everything with the given context, except for the exception
stack.
<p>
A commonly used general scheme is therefore to create a 'base' context
at program start up, and to clone this repeatedly to get new contexts
that can be used on new threads.
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,366 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Progressive Loading</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF Progressive Loading</h1>
</header>
<article>
<p>
How to do progressive loading with MuPDF.
<h2>What is progressive loading?</h2>
<p>
The idea of progressive loading is that as you download a PDF file
into a browser, you can display the pages as they appear.
<p>
MuPDF can make use of 2 different mechanisms to achieve this. The
first relies on the file being "linearized", the second relies on
the caller of MuPDF having fine control over the http fetch and on
the server supporting byte-range fetches.
<p>
For optimum performance a file should be both linearized and be
available over a byte-range supporting link, but benefits can still
be had with either one of these alone.
<h2>Progressive download using "linearized" files</h2>
<p>
Adobe defines "linearized" PDFs as being ones that have both a
specific layout of objects and a small amount of extra
information to help avoid seeking within a file. The stated aim
is to deliver the first page of a document in advance of the whole
document downloading, whereupon subsequent pages will become
available. Adobe also refers to these as "Optimized for fast web
view" or "Web Optimized".
<p>
In fact, the standard outlines (poorly) a mechanism by which 'hints'
can be included that enable the subsequent pages to be found within
the file too. Unfortunately this is very poorly supported with
many tools, and so the hints have to be treated with suspicion.
<p>
MuPDF will attempt to use hints if they are available, but will also
use a linear search of the file to discover pages if not. This means
that the first page will be displayed quickly, and then subsequent
ones will appear with 'incomplete' renderings that improve over time
as more and more resources are gradually delivered.
<p>
Essentially the file starts with a slightly modified header, and the
first object in the file is a special one (the linearization object)
that a) indicates that the file is linearized, and b) gives some
useful information (like the number of pages in the file etc).
<p>
This object is then followed by all the objects required for the
first page, then the "hint stream", then sets of object for each
subsequent page in turn, then shared objects required for those
pages, then various other random things.
<p>
[Yes, really. While page 1 is sent with all the objects that it
uses, shared or otherwise, subsequent pages do not get shared
resources until after all the unshared page objects have been
sent.]
<h2>The Hint Stream</h2>
<p>
Adobe intended Hint Stream to be useful to facilitate the display
of subsequent pages, but it has never used it. Consequently you
can't trust people to write it properly - indeed Adobe outputs
something that doesn't quite conform to the spec.
<p>
Consequently very few people actually use it. MuPDF will use it
after sanity checking the values, and should cope with illegal/
incorrect values.
<h2>So how does MuPDF handle progressive loading?</h2>
<p>
MuPDF has made various extensions to its mechanisms for handling
progressive loading.
<ul>
<li> Progressive streams
<p>
At its lowest level MuPDF reads file data from a fz_stream,
using the fz_open_document_with_stream call. (fz_open_document
is implemented by calling this). We have extended the fz_stream
slightly, giving the system a way to ask for meta information
(or perform meta operations) on a stream.
<p>
Using this mechanism MuPDF can query:
<ul>
<li> whether a stream is progressive or not (i.e. whether the
entire stream is accessible immediately)
<li> what the length of a stream should ultimately be (which an
http fetcher should know from the Content-Length header),
</ul>
<p>
With this information MuPDF can decide whether to use its normal
object reading code, or whether to make use of a linearized
object. Knowing the length enables us to check with the length
value given in the linearized object - if these differ, the
assumption is that an incremental save has taken place, thus the
file is no longer linearized.
<p>
When data is pulled from a progressive stream, if we attempt to
read data that is not currently available, the stream should
throw a FZ_ERROR_TRYLATER error. This particular error code
will be interpreted by the caller as an indication that it
should retry the parsing of the current objects at a later time.
<p>
When a MuPDF call is made on a progressive stream, such as
fz_open_document_with_stream, or fz_load_page, the caller should
be prepared to handle a FZ_ERROR_TRYLATER error as meaning that
more data is required before it can continue. No indication is
directly given as to exactly how much more data is required, but
as the caller will be implementing the progressive fz_stream
that it has passed into MuPDF to start with, it can reasonably
be expected to figure out an estimate for itself.
<li> Cookie
<p>
Once a page has been loaded, if its contents are to be 'run'
as normal (using e.g. fz_run_page) any error (such as failing
to read a font, or an image, or even a content stream belonging
to the page) will result in a rendering that aborts with an
FZ_ERROR_TRYLATER error. The caller can catch this and display
a placeholder instead.
<p>
If each pages data was entirely self-contained and sent in
sequence this would perhaps be acceptable, with each page
appearing one after the other. Unfortunately, the linearization
procedure as laid down by Adobe does NOT do this: objects shared
between multiple pages (other than the first) are not sent with
the pages themselves, but rather AFTER all the pages have been
sent.
<p>
This means that a document that has a title page, then contents
that share a font used on pages 2 onwards, will not be able to
correctly display page 2 until after the font has arrived in
the file, which will not be until all the page data has been
sent.
<p>
To mitigate against this, MuPDF provides a way whereby callers
can indicate that they are prepared to accept an 'incomplete'
rendering of the file (perhaps with missing images, or with
substitute fonts).
<p>
Callers prepared to tolerate such renderings should set the
'incomplete_ok' flag in the cookie, then call fz_run_page etc
as normal. If a FZ_ERROR_TRYLATER error is thrown at any point
during the page rendering, the error will be swallowed, the
'incomplete' field in the cookie will become non-zero and
rendering will continue. When control returns to the caller
the caller can check the value of the 'incomplete' field and
know that the rendering it received is not authoritative.
</ul>
<h2>Progressive loading using byte range requests</h2>
<p>
If the caller has control over the http fetch, then it is possible
to use byte range requests to fetch the document 'out of order'.
This enables non-linearized files to be progressively displayed as
they download, and fetches complete renderings of pages earlier than
would otherwise be the case. This process requires no changes within
MuPDF itself, but rather in the way the progressive stream learns
from the attempts MuPDF makes to fetch data.
<p>
Consider for example, an attempt to fetch a hypothetical file from
a server.
<ul>
<li><p>
The initial http request for the document is sent with a "Range:"
header to pull down the first (say) 4k of the file.
<li><p>
As soon as we get the header in from this initial request, we can
respond to meta stream operations to give the length, and whether
byte requests are accepted.
<ul>
<li><p>
If the header indicates that byte ranges are acceptable the
stream proceeds to go into a loop fetching chunks of the file
at a time (not necessarily in-order). Otherwise the server
will ignore the Range: header, and just serve the whole file.
<li><p>
If the header indicates a content-length, the stream returns
that.
</ul>
<li><p>
MuPDF can then decide how to proceed based upon these flags and
whether the file is linearized or not. (If the file contains a
linearized object, and the content length matches, then the file
is considered to be linear, otherwise it is not).
<p>
If the file is linear:
<ul>
<li><p>
We proceed to read objects out of the file as it downloads.
This will provide us the first page and all its resources. It
will also enable us to read the hint streams (if present).
<li><p>
Once we have read the hint streams, we unpack (and sanity
check) them to give us a map of where in the file each object
is predicted to live, and which objects are required for each
page. If any of these values are out of range, we treat the
file as if there were no hint streams.
<li><p>
If we have hints, any attempt to load a subsequent page will
cause MuPDF to attempt to read exactly the objects required.
This will cause a sequence of seeks in the fz_stream followed
by reads. If the stream does not have the data to satisfy that
request yet, the stream code should remember the location that
was fetched (and fetch that block in the background so that
future retries will succeed) and should raise an
FZ_ERROR_TRYLATER error.
<p>
[Typically therefore when we jump to a page in a linear file
on a byte request capable link, we will quickly see a rough
rendering, which will improve fairly fast as images and fonts
arrive.]
<li><p>
Regardless of whether we have hints or byte requests, on every
fz_load_page call MuPDF will attempt to process more of the
stream (that is assumed to be being downloaded in the
background). As linearized files are guaranteed to have pages
in order, pages will gradually become available. In the absence
of byte requests and hints however, we have no way of getting
resources early, so the renderings for these pages will remain
incomplete until much more of the file has arrived.
<p>
[Typically therefore when we jump to a page in a linear file
on a non byte request capable link, we will see a rough
rendering for that page as soon as data arrives for it (which
will typically take much longer than would be the case with
byte range capable downloads), and that will improve much more
slowly as images and fonts may not appear until almost the
whole file has arrived.]
<li><p>
When the whole file has arrived, then we will attempt to read
the outlines for the file.
</ul>
<p>
For a non-linearized PDF on a byte request capable stream:
<ul>
<li><p>
MuPDF will immediately seek to the end of the file to attempt
to read the trailer. This will fail with a FZ_ERROR_TRYLATER
due to the data not being here yet, but the stream code should
remember that this data is required and it should be prioritized
in the background fetch process.
<li><p>
Repeated attempts to open the stream should eventually succeed
therefore. As MuPDF jumps through the file trying to read first
the xrefs, then the page tree objects, then the page contents
themselves etc, the background fetching process will be driven
by the attempts to read the file in the foreground.
<p>
[Typically therefore the opening of a non-linearized file will
be slower than a linearized one, as the xrefs/page trees for a
non-linear file can be 20%+ of the file data. Once past this
initial point however, pages and data can be pulled from the
file almost as fast as with a linearized file.]
</ul>
<p>
For a non-linearized PDF on a non-byte request capable stream:
<ul>
<li><p>
MuPDF will immediately seek to the end of the file to attempt
to read the trailer. This will fail with a FZ_ERROR_TRYLATER
due to the data not being here yet. Subsequent retries will
continue to fail until the whole file has arrived, whereupon
the whole file will be instantly available.
<p>
[This is the worst case situation - nothing at all can be
displayed until the entire file has downloaded.]
</ul>
<p>
A typical structure for a fetcher process (see curl-stream.c in
mupdf-curl as an example) might therefore look like this:
<ul>
<li><p>
We consider the file as an (initially empty) buffer which we are
filling by making requests. In order to ensure that we make
maximum use of our download link, we ensure that whenever
one request finishes, we immediately launch another. Further, to
avoid the overheads for the request/response headers being too
large, we may want to divide the file into 'chunks', perhaps 4 or 32k
in size.
<li><p>
We can then have a receiver process that sits there in a loop
requesting chunks to fill this buffer. In the absence of
any other impetus the receiver should request the next 'chunk'
of data from the file that it does not yet have, following the last
fill point. Initially we start the fill point at the beginning of
the file, but this will move around based on the requests made of
the progressive stream.
<li><p>
Whenever MuPDF attempts to read from the stream, we check to see if
we have data for this area of the file already. If we do, we can
return it. If not, we remember this as the next "fill point" for our
receiver process and throw a FZ_ERROR_TRYLATER error.
</ul>
</ul>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Coding Style</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF Coding Style</h1>
</header>
<article>
<h2>Names</h2>
<p>
Functions should be named according to one of the following schemes:
<ul>
<li> verb_noun
<li> verb_noun_with_noun
<li> noun_attribute
<li> set_noun_attribute
<li> noun_from_noun -- convert from one type to another (avoid noun_to_noun)
</ul>
<p>
Prefixes are mandatory for exported functions, macros, enums, globals and types.
<ul>
<li> fz for common code
<li> pdf, xps, etc., for interpreter specific code
</ul>
<p>
Prefixes are optional (but encouraged) for private functions and types.
<p>
Avoid using 'get' as this is a meaningless and redundant filler word.
<p>
These words are reserved for reference counting schemes:
<ul>
<li> new, find, load, open, keep -- return objects that you are responsible for freeing.
<li> drop -- relinquish ownership of the object passed in.
</ul>
<p>
When searching for an object or value, the name used depends on whether
returning the value is passing ownership:
<ul>
<li> lookup -- return a value or borrowed pointer
<li> find -- return an object that the caller is responsible for freeing
</ul>
<h2>Types</h2>
<p>
Various different integer types are used throughout MuPDF.
<p>
In general:
<ul>
<li> int is assumed to be 32bit at least.
<li> short is assumed to be exactly 16 bits.
<li> char is assumed to be exactly 8 bits.
<li> array sizes, string lengths, and allocations are measured using size_t.
size_t is 32bit in 32bit builds, and 64bit on all 64bit builds.
<li> buffers of data use unsigned chars (or uint8_t).
<li> Offsets within files/streams are represented using int64_t.
</ul>
<p>
In addition, we use floats (and avoid doubles when possible), assumed to be IEEE compliant.
<h2>Reference counting</h2>
<p>
Reference counting uses special words in functions to make it easy to remember
and follow the rules.
<p>
Words that take ownership: new, find, load, open, keep.
<p>
Words that release ownership: drop.
<p>
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.
<p>
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.
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,91 @@
function BBoxDevice(bbox) {
function extend(x,y) {
if (x < bbox[0]) bbox[0] = x;
if (x > bbox[2]) bbox[2] = x;
if (y < bbox[1]) bbox[1] = y;
if (y > bbox[3]) bbox[3] = y;
}
function extendPoint(m, px, py) {
var x = px * m[0] + py * m[2] + m[4];
var y = px * m[1] + py * m[3] + m[5];
extend(x, y);
}
function extendRect(m, r) {
var x0 = r[0], y0 = r[1];
var x1 = r[2], y1 = r[3];
extendPoint(m, x0, y0);
extendPoint(m, x1, y0);
extendPoint(m, x0, y1);
extendPoint(m, x1, y1);
}
function PathBounder(ctm) {
return {
moveTo: function (x,y) { extendPoint(ctm, x, y) },
lineTo: function (x,y) { extendPoint(ctm, x, y) },
curveTo: function (x1,y1,x2,y2,x3,y3) {
extendPoint(ctm, x1, y1);
extendPoint(ctm, x2, y2);
extendPoint(ctm, x3, y3);
},
};
}
function TextBounder(ctm) {
return {
showGlyph: function (font,trm,gid,ucs,wmode,bidi) {
var bbox = [ 0, -0.2, font.advanceGlyph(gid, 0), 0.8 ];
extendRect(Concat(trm, ctm), bbox);
},
};
}
return {
fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) {
path.walk(new PathBounder(ctm));
},
clipPath: function (path, evenOdd, ctm) {
path.walk(new PathBounder(ctm));
},
strokePath: function (path, stroke, ctm, colorSpace, color, alpha) {
path.walk(new PathBounder(ctm));
},
clipStrokePath: function (path, stroke, ctm) {
path.walk(new PathBounder(ctm));
},
fillText: function (text, ctm, colorSpace, color, alpha) {
text.walk(new TextBounder(ctm));
},
clipText: function (text, ctm) {
text.walk(new TextBounder(ctm));
},
strokeText: function (text, stroke, ctm, colorSpace, color, alpha) {
text.walk(new TextBounder(ctm));
},
clipStrokeText: function (text, stroke, ctm) {
text.walk(new TextBounder(ctm));
},
ignoreText: function (text, ctm) {
text.walk(new TextBounder(ctm));
},
fillShade: function (shade, ctm, alpha) {
var bbox = shade.bound(ctm);
extend(bbox[0], bbox[1]);
extend(bbox[2], bbox[3]);
},
fillImage: function (image, ctm, alpha) {
extendRect(ctm, [0,0,1,1]);
},
fillImageMask: function (image, ctm, colorSpace, color, alpha) {
extendRect(ctm, [0,0,1,1]);
},
};
}
if (scriptArgs.length != 2)
print("usage: mutool run bbox-device.js document.pdf pageNumber")
else {
var doc = new Document(scriptArgs[0]);
var page = doc.loadPage(parseInt(scriptArgs[1])-1);
var bbox = [Infinity, Infinity, -Infinity, -Infinity];
page.run(new BBoxDevice(bbox), Identity);
print("original bbox:", page.bound());
print("computed bbox:", bbox.map(function (x) { return Math.round(x); }));
}

View File

@ -0,0 +1,19 @@
// Create a PDF containing thumbnails of pages rendered from another PDF.
var pdf = new PDFDocument()
var subdoc = new Document("pdfref17.pdf")
var resources = { XObject: {} }
var contents = new Buffer()
for (var i=0; i < 5; ++i) {
var pixmap = subdoc.loadPage(1140+i).toPixmap([0.2,0,0,0.2,0,0], DeviceRGB, true)
resources.XObject["Im" + i] = pdf.addImage(new Image(pixmap))
contents.writeLine("q 100 0 0 150 " + (50+100*i) + " 50 cm /Im" + i + " Do Q")
}
var page = pdf.addPage([0,0,100+i*100,250], 0, resources, contents)
pdf.insertPage(-1, page)
pdf.save("out.pdf")

View File

@ -0,0 +1,45 @@
// Use device interface to draw some graphics and save as a PNG.
var font = new Font("Times-Roman");
var image = new Image("example.png");
var path, text;
var pixmap = new Pixmap(DeviceRGB, [0,0,500,600], false);
pixmap.clear(255);
var device = new DrawDevice(Identity, pixmap);
var transform = [2,0,0,2,0,0]
{
text = new Text();
{
text.showString(font, [16,0,0,-16,100,30], "Hello, world!");
text.showString(font, [0,16,16,0,15,100], "Hello, world!");
}
device.fillText(text, transform, DeviceGray, [0], 1);
path = new Path();
{
path.moveTo(10, 10);
path.lineTo(90, 10);
path.lineTo(90, 90);
path.lineTo(10, 90);
path.closePath();
}
device.fillPath(path, false, transform, DeviceRGB, [1,0,0], 1);
device.strokePath(path, {dashes:[5,10], lineWidth:3, lineCap:'Round'}, transform, DeviceRGB, [0,0,0], 1);
path = new Path();
{
path.moveTo(100,100);
path.curveTo(150,100, 200,150, 200,200);
path.curveTo(200,300, 0,300, 100,100);
path.closePath();
}
device.clipPath(path, true, transform);
{
device.fillImage(image, Concat(transform, [300,0,0,300,0,0]), 1);
}
device.popClip();
}
device.close();
pixmap.saveAsPNG("out.png");

View File

@ -0,0 +1,9 @@
// Draw all pages in a document and save them as PNG files.
var doc = new Document(scriptArgs[0]);
var n = doc.countPages();
for (var i = 0; i < n; ++i) {
var page = doc.loadPage(i);
var pixmap = page.toPixmap(Identity, DeviceRGB);
pixmap.saveAsPNG("out" + (i+1) + ".png");
}

View File

@ -0,0 +1,135 @@
/*
How to use MuPDF to render a single page and print the result as
a PPM to stdout.
To build this example in a source tree and render first page at
100% zoom with no rotation, run:
make examples
./build/debug/example document.pdf 1 100 0 > page1.ppm
To build from installed sources, and render the same document, run:
gcc -I/usr/local/include -o example \
/usr/local/share/doc/mupdf/examples/example.c \
/usr/local/lib/libmupdf.a \
/usr/local/lib/libmupdfthird.a \
-lm
./example document.pdf 1 100 0 > page1.ppm
*/
#include <mupdf/fitz.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *input;
float zoom, rotate;
int page_number, page_count;
fz_context *ctx;
fz_document *doc;
fz_pixmap *pix;
fz_matrix ctm;
int x, y;
if (argc < 3)
{
fprintf(stderr, "usage: example input-file page-number [ zoom [ rotate ] ]\n");
fprintf(stderr, "\tinput-file: path of PDF, XPS, CBZ or EPUB document to open\n");
fprintf(stderr, "\tPage numbering starts from one.\n");
fprintf(stderr, "\tZoom level is in percent (100 percent is 72 dpi).\n");
fprintf(stderr, "\tRotation is in degrees clockwise.\n");
return EXIT_FAILURE;
}
input = argv[1];
page_number = atoi(argv[2]) - 1;
zoom = argc > 3 ? atof(argv[3]) : 100;
rotate = argc > 4 ? atof(argv[4]) : 0;
/* Create a context to hold the exception stack and various caches. */
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
if (!ctx)
{
fprintf(stderr, "cannot create mupdf context\n");
return EXIT_FAILURE;
}
/* Register the default file types to handle. */
fz_try(ctx)
fz_register_document_handlers(ctx);
fz_catch(ctx)
{
fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx));
fz_drop_context(ctx);
return EXIT_FAILURE;
}
/* Open the document. */
fz_try(ctx)
doc = fz_open_document(ctx, input);
fz_catch(ctx)
{
fprintf(stderr, "cannot open document: %s\n", fz_caught_message(ctx));
fz_drop_context(ctx);
return EXIT_FAILURE;
}
/* Count the number of pages. */
fz_try(ctx)
page_count = fz_count_pages(ctx, doc);
fz_catch(ctx)
{
fprintf(stderr, "cannot count number of pages: %s\n", fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return EXIT_FAILURE;
}
if (page_number < 0 || page_number >= page_count)
{
fprintf(stderr, "page number out of range: %d (page count %d)\n", page_number + 1, page_count);
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return EXIT_FAILURE;
}
/* Compute a transformation matrix for the zoom and rotation desired. */
/* The default resolution without scaling is 72 dpi. */
ctm = fz_scale(zoom / 100, zoom / 100);
ctm = fz_pre_rotate(ctm, rotate);
/* Render page to an RGB pixmap. */
fz_try(ctx)
pix = fz_new_pixmap_from_page_number(ctx, doc, page_number, ctm, fz_device_rgb(ctx), NULL, 0);
fz_catch(ctx)
{
fprintf(stderr, "cannot render page: %s\n", fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return EXIT_FAILURE;
}
/* Print image data in ascii PPM format. */
printf("P3\n");
printf("%d %d\n", pix->w, pix->h);
printf("255\n");
for (y = 0; y < pix->h; ++y)
{
unsigned char *p = &pix->samples[y * pix->stride];
for (x = 0; x < pix->w; ++x)
{
if (x > 0)
printf(" ");
printf("%3d %3d %3d", p[0], p[1], p[2]);
p += pix->n;
}
printf("\n");
}
/* Clean up. */
fz_drop_pixmap(ctx, pix);
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,33 @@
// A simple script to fix the broken fonts in PDF files generated by S22PDF.
if (scriptArgs.length != 2) {
print("usage: mutool run fix-s22pdf.js input.pdf output.pdf");
quit();
}
var doc = new PDFDocument(scriptArgs[0]);
var font = new Font("zh-Hans");
var song = doc.addCJKFont(font, "zh-Hans", "H", "serif");
var heiti = doc.addCJKFont(font, "zh-Hans", "H", "sans-serif");
song.Encoding = 'GBK-EUC-H';
heiti.Encoding = 'GBK-EUC-H';
var MAP = {
"/#CB#CE#CC#E5": song, // SimSun
"/#BA#DA#CC#E5": heiti, // SimHei
"/#BF#AC#CC#E5_GB2312": song, // SimKai
"/#B7#C2#CB#CE_GB2312": heiti, // SimFang
"/#C1#A5#CA#E9": song, // SimLi
}
var i, n = doc.countPages();
for (i = 0; i < n; ++i) {
var fonts = doc.findPage(i).Resources.Font;
fonts.forEach(function (name, font) {
if (font.BaseFont in MAP && font.Encoding == 'WinAnsiEncoding')
fonts[name] = MAP[font.BaseFont];
});
}
doc.save(scriptArgs[1]);

View File

@ -0,0 +1,39 @@
// Script to create a PDF from JPEG2000 images.
// Each image be put on its own page.
// This script can be used to create files to test JPEG2000 support in PDF viewers.
var doc = new PDFDocument();
function addJPXImage(filename, w, h) {
return doc.addRawStream(
readFile(filename),
{
Type: "XObject",
Subtype: "Image",
Width: w,
Height: h,
Filter: "JPXDecode"
}
);
}
function addJPXPage(filename) {
var image = new Image(filename);
var w = image.getWidth();
var h = image.getHeight();
var mediabox = [0, 0, w, h];
var resources = { XObject: { I: addJPXImage(filename, w, h) } };
var contents = "q " + w + " 0 0 " + h + " 0 0 cm /I Do Q";
doc.insertPage(-1, doc.addPage(mediabox, 0, resources, contents));
}
var i, n = scriptArgs.length;
if (n < 1) {
print("usage: mutool run jpx-to-pdf.js file.jpx ...");
quit();
}
for (i = 0; i < n; ++i) {
addJPXPage(scriptArgs[i]);
}
doc.save("out.pdf", "ascii,pretty");

View File

@ -0,0 +1,297 @@
/*
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.
To build this example in a source tree and render every page as a
separate PNG, run:
make examples
./build/debug/multi-threaded document.pdf
To build from installed sources, and render the same document, run:
gcc -I/usr/local/include -o multi-threaded \
/usr/local/share/doc/mupdf/examples/multi-threaded.c \
/usr/local/lib/libmupdf.a \
/usr/local/lib/libmupdfthird.a \
-lpthread -lm
./multi-threaded 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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>
// A convenience function for dying abruptly on pthread errors.
void
fail(char *msg)
{
fprintf(stderr, "%s\n", 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;
fz_device *dev;
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);
dev = fz_new_draw_device(ctx, &fz_identity, pix);
fz_run_display_list(ctx, list, dev, &fz_identity, &bbox, NULL);
fz_close_device(ctx, dev);
fz_drop_device(ctx, dev);
// This threads context is freed.
fz_drop_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 = argc >= 2 ? argv[1] : "";
pthread_t *thread = NULL;
fz_locks_context locks;
pthread_mutex_t mutex[FZ_LOCK_MAX];
fz_context *ctx;
fz_document *doc;
int threads;
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.
ctx = fz_new_context(NULL, &locks, FZ_STORE_UNLIMITED);
// Register default file types.
fz_register_document_handlers(ctx);
// Open the PDF, XPS or CBZ document. Note, this binds doc to ctx.
// You must only ever use doc with ctx - never a clone of it!
doc = fz_open_document(ctx, filename);
// Retrieve the number of pages, which translates to the
// number of threads used for rendering pages.
threads = fz_count_pages(ctx, doc);
fprintf(stderr, "spawning %d threads, one per page...\n", threads);
thread = malloc(threads * sizeof (pthread_t));
for (i = 0; i < threads; i++)
{
fz_page *page;
fz_rect bbox;
fz_irect rbox;
fz_display_list *list;
fz_device *dev;
fz_pixmap *pix;
struct data *data;
// Load the relevant page for each thread. Note, that this
// cannot be done on the worker threads, as each use of doc
// uses ctx, and only one thread can be using ctx at a time.
page = fz_load_page(ctx, doc, i);
// Compute the bounding box for each page.
fz_bound_page(ctx, page, &bbox);
// Create a display list that will hold the drawing
// commands for the page. Once we have the display list
// this can safely be used on any other thread as it is
// not bound to a given context.
list = fz_new_display_list(ctx, &bbox);
// Run the loaded page through a display list device
// to populate the page's display list.
dev = fz_new_list_device(ctx, list);
fz_run_page(ctx, page, dev, &fz_identity, NULL);
fz_close_device(ctx, dev);
fz_drop_device(ctx, dev);
// The page is no longer needed, all drawing commands
// are now in the display list.
fz_drop_page(ctx, page);
// Create a white pixmap using the correct dimensions.
pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), fz_round_rect(&rbox, &bbox), NULL, 0);
fz_clear_pixmap_with_value(ctx, pix, 0xff);
// Populate the data structure to be sent to the
// rendering thread for this page.
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_save_pixmap_as_png(ctx, data->pix, filename);
// Free the thread's pixmap and display list since
// they were allocated by the main thread above.
fz_drop_pixmap(ctx, data->pix);
fz_drop_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_drop_document(ctx, doc);
fz_drop_context(ctx);
return 0;
}

View File

@ -0,0 +1,61 @@
// Create a PDF from scratch.
// This example creates a new PDF file from scratch, using only the low level APIs.
// This assumes a basic working knowledge of the PDF file format.
// Create a new empty document with no pages.
var pdf = new PDFDocument()
// Create and add a font resource.
var font = pdf.addObject({
Type: "Font",
Subtype: "Type1",
Encoding: "WinAnsiEncoding",
BaseFont: "Times-Roman",
})
// Create and add an image resource:
var image = pdf.addRawStream(
// The raw stream contents, hex encoded to match the Filter entry:
"004488CCEEBB7733>",
// The image object dictionary:
{
Type: "XObject",
Subtype: "Image",
Width: 4,
Height: 2,
BitsPerComponent: 8,
ColorSpace: "DeviceGray",
Filter: "ASCIIHexDecode",
}
);
// Create resource dictionary.
var resources = pdf.addObject({
Font: { Tm: font },
XObject: { Im0: image },
})
// Create content stream.
var buffer = new Buffer()
buffer.writeLine("10 10 280 330 re s")
buffer.writeLine("q 200 0 0 200 50 100 cm /Im0 Do Q")
buffer.writeLine("BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET")
var contents = pdf.addStream(buffer)
// Create page object.
var page = pdf.addObject({
Type: "Page",
MediaBox: [0,0,300,350],
Contents: contents,
Resources: resources,
})
// Insert page object into page tree.
var pagetree = pdf.getTrailer().Root.Pages
pagetree.Count = 1
pagetree.Kids = [ page ]
page.Parent = pagetree
// Save the document.
pdf.save("out.pdf")

View File

@ -0,0 +1,35 @@
// Create a PDF from scratch using helper functions.
// This example creates a new PDF file from scratch, using helper
// functions to create resources and page objects.
// This assumes a basic working knowledge of the PDF file format.
// Create a new empty document with no pages.
var pdf = new PDFDocument()
// Load built-in font and create WinAnsi encoded simple font resource.
var font = pdf.addSimpleFont(new Font("Times-Roman"))
// Load PNG file and create image resource.
var image = pdf.addImage(new Image("example.png"))
// Create resource dictionary.
var resources = pdf.addObject({
Font: { Tm: font },
XObject: { Im0: image },
})
// Create content stream data.
var contents =
"10 10 280 330 re s\n" +
"q 200 0 0 200 50 100 cm /Im0 Do Q\n" +
"BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET\n"
// Create a new page object.
var page = pdf.addPage([0,0,300,350], 0, resources, contents)
// Insert page object at the end of the document.
pdf.insertPage(-1, page)
// Save the document to file.
pdf.save("out.pdf", "pretty,ascii,compress-images,compress-fonts")

View File

@ -0,0 +1,55 @@
// Find all JPEG-2000 images and turn them into regular images.
var doc = new PDFDocument(scriptArgs[0]);
function isJPXImage(ref) {
if ("Filter" in ref) {
var filter = ref.Filter;
if (filter == "JPXDecode")
return true;
if (filter.isArray())
for (var i = 0; i < filter.length; ++i)
if (filter[i] == "JPXDecode")
return true;
}
return false;
}
var i, n, ref;
var jpxList = {};
var smaskList = {};
// Preload and destroy all JPX images.
n = doc.countObjects();
for (i=1; i < n; ++i) {
ref = doc.newIndirect(i, 0);
if (isJPXImage(ref)) {
print("Loading JPX image:", i)
jpxList[i] = doc.loadImage(ref);
if ("SMask" in ref)
smaskList[i] = ref.SMask;
ref.writeObject(null); // make sure we don't reuse the JPX image resource
}
}
for (i in jpxList) {
ref = doc.newIndirect(i, 0);
var jpx = jpxList[i];
var pix = jpx.toPixmap();
var raw = new Image(pix);
// Create a new image, then copy the data to the old object, then delete it.
print("Decompressed image:", i);
var img = doc.addImage(raw);
if (i in smaskList)
img.SMask = smaskList[i];
ref.writeObject(img.resolve());
ref.writeRawStream(img.readRawStream());
doc.deleteObject(img);
// Invoke the GC to free intermediate pixmaps and images.
gc();
}
doc.save(scriptArgs[1], "compress,garbage=compact");

View File

@ -0,0 +1,67 @@
// A re-implementation of "mutool merge" in JavaScript.
function graftObject(dstDoc, srcDoc, srcObj, map) {
var srcNum, dstRef, dstObj
if (!map)
map = []
if (srcObj.isIndirect()) {
srcNum = srcObj.toIndirect()
if (map[srcNum])
return map[srcNum]
map[srcNum] = dstRef = dstDoc.createObject()
dstRef.writeObject(graftObject(dstDoc, srcDoc, srcObj.resolve(), map))
if (srcObj.isStream())
dstRef.writeRawStream(srcObj.readRawStream())
return dstRef
}
if (srcObj.isArray()) {
dstObj = dstDoc.newArray()
srcObj.forEach(function (key, val) {
dstObj[key] = graftObject(dstDoc, srcDoc, val, map)
})
return dstObj
}
if (srcObj.isDictionary()) {
dstObj = dstDoc.newDictionary()
srcObj.forEach(function (key, val) {
dstObj[key] = graftObject(dstDoc, srcDoc, val, map)
})
return dstObj
}
return srcObj /* primitive objects are not bound to a document */
}
function copyPage(dstDoc, srcDoc, pageNumber, map) {
var srcPage, dstPage
srcPage = srcDoc.findPage(pageNumber)
dstPage = dstDoc.newDictionary()
dstPage.Type = dstDoc.newName("Page")
if (srcPage.MediaBox) dstPage.MediaBox = graftObject(dstDoc, srcDoc, srcPage.MediaBox, map)
if (srcPage.Rotate) dstPage.Rotate = graftObject(dstDoc, srcDoc, srcPage.Rotate, map)
if (srcPage.Resources) dstPage.Resources = graftObject(dstDoc, srcDoc, srcPage.Resources, map)
if (srcPage.Contents) dstPage.Contents = graftObject(dstDoc, srcDoc, srcPage.Contents, map)
dstDoc.insertPage(-1, dstDoc.addObject(dstPage))
}
function copyAllPages(dstDoc, srcDoc) {
var k, n = srcDoc.countPages()
var srcMap = []
for (k = 0; k < n; ++k)
copyPage(dstDoc, srcDoc, k, srcMap)
}
function pdfmerge() {
var srcDoc, dstDoc, i
dstDoc = new PDFDocument()
for (i = 1; i < scriptArgs.length; ++i) {
srcDoc = new PDFDocument(scriptArgs[i])
copyAllPages(dstDoc, srcDoc)
}
dstDoc.save(scriptArgs[0], "compress")
}
if (scriptArgs.length < 2)
print("usage: mutool run pdf-merge.js output.pdf input1.pdf input2.pdf ...")
else
pdfmerge()

View File

@ -0,0 +1,62 @@
// List and extract embedded files in a PDF document.
if (scriptArgs.length != 1 && scriptArgs.length != 3) {
print("usage: mutool run pdf-portfolio.js input.pdf [index filename]");
print(" List embedded files, or extract an embedded file from a PDF document.")
quit();
}
var doc = new PDFDocument(scriptArgs[0]);
var Root = doc.getTrailer().Root
if (!("EmbeddedFiles" in Root.Names)) {
print("Document has no embedded files!");
quit();
}
function mapNameTree(N, fn) {
function mapNameTreeNames(NN) {
var i, n = NN.length;
for (i = 0; i < n; i += 2)
fn(NN[i], NN[i+1]);
}
function mapNameTreeKids(NK) {
var i, n = NK.length;
for (i = 0; i < n; ++i)
mapNameTree(NK[i], fn)
}
if ("Names" in N)
mapNameTreeNames(N.Names);
if ("Kids" in N)
mapNameTreeKids(N.Kids);
}
function fileNameFromFS(fs) {
if ("UF" in fs) return fs.UF.asString();
if ("F" in fs) return fs.F.asString();
if ("Unix" in fs) return fs.Unix.asString();
if ("DOS" in fs) return fs.DOS.asString();
if ("Mac" in fs) return fs.Mac.asString();
return "Untitled";
}
if (scriptArgs.length == 1) {
var idx = 1;
mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
print(idx, name.asString());
print("\tFilename:", fileNameFromFS(fs));
if ("Desc" in fs)
print("\tDescription:", fs.Desc.asString());
++idx;
});
}
if (scriptArgs.length == 3) {
var idx = 1;
mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
if (idx == scriptArgs[1]) {
print("Saving embedded file", idx, "as:", scriptArgs[2]);
fs.EF.F.readStream().save(scriptArgs[2]);
}
++idx;
});
}

View File

@ -0,0 +1,102 @@
var Q = JSON.stringify
var pathPrinter = {
moveTo: function (x,y) { print("moveTo", x, y) },
lineTo: function (x,y) { print("lineTo", x, y) },
curveTo: function (x1,y1,x2,y2,x3,y3) { print("curveTo", x1, y1, x2, y2, x3, y3) },
closePath: function () { print("closePath") },
}
var textPrinter = {
showGlyph: function (f,m,g,u,v,b) { print("glyph",f,m,g,u,v,b) },
}
var traceDevice = {
fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) {
print("fillPath", evenOdd, ctm, colorSpace, color, alpha)
path.walk(pathPrinter)
},
clipPath: function (path, evenOdd, ctm) {
print("clipPath", evenOdd, ctm)
path.walk(pathPrinter)
},
strokePath: function (path, stroke, ctm, colorSpace, color, alpha) {
print("strokePath", Q(stroke), ctm, colorSpace, color, alpha)
path.walk(pathPrinter)
},
clipStrokePath: function (path, stroke, ctm) {
print("clipStrokePath", Q(stroke), ctm)
path.walk(pathPrinter)
},
fillText: function (text, ctm, colorSpace, color, alpha) {
print("fillText", ctm, colorSpace, color, alpha)
text.walk(textPrinter)
},
clipText: function (text, ctm) {
print("clipText", ctm)
text.walk(textPrinter)
},
strokeText: function (text, stroke, ctm, colorSpace, color, alpha) {
print("strokeText", Q(stroke), ctm, colorSpace, color, alpha)
text.walk(textPrinter)
},
clipStrokeText: function (text, stroke, ctm) {
print("clipStrokeText", Q(stroke), ctm)
text.walk(textPrinter)
},
ignoreText: function (text, ctm) {
print("ignoreText", ctm)
text.walk(textPrinter)
},
fillShade: function (shade, ctm, alpha) {
print("fillShade", shade, ctm, alpha)
},
fillImage: function (image, ctm, alpha) {
print("fillImage", image, ctm, alpha)
},
fillImageMask: function (image, ctm, colorSpace, color, alpha) {
print("fillImageMask", image, ctm, colorSpace, color, alpha)
},
clipImageMask: function (image, ctm) {
print("clipImageMask", image, ctm)
},
beginMask: function (area, luminosity, colorspace, color) {
print("beginMask", area, luminosity, colorspace, color)
},
endMask: function () {
print("endMask")
},
popClip: function () {
print("popClip")
},
beginGroup: function (area, isolated, knockout, blendmode, alpha) {
print("beginGroup", area, isolated, knockout, blendmode, alpha)
},
endGroup: function () {
print("endGroup")
},
beginTile: function (area, view, xstep, ystep, ctm, id) {
print("beginTile", area, view, xstep, ystep, ctm, id)
return 0
},
endTile: function () {
print("endTile")
},
close: function () {
print("close")
},
}
if (scriptArgs.length != 2)
print("usage: mutool run trace-device.js document.pdf pageNumber")
else {
var doc = new Document(scriptArgs[0]);
var page = doc.loadPage(parseInt(scriptArgs[1])-1);
page.run(traceDevice, Identity);
}

142
mupdf/docs/index.html Normal file
View File

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF Documentation</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF Documentation</h1>
</header>
<article>
<p>
MuPDF is an open source software framework for viewing and converting PDF, XPS, and E-book documents.
There are viewers for various platforms,
several command line tools,
and a software library for building tools and applications.
<h2>Viewers</h2>
<p>
For Linux and Windows there are two viewers. One is a very basic viewer using x11 and win32, respectively.
It has been supplanted by a newer viewer using OpenGL for rendering, which has more features
such as table of contents, unicode search, etc.
We keep the old viewers around for older systems where OpenGL is not available.
<p>
Read the <a href="manual-mupdf-gl.html">manual for the new Linux and Windows viewer</a>.
<p>
Android currently has several different viewers with varying degrees of complexity:
<dl>
<dt><a href="https://play.google.com/store/apps/details?id=com.artifex.mupdfdemo">MuPDF</a>
<dd>The main app on Google Play. Supports forms and annotations.
<dt><a href="https://play.google.com/store/apps/details?id=com.artifex.mupdf.viewer.app">MuPDF viewer</a>
<dd>A slimmed down viewer only variant of the main app.
<dt><a href="https://play.google.com/store/apps/details?id=com.artifex.mupdf.mini.app">MuPDF mini</a>
<dd>A minimal code example of a document viewer.
</dl>
<p>
The iOS viewer is available on the <a href="https://itunes.apple.com/us/app/mupdf/id482941798">App Store</a>.
<h2>Command Line Tools</h2>
<p>
The command line tools are all gathered into one umbrella command: mutool.
<p>
For rendering and converting documents there are three commands available:
<dl>
<dt><a href="manual-mutool-draw.html">mutool draw</a>
<dd>This is the more customizable tool, but also has a more difficult set of command line options.
It is primarily used for rendering a document to image files.
<dt><a href="manual-mutool-convert.html">mutool convert</a>
<dd>This tool is used for converting documents into other formats, and is easier to use.
<dt><a href="manual-mutool-trace.html">mutool trace</a>
<dd>This is a debugging tool used for printing a trace of the graphics device calls on a page.
</dl>
<p>
There are also several tools specifically for working with PDF files:
<dl>
<dt><a href="manual-mutool-show.html">mutool show</a>
<dd>A tool for displaying the internal objects in a PDF file.
<dt><a href="manual-mutool-extract.html">mutool extract</a>
<dd>Extract images and embedded font resources.
<dt><a href="manual-mutool-clean.html">mutool clean</a>
<dd>Rewrite PDF file. Used to fix broken files, or to make a PDF file human editable.
<dt><a href="manual-mutool-merge.html">mutool merge</a>
<dd>Merge pages from multiple input files into a new PDF.
<dt><a href="manual-mutool-create.html">mutool create</a>
<dd>Create a new PDF file from a text file with graphics commands.
</dl>
<p>
And finally, there is a tool for doing anything you can imagine:
<dl>
<dt><a href="manual-mutool-run.html">mutool run</a>
<dd>A tool for running Javascript programs with access to the MuPDF library functions.
</dl>
<h2>Library</h2>
<p>
The library is written in portable C.
<!--
To learn more about the C interface, read the <a href="book/nav.xhtml">MuPDF Explored</a> book.
The book is also available as a <a href="book.pdf">PDF</a> and <a href="book.epub">EPUB</a> file.
-->
<ul>
<li><a href="building.html">How to build the library</a>.
<li><a href="coding-overview.html">Overview</a>.
<li><a href="coding-style.html">Coding style</a>.
<li><a href="coding-progressive.html">Progressive loading</a>.
<li><a href="thirdparty.html">List of third party libraries</a>.
<li><a href="api/index.html">MuPDF API reference manual.</a>.
<li><a href="api/changes.html">Changes in the public API between versions</a>.
</ul>
<p>
There is also a Java library, which uses JNI to provide access to the C library.
The Java classes provide an interface very similar to that available in the
<a href="manual-mutool-run.html">mutool run</a> command line tool.
This Java library also powers the Android SDK.
<p>
If you want to build an application for Android, you have several options. You
can base it off one of the existing viewers, or build a new app using the Java
library directly.
<ul>
<li><a href="android-sdk.html">Android SDK documentation</a>.
</ul>
<h2>Contributing</h2>
<p>
We welcome patches from outside contributors.
If you want to contribute patches to MuPDF, please review and sign the
<a href="https://www.artifex.com/wp-content/uploads/2017/02/Contributor-License-Agreement-2012.pdf">
Artifex Contributor License Agreement</a>.
<p>
Artifex Software also has a <a href="https://www.artifex.com/developers-bug-bounty-program/">bug bounty program</a>.
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="320"
height="320"
id="svg2">
<defs
id="defs4">
<clipPath
id="clipPath3051">
<path
d="M 0,792 612,792 612,0 0,0 0,792 z"
id="path3053" />
</clipPath>
<clipPath
id="clipPath2999">
<path
d="M 0,0 612,0 612,792 0,792 0,0 z"
id="path3001" />
</clipPath>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-266.37323,-267.38146)"
id="layer1">
<g
transform="matrix(1.25,0,0,-1.25,6.6577275,1024.0891)"
id="g2993">
<g
clip-path="url(#clipPath2999)"
id="g2997">
<g
transform="translate(340.14937,477.78063)"
id="g3023">
<path
d="m 0,0 -19.833,-57.952 -42.766,125.606 -35.923,0 0,-160.107 21.734,0 0,130.088 44.088,-130.088 21.169,0 27.767,81.932 C 10.307,-7.801 4.847,-4.246 0,0"
id="path3025"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
<g
transform="translate(442.76443,529.86787)"
id="g3027">
<path
d="m 0,0 c 0,32.498 -26.342,58.841 -58.84,58.841 -32.499,0 -58.84,-26.343 -58.84,-58.841 0,-32.499 26.341,-58.842 58.84,-58.842 C -26.342,-58.842 0,-32.499 0,0"
id="path3029"
style="fill:#4386b5;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
<g
transform="translate(440.44413,529.86787)"
id="g3031">
<path
d="m 0,0 c 0,-29.194 -25.303,-52.857 -56.52,-52.857 -31.216,0 -56.519,23.663 -56.519,52.857 0,29.194 25.303,52.857 56.519,52.857 C -25.303,52.857 0,29.194 0,0 m -118.377,0 c 0,-34.166 27.693,-61.857 61.857,-61.857 34.165,0 61.858,27.691 61.858,61.857 0,34.164 -27.693,61.855 -61.858,61.855 -34.164,0 -61.857,-27.691 -61.857,-61.855"
id="path3033"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
<g
transform="translate(374.38717,526.29433)"
id="g3035">
<path
d="m 0,0 0,-41.297 c -4.614,0.775 -9.004,2.076 -13.086,3.832 L 0,0 z m 29.787,3.459 c 0,21.194 3.114,25.225 20.566,25.36 -0.386,0.579 -0.805,1.134 -1.215,1.695 0.028,-0.028 0.058,-0.054 0.086,-0.082 -0.122,0.168 -0.255,0.326 -0.379,0.492 -0.29,0.389 -0.586,0.772 -0.888,1.152 -0.357,0.45 -0.724,0.892 -1.097,1.329 -0.277,0.325 -0.553,0.651 -0.839,0.969 -0.47,0.522 -0.956,1.029 -1.448,1.531 -0.213,0.217 -0.418,0.44 -0.635,0.653 -8.753,8.609 -20.75,13.928 -33.998,13.928 -16.16,0 -30.463,-7.905 -39.283,-20.053 9.44,9.555 23.53,15.626 39.283,15.626 10.552,0 20.349,-2.734 28.51,-7.405 l -48.092,0 -21.513,-62.485 c 0.634,-1.011 1.318,-1.962 2.024,-2.884 -0.069,0.069 -0.143,0.134 -0.212,0.204 8.82,-12.149 23.123,-20.053 39.283,-20.053 16.161,0 30.465,7.905 39.284,20.054 -5.223,-5.286 -11.873,-9.499 -19.437,-12.215 l 0,42.184 z"
id="path3037"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
<g
transform="translate(377.11667,449.31773)"
id="g3039">
<path
d="M 0,0 0,6.361 C 0,7.465 0.896,8.197 2,7.994 3.104,7.792 4,6.731 4,5.627 L 4,-0.26 c 1.059,-0.043 2.115,-0.07 3.164,-0.07 3.894,0 7.861,0.311 11.826,0.893 l 0,12.333 c -3.826,-0.678 -7.758,-1.052 -11.779,-1.052 -3.884,0 -7.685,0.349 -11.388,0.982 l 0,-12.336 C -2.783,0.294 -1.39,0.125 0,0"
id="path3041"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
<g
transform="translate(384.28077,445.98813)"
id="g3043">
<path
d="m 0,0 c -1.049,0 -2.105,0.028 -3.164,0.069 l 0,-55.768 c 0,-1.104 -0.896,-1.835 -2,-1.633 -1.105,0.203 -2,1.263 -2,2.367 l 0,55.278 c -1.39,0.121 -2.783,0.285 -4.177,0.474 l 0,-60.255 c 0,0 3.861,-2.493 11.388,-2.493 7.527,0 11.779,2.564 11.779,2.564 l 0,60.255 C 7.862,0.296 3.896,0 0,0"
id="path3045"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 KiB

Binary file not shown.

BIN
mupdf/docs/logo/mupdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

497
mupdf/docs/logo/mupdf.xpm Normal file
View File

@ -0,0 +1,497 @@
/* XPM */
static char *mupdf[] = {
/* width height ncolors chars_per_pixel */
"48 48 442 2",
/* colors */
" c #000000",
" . c #2E4558",
" X c #252121",
" o c #AFAFAF",
" O c #28313B",
" + c #231F1F",
" @ c #686666",
" # c #98BDD7",
" $ c #201B1C",
" % c #7CABCC",
" & c #4487B6",
" * c #DFDEDE",
" = c #4285B4",
" - c #615E5F",
" ; c #605E5E",
" : c #23262C",
" > c #D9D8D8",
" , c #F7FAFC",
" < c #D7D6D6",
" 1 c #BFD6E6",
" 2 c #6BA0C5",
" 3 c #232122",
" 4 c #555253",
" 5 c #CDCCCC",
" 6 c #E7EFF6",
" 7 c #4786B2",
" 8 c #CADDEA",
" 9 c #4085B5",
" 0 c #AECBDF",
" q c #CBCACA",
" w c #92B9D4",
" e c #365F7D",
" r c #5A95BE",
" t c #3E83B3",
" y c #304B60",
" u c #C7C6C6",
" i c #4D8EBB",
" p c #F1F6F9",
" a c #C1C0C0",
" s c #454243",
" d c #669CC3",
" f c #81AECD",
" g c #7A7777",
" h c #434041",
" j c #3E779F",
" k c #272E36",
" l c #413E3F",
" z c #3F3C3D",
" x c #5895BF",
" c c #3D3A3B",
" v c #C6DBE9",
" b c #B8B6B7",
" n c #4282B0",
" m c #FDFDFE",
" M c #B7B6B6",
" N c #8DB5D2",
" B c #242529",
" V c #B3B2B2",
" C c #222327",
" Z c #B0AEAF",
" A c #EDF4F8",
" S c #686565",
" D c #488AB9",
" F c #9ABED8",
" G c #7EACCD",
" H c #ECF2F7",
" J c #211C1C",
" K c #666363",
" L c #F1F1F2",
" P c #ABAAAA",
" I c #4588B6",
" U c #A9A8A8",
" Y c #2D2A2B",
" T c #A7A6A6",
" R c #615D5E",
" E c #2B2829",
" W c #8DB7D5",
" Q c #F9FBFD",
" ! c #DDE9F2",
" ~ c #F8FBFC",
" ^ c #DCE9F1",
" / c #A5C5DC",
" ( c #89B3D1",
" ) c #5C5959",
" _ c #A4C5DB",
" ` c #335A76",
" ' c #518FBB",
" ] c #E6E7E7",
" [ c #5A5757",
" { c #232021",
" } c #33536C",
" | c #98BED9",
". c #E0E1E1",
".. c #7CACCE",
".X c #4488B8",
".o c #2D3F4F",
".O c #999898",
".+ c #4388B7",
".@ c #5E98C1",
".# c #CDCDCB",
".$ c #524F4F",
".% c #B0CCE0",
".& c #979696",
".* c #78A8CA",
".= c #5C96BF",
".- c #969495",
".; c #4084B4",
".: c #252930",
".> c #949293",
"., c #929091",
".< c #417FAB",
".1 c #4F8FBC",
".2 c #F3F7FA",
".3 c #D3D3D4",
".4 c #D7E5EF",
".5 c #222023",
".6 c #9FC1D9",
".7 c #679DC3",
".8 c #37678A",
".9 c #4B8BB8",
".0 c #3E769E",
".q c #3C749C",
".w c #403D3D",
".e c #92BAD6",
".r c #C8DCEA",
".t c #FEFEFE",
".y c #3D393A",
".u c #3B3738",
".i c #355974",
".p c #353132",
".a c #7A7879",
".s c #498BB9",
".d c #9BBFD8",
".f c #4E8AB4",
".g c #787677",
".h c #F2F2F2",
".j c #F0F0F0",
".k c #2F2B2C",
".l c #EEEEEE",
".z c #727071",
".x c #26282D",
".c c #ECECEC",
".v c #2B2728",
".b c #FAFCFD",
".n c #EAEAEA",
".m c #DEEAF2",
".M c #E9EAE9",
".N c #C2D8E7",
".B c #6E6C6D",
".V c #5390BC",
".C c #E8E8E8",
".Z c #6EA2C6",
".A c #272324",
".S c #E7E6E7",
".D c #E6E6E6",
".F c #252122",
".G c #29333D",
".H c #E4E4E4",
".J c #3F7AA5",
".K c #231F20",
".L c #E2E2E2",
".P c #211D1E",
".I c #E0E0E0",
".U c #EAF1F7",
".Y c #6099C2",
".T c #1F1B1C",
".R c #E9F1F6",
".E c #CDDFEB",
".W c #4387B6",
".Q c #96BBD6",
".! c #B1CDE0",
".~ c #DEDEDE",
".^ c #79A9CA",
"./ c #4285B5",
".( c #272A31",
".) c #5D97BF",
"._ c #4185B4",
".` c #DCDCDC",
".' c #959393",
".] c #DADADA",
".[ c #314B5F",
".{ c #D8D8D8",
".} c #D7D8D7",
".| c #D6D6D6",
"X c #F5F8FB",
"X. c #D4D4D4",
"XX c #6AA0C5",
"Xo c #BDD4E5",
"XO c #3A6A8C",
"X+ c #232123",
"X@ c #D3D4D3",
"X# c #D2D2D2",
"X$ c #D0D0D0",
"X% c #CECECE",
"X& c #CCCCCC",
"X* c #CADDEB",
"X= c #37617F",
"X- c #242A31",
"X; c #CACACA",
"X: c #C8DBE9",
"X> c #90B7D3",
"X, c #817F7F",
"X< c #3F7EAB",
"X1 c #548FB9",
"X2 c #355873",
"X3 c #7D7B7B",
"X4 c #C2C2C2",
"X5 c #4B8CBA",
"X6 c #C0C0C0",
"X7 c #D4E4EE",
"X8 c #81AECE",
"X9 c #659CC3",
"X0 c #787576",
"Xq c #4788B6",
"Xw c #252C35",
"Xe c #757373",
"Xr c #BABABA",
"Xt c #FCFDFE",
"Xy c #B6B6B6",
"Xu c #C4D9E8",
"Xi c #706D6E",
"Xp c #8CB5D2",
"Xa c #70A3C7",
"Xs c #8BB5D1",
"Xd c #5491BC",
"Xf c #5391BB",
"Xg c #282424",
"Xh c #272223",
"Xj c #6C696A",
"Xk c #2F4659",
"Xl c #6B6969",
"Xz c #407BA5",
"Xx c #6A6768",
"Xc c #E4E3E3",
"Xv c #3E79A3",
"Xb c #231E1F",
"Xn c #221E1E",
"Xm c #E2E1E1",
"XM c #211C1D",
"XN c #EBF2F7",
"XB c #201C1C",
"XV c #CFE0EC",
"XC c #4588B7",
"XZ c #B3CEE1",
"XA c #366384",
"XS c #5F98C0",
"XD c #4386B5",
"XF c #DEDDDD",
"XG c #2B3D4B",
"XH c #615F5F",
"XJ c #5F5D5D",
"XK c #5E5B5C",
"XL c #DCE9F2",
"XP c #407DA8",
"XI c #86B1CF",
"XU c #D4D3D3",
"XY c #3A698B",
"XT c #3E7BA6",
"XR c #232022",
"XE c #545152",
"XW c #999899",
"XQ c #79AACC",
"X! c #524F50",
"X~ c #CCCDCB",
"X^ c #3D749B",
"X/ c #93BAD5",
"X( c #77A8CA",
"X) c #37607E",
"X_ c #5B96BF",
"X` c #3F84B4",
"X' c #CAC9C9",
"X] c #C6C5C5",
"X[ c #3F7DAA",
"X{ c #F2F7FA",
"X} c #C2C1C1",
"X| c #212023",
"o c #9EC1D9",
"o. c #444142",
"oX c #3F78A0",
"oo c #90B8D5",
"oO c #FEFEFF",
"o+ c #E2ECF4",
"o@ c #2B3A47",
"o# c #25262A",
"o$ c #B1AFB0",
"o% c #28313A",
"o& c #221D1D",
"o* c #262F38",
"o= c #629BC2",
"o- c #302D2E",
"o; c #6199C1",
"o: c #201B1B",
"o> c #4587B6",
"o, c #F0F0F1",
"o< c #2D3E4C",
"o1 c #2E2B2C",
"o2 c #4385B4",
"o3 c #A8A7A7",
"o4 c #A7A5A6",
"o5 c #3D7197",
"o6 c #4183B2",
"o7 c #4083B1",
"o8 c #A5A3A4",
"o9 c #3B6F95",
"o0 c #5290BC",
"oq c #A4C4DB",
"ow c #E9F1F7",
"oe c #4387B7",
"or c #E7EFF5",
"ot c #CBDDEA",
"oy c #4185B5",
"ou c #5B95BE",
"oi c #3F83B3",
"op c #939192",
"oa c #929191",
"os c #2B3743",
"od c #4C4849",
"of c #2A3742",
"og c #F4F8FB",
"oh c #D8E6F0",
"oj c #4C8CB9",
"ok c #211F22",
"ol c #CFD0D0",
"oz c #444041",
"ox c #262C34",
"oc c #413E3E",
"ov c #403C3D",
"ob c #3B739B",
"on c #858384",
"om c #FFFFFF",
"oM c #E3EDF4",
"oN c #5995BF",
"oB c #3E3A3B",
"oV c #C7DBE9",
"oC c #2F4B61",
"oZ c #5793BD",
"oA c #3C3839",
"oS c #2A3945",
"oD c #7E7D7D",
"oF c #345873",
"oG c #363233",
"oH c #7B797A",
"oJ c #EFF4F9",
"oK c #EEF4F8",
"oL c #F3F3F3",
"oP c #9ABED7",
"oI c #4788B7",
"oU c #629AC1",
"oY c #ACAAAA",
"oT c #F1F1F1",
"oR c #EFEFEF",
"oE c #737172",
"oW c #EDEDED",
"oQ c #A9C9DF",
"o! c #FBFDFE",
"o~ c #EBEBEB",
"o^ c #DFEBF3",
"o/ c #4581AB",
"o( c #6F6D6E",
"o) c #EAE9EA",
"o_ c #E9E9E9",
"o` c #C1D7E6",
"o' c #E7E7E7",
"o] c #E6E7E6",
"o[ c #E5E5E5",
"o{ c #3F7BA5",
"o} c #242021",
"o| c #E3E3E3",
"O c #3E79A4",
"O. c #221E1F",
"OX c #26303A",
"Oo c #9C9A9A",
"OO c #E1E1E1",
"O+ c #201C1D",
"O@ c #4488B7",
"O# c #DFDFDF",
"O$ c #7BAACC",
"O% c #356384",
"O& c #1E1A1B",
"O* c #4386B6",
"O= c #4286B5",
"O- c #95BAD5",
"O; c #DDDDDD",
"O: c #1C1819",
"O> c #DBDBDB",
"O, c #D9D9D9",
"O< c #D7D7D7",
"O1 c #417FAA",
"O2 c #DAE7F1",
"O3 c #F5F9FB",
"O4 c #D5D5D5",
"O5 c #242224",
"O6 c #D4D3D4",
"O7 c #85B1CF",
"O8 c #D3D3D3",
"O9 c #699FC4",
"O0 c #4D8DB9",
"Oq c #222022",
"Ow c #34556F",
"Oe c #D1D1D1",
"Or c #D0CFD0",
"Ot c #8A8888",
"Oy c #CFCFCF",
"Ou c #CDCDCD",
"Oi c #CCCDCC",
"Op c #CADEEB",
"Oa c #E5EEF5",
"Os c #C9DCEA",
"Od c #ADCADF",
"Of c #C8DCE9",
"Og c #91B8D4",
"Oh c #5994BE",
"Oj c #3D82B3",
"Ok c #5894BD",
"Ol c #3C82B2",
"Oz c #4181AD",
"Ox c #3B3737",
"Oc c #C5C5C5",
"Ov c #293643",
"Ob c #3E7DAA",
"On c #C1C1C1",
"Om c #353131",
"OM c #D4E3EE",
"ON c #B8D1E3",
"OB c #BFBFBF",
"OV c #9CBFD8",
"OC c #80ADCD",
"OZ c #649BC2",
"OA c #4889B7",
"OS c #BDBDBD",
"OD c #2E292A",
"OF c #4283B1",
"OG c #B7B7B7",
"OH c #4183B0",
"OJ c #5794BF",
"OK c #A7C6DC",
"OL c #365B77",
"OP c #8BB4D1",
"OI c #282324",
"OU c #272323",
"OY c #6C6A6A",
"OT c None",
/* pixels */
" oToToToT L.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h LoToToToT ",
"o,.joToToToToToToToToToToToToToToToToToToToT.h.h.h.hoToToToToToToToToToToToToToToToToToToToT.j.j",
".j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.joToLoLoR.D.~ > >.~.DoRoLoLoT.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j.j",
"oRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoT.hXcOBoaXjX!oz c cozX!XjoaOBXc.hoToRoRoRoRoRoRoRoRoRoRoRoRoRoRoR",
".l.l.l.l.l.l.l.l.l.l.l.l.loR.j <.'X! Y.P.To: $ J J $o:.T.P YX!.' <.joR.l.l.l.l.l.l.l.l.l.l.l.l.l",
".l.l.l.l.l.l.l.l.l.l.l.l.jXm.&oz + $o& 3.x OoSXGXGoS O.x 3o& $ +oz.&Xm.j.l.l.l.l.l.l.l.l.l.l.l.l",
"oWoWoWoWoWoWoWoWoWoWoWoR uXK X $XRo% yXA.qo/.fX1X1.fo/.qXA yo%XR $ XXK uoRoWoWoWoWoWoWoWoWoWoWoW",
".c.c.c.c.c.c.c.c.c.coW Z z $ {os eXTo0..oQX*XLoMoMXLOpoQ..o0XT eos { $ z ZoW.c.c.c.c.c.c.c.c.c.c",
"o~o~o~o~o~o~o~o~o~.co3.p $.(X2X[OJ FOM !Of 0.d wOg.d 0Os.mOM FOJObX2.( $.po3.co~o~o~o~o~o~o~o~o~",
".n.n.n.n.n.n.n.noW VoGXMoso9XC G.N.!.^XfXD tOjOlOlOj tXDXd.^.% 1O$O@o9osXMoG VoW.n.n.n.n.n.n.n.n",
".n.n.n.n.n.n.n.c qo.XBo<XvX5 No oUO0 fOPXpXpXpXpXpXpXpXpOP ( NOdo^OV.sXvo<XBo. q.c.n.n.n.n.n.n.n",
"o_o_o_o_o_o_.M.L @ $o@o{.s.^.Z & t.* ~omomomomomomomomomomomom.toO.b _ D.Jo@ $ @.Lo)o_o_o_o_o_o_",
".C.C.C.C.C.Co~o8Xg kX^oeoZXf._XDXD 0omomomomomomomomomomomomomomomom.b #XCX^ kXgo8o~.C.C.C.C.C.C",
"o'o'o'o'o'.CO>.$okX=oeXDo>O=XD./Xd.momomomomomomomomomomomomomom pX7.NOK 'oeX=ok.$O>.Co'o'o'o'o'",
" ]o'o'o'.So_ TXh.o nXDXDXDXDXD.; %.bomomomomomomomomomomomomoOo`O9ojo>XDXDXD n.oXh To_ ]o'o'o'.S",
".D.D.D.D.Do| SX|XY.+XDXDXDXDXDXDXZomomomomomomomomomomomomom.4Xd.;O=XDXDXDXD.+XYX| So|.D.D.D.D.D",
"o[o[o[o[.D 5OxOvOzO*XDXDXDXD =oZo+omomomomomomomomomomomomomoP.;XDXDXDXDXDXDO*OzOvOx 5o]o[o[o[o[",
".H.H.H.Ho' POU }oeXDXDXDXDXD.;X8o!omomomomomomomomomomomom.bX(.;XDXDXDXDXDXDXDoe }OU Po'.H.H.H.H",
"o|o|o|o|.DOt.5XO.+XDXDXDXDXD &ONomomomomomomomomomomomomom.2.7._XDXDXDXDXDXDXD.+XO.5Ot.Do|o|o|o|",
"o|o|o|o|o|Xi : j.WXDXDXDXD = rOaomomomomomomomomomomomomom AXS._XDXDXDXDXDXDXD.W j :Xio|o|o|o|o|",
".L.L.L.L.I RXwXP.WXDXDXDXD.;XI momomomomomomomomomomomomomXN.=._XDXDXDXDXDXDXD.WXPXw R.I.L.L.L.L",
"OOOOOOOOO; [OX.<O*XDXDXDXD IXoomomomomomomomomomomomomomom.UX_._XDXDXDXDXDXDXDO*.<OX [O;OOOOOOOO",
".I.I.I.IO; )o*O1O*XDXDXD._.).Romomomomomog ~omomomomomomom.UX_._XDXDXDXDXDXDXDO*O1o* )O;.I.I.I.I",
"O#O#O#O#O# KX-Xz.WXDXDXD.;XsoOomomomomom vowomomomomomomom.UX_._XDXDXDXDXDXDXD.WXzX- KO#O#O#O#O#",
"O#O#O#O#. g Co5oeXDXDXDXq.Nomomomomom ,X>oromomomomomomom.UX_._XDXDXDXDXDXDXDoeo5 C gOOO#O#O#O#",
".~.~.~.~OO.- {X).XXDXD._o; HomomomomomohO9.Romomomomomomom.UX_._XDXDXDXDXDXDXD.XX) {.-OO.~.~.~.~",
"O;O;O;O;O#XyOD .o2XDXD.;Ogomomomomomom / r.Uomomomomomomom.UX_._XDXDXDXDXDXDXDo2 .ODXyO#O;O;O;O;",
".`.`.`.`O;Oeod.:oX.WXDOAoVomomomomomO3XaOk.Uomomomomomomom.UX_._XDXDXDXDXDXD.WoX.:odOeO;.`.`.`.`",
"O>O>O>O>O>O;X,.POw.W._ doJomomomomomOMoj r.Uomomomomomomom.UX_._XDXDXDXDXDXD.WOw.PX,O;O>O>O>O>O>",
"O>O>O>O>O>O;XrOmox.0 9X8Xtomomomomom.6X`ou.Uomomomomomomom.UX_._XDXDXDXDXDoe.0oxOmXrO;O>O>O>O>O>",
".].].].].].]O,.z JXkOH.VotomomomomX{ 2oiou.Uomomomomomomom.UX_._XDO= &O0 &OFXk J.zO,.].].].].].]",
"O,O,O,O,O,O,O>OS.yOq.i._OZ ^omomom.E.9._ou.Uomomomomomomom.UX_._._.9.ZXdO=.iOq.yOSO>O,O,O,O,O,O,",
".{.{.{.{.{.{.{.].,.A BX)oyXXO2omom.Q.;._ou.Uomomomomomomom.UOh._ dO-X9O=X) BOI.,.].{.{.{.{.{.{.{",
"O<O<O<O<O<O<O<.{O8o(Xno#OLo7.YXuX O7oIoiOk.Romomomomomomom HOCoqOdo=o6OLo#Xno(O8.{O<O<O<O<O<O<O<",
"O<O<O<O<O<O<O<O<.{X'XJ.PO5.[O iOgXVX:OVXsoKomomomomomomom.bOMX/.1O .[O5.PXJX'.{O<O<O<O<O<O<O<O<",
".|.|.|.|.|.|.|.|.|.}X]XH.KXn.G eX<oN.e 8 6 Qomomomom.bXN.roo xX< e.GXn.KXHX].}.|.|.|.|.|.|.|.|.|",
"O4O4O4O4O4O4O4O4O4O4O<X;Xe.vXBX+ofoFob 7.@XQ W | | WXQ.@ 7oboFofX+XB.vXeX;O<O4O4O4O4O4O4O4O4O4O4",
"X.X.X.X.X.X.X.X.X.X.X.O4X#XW sO. J.K.xo@oC `O%.8.8O% `oCo@.x.K JO. sXWX#O4X.X.X.X.X.X.X.X.X.X.X.",
"O8O8O8O6O8XUXUO8O8XUXUO8X..|OnX,oc.F $ Jo&XbXRO5O5XRXbo& J $.FocX,On.|X.O8XUX@X@O8.3O8O8O8O8O8X@",
"O8O8O8O8O8O8O8O8O8O8O8O8O8O8X.X. aop ; c Eo}.PXMXM.Po} E c ;op aX.X.O8O8O8O8O8O8O8O8O8O8O8O8O8O8",
"X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#O8O4X$X6 P.-onX3X3on.- PX6X$O4O8X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#",
"OeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeO8X4OGOnOcOcX} MOSX#OeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOeOe",
"X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$O8ono-oAov.w.u.koEX#X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$X$",
"X$X$X$X$X$X$X$X$X$olX$X$X$X$X$X$X$X$X$X#oD l.>o1O+.P.T.BOeX$X$X$X$X$X$X$OrOrX$X$X$X$X$X$X$X$X$X$",
"OyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyX#oHXEXFoBO&.TO:OYX$OyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOyOy",
"X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%Oy POo.CX0 -Xx.g TOyX%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%X%",
"X%X%OuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuX% oo$.h boYo4.O UX%OuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuX%X%",
" Ou.#OuOuOiX&X&X&X&X&X&X&X&X&X&X&X&X&Oy.a 4 * h.K.KO&XlX%X&X&X&X&X&X&X&X&X&X&X&X&X&X&OuOuX~Ou "
};

211
mupdf/docs/man/mupdf.1 Normal file
View File

@ -0,0 +1,211 @@
.TH MUPDF 1 "Jul 30, 2019"
.\" Please adjust this date whenever revising the manpage.
.\" no hyphenation
.nh
.\" adjust left
.ad l
.SH NAME
mupdf \- MuPDF is a lightweight PDF viewer written in portable C
.SH SYNOPSIS
.B mupdf
.RI [ options ] " file"
.SH DESCRIPTION
.B MuPDF
is a document viewer that can show
.B PDF,
.B XPS,
.B EPUB,
.B XHTML,
.B CBZ,
and various image formats such as
.B PNG,
.B JPEG,
.B GIF,
and
.B TIFF.
.SH OPTIONS
A description of each of the supported options is included below.
.TP
.B \-p password
Uses the given password to open an encrypted PDF file.
The password is tried both as user and owner password.
.TP
.B \-r resolution
Changes the initial zoom level, specified as the resolution in dpi.
The default value is 72.
.TP
.B \-A bits
Changes the anti-aliasing quality, specified as a number of bits between 0
(off) and 8 (best).
The default value is 8.
.TP
.B \-C RRGGBB
Sets the full-page tint using hexadecimal color syntax.
The default value is FFFAF0.
.TP
.B \-W width
Page width in points for EPUB layout.
.TP
.B \-H height
Page height in points for EPUB layout.
.TP
.B \-S size
Font size in points for EPUB layout.
.TP
.B \-U CSS-file
User style sheet for EPUB layout.
.SH MOUSE BEHAVIOR
.TP
.B Left mouse button click
A left click on a hyper link follows the link.
In presentation mode advances to the next page.
.TP
.B Right mouse button click
In presentation mode goes back to the previous page.
.TP
.B Left mouse button drag
Pan the page.
Panning beyond the bottom or top
edge will go to the next or previous page.
.TP
.B Right mouse button drag
Select text in an area.
On X11, the selected text
can be pasted in another application with a middle click.
Press
.B Ctrl+C
to copy the selected text to the clipboard.
On Windows, the selected text will automatically be copied
to the clipboard.
.TP
.B Scroll wheel
Pan page up or down.
Does not change page when reaching the bottom or top edge.
.TP
.B Shift + Scroll wheel
Pan page left or right.
.TP
.B Control + Scroll wheel
Zoom in or out.
.SH KEY BINDINGS
.PP
Page navigation:
.TP
.B . pgdn space
Go to the next page.
.TP
.B , pgup b backspace
Go to the previous page.
.TP
.B 123g
Go to page 123.
.TP
.B g, G
Go to the first or last page.
.TP
.B m
Mark current page for snap back.
Up to 256 pages can be marked.
.TP
.B t
Pop back to the latest mark.
.TP
.B [0\(en9]m
Save the current page number in the numbered register.
.TP
.B [0\(en9]t
Go to the page saved in the numbered register.
.PP
Zooming and rotating:
.TP
.B +, \-
Zoom in or out.
.TP
.B W, H
Zoom page to exactly fit width/height of window.
.TP
.B Z
Zoom page to fit either to width or height of window.
.TP
.B z
Reset zoom level.
.TP
.B [, ]
Rotate page left (counter-clockwise) or right (clockwise).
.TP
.B w
Shrinkwrap window to fit the page.
.TP
.B f
Toggles fullscreen mode.
.PP
Panning:
.TP
.B h, left, j, k, l, right
Pan page left, down, up, or right.
.PP
Searching:
.TP
.B /, ?
Search for text forwards or backwards.
.TP
.B n, N
Find the next/previous search result.
.PP
Miscellaneous:
.TP
.B <, >
Increase/decrease EPUB/XHTML font size.
.TP
.B r
Reload file.
.TP
.B p
Toggle presentation mode.
.TP
.B c
Toggle between color and grayscale rendering.
.TP
.B C
Toggle full-page color tinting.
.TP
.B I
Toggle between normal and inverted color rendering.
.TP
.B E
Toggle ICC color mode.
.TP
.B e
Toggle spot color mode.
.TP
.B S
Save updated document file.
.TP
.B q
Quit.
.SH SIGNALS
.TP
.B SIGHUP
Sending a \fBSIGHUP\fR signal to the mupdf process will also cause the viewed
file to be reloaded automatically, for use in e.g.\& build scripts.
.SH SEE ALSO
.BR mutool (1).
.SH AUTHOR
MuPDF is Copyright 2006\(en2019 Artifex Software, Inc.

421
mupdf/docs/man/mutool.1 Normal file
View File

@ -0,0 +1,421 @@
.TH "MUTOOL" "1" "January 12, 2016"
.\" Please adjust this date whenever revising the manpage.
.\" no hyphenation
.nh
.\" adjust left
.ad l
.SH NAME
mutool \- all purpose tool for dealing with PDF files
.SH SYNOPSIS
mutool <sub-command> [options]
.SH DESCRIPTION
mutool is a tool based on MuPDF for dealing with document files in various manners.
There are several sub commands available, as described below.
.SH DRAW
mutool draw [options] file [pages]
.PP
The draw command will render a document to image files,
convert to another vector format, or extract the text content.
.PP
The supported input document formats are: pdf, xps, cbz, and epub.
.PP
The supported output image formats are: pbm, pgm, ppm, pam, png, pwg, pcl and ps.
The supported output vector formats are: svg, pdf, and debug trace (as xml).
The supported output text formats are: plain text, html, and structured text (as xml).
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-o output
The output format is inferred from the output filename.
Embed %d in the name to indicate the page number (for example: "page%d.png").
Printf modifiers are supported, for example "%03d".
If no output is specified, the output will go to stdout.
.TP
.B \-F format
Enforce a specific output format. Only necessary when outputting to stdout
since normally the output filename is used to infer the output format.
.TP
.B \-R angle
Rotate clockwise by given number of degrees.
.TP
.B \-r resolution
Render the page at the specified resolution.
The default resolution is 72 dpi.
.TP
.B \-w width
Render the page at the specified width (or, if the -r flag is used,
render with a maximum width).
.TP
.B \-h height
Render the page at the specified height (or, if the -r flag is used,
render with a maximum height).
.TP
.B \-f
Fit exactly; ignore the aspect ratio when matching specified width/heights.
.TP
.B \-B bandheight
Render in banded mode with each band no taller than the given height. This uses
less memory during rendering. Only compatible with pam, pgm, ppm, pnm and png
output formats. Banded rendering and md5 checksumming may not be used at the
same time.
.TP
.B \-W width
Page width in points for EPUB layout.
.TP
.B \-H height
Page height in points for EPUB layout.
.TP
.B \-S size
Font size in points for EPUB layout.
.TP
.B \-U filename
User CSS stylesheet for EPUB layout.
.TP
.B \-c colorspace
Render in the specified colorspace.
Supported colorspaces are: mono, gray, grayalpha, rgb, rgbalpha, cmyk, cmykalpha.
Some abbreviations are allowed: m, g, ga, rgba, cmyka.
The default is chosen based on the output format.
.TP
.B -G gamma
Apply gamma correction.
Some typical values are 0.7 or 1.4 to thin or darken text rendering.
.TP
.B -I
Invert colors.
.TP
.B \-s [mft5]
Show various bits of information:
.B m
for glyph cache and total memory usage,
.B f
for page features such as whether the page is grayscale or color,
.B t
for per page rendering times as well statistics, and
.B 5
for md5 checksums of rendered images that can be used to check if rendering has
changed.
.TP
.B \-A bits
Specify how many bits of anti-aliasing to use. The default is 8.
.TP
.B \-D
Disable use of display lists. May cause slowdowns, but should reduce
the amount of memory used.
.TP
.B \-i
Ignore errors.
.TP
.B \-L
Low memory mode (avoid caching objects by clearing cache after each page).
.TP
.B \-P
Run interpretation and rendering at the same time.
.TP
.B pages
Comma separated list of page numbers and ranges (for example: 1,5,10-15).
If no pages are specified, then all pages will be rendered.
.SH CLEAN
mutool clean [options] input.pdf [output.pdf] [pages]
.PP
The clean command pretty prints and rewrites the syntax of a PDF file.
It can be used to repair broken files, expand compressed streams, filter
out a range of pages, etc.
.PP
If no output file is specified, it will write the cleaned PDF to "out.pdf"
in the current directory.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-g
Garbage collect objects that have no references from other objects.
Give the option twice to also renumber all objects and compact the cross reference table.
Give it three times to also merge and reuse duplicate objects.
Give it four times to also merge and reuse duplicate streams.
.TP
.B \-s
Rewrite content streams.
.TP
.B \-d
Decompress streams. This will make the output file larger, but provides
easy access for reading and editing the contents with a text editor.
.TP
.B \-l
Linearize output. Create a "Web Optimized" output file.
.TP
.B \-i
Toggle decompression of image streams. Use in conjunction with -d to leave
images compressed.
.TP
.B \-f
Toggle decompression of font streams. Use in conjunction with -d to leave
fonts compressed.
.TP
.B \-a
ASCII Hex encode binary streams. Use in conjunction with -d and -i or -f to
ensure that although the images and/or fonts are compressed, the resulting
file can still be viewed and edited with a text editor.
.TP
.B \-z
Deflate uncompressed streams.
If combined with -d, any decompressed streams will be recompressed.
If combined with -a, the streams will also be hex encoded after compression.
.TP
.B pages
Comma separated list of page numbers and ranges to include.
.SH EXTRACT
mutool extract [options] file.pdf [object numbers]
.PP
The extract command can be used to extract images and font files from a PDF.
If no object numbers are given on the command line, all images and fonts
will be extracted.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-r
Convert images to RGB when extracting them.
.SH INFO
mutool info [options] file.pdf [pages]
.PP
The info command lists the resources used on each page in a PDF file.
The default is to list all resource types, but if one
or more flags are given, only the flagged types will be shown.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B -F
List fonts.
.TP
.B -I
List images.
.TP
.B -M
List page dimensions.
.TP
.B -S
List shadings.
.TP
.B -P
List patterns.
.TP
.B -X
List form and postscript XObjects.
.TP
.B pages
Comma separated list of page numbers and ranges to include.
.SH CREATE
mutool create [-o output.pdf] [options] page1.txt [page2.txt ...]
.PP
The create command creates a new PDF file with the contents created
from one or more input files containing graphics commands.
.TP
.B \-o output
If no output file is specified, it will write the created PDF to "out.pdf"
in the current directory.
.TP
.B page.txt
A page is created for each input file, with the contents of the file copied
into the content stream. Special comments in the input files are parsed to
define the page dimensions and font and image resources:
.PP
%%MediaBox 0 0 500 800
.br
%%Rotate 90
.br
%%Font Tm Times-Roman
.br
%%Font Fn0 path/to/font/file.ttf
.br
%%Image Im0 path/to/image.png
.TP
.B \-O
Comma separated list of format specific output options:
.IP
.B decompress
.br
Decompress all object streams.
.IP
.B compress
.br
Compress all object streams.
.IP
.B compress-fonts
.br
Compress object streams for embedded fonts.
.IP
.B compress-images
.br
Compress object streams for images.
.IP
.B ascii
.br
Encode object streams using ASCII hex encoding.
.IP
.B pretty
.br
Pretty-print objects with indentation.
.IP
.B linearize
.br
Optimize document for progressive loading in viewers.
.IP
.B sanitize
.br
Clean up graphics command in content streams.
.IP
.B garbage[=compact|deduplicate]
.br
Garbage collect unused objects. With
.B compact
the cross-reference table will also be compacted. With
.B deduplicate
duplicate objects will also be recombined.
.SH PAGES
mutool pages [options] input.pdf [pages ...]
.PP
The pages command dumps information about the size and orientation
of pages within the document.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B pages
Comma separated list of page numbers and ranges to include.
.SH POSTER
mutool poster [options] input.pdf [output.pdf]
.PP
The poster command splits each page into tiles, and puts each tile on
a page of its own. It's useful for printing a large page onto smaller
pieces of paper that can then be glued together to create a large poster.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-x factor
Split the page into this many horizontal pieces.
.TP
.B \-y factor
Split the page into this many vertical pieces.
.PP
The output will have x times y number of pages for each input page.
.SH SHOW
mutool show [options] file.pdf [object numbers ...]
.PP
The show command will print the specified objects and streams to stdout.
Streams are decoded and non-printable characters are represented
with a period by default.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-o file
Write output to file instead of stdout.
.TP
.B \-b
Print streams as binary data and omit the object header.
.TP
.B \-e
Print streams in their original encoded (or compressed) form.
.PP
Specify objects by number, or use one of the following special names:
.TP
.B 'xref' or 'x'
Print the cross reference table.
.TP
.B 'trailer' or 't'
Print the trailer dictionary.
.TP
.B 'encrypt' or 'e'
Print the encryption dictionary.
.TP
.B 'pagetree' or 'p'
List the object numbers for every page.
.TP
.B 'grep' or 'g'
Print all the objects in the file in a compact one-line format suitable for piping to grep.
.TP
.B 'outline' or 'o'
Print the outline (table of contents).
.SH RUN
mutool run script.js [arguments]
.PP
Executes a Javascript program which has access to most of the features of the
MuPDF library. The command supports ECMAScript 5 syntax in strict mode. All of
the MuPDF constructors and function live in the global object, and the command
line arguments are accessible from the global argv object.
.PP
If invoke without any arguments, it will drop you into an interactive REPL
(read-eval-print-loop). On the interactive prompt, if you prefix a line with an
equal character it will automatically print the results of the line.
.PP
See the MuPDF documentation for details about the Javascript interfaces.
.SH CONVERT
mutool convert [options] file [pages]
.PP
The convert command is used to convert a file from one format to another.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-A bits
Specify how many bits of anti-aliasing to use. The default is 8.
.TP
.B \-W width
Page width in points for EPUB layout.
.TP
.B \-H height
Page height in points for EPUB layout.
.TP
.B \-S size
Font size in points for EPUB layout.
.TP
.B \-U filename
User CSS stylesheet for EPUB layout.
.TP
.B \-o output
The output format is inferred from the output filename.
Embed %d in the name to indicate the page number (for example: "page%d.png").
Printf modifiers are supported, for example "%03d".
If no output is specified, the output will go to stdout.
.TP
.B \-F format
Enforce a specific output format. Only necessary when outputting to stdout
since normally the output filename is used to infer the output format.
.TP
.B \-O
Comma separated list of format specific output options:
.SH MERGE
mutool merge [options] file1 [pages] file2 [pages] ...
.PP
The merge command is used to pick out pages from two or more files and merge
them in order into a new output file.
.TP
.B \-o output
The output filename.
.TP
.B \-O
See mutool create for details on this option.
.SH SEE ALSO
.BR mupdf (1),
.SH AUTHOR
MuPDF is Copyright 2006-2017 Artifex Software, Inc.

View File

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html>
<head>
<title>MuPDF OpenGL Viewer</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>MuPDF OpenGL Viewer</h1>
</header>
<article>
<p>
The OpenGL based viewer can read PDF, XPS, CBZ, EPUB, and FB2 documents.
It compiles on any platform that has a <a href="http://freeglut.sourceforge.net/">GLUT</a> library.
The latest release builds on Linux, Windows, and MacOS.
<h2>Command Line Options</h2>
<pre>
mupdf-gl [options] document [page]
</pre>
<dl>
<dt>-p password
<dd>The password needed to open a password protected PDF file.
<dt>-r resolution
<dd>Set the initial zoom level, specified as DPI. The default value is 72.
<dt>-W width
<dd>Set the page width in points for EPUB layout.
<dt>-H height
<dd>Set the page height in points for EPUB layout.
<dt>-S size
<dd>Set the default font size in points for EPUB layout.
<dt>-U stylesheet
<dd>Specify a CSS file containing user styles to load for EPUB layout.
<dt>-X
<dd>Ignore publisher styles for EPUB layout.
</dl>
<h2>Mouse Bindings</h2>
<p>
The middle mouse button (scroll wheel button) pans the document view.
<p>
The right mouse button selects a region and copies the marked text to the clipboard.
<h2>Key Bindings</h2>
<p>
Several commands can take a number argument entered before the key, to modify the command.
For example, to zoom to 150 dpi, type "150z".
<table>
<tr><td>F1<td>Display help.
<tr><td>i<td>Show document information.
<tr><td>o<td>Show document outline.
<tr><td>L<td>Highlight links.
<tr><td>F<td>Highlight form fields.
<tr><td>a<td>Show annotation editor.
<tr><td>r<td>Reload document.
<tr><td>S<td>Save document (only for PDF).
<tr><td>q<td>Quit viewer.
<tr><td>&nbsp;
<tr><td>&lt;<td>Decrease E-book font size.
<tr><td>&gt;<td>Increase E-book font size.
<tr><td>I<td>Toggle inverted color mode.
<tr><td>C<td>Toggle tinted color mode.
<tr><td>E<td>Toggle ICC color management.
<tr><td>e<td>Toggle spot color emulation.
<tr><td>A<td>Toggle anti-aliasing.
<tr><td>&nbsp;
<tr><td>f<td>Toggle fullscreen.
<tr><td>w<td>Shrinkwrap window to fit page.
<tr><td>W<td>Fit page width to window.
<tr><td>H<td>Fit page height to window.
<tr><td>Z<td>Fit page size to window.
<tr><td>[number] z<td>Set zoom resolution in DPI.
<tr><td>+<td>Zoom in.
<tr><td>-<td>Zoom out.
<tr><td>[<td>Rotate counter-clockwise.
<tr><td>]<td>Rotate clockwise.
<tr><td>[arrows] or h, j, k, l<td>Pan page in small increments.
<tr><td>&nbsp;
<tr><td>b<td>Smart move one screenful backward.
<tr><td>[space]<td>Smart move one screenful forward.
<tr><td>[comma] or [page up]<td>Go one page backward.
<tr><td>[period] or [page down]<td>Go one page forward.
<tr><td>[number] g<td>Go to page number.
<tr><td>G<td>Go to last page.
<tr><td>&nbsp;
<tr><td>m<td>Save current page to navigation history.
<tr><td>t<td>Go back in navigation history.
<tr><td>T<td>Go forward in navigation history.
<tr><td>[number] m<td>Save current page in numbered bookmark.
<tr><td>[number] t<td>Go to numbered bookmark.
<tr><td>&nbsp;
<tr><td>/<td>Start searching forward.
<tr><td>?<td>Start searching backward.
<tr><td>n<td>Continue searching forward.
<tr><td>N<td>Continue searching backward.
</table>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool clean</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool clean</h1>
</header>
<article>
<p>
The clean command pretty prints and rewrites the syntax of a PDF file.
It can be used to repair broken files, expand compressed streams,
filter out a range of pages, etc.
<pre>
mutool clean [options] input.pdf [output.pdf] [pages]
</pre>
<p>
If no output file is specified, it will write the cleaned PDF to
"out.pdf" in the current directory.
<dl>
<dt> -p password
<dd> Use the specified password if the file is encrypted.
<dt> -g
<dd> Garbage collect objects that have no references from other
objects. Give the option twice to renumber all objects and
compact the cross reference table. Give it three times to merge
and reuse duplicate objects.
<dt> -s
<dd> Rewrite content streams.
<dt> -d
<dd> Decompress streams. This will make the output file larger, but
provides easy access for reading and editing the contents with a
text editor.
<dt> -l
<dd> Linearize output. Create a "Web Optimized" output file.
<dt> -i
<dd> Toggle decompression of image streams. Use in conjunction with
-d to leave images compressed.
<dt> -f
<dd> Toggle decompression of font streams. Use in conjunction with -d
to leave fonts compressed.
<dt> -a
<dd> ASCII Hex encode binary streams. Use in conjunction with -d and
-i or -f to ensure that although the images and/or fonts are
compressed, the resulting file can still be viewed and edited
with a text editor.
<dt> -z
<dd> Deflate uncompressed streams. If combined with -d, any
decompressed streams will be recompressed. If combined with -a,
the streams will also be hex encoded after compression.
<dt> pages
<dd> Comma separated list of page numbers and ranges to include.
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool convert</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool convert</h1>
</header>
<article>
<p>
The 'mutool convert' command converts an input file into another format.
<pre>
mutool convert [options] -o <i>output input</i> [pages]
</pre>
<p>
The command line options are:
<dl>
<dt><i>input</i>
<dd>Input file name.
The input can be any of the document formats supported by MuPDF: PDF, XPS, CBZ, unprotected EPUB, FB2, etc.
<dt>[pages]
<dd>Comma separated list of page ranges. The first page is "1", and the last page is "N". The default is "1-N".
<dt>-p <i>password</i>
<dd>Password to use for password protected PDF documents.
</dl>
<dl>
<dt>-o <i>filename</i>
<dd>The output file name.
The output file name may have a "%d" in the path, which will be replaced with the page number.
If there is no %d, the page number will be appended at the end of the file name for single page formats.
<dt>-F <i>format</i>
<dd>The output format. If missing, it is inferred from the output file name extension.
See below for which formats are supported.
<dt>-O <i>options</i>
<dd>Comma separated list of output options.
The set of available options varies depending on the output format.
See below for details.
</dl>
<dl>
<dt>-A <i>bits</i>
<dd>Number of bits of anti-aliasing to use (0 to 8) when rendering to image based formats. The default is 8.
<dt>-W <i>width</i>
<dd>Page width in points for EPUB layout.
<dt>-H <i>height</i>
<dd>Page height in points for EPUB layout.
<dt>-S <i>font-size</i>
<dd>Font size in points for EPUB layout.
<dt>-U <i>stylesheet.css</i>
<dd>File name of user style sheet for EPUB layout.
<dt>-X
<dd>Disable document styles for EPUB layout.
</dl>
<h2>
Image output
</h2>
<p>
CBZ (comic book zip) is a multi-page image format.
<p>
The following single page image formats are also supported: PNG, PNM, PAM, PBM, PKM.
Each page is written to a separate file.
<p>
The output options (-O flag) for image formats are:
<dl>
<dt>rotate=<i>N</i> <dd>Rotate rendered pages <i>N</i> degrees counter-clockwise.
<dt>resolution=<i>N</i> <dd>Set both X and Y resolution in pixels per inch.
<dt>x-resolution=<i>N</i> <dd>Set X resolution in pixels per inch.
<dt>y-resolution=<i>N</i> <dd>Set Y resolution in pixels per inch.
<dt>width=<i>N</i> <dd>Render pages to fit <i>N</i> pixels wide (ignore resolution options).
<dt>height=<i>N</i> <dd>Render pages to fit <i>N</i> pixels tall (ignore resolution options).
<dt>colorspace=gray/rgb/cmyk <dd>Render using specified colorspace (if output format supports it).
<dt>alpha <dd>Render pages with an alpha channel and transparent background (if output format supports it).
</dl>
<h2>
PDF output
</h2>
<p>
With PDF output, we will create a new PDF file that matches the visual appearance.
The PDF output is still a work in progress, so some features may not work.
<p>
If the input is PDF, the output will have nothing in common except the visual appearance.
All bookmarks, annotations, forms, etc, will be thrown away. If you want to do a PDF to PDF
conversion, 'mutool clean' is a better tool to use.
<p>
The PDF output options are:
<dl>
<dt>decompress <dd> Decompress all streams (except compress-fonts/images).
<dt>compress <dd> Compress all streams.
<dt>compress-fonts <dd> Compress embedded fonts.
<dt>compress-images <dd> Compress images.
<dt>ascii <dd> ASCII hex encode binary streams.
<dt>pretty <dd> Pretty-print objects with indentation.
<dt>linearize <dd> Optimize for web browsers.
<dt>sanitize <dd> Clean up graphics commands in content streams.
<dt>garbage <dd> Garbage collect unused objects.
<dt>garbage=compact <dd> ... and compact cross reference table.
<dt>garbage=deduplicate <dd> ... and remove duplicate objects.
</dl>
<h2>
SVG output
</h2>
<p>
SVG output is a single page format, so we will write one SVG file for each input page.
<p>
The SVG output options are:
<dl>
<dt>text=text <dd> Emit text as <text> elements (inaccurate fonts).
<dt>text=path <dd> Emit text as <path> elements (accurate fonts).
<dt>no-reuse-images <dd> Do not reuse images using &lt;symbol&gt; definitions.
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool create</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool create</h1>
</header>
<article>
<p>
The create command creates a new PDF file with the contents created
from one or more input files containing graphics commands.
<pre>
mutool create [-o output.pdf] [-O options] page1.txt [page2.txt ...]
</pre>
<p>
If no output file is specified, it will write the created PDF to "out.pdf" in the current directory.
<p>
The -O argument is a comma separated list of options for writing the PDF file:
<dl>
<dt> decompress
<dd> Decompress all object streams.
<dt> compress
<dd> Compress all object streams.
<dt> compress-fonts
<dd> Compress object streams for embedded fonts.
<dt> compress-images
<dd> Compress object streams for images.
<dt> ascii
<dd> Encode object streams using ASCII hex encoding.
<dt> pretty
<dd> Pretty-print objects with indentation.
<dt> linearize
<dd> Optimize document for progressive loading in viewers.
<dt> sanitize
<dd> Clean up graphics command in content streams.
<dt> garbage[=compact|deduplicate]
<dd> Garbage collect unused objects. With compact the cross-reference
table will also be compacted. With deduplicate duplicate objects
will also be recombined.
</dl>
<p>
A page is created for each input file, with the contents of the
file copied into the content stream. Special comments in the
input files are parsed to define the page dimensions and font
and image resources:
<pre>
%%MediaBox 0 0 500 800
%%Rotate 90
%%Image Im0 path/to/image.png
</pre>
<p>
Font resources can be created by either giving the name of a standard PDF font, or by giving
the path to a font file. If a third argument is present and either "Greek" or "Cyrillic" the
font will be encoded using ISO 8859-7 or KOI8-U, respectively.
<pre>
%%Font Tm Times-Roman
%%Font TmG Times-Roman Greek
%%Font TmC Times-Roman Cyrillic
%%Font Fn0 path/to/font/file.ttf
%%Font Fn1 path/to/font/file.ttf Cyrillic
</pre>
<p>
CJK fonts can be created by passing a language tag for one of the 4 CID orderings:
zh-Hant, zh-Hans, ja, or ko (Traditional Chinese, Simplified Chinese, Japanese, Korean).
The CJK font will use the UTF-16 encoding.
A font file will not be embedded, so a PDF viewer will use a substitute font.
<pre>
%%CJKFont Batang ko
%%CJKFont Mincho ja
%%CJKFont Ming zh-Hant
%%CJKFont Song zh-Hans
</pre>
<p>
An example input file:
<pre>
%%MediaBox 0 0 595 842
%%Font TmRm Times-Roman
%%Font Helv-C Helvetica Cyrillic
%%Font Helv-G Helvetica Greek
%%CJKFont Song zh-Hant
%%CJKFont Mincho ja
%%CJKFont Batang ko
%%Image I0 logo/mupdf-simplified-logo.png
% Draw an image.
q
480 0 0 480 50 250 cm
/I0 Do
Q
% Draw a triangle.
q
1 0 0 rg
50 50 m
100 200 l
200 50 l
f
Q
% Show some text.
q
0 0 1 rg
BT /TmRm 24 Tf 50 760 Td (Hello, world!) Tj ET
BT /Helv-C 24 Tf 50 730 Td &lt;fac4d2c1d7d3d4d7d5cad4c521&gt; Tj ET
BT /Helv-G 24 Tf 50 700 Td &lt;eae1ebe7ecddf1e1&gt; Tj ET
BT /Song 24 Tf 50 670 Td &lt;4F60 597D&gt; Tj ET
BT /Mincho 24 Tf 50 640 Td &lt;3053 3093 306b 3061 306f&gt; Tj ET
BT /Batang 24 Tf 50 610 Td &lt;c548 b155 d558 c138 c694&gt; Tj ET
Q
</pre>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,138 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool draw</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool draw</h1>
</header>
<article>
<p>
The draw command will render a document to image files, convert to
another vector format, or extract the text content.
<pre>
mutool draw [options] file [pages]
</pre>
<p>
The supported input document formats are: pdf, xps, cbz, and epub.
<p>
The supported output image formats are: pbm, pgm, ppm, pam, png,
pwg, pcl and ps. The supported output vector formats are: svg, pdf,
and debug trace (as xml). The supported output text formats are: plain
text, html, and structured text (as xml).
<p>
Options:
<dl>
<dt> -p password
<dd> Use the specified password if the file is encrypted.
<dt> -o output
<dd> The output format is inferred from the output filename. Embed
%d in the name to indicate the page number (for example:
"page%d.png"). Printf modifiers are supported, for example "%03d". If no
output is specified, the output will go to stdout.
<dt> -F format
<dd> Enforce a specific output format. Only necessary when outputting
to stdout since normally the output filename is used to infer
the output format.
<dt> -R angle
<dd> Rotate clockwise by given number of degrees.
<dt> -r resolution
<dd> Render the page at the specified resolution. The default
resolution is 72 dpi.
<dt> -w width
<dd> Render the page at the specified width (or, if the -r flag is
used, render with a maximum width).
<dt> -h height
<dd> Render the page at the specified height (or, if the -r flag is
used, render with a maximum height).
<dt> -f
<dd> Fit exactly; ignore the aspect ratio when matching specified
width/heights.
<dt> -B bandheight
<dd> Render in banded mode with each band no taller than the given
height. This uses less memory during rendering. Only compatible
with pam, pgm, ppm, pnm and png output formats. Banded rendering
and md5 checksumming may not be used at the same time.
<dt> -W width
<dd> Page width in points for EPUB layout.
<dt> -H height
<dd> Page height in points for EPUB layout.
<dt> -S size
<dd> Font size in points for EPUB layout.
<dt> -U filename
<dd> User CSS stylesheet for EPUB layout.
<dt> -c colorspace
<dd> Render in the specified colorspace. Supported colorspaces are:
mono, gray, grayalpha, rgb, rgbalpha, cmyk, cmykalpha. Some
abbreviations are allowed: m, g, ga, rgba, cmyka. The default
is chosen based on the output format.
<dt> -G gamma
<dd> Apply gamma correction. Some typical values are 0.7 or 1.4 to
thin or darken text rendering.
<dt> -I
<dd> Invert colors.
<dt> -s [mft5]
<dd> Show various bits of information: m for glyph cache and total
memory usage, f for page features such as whether the page is
grayscale or color, t for per page rendering times as well
statistics, and 5 for md5 checksums of rendered images that can
be used to check if rendering has changed.
<dt> -A bits
<dd> Specify how many bits of anti-aliasing to use. The default is 8.
<dt> -D
<dd> Disable use of display lists. May cause slowdowns, but should
reduce the amount of memory used.
<dt> -i
<dd> Ignore errors.
<dt> -L
<dd> Low memory mode (avoid caching objects by clearing cache after each page).
<dt> -P
<dd> Run interpretation and rendering at the same time.
<dt> pages
<dd> Comma separated list of page numbers and ranges (for example:
1,5,10-15). If no pages are specified, then all pages will be
rendered.
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool extract</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool extract</h1>
</header>
<article>
<p>
The extract command can be used to extract images and font files from a PDF file.
<pre>
mutool extract [options] file.pdf [object numbers]
</pre>
<p>
Options:
<dl>
<dt> -p password
<dd> Use the specified password if the file is encrypted.
<dt> -r
<dd> Convert images to RGB when extracting them.
</dl>
<p>
If no object numbers are given on the command line, all images
and fonts will be extracted.
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool merge</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool merge</h1>
</header>
<article>
<p>
The merge command is used to pick out pages from two or more files and
merge them in order into a new output file.
<pre>
mutool merge [options] file1 [pages] file2 [pages] ...
</pre>
<p>
Options:
<dl>
<dt> -o output
<dd> The output filename.
<dt> -O options
<dd> See <a href="manual-mutool-create.html">mutool create</a> for details on this option.
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,824 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool run</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool run</h1>
</header>
<article>
<p>
The 'mutool run' command executes a JavaScript program, which has access to most of the features of the MuPDF library.
The command supports ECMAScript 5 syntax in strict mode.
All of the MuPDF constructors and functions live in the global object, and the
command line arguments are accessible from the global 'scriptArgs' object.
The name of the script is in the global 'scriptPath' variable.
<pre>
mutool run script.js [ arguments ... ]
</pre>
<p>
If invoked without any arguments, it will drop you into an interactive REPL (read-eval-print-loop).
<h2>
Example scripts
</h2>
<p>
Create and edit PDF documents:
<ul>
<li><a href="examples/pdf-create-lowlevel.js">pdf-create-lowlevel.js</a>: Create PDF document from scratch using only low level functions.
<li><a href="examples/pdf-create.js">pdf-create.js</a>: Create PDF document from scratch, using helper functions.
<li><a href="examples/pdf-merge.js">pdf-merge.js</a>: Merge pages from multiple PDF documents into one PDF file.
</ul>
<p>
Graphics and the device interface:
<ul>
<li><a href="examples/draw-document.js">draw-document.js</a>: Draw all pages in a document to PNG files.
<li><a href="examples/draw-device.js">draw-device.js</a>: Use device API to draw graphics and save as a PNG file.
<li><a href="examples/trace-device.js">trace-device.js</a>: Implement a device in JavaScript.
</ul>
<p>
Advanced examples:
<ul>
<li><a href="examples/create-thumbnail.js">create-thumbnail.js</a>: Create a PDF from rendered page thumbnails.
</ul>
<h2>
JavaScript Shell
</h2>
<p>
Several global functions that are common for command line shells are available:
<dl>
<dt>gc(report)
<dd>Run the garbage collector to free up memory. Optionally report statistics on the garbage collection.
<dt>load(fileName)
<dd>Load and execute script in 'fileName'.
<dt>print(...)
<dd>Print arguments to stdout, separated by spaces and followed by a newline.
<dt>quit()
<dd>Exit the shell.
<dt>read(fileName)
<dd>Read the contents of a file and return them as a UTF-8 decoded string.
<dt>readline()
<dd>Read one line of input from stdin and return it as a string.
<dt>require(module)
<dd>Load a JavaScript module.
<dt>write(...)
<dd>Print arguments to stdout, separated by spaces.
</dl>
<h2>
Buffer
</h2>
<p>
The Buffer objects are used for working with binary data.
They can be used much like arrays, but are much more efficient since they
only store bytes.
<dl>
<dt>new Buffer()
<dd>Create a new empty buffer.
<dt>readFile(fileName)
<dd>Create a new buffer with the contents of a file.
<dt>Buffer#length
<dd>The number of bytes in the buffer.
<dt>Buffer#[n]
<dd>Read/write the byte at index 'n'. Will throw exceptions on out of bounds accesses.
<dt>Buffer#writeByte(b)
<dd>Append a single byte to the end of the buffer.
<dt>Buffer#writeRune(c)
<dd>Encode a unicode character as UTF-8 and append to the end of the buffer.
<dt>Buffer#writeLine(...)
<dd>Append arguments to the end of the buffer, separated by spaces, ending with a newline.
<dt>Buffer#write(...)
<dd>Append arguments to the end of the buffer, separated by spaces.
<dt>Buffer#writeBuffer(data)
<dd>Append the contents of the 'data' buffer to the end of the buffer.
<dt>Buffer#save(fileName)
<dd>Write the contents of the buffer to a file.
</dl>
<h2>
Matrices and Rectangles
</h2>
<p>
All dimensions are in points unless otherwise specified.
<p>
Matrices are simply 6-element arrays representing a 3-by-3 transformation matrix as
<pre>
/ a b 0 \
| c d 0 |
\ e f 1 /
</pre>
<p>
This matrix is represented in JavaScript as <code>[a,b,c,d,e,f]</code>.
<dl>
<dt>Identity
<dd>The identity matrix, short hand for <code>[1,0,0,1,0,0]</code>.
<dt>Scale(sx, sy)
<dd>Return a scaling matrix, short hand for <code>[sx,0,0,sy,0,0]</code>.
<dt>Translate(tx, ty)
<dd>Return a translation matrix, short hand for <code>[1,0,0,1,tx,ty]</code>.
<dt>Concat(a, b)
<dd>Concatenate matrices a and b. Bear in mind that matrix multiplication is not commutative.
</dl>
<p>
Rectangles are 4-element arrays, specifying the minimum and maximum corners (typically
upper left and lower right, in a coordinate space with the origin at the top left with
descending y): <code>[ulx,uly,lrx,lry]</code>.
<p>
If the minimum x coordinate is bigger than the maximum x coordinate, MuPDF treats the rectangle
as infinite in size.
<h2>
Document and Page
</h2>
<p>
MuPDF can open many document types (PDF, XPS, CBZ, EPUB, FB2 and a handful of image formats).
<dl>
<dt>new Document(fileName)
<dd>Open the named document.
<dt>Document#needsPassword()
<dd>Returns true if a password is required to open this password protected PDF.
<dt>Document#authenticatePassword(password)
<dd>Returns true if the password matches.
<dt>Document#getMetaData(key)
<dd>Return various meta data information. The common keys are: "format", "encryption", "info:Author", and "info:Title".
<dt>Document#layout(pageWidth, pageHeight, fontSize)
<dd>Layout a reflowable document (EPUB, FB2, or XHTML) to fit the specified page and font size.
<dt>Document#countPages()
<dd>Count the number of pages in the document. This may change if you call the layout function with different parameters.
<dt>Document#loadPage(number)
<dd>Returns a Page object for the given page number. Page number zero (0) is the first page in the document.
<dt>Document#loadOutline()
<dd>Returns an array with the outline (table of contents).
In the array is an object for each heading with the property 'title', and a property 'page' containing the page number.
If the object has a 'down' property, it contains an array with all the sub-headings for that entry.
<dt>Document#isPDF()
<dd>Returns true if the document is a PDF document.
</dl>
<dl>
<dt>setUserCSS(userStylesheet, usePublisherStyles)
<dd>Set user styles and whether to use publisher styles when laying out reflowable documents.
</dl>
<dl>
<dt>Page#bound()
<dd>Returns a rectangle containing the page dimensions.
<dt>Page#run(device, transform, skipAnnotations)
<dd>Calls device functions for all the contents on the page, using the specified transform matrix.
The device can be one of the built-in devices or a JavaScript object with methods for the device calls.
The transform maps from user space points to device space pixels.
If skipAnnotations is true, ignore annotations.
<dt>Page#toPixmap(transform, colorspace, alpha, skipAnnotations)
<dd>Render the page into a Pixmap, using the transform and colorspace.
If alpha is true, the page will be drawn on a transparent background, otherwise white.
<dt>Page#toDisplayList(skipAnnotations)
<dd>Record the contents on the page into a DisplayList.
<dt>Page#toStructuredText(options)
<dd>Extract the text on the page into a StructuredText object.
The options argument is a comma separated list of flags: preserve-ligatures, preserve-whitespace, and preserve-images.
<dt>Page#search(needle)
<dd>Search for 'needle' text on the page, and return an array with rectangles of all matches found.
<dt>Page#getAnnotations()
<dd>Return array of all annotations on the page.
<dt>Page#getLinks()
<dd>Return an array of all the links on the page.
Each link is an object with a 'bounds' property, and either a 'page' or 'uri' property,
depending on whether it's an internal or external link.
<dt>Page#isPDF()
<dd>Returns true if the page is from a PDF document.
</dl>
<dl>
<dt>Annotation#bound()
<dd>Returns a rectangle containing the location and dimension of the annotation.
<dt>Annotation#run(device, transform)
<dd>Calls device functions to draw the annotation.
<dt>Annotation#toPixmap(transform, colorspace, alpha)
<dd>Render the annotation into a Pixmap, using the transform and colorspace.
<dt>Annotation#toDisplayList()
<dd>Record the contents of the annotation into a DisplayList.
<dt>Annotation#isPDF()
<dd>Returns true if the annotation is from a PDF document.
</dl>
<h2>
StructuredText
</h2>
<p>
StructuredText objects hold text from a page that has been analyzed and grouped into blocks, lines and spans.
</p>
<dl>
<dt>StructuredText#search(needle)
<dd>Search the text for all instances of 'needle', and return an array with rectangles of all matches found.
<dt>StructuredText#highlight(p, q)
<dd>Return an array with rectangles needed to highlight a selection defined by the start and end points.
<dt>StructuredText#copy(p, q)
<dd>Return the text from the selection defined by the start and end points.
</dl>
<h2>
ColorSpace
</h2>
<dl>
<dt>DeviceGray
<dd>The default grayscale colorspace.
<dt>DeviceRGB
<dd>The default RGB colorspace.
<dt>DeviceBGR
<dd>The default RGB colorspace, but with components in reverse order.
<dt>DeviceCMYK
<dd>The default CMYK colorspace.
<dt>ColorSpace#getNumberOfComponents()
<dd>A grayscale colorspace has one component, RGB has 3, CMYK has 4, and DeviceN may have any number of components.
</dl>
<h2>
Pixmap
</h2>
<p>
A Pixmap object contains a color raster image (short for pixel map).
The components in a pixel in the pixmap are all byte values, with the transparency as the last component.
A pixmap also has a location (x, y) in addition to its size; so that they can easily be used to represent
tiles of a page.
<dl>
<dt>new Pixmap(colorspace, bounds, alpha)
<dd>Create a new pixmap. The pixel data is <b>not</b> initialized; and will contain garbage.
<dt>Pixmap#clear(value)
<dd>Clear the pixels to the specified value. Pass 255 for white, or undefined for transparent.
<dt>Pixmap#bound()
<dd>Return the pixmap bounds.
<dt>Pixmap#getWidth()
<dt>Pixmap#getHeight()
<dt>Pixmap#getNumberOfComponents()
<dd>Number of colors; plus one if an alpha channel is present.
<dt>Pixmap#getAlpha()
<dd>True if alpha channel is present.
<dt>Pixmap#getStride()
<dd>Number of bytes per row.
<dt>Pixmap#getColorSpace()
<dt>Pixmap#getXResolution()
<dt>Pixmap#getYResolution()
<dd>Image resolution in dots per inch.
<dt>Pixmap#getSample(x, y, k)
<dd>Get the value of component k at position x, y (relative to the image origin: 0, 0 is the top left pixel).
<dt>Pixmap#saveAsPNG(fileName, saveAlpha)
<dd>Save the pixmap as a PNG. Only works for Gray and RGB images.
</dl>
<h2>
DrawDevice
</h2>
<p>
The DrawDevice can be used to render to a Pixmap; either by running a Page with it or by calling its methods directly.
<dl>
<dt>new DrawDevice(transform, pixmap)
<dd>Create a device for drawing into a pixmap. The pixmap bounds used should match the transformed page bounds,
or you can adjust them to only draw a part of the page.
</dl>
<h2>
DisplayList and DisplayListDevice
</h2>
<p>
A display list records all the device calls for playback later.
If you want to run a page through several devices, or run it multiple times for any other reason,
recording the page to a display list and replaying the display list may be a performance gain
since then you can avoid reinterpreting the page each time. Be aware though, that a display list
will keep all the graphics required in memory, so will increase the amount of memory required.
<dl>
<dt>new DisplayList(mediabox)
<dd>Create an empty display list. The mediabox rect has the bounds of the page in points.
<dt>DisplayList#run(device, transform)
<dd>Play back the recorded device calls onto the device.
<dt>DisplayList#toPixmap(transform, colorspace, alpha)
<dd>Render display list to a pixmap. If alpha is true, it will render to a transparent background, otherwise white.
<dt>DisplayList#toStructuredText(options)
<dd>Extract the text in the display list into a StructuredText object.
The options argument is a comma separated list of flags: preserve-ligatures, preserve-whitespace, and preserve-images.
<dt>DisplayList#search(needle)
<dd>Search the display list text for all instances of 'needle', and return an array with rectangles of all matches found.
<dd>
</dl>
<dl>
<dt>new DisplayListDevice(displayList)
<dd>Create a device for recording onto a display list.
</dl>
<h2>
Device
</h2>
<p>
All built-in devices have the methods listed below. Any function that accepts a device will also
accept a JavaScript object with the same methods. Any missing methods are simply ignored, so you
only need to create methods for the device calls you care about.
<p>
Many of the methods take graphics objects as arguments: Path, Text, Image and Shade.
<p>
The stroking state is a dictionary with keys for:
<dl>
<dt>startCap, dashCap, endCap:
<dd>"Butt", "Round", "Square", or "Triangle".
<dt>lineCap:
<dd>Set startCap, dashCap, and endCap all at once.
<dt>lineJoin:
<dd>"Miter", "Round", "Bevel", or "MiterXPS".
<dt>lineWidth:
<dd>Thickness of the line.
<dt>miterLimit:
<dd>Maximum ratio of the miter length to line width, before beveling the join instead.
<dt>dashPhase:
<dd>Starting offset for dash pattern.
<dt>dashes:
<dd>Array of on/off dash lengths.
</dl>
<p>
Colors are specified as arrays with the appropriate number of components for the color space.
<p>
The methods that clip graphics must be balanced with a corresponding popClip.
<dl>
<dt>Device#fillPath(path, evenOdd, transform, colorspace, color, alpha)
<dt>Device#strokePath(path, stroke, transform)
<dt>Device#clipPath(path, evenOdd, transform, colorspace, color, alpha)
<dt>Device#clipStrokePath(path, stroke, transform)
<dd>Fill/stroke/clip a path.
</dl>
<dl>
<dt>Device#fillText(text, transform, colorspace, color, alpha)
<dt>Device#strokeText(text, stroke, transform, colorspace, color, alpha)
<dt>Device#clipText(text, transform)
<dt>Device#clipStrokeText(text, stroke, transform)
<dd>Fill/stroke/clip a text object.
<dt>Device#ignoreText(text, transform)
<dd>Invisible text that can be searched but should not be visible, such as for overlaying a scanned OCR image.
</dl>
<dl>
<dt>Device#fillShade(shade, transform, alpha)
<dd>Fill a shade (a.k.a. gradient). TODO: this details of gradient fills are not exposed to JavaScript yet.
<dt>Device#fillImage(shade, transform, alpha)
<dd>Draw an image. An image always fills a unit rectangle [0,0,1,1], so must be transformed to be placed and drawn at the appropriate size.
<dt>Device#fillImageMask(shade, transform, colorspace, color, alpha)
<dd>An image mask is an image without color. Fill with the color where the image is opaque.
<dt>Device#clipImageMask(shade, transform)
<dd>Clip graphics using the image to mask the areas to be drawn.
</dl>
<dl>
<dt>Device#beginMask(area, luminosity, backdropColorspace, backdropColor)
<dt>Device#endMask()
<dd>Create a soft mask. Any drawing commands between beginMask and endMask are grouped and used as a clip mask.
If luminosity is true, the mask is derived from the luminosity (grayscale value) of the graphics drawn;
otherwise the color is ignored completely and the mask is derived from the alpha of the group.
</dl>
<dl>
<dt>Device#popClip()
<dd>Pop the clip mask installed by the last clipping operation.
</dl>
<dl>
<dt>Device#beginGroup(area, isolated, knockout, blendmode, alpha)
<dt>Device#endGroup()
<dd>Push/pop a transparency blending group. Blendmode is one of the standard PDF blend modes: "Normal", "Multiply", "Screen", etc. See the PDF reference for details on isolated and knockout.
</dl>
<dl>
<dt>Device#beginTile(areaRect, viewRect, xStep, yStep, transform)
<dt>Device#endTile()
<dd>Draw a tiling pattern. Any drawing commands between beginTile and endTile are grouped and then repeated across the whole page.
Apply a clip mask to restrict the pattern to the desired shape.
</dl>
<dl>
<dt>Device#close()
<dd>Tell the device that we are done, and flush any pending output.
</dl>
<h2>
Path
</h2>
<p>
A Path object represents vector graphics as drawn by a pen. A path can be either stroked or filled, or used as a clip mask.
<dl>
<dt>new Path()
<dd>Create a new empty path.
<dt>Path#moveTo(x, y)
<dd>Lift and move the pen to the coordinate.
<dt>Path#lineTo(x, y)
<dd>Draw a line to the coordinate.
<dt>Path#curveTo(x1, y1, x2, y2, x3, y3)
<dd>Draw a cubic bezier curve to (x3,y3) using (x1,y1) and (x2,y2) as control points.
<dt>Path#closePath()
<dd>Close the path by drawing a line to the last moveTo.
<dt>Path#rect(x1, y1, x2, y2)
<dd>Shorthand for moveTo, lineTo, lineTo, lineTo, closePath to draw a rectangle.
<dt>Path#walk(pathWalker)
<dd>Call moveTo, lineTo, curveTo and closePath methods on the pathWalker object to replay the path.
</dl>
<h2>
Text
</h2>
<p>
A Text object contains text.
<dl>
<dt>new Text()
<dd>Create a new empty text object.
<dt>Text#showGlyph(font, transform, glyph, unicode, wmode)
<dd>Add a glyph to the text object. Transform is the text matrix, specifying font size and glyph location. For example: <code>[size,0,0,-size,x,y]</code>.
Glyph and unicode may be -1 for n-to-m cluster mappings.
For example, the "fi" ligature would be added in two steps: first the glyph for the 'fi' ligature and the unicode value for 'f';
then glyph -1 and the unicode value for 'i'.
WMode is 0 for horizontal writing, and 1 for vertical writing.
<dt>Text#showString(font, transform, string)
<dd>Add a simple string to the text object. Will do font substitution if the font does not have all the unicode characters required.
<dt>Text#walk(textWalker)
<dd>Call the showGlyph method on the textWalker object for each glyph in the text object.
</dl>
<h2>
Font
</h2>
<p>
Font objects can be created from TrueType, OpenType, Type1 or CFF fonts.
In PDF there are also special Type3 fonts.
<dl>
<dt>new Font(fontName or fileName)
<dd>Create a new font, either using a built-in font name or a filename.
<br>The built-in standard PDF fonts are:
Times-Roman, Times-Italic, Times-Bold, Times-BoldItalic,
Helvetica, Helvetica-Oblique, Helvetica-Bold, Helvetica-BoldOblique,
Courier, Courier-Oblique, Courier-Bold, Courier-BoldOblique,
Symbol, and ZapfDingbats.
<br>The built-in CJK fonts are referenced by language code: zh-Hant, zh-Hans, ja, ko.
<dt>Font#getName()
<dd>Get the font name.
<dt>Font#encodeCharacter(unicode)
<dd>Get the glyph index for a unicode character. Glyph zero (.notdef) is returned if the font does not have a glyph for the character.
<dt>Font#advanceGlyph(glyph, wmode)
<dd>Return advance width for a glyph in either horizontal or vertical writing mode.
</dl>
<h2>
Image
</h2>
<p>
Image objects are similar to Pixmaps, but can contain compressed data.
<dl>
<dt>new Image(pixmap or fileName)
<dd>Create a new image from a pixmap data, or load an image from a file.
<dt>Image#getWidth()
<dt>Image#getHeight()
<dd>Image size in pixels.
<dt>Image#getXResolution()
<dt>Image#getYResolution()
<dd>Image resolution in dots per inch.
<dt>Image#getColorSpace()
<dt>Image#toPixmap(scaledWidth, scaledHeight)
<dd>Create a pixmap from the image. The scaledWidth and scaledHeight arguments are optional,
but may be used to decode a down-scaled pixmap.
</dl>
<h2>
Document Writer
</h2>
<p>
Document writer objects are used to create new documents in several formats.
<dl>
<dt>new DocumentWriter(filename, format, options)
<dd>Create a new document writer to create a document with the specified format and output options.
If format is null it is inferred from the filename extension. The options argument is a comma separated list
of flags and key-value pairs. See below for more details.
<dt>DocumentWriter#beginPage(mediabox)
<dd>Begin rendering a new page. Returns a Device that can be used to render the page graphics.
<dt>DocumentWriter#endPage(device)
<dd>Finish the page rendering.
The argument must be the same device object that was returned by the beginPage method.
<dt>DocumentWriter#close()
<dd>Finish the document and flush any pending output.
</dl>
<p>
The output formats and options supported are the same as in the
<a href="manual-mutool-convert.html">mutool convert</a> command.
<h2>
PDFDocument and PDFObject
</h2>
<p>
With MuPDF it is also possible to create, edit and manipulate PDF documents
using low level access to the objects and streams contained in a PDF file.
A PDFDocument object is also a Document object. You can test a Document object
to see if it is safe to use as a PDFDocument by calling document.isPDF().
<dl>
<dt>new PDFDocument()
<dd>Create a new empty PDF document.
<dt>new PDFDocument(fileName)
<dd>Load a PDF document from file.
<dt>PDFDocument#save(fileName, options)
<dd>Write the PDF document to file.
The write options are a string of comma separated options (see the document writer <a href="#pdf-write-options">options</a>).
</dl>
<h3>
PDF Object Access
</h3>
<p>
A PDF document contains objects, similar to those in JavaScript: arrays, dictionaries, strings, booleans, and numbers.
At the root of the PDF document is the trailer object; which contains pointers to the meta data dictionary and the
catalog object which contains the pages and other information.
<p>
Pointers in PDF are also called indirect references,
and are of the form "32 0 R" (where 32 is the object number, 0 is the generation, and R is magic syntax).
All functions in MuPDF dereference indirect references automatically.
<p>
PDF has two types of strings: /Names and (Strings). All dictionary keys are names.
<p>
Some dictionaries in PDF also have attached binary data. These are called streams, and may be compressed.
<dl>
<dt>PDFDocument#getTrailer()
<dd>The trailer dictionary. This contains indirect references to the Root and Info dictionaries.
<dt>PDFDocument#countObjects()
<dd>Return the number of objects in the PDF. Object number 0 is reserved, and may not be used for anything.
<dt>PDFDocument#createObject()
<dd>Allocate a new numbered object in the PDF, and return an indirect reference to it.
The object itself is uninitialized.
<dt>PDFDocument#deleteObject(obj)
<dd>Delete the object referred to by the indirect reference.
</dl>
<p>
PDFObjects are always bound to the document that created them.
Do NOT mix and match objects from one document with another document!
<dl>
<dt>PDFDocument#addObject(obj)
<dd>Add 'obj' to the PDF as a numbered object, and return an indirect reference to it.
<dt>PDFDocument#addStream(buffer, object)
<dd>Create a stream object with the contents of 'buffer', add it to the PDF, and return an indirect reference to it. If object is defined, it will be used as the stream object dictionary.
<dt>PDFDocument#addRawStream(buffer, object)
<dd>Create a stream object with the contents of 'buffer', add it to the PDF, and return an indirect reference to it.
If object is defined, it will be used as the stream object dictionary.
The buffer must contain already compressed data that matches the Filter and DecodeParms.
<dt>PDFDocument#newNull()
<dt>PDFDocument#newBoolean(boolean)
<dt>PDFDocument#newInteger(number)
<dt>PDFDocument#newReal(number)
<dt>PDFDocument#newString(string)
<dt>PDFDocument#newName(string)
<dt>PDFDocument#newIndirect(objectNumber, generation)
<dt>PDFDocument#newArray()
<dt>PDFDocument#newDictionary()
</dl>
<p>
The following functions can be used to copy objects from one document to another:
<dl>
<dt>PDFDocument#graftObject(object)
<dd>Deep copy an object into the destination document. This function will not remember previously
copied objects.
If you are copying several objects from the same source document using multiple calls, you should
use a graft map instead.
<dt>PDFDocument#newGraftMap()
<dd>Create a graft map for the source document, so that objects that have already been copied can be found again.
<dt>PDFGraftMap#graftObject(object)
<dd>Use the graft map to copy objects, with the ability to remember previously copied objects.
</dl>
<p>
All functions that take PDF objects, do automatic translation between JavaScript objects
and PDF objects using a few basic rules. Null, booleans, and numbers are translated directly.
JavaScript strings are translated to PDF names, unless they are surrounded by parentheses:
"Foo" becomes the PDF name /Foo and "(Foo)" becomes the PDF string (Foo).
<p>
Arrays and dictionaries are recursively translated to PDF arrays and dictionaries.
Be aware of cycles though! The translation does NOT cope with cyclic references!
<p>
The translation goes both ways: PDF dictionaries and arrays can be accessed similarly
to JavaScript objects and arrays by getting and setting their properties.
<dl>
<dt>PDFObject#get(key or index)
<dt>PDFObject#put(key or index, value)
<dt>PDFObject#delete(key or index)
<dd>Access dictionaries and arrays. Dictionaries and arrays can also be accessed using normal property syntax: obj.Foo = 42; delete obj.Foo; x = obj[5].
<dt>PDFObject#resolve()
<dd>If the object is an indirect reference, return the object it points to; otherwise return the object itself.
<dt>PDFObject#isArray()
<dt>PDFObject#isDictionary()
<dt>PDFObject#forEach(function(key,value){...})
<dd>Iterate over all the entries in a dictionary or array and call fun for each key-value pair.
<dt>PDFObject#length
<dd>Length of the array.
<dt>PDFObject#push(item)
<dd>Append item to the end of the array.
</dl>
<p>
The only way to access a stream is via an indirect object, since all streams
are numbered objects.
<dl>
<dt>PDFObject#isIndirect()
<dd>Is the object an indirect reference.
<dt>PDFObject#asIndirect()
<dd>Return the object number the indirect reference points to.
<dt>PDFObject#isStream()
<dd>True if the object is an indirect reference pointing to a stream.
<dt>PDFObject#readStream()
<dd>Read the contents of the stream object into a Buffer.
<dt>PDFObject#readRawStream()
<dd>Read the raw, uncompressed, contents of the stream object into a Buffer.
<dt>PDFObject#writeObject(obj)
<dd>Update the object the indirect reference points to.
<dt>PDFObject#writeStream(buffer)
<dd>Update the contents of the stream the indirect reference points to.
This will update the Length, Filter and DecodeParms automatically.
<dt>PDFObject#writeRawStream(buffer)
<dd>Update the contents of the stream the indirect reference points to.
The buffer must contain already compressed data that matches the Filter and DecodeParms.
This will update the Length automatically, but leave the Filter and DecodeParms untouched.
</dl>
<p>
Primitive PDF objects such as booleans, names, and numbers can usually be treated like JavaScript values.
When that is not sufficient use these functions:
<dl>
<dt>PDFObject#isNull()
<dd>Is the object the 'null' object?
<dt>PDFObject#isBoolean()
<dd>Is the object a boolean?
<dt>PDFObject#asBoolean()
<dd>Get the boolean primitive value.
<dt>PDFObject#isNumber()
<dd>Is the object a number?
<dt>PDFObject#asNumber()
<dd>Get the number primitive value.
<dt>PDFObject#isName()
<dd>Is the object a name?
<dt>PDFObject#asName()
<dd>Get the name as a string.
<dt>PDFObject#isString()
<dd>Is the object a string?
<dt>PDFObject#asString()
<dd>Convert a "text string" to a javascript unicode string.
<dt>PDFObject#asByteString()
<dd>Convert a string to an array of byte values.
</dl>
<h3>
PDF Page Access
</h3>
<p>
All page objects are structured into a page tree, which defines the order the pages appear in.
<dl>
<dt>PDFDocument#countPages()
<dd>Number of pages in the document.
<dt>PDFDocument#findPage(number)
<dd>Return the page object for a page number. The first page is number zero.
<dt>PDFDocument#deletePage(number)
<dd>Delete the numbered page.
<dt>PDFDocument#insertPage(at, page)
<dd>Insert the page object in the page tree at the location. If 'at' is -1, at the end of the document.
</dl>
<p>
Pages consist of a content stream, and a resource dictionary containing all of the fonts and images used.
<dl>
<dt>PDFDocument#addPage(mediabox, rotate, resources, contents)
<dd>Create a new page object. Note: this function does NOT add it to the page tree.
<dt>PDFDocument#addSimpleFont(font, encoding)
<dd>Create a PDF object from the Font object as a simple font.
Encoding is either "Latin" (CP-1252), "Greek" (ISO-8859-7), or "Cyrillic" (KOI-8U).
The default is "Latin".
<dt>PDFDocument#addCJKFont(font, language, wmode, style)
<dd>Create a PDF object from the Font object as a UTF-16 encoded CID font for the given
language ("zh-Hant", "zh-Hans", "ko", or "ja"),
writing mode ("H" or "V"),
and style ("serif" or "sans-serif").
<dt>PDFDocument#addFont(font)
<dd>Create a PDF object from the Font object as an Identity-H encoded CID font.
<dt>PDFDocument#addImage(image)
<dd>Create a PDF object from the Image object.
<dt>PDFDocument#loadImage(obj)
<dd>Load an Image from a PDF object (typically an indirect reference to an image resource).
</dl>
<h3>
PDF Annotations (WORK IN PROGRESS!)
</h3>
<dl>
<dt>PDFPage#createAnnotation(type)
<dd>Create a new blank annotation of a given type.
The type must be one of the annotation subtypes listed in the PDF reference.
<dt>PDFPage#deleteAnnotation(annot)
<dd>Delete the annotation from the page.
</dl>
<dl>
<dt>PDFAnnotation#getType()
<dd>Return the annotation subtype.
<dt>PDFAnnotation#getFlags(), #setFlags(flags)
<dd>Get/set the annotation flags.
<dt>PDFAnnotation#getContents(), #setContents(text)
<dt>PDFAnnotation#getRect(), #setRect(rect)
<dt>PDFAnnotation#getBorder(), #setBorder(width)
<dt>PDFAnnotation#getColor(), #setColor(color)
<dt>PDFAnnotation#getQuadPoints(), #setQuadPoints(quadPoints)
<dt>PDFAnnotation#getInkList(), #setInkList(inkList)
<dt>PDFAnnotation#updateAppearance()
<dd>Update the appearance stream to account for changes in the annotation.
</dl>
<h2>
TODO
</h2>
<p>
There are several areas in MuPDF that still need bindings to access from JavaScript:
<ul>
<li>Shadings
<li>PDFDocument#graftObject()
<li>PDFWriteDevice
<li>DocumentWriter
</ul>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool show</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool show</h1>
</header>
<article>
<p>
The show command will print the specified objects and streams to
stdout. Streams are decoded and non-printable characters are
represented with a period by default.
<pre>
mutool show [options] file.pdf ( xref | outline | grep | <i>&lt;path&gt;</i> ) *
</pre>
<p>
Options:
<dl>
<dt> -p password
<dd> Use the specified password if the file is encrypted.
<dt> -o file
<dd> Write output to file instead of stdout.
<dt> -e
<dd> Print streams in their original encoded (or compressed) form.
<dt> -b
<dd> Print streams as binary data, and omit the object.
<dt> -g
<dd> Print objects in a one-line form suitable for grep, and omit stream data.
</dl>
<p>
Specify what to show by using one of the following keywords, or specify a path
to an object:
<dl>
<dt> xref
<dd> Print the cross reference table.
<dt> outline
<dd> Print the outline (table of contents).
<dt> pages
<dd> List the object numbers for every page.
<dt> grep
<dd> Print all the objects in the file in a compact one-line format
suitable for piping to grep.
</dl>
<p>
A path starts with either an object number, a property in the trailer
dictionary, or the keyword "trailer" or "pages". Separate elements with
a period '.' or slash '/'.
Select a page object by using pages/<i>N</i> where N is the page number.
The first page is number 1.
You can also use '*' as an element to iterate over all array indices
or dictionary properties in an object.
<dl>
<dt> Find the number of pages in a document:
<dd> <tt>mutool show $FILE trailer/Pages/Count</tt>
<dt> Print the raw content stream of the first page:
<dd> <tt>mutool show -b $FILE pages/1/Contents</tt>
<dt> Show all JPEG compressed stream objects:
<dd> <tt>mutool show $FILE grep | grep '/Filter/DCTDecode'</tt>
</dl>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>mutool trace</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>mutool trace</h1>
</header>
<article>
<p>
The 'mutool trace' command prints a trace of device calls needed to render a page.
<pre>
mutool trace [options] input [pages]
</pre>
<p>
The command line options are:
<dl>
<dt><i>input</i>
<dd>Input file name.
The input can be any of the document formats supported by MuPDF: PDF, XPS, CBZ, unprotected EPUB, FB2, etc.
<dt>[pages]
<dd>Comma separated list of page ranges. The first page is "1", and the last page is "N". The default is "1-N".
<dt>-p <i>password</i>
<dd>Password to use for password protected PDF documents.
</dl>
<dl>
<dt>-W <i>width</i>
<dd>Page width in points for EPUB layout.
<dt>-H <i>height</i>
<dd>Page height in points for EPUB layout.
<dt>-S <i>font-size</i>
<dd>Font size in points for EPUB layout.
<dt>-U <i>stylesheet.css</i>
<dd>File name of user style sheet for EPUB layout.
<dt>-X
<dd>Disable document styles for EPUB layout.
</dl>
<dl>
<dt>-d
<dd>Use display list. Run the page to a display list first, then trace running the display list.
</dl>
<p>
The trace takes the form of an XML document, with the root element being the document,
its children each page, and one page child element for each device call on that page.
<p>
An example trace:
<pre>
&lt;document filename="hello.pdf"&gt;
&lt;page number="1" mediabox="0 0 595 842"&gt;
&lt;fill_path winding="nonzero" colorspace="DeviceRGB" color="1 0 0" matrix="1 0 0 -1 0 842"&gt;
&lt;moveto x="50" y="50"/&gt;
&lt;lineto x="100" y="200"/&gt;
&lt;lineto x="200" y="50"/&gt;
&lt;/fill_path&gt;
&lt;fill_text colorspace="DeviceRGB" color="0" matrix="1 0 0 -1 0 842"&gt;
&lt;span font="Times-Roman" wmode="0" trm="100 0 0 100"&gt;
&lt;g unicode="H" glyph="H" x="50" y="500" /&gt;
&lt;g unicode="e" glyph="e" x="122.2" y="500" /&gt;
&lt;g unicode="l" glyph="l" x="166.6" y="500" /&gt;
&lt;g unicode="l" glyph="l" x="194.4" y="500" /&gt;
&lt;g unicode="o" glyph="o" x="222.2" y="500" /&gt;
&lt;g unicode="!" glyph="exclam" x="272.2" y="500" /&gt;
&lt;/span&gt;
&lt;/fill_text&gt;
&lt;/page&gt;
&lt;/document&gt;
</pre>
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

33
mupdf/docs/style.css Normal file
View File

@ -0,0 +1,33 @@
h1, footer { font-family: sans-serif; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.25rem; }
ul li { list-style-type: circle; }
pre, table, ol, dl { margin-left: 2rem; }
li { margin: 0; }
th, td { text-align: left; vertical-align: top; }
body { margin: 0; }
h1 {
font-weight: normal;
margin: 0;
padding: 1rem 2rem;
}
header {
color: white;
background: no-repeat;
background-color: #506b80;
background-image: url("logo/mupdf-icon.png");
background-position: bottom right;
padding-right: 72px;
min-height: 72px;
}
article {
max-width: 50rem;
margin: 2rem;
}
footer {
background-color: #ddd;
color: #303030;
padding: 1rem 2rem;
}

25
mupdf/docs/template.html Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>$TITLE</title>
<link rel="stylesheet" href="style.css" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<header>
<h1>$TITLE</h1>
</header>
<article>
$CONTENT
</article>
<footer>
<a href="http://artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Third party libraries used by MuPDF</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<header>
<h1>Third party libraries used by MuPDF</h1>
</header>
<article>
<p>
These are the third party libraries used by MuPDF.
<table width="100%">
<tr><th>Library <th>Version <th>Function <th>License
<tr><td><i>Required:</i>
<tr><td><a href="http://www.freetype.org/">freetype</a><td>2.10.0<td>Font scaling and rendering <td>BSD-style
<tr><td><a href="http://www.harfbuzz.org/">harfbuzz</a><td>1.3.2 with patches <td>Text shaping <td>MIT-style
<tr><td><a href="http://www.ijg.org/">libjpeg</a><td>9.0 with patches <td>JPEG decoding <td>BSD-style
<tr><td><a href="http://git.ghostscript.com/?p=thirdparty-lcms2.git;a=summary">Incompatible fork of lcms2</a><td>2.9rc1 with patches<td>Color management <td>MIT-style
<tr><td><a href="http://www.openjpeg.org/">openjpeg</a><td>2.3.0 with patches <td>JPEG 2000 decoding <td>BSD-style
<tr><td><a href="http://www.zlib.net/">zlib</a><td>1.2.11<td>Deflate compression <td>zlib License
<tr><td><i>Optional:</i>
<tr><td><a href="http://freeglut.sourceforge.net/">FreeGLUT</a><td>3.0.0 with patches <td>OpenGL API for UI<td>MIT-style
<tr><td><a href="http://curl.haxx.se/">curl</a><td>7.64.1 with patches <td>HTTP data transfer <td>MIT-style
<tr><td><a href="http://www.luratech.com/">Luratech JP2</a><td>N/A<td>JPEG 2000 decoding <td>commercial
<tr><td><a href="http://www.luratech.com/">Luratech JBIG2</a><td>N/A<td>JBIG2 decoding <td>commercial
<tr><td><a href="https://www.itu.int/rec/T-REC-T.835/">JPEG-XR reference</a><td>1.8 with patches <td>JPEG-XR decoding <td>special
</table>
<p>
NOTE:
<a href="http://jbig2dec.com/">jbig2dec</a> and
<a href="http://mujs.com/">MuJS</a>
are included in "thirdparty" but are copyright Artifex Software Inc.
</article>
<footer>
<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a>
Copyright &copy; 2006-2018 Artifex Software Inc.
</footer>
</body>
</html>

View File

@ -0,0 +1,69 @@
#ifndef MUDPF_FITZ_H
#define MUDPF_FITZ_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mupdf/fitz/version.h"
#include "mupdf/fitz/config.h"
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/crypt.h"
#include "mupdf/fitz/getopt.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/hash.h"
#include "mupdf/fitz/pool.h"
#include "mupdf/fitz/string-util.h"
#include "mupdf/fitz/tree.h"
#include "mupdf/fitz/bidi.h"
#include "mupdf/fitz/xml.h"
/* I/O */
#include "mupdf/fitz/buffer.h"
#include "mupdf/fitz/stream.h"
#include "mupdf/fitz/compress.h"
#include "mupdf/fitz/compressed-buffer.h"
#include "mupdf/fitz/filter.h"
#include "mupdf/fitz/output.h"
#include "mupdf/fitz/archive.h"
/* Resources */
#include "mupdf/fitz/store.h"
#include "mupdf/fitz/color.h"
#include "mupdf/fitz/pixmap.h"
#include "mupdf/fitz/bitmap.h"
#include "mupdf/fitz/image.h"
#include "mupdf/fitz/shade.h"
#include "mupdf/fitz/font.h"
#include "mupdf/fitz/path.h"
#include "mupdf/fitz/text.h"
#include "mupdf/fitz/separation.h"
#include "mupdf/fitz/glyph.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/display-list.h"
#include "mupdf/fitz/structured-text.h"
#include "mupdf/fitz/transition.h"
#include "mupdf/fitz/glyph-cache.h"
/* Document */
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/outline.h"
#include "mupdf/fitz/document.h"
#include "mupdf/fitz/util.h"
/* Output formats */
#include "mupdf/fitz/writer.h"
#include "mupdf/fitz/band-writer.h"
#include "mupdf/fitz/write-pixmap.h"
#include "mupdf/fitz/output-svg.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,70 @@
#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"
typedef struct fz_archive_s fz_archive;
struct fz_archive_s
{
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))
fz_archive *fz_open_archive(fz_context *ctx, const char *filename);
fz_archive *fz_open_archive_with_stream(fz_context *ctx, fz_stream *file);
fz_archive *fz_open_directory(fz_context *ctx, const char *path);
int fz_is_directory(fz_context *ctx, const char *path);
void fz_drop_archive(fz_context *ctx, fz_archive *arch);
const char *fz_archive_format(fz_context *ctx, fz_archive *arch);
int fz_count_archive_entries(fz_context *ctx, fz_archive *arch);
const char *fz_list_archive_entry(fz_context *ctx, fz_archive *arch, int idx);
int fz_has_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
fz_stream *fz_open_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
fz_buffer *fz_read_archive_entry(fz_context *ctx, fz_archive *arch, const char *name);
int fz_is_tar_archive(fz_context *ctx, fz_stream *file);
fz_archive *fz_open_tar_archive(fz_context *ctx, const char *filename);
fz_archive *fz_open_tar_archive_with_stream(fz_context *ctx, fz_stream *file);
int fz_is_zip_archive(fz_context *ctx, fz_stream *file);
fz_archive *fz_open_zip_archive(fz_context *ctx, const char *path);
fz_archive *fz_open_zip_archive_with_stream(fz_context *ctx, fz_stream *file);
typedef struct fz_zip_writer_s fz_zip_writer;
fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename);
fz_zip_writer *fz_new_zip_writer_with_output(fz_context *ctx, fz_output *out);
void fz_write_zip_entry(fz_context *ctx, fz_zip_writer *zip, const char *name, fz_buffer *buf, int compress);
void fz_close_zip_writer(fz_context *ctx, fz_zip_writer *zip);
void fz_drop_zip_writer(fz_context *ctx, fz_zip_writer *zip);
#endif

View File

@ -0,0 +1,46 @@
#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"
/*
fz_band_writer
*/
typedef struct fz_band_writer_s fz_band_writer;
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_drop_band_writer_fn)(fz_context *ctx, fz_band_writer *writer);
struct fz_band_writer_s
{
fz_drop_band_writer_fn *drop;
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))
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);
void fz_write_band(fz_context *ctx, fz_band_writer *writer, int stride, int band_height, const unsigned char *samples);
void fz_drop_band_writer(fz_context *ctx, fz_band_writer *writer);
#endif

View File

@ -0,0 +1,87 @@
/*
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"
typedef enum fz_bidi_direction_e
{
FZ_BIDI_LTR = 0,
FZ_BIDI_RTL = 1,
FZ_BIDI_NEUTRAL = 2
}
fz_bidi_direction;
typedef enum fz_bidi_flags_e
{
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

View File

@ -0,0 +1,50 @@
#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.
*/
typedef struct fz_bitmap_s fz_bitmap;
fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
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_s fz_halftone;
fz_bitmap *fz_new_bitmap_from_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht);
fz_bitmap *fz_new_bitmap_from_pixmap_band(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht, int band_start);
struct fz_bitmap_s
{
int refs;
int w, h, stride, n;
int xres, yres;
unsigned char *samples;
};
fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n, int xres, int yres);
void fz_bitmap_details(fz_bitmap *bitmap, int *w, int *h, int *n, int *stride);
void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps);
fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
void fz_drop_halftone(fz_context *ctx, fz_halftone *ht);
#endif

View File

@ -0,0 +1,62 @@
#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.
*/
typedef struct fz_buffer_s fz_buffer;
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
size_t fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap);
const char *fz_string_from_buffer(fz_context *ctx, fz_buffer *buf);
fz_buffer *fz_new_buffer(fz_context *ctx, size_t capacity);
fz_buffer *fz_new_buffer_from_data(fz_context *ctx, unsigned char *data, size_t size);
fz_buffer *fz_new_buffer_from_shared_data(fz_context *ctx, const unsigned char *data, size_t size);
fz_buffer *fz_new_buffer_from_copied_data(fz_context *ctx, const unsigned char *data, size_t size);
fz_buffer *fz_new_buffer_from_base64(fz_context *ctx, const char *data, size_t size);
void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, size_t capacity);
void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
void fz_clear_buffer(fz_context *ctx, fz_buffer *buf);
void fz_append_buffer(fz_context *ctx, fz_buffer *destination, fz_buffer *source);
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);
void fz_append_printf(fz_context *ctx, fz_buffer *buffer, const char *fmt, ...);
void fz_append_vprintf(fz_context *ctx, fz_buffer *buffer, const char *fmt, va_list args);
void fz_append_pdf_string(fz_context *ctx, fz_buffer *buffer, const char *text);
void fz_terminate_buffer(fz_context *ctx, fz_buffer *buf);
void fz_md5_buffer(fz_context *ctx, fz_buffer *buffer, unsigned char digest[16]);
size_t fz_buffer_extract(fz_context *ctx, fz_buffer *buf, unsigned char **data);
#endif

View File

@ -0,0 +1,243 @@
#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"
typedef struct fz_colorspace_s fz_colorspace;
typedef struct fz_pixmap_s fz_pixmap;
#if FZ_ENABLE_ICC
typedef struct fz_icc_instance_s fz_icc_instance;
typedef struct fz_icc_profile_s fz_icc_profile;
typedef struct fz_icc_link_s fz_icc_link;
#endif
/* 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 fz_color_params_s fz_color_params;
struct fz_color_params_s
{
uint8_t ri; /* rendering intent */
uint8_t bp; /* black point compensation */
uint8_t op; /* overprinting */
uint8_t opm; /* overprint mode */
};
extern const fz_color_params fz_default_color_params;
int fz_lookup_rendering_intent(const char *name);
const char *fz_rendering_intent_name(int ri);
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,
};
struct fz_colorspace_s
{
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;
};
fz_colorspace *fz_new_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, int n, const char *name);
fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
void fz_drop_colorspace_imp(fz_context *ctx, fz_storable *cs_);
void fz_drop_colorspace_store_key(fz_context *ctx, fz_colorspace *cs);
fz_colorspace *fz_keep_colorspace_store_key(fz_context *ctx, fz_colorspace *cs);
fz_colorspace *fz_new_indexed_colorspace(fz_context *ctx, fz_colorspace *base, int high, unsigned char *lookup);
fz_colorspace *fz_new_icc_colorspace(fz_context *ctx, enum fz_colorspace_type type, int flags, const char *name, fz_buffer *buf);
fz_colorspace *fz_new_cal_gray_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma);
fz_colorspace *fz_new_cal_rgb_colorspace(fz_context *ctx, float wp[3], float bp[3], float gamma[3], float matrix[9]);
fz_buffer *fz_new_icc_data_from_cal(fz_context *ctx, float wp[3], float bp[3], float gamma[3], float matrix[9], int n);
enum fz_colorspace_type fz_colorspace_type(fz_context *ctx, fz_colorspace *cs);
const char *fz_colorspace_name(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_n(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_is_subtractive(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_device_n_has_only_cmyk(fz_context *ctx, fz_colorspace *cs);
int fz_colorspace_device_n_has_cmyk(fz_context *ctx, fz_colorspace *cs);
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);
int fz_is_valid_blend_colorspace(fz_context *ctx, fz_colorspace *cs);
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);
void fz_colorspace_name_process_colorants(fz_context *ctx, fz_colorspace *cs);
void fz_colorspace_name_colorant(fz_context *ctx, fz_colorspace *cs, int n, const char *name);
const char *fz_colorspace_colorant(fz_context *ctx, fz_colorspace *cs, int n);
/* Color conversion */
typedef struct fz_color_converter_s fz_color_converter;
typedef void (fz_color_convert_fn)(fz_context *ctx, fz_color_converter *cc, const float *src, float *dst);
struct fz_color_converter_s
{
fz_color_convert_fn *convert;
fz_color_convert_fn *convert_via;
fz_colorspace *ds;
fz_colorspace *ss;
fz_colorspace *ss_via;
void *opaque;
#if FZ_ENABLE_ICC
fz_icc_link *link;
#endif
};
fz_color_convert_fn *fz_lookup_fast_color_converter(fz_context *ctx, fz_colorspace *ss, fz_colorspace *ds);
void fz_find_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ss, fz_colorspace *ds, fz_colorspace *is, fz_color_params params);
void fz_drop_color_converter(fz_context *ctx, fz_color_converter *cc);
void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ss, fz_colorspace *ds, fz_colorspace *is, fz_color_params params);
void fz_fin_cached_color_converter(fz_context *ctx, fz_color_converter *cc);
void fz_clamp_color(fz_context *ctx, fz_colorspace *cs, const float *in, float *out);
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 */
typedef struct fz_default_colorspaces_s fz_default_colorspaces;
struct fz_default_colorspaces_s
{
int refs;
fz_colorspace *gray;
fz_colorspace *rgb;
fz_colorspace *cmyk;
fz_colorspace *oi;
};
fz_default_colorspaces *fz_new_default_colorspaces(fz_context *ctx);
fz_default_colorspaces* fz_keep_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
void fz_drop_default_colorspaces(fz_context *ctx, fz_default_colorspaces *default_cs);
fz_default_colorspaces *fz_clone_default_colorspaces(fz_context *ctx, fz_default_colorspaces *base);
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);
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);
/*
Color convert a pixmap. The passing of default_cs is needed due to the base cs of the image possibly
needing to be treated as being in one of the page default color spaces.
*/
void fz_convert_pixmap_samples(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, fz_colorspace *prf, const fz_default_colorspaces *default_cs, fz_color_params color_params, int copy_spots);
void fz_fast_any_to_alpha(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots);
void fz_convert_fast_pixmap_samples(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots);
void fz_convert_slow_pixmap_samples(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, fz_colorspace *prf, fz_color_params params, int copy_spots);
/* Color management engine */
#if FZ_ENABLE_ICC
void fz_new_icc_context(fz_context *ctx);
void fz_drop_icc_context(fz_context *ctx);
fz_icc_profile *fz_new_icc_profile(fz_context *ctx, unsigned char *data, size_t size);
void fz_drop_icc_profile(fz_context *ctx, fz_icc_profile *profile);
void fz_icc_profile_name(fz_context *ctx, fz_icc_profile *profile, char *name, size_t size);
int fz_icc_profile_components(fz_context *ctx, fz_icc_profile *profile);
int fz_icc_profile_is_lab(fz_context *ctx, fz_icc_profile *profile);
fz_icc_link *fz_new_icc_link(fz_context *ctx,
fz_colorspace *src, int src_extras,
fz_colorspace *dst, int dst_extras,
fz_colorspace *prf,
fz_color_params color_params,
int format,
int copy_spots);
void fz_drop_icc_link_imp(fz_context *ctx, fz_storable *link);
void fz_drop_icc_link(fz_context *ctx, fz_icc_link *link);
fz_icc_link *fz_find_icc_link(fz_context *ctx,
fz_colorspace *src, int src_extras,
fz_colorspace *dst, int dst_extras,
fz_colorspace *prf,
fz_color_params color_params,
int format,
int copy_spots);
void fz_icc_transform_color(fz_context *ctx, fz_color_converter *cc, const float *src, float *dst);
void fz_icc_transform_pixmap(fz_context *ctx, fz_icc_link *link, fz_pixmap *src, fz_pixmap *dst, int copy_spots);
#endif
struct fz_colorspace_context_s
{
int ctx_refs;
fz_colorspace *gray, *rgb, *bgr, *cmyk, *lab;
#if FZ_ENABLE_ICC
void *icc_instance;
#endif
};
#endif

View File

@ -0,0 +1,22 @@
#ifndef MUPDF_FITZ_COMPRESS_H
#define MUPDF_FITZ_COMPRESS_H
#include "mupdf/fitz/system.h"
typedef enum
{
FZ_DEFLATE_NONE = 0,
FZ_DEFLATE_BEST_SPEED = 1,
FZ_DEFLATE_BEST = 9,
FZ_DEFLATE_DEFAULT = -1
} fz_deflate_level;
size_t fz_deflate_bound(fz_context *ctx, size_t size);
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);
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);
unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compressed_length, fz_buffer *buffer, fz_deflate_level level);
#endif

View File

@ -0,0 +1,96 @@
#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"
typedef struct fz_compression_params_s fz_compression_params;
typedef struct fz_compressed_buffer_s fz_compressed_buffer;
size_t fz_compressed_buffer_size(fz_compressed_buffer *buffer);
fz_stream *fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *);
fz_stream *fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *, int *l2factor);
fz_stream *fz_open_image_decomp_stream(fz_context *ctx, fz_stream *, fz_compression_params *, int *l2factor);
int fz_recognize_image_format(fz_context *ctx, unsigned char p[8]);
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,
};
struct fz_compression_params_s
{
int type;
union {
struct {
int color_transform; /* Use -1 for unset */
} jpeg;
struct {
int smask_in_data;
} jpx;
struct {
fz_jbig2_globals *globals;
} 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;
};
struct fz_compressed_buffer_s
{
fz_compression_params params;
fz_buffer *buffer;
};
void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf);
#endif

View File

@ -0,0 +1,169 @@
#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 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 */
/* To skip the CJK font, enable: (this implicitly enables TOFU_CJK_EXT and TOFU_CJK_LANG) */
/* #define TOFU_CJK */
/* 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_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
#endif /* FZ_CONFIG_H */

View File

@ -0,0 +1,329 @@
#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"
typedef struct fz_font_context_s fz_font_context;
typedef struct fz_colorspace_context_s fz_colorspace_context;
typedef struct fz_style_context_s fz_style_context;
typedef struct fz_tuning_context_s fz_tuning_context;
typedef struct fz_store_s fz_store;
typedef struct fz_glyph_cache_s fz_glyph_cache;
typedef struct fz_document_handler_context_s fz_document_handler_context;
typedef struct fz_context_s fz_context;
typedef struct fz_alloc_context_s fz_alloc_context;
struct fz_alloc_context_s
{
void *user;
void *(*malloc)(void *, size_t);
void *(*realloc)(void *, void *, size_t);
void (*free)(void *, void *);
};
typedef struct fz_error_stack_slot_s fz_error_stack_slot;
struct fz_error_stack_slot_s
{
int state, code;
fz_jmp_buf buffer;
};
typedef struct fz_error_context_s fz_error_context;
struct fz_error_context_s
{
fz_error_stack_slot *top;
fz_error_stack_slot stack[256];
int errcode;
void *print_user;
void (*print)(void *user, const char *message);
char message[256];
};
typedef struct fz_warn_context_s fz_warn_context;
struct fz_warn_context_s
{
void *print_user;
void (*print)(void *user, const char *message);
int count;
char message[256];
};
typedef struct fz_aa_context_s fz_aa_context;
struct fz_aa_context_s
{
int hscale;
int vscale;
int scale;
int bits;
int text_bits;
float min_line_width;
};
/*
Exception macro definitions. Just treat these as a black box - pay no
attention to the man behind the curtain.
*/
void fz_var_imp(void *);
#define fz_var(var) fz_var_imp((void *)&(var))
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);
#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))
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);
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);
const char *fz_caught_message(fz_context *ctx);
int fz_caught(fz_context *ctx);
void fz_rethrow_if(fz_context *ctx, int errcode);
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_COUNT
};
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 fz_locks_context_s fz_locks_context;
struct fz_locks_context_s
{
void *user;
void (*lock)(void *user, int lock);
void (*unlock)(void *user, int lock);
};
enum {
FZ_LOCK_ALLOC = 0,
FZ_LOCK_FREETYPE,
FZ_LOCK_GLYPHCACHE,
FZ_LOCK_MAX
};
struct fz_context_s
{
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
/* TODO: should these be unshared? */
fz_document_handler_context *handler;
fz_style_context *style;
fz_tuning_context *tuning;
/* shared contexts */
fz_font_context *font;
fz_colorspace_context *colorspace;
fz_store *store;
fz_glyph_cache *glyph_cache;
};
/*
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,
};
fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
fz_context *fz_clone_context(fz_context *ctx);
void fz_drop_context(fz_context *ctx);
void fz_set_user_context(fz_context *ctx, void *user);
void *fz_user_context(fz_context *ctx);
void fz_default_error_callback(void *user, const char *message);
void fz_default_warning_callback(void *user, const char *message);
void fz_set_error_callback(fz_context *ctx, void (*print)(void *user, const char *message), void *user);
void fz_set_warning_callback(fz_context *ctx, void (*print)(void *user, const char *message), 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);
void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg);
void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg);
int fz_aa_level(fz_context *ctx);
void fz_set_aa_level(fz_context *ctx, int bits);
int fz_text_aa_level(fz_context *ctx);
void fz_set_text_aa_level(fz_context *ctx, int bits);
int fz_graphics_aa_level(fz_context *ctx);
void fz_set_graphics_aa_level(fz_context *ctx, int bits);
float fz_graphics_min_line_width(fz_context *ctx);
void fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width);
const char *fz_user_css(fz_context *ctx);
void fz_set_user_css(fz_context *ctx, const char *text);
int fz_use_document_css(fz_context *ctx);
void fz_set_use_document_css(fz_context *ctx, int use);
void fz_enable_icc(fz_context *ctx);
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.
*/
#define fz_malloc_struct(CTX, TYPE) \
((TYPE*)Memento_label(fz_calloc(CTX, 1, sizeof(TYPE)), #TYPE))
/*
* Allocate uninitialized memory for an array of structures, and tag the
* pointer for Memento. Does NOT clear the memory!
*/
#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 "[]"))
void *fz_malloc(fz_context *ctx, size_t size);
void *fz_calloc(fz_context *ctx, size_t count, size_t size);
void *fz_realloc(fz_context *ctx, void *p, size_t size);
void fz_free(fz_context *ctx, void *p);
void *fz_malloc_no_throw(fz_context *ctx, size_t size);
void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);
void *fz_realloc_no_throw(fz_context *ctx, void *p, size_t size);
char *fz_strdup(fz_context *ctx, const char *s);
void *fz_zlib_alloc(void *ctx, unsigned int items, unsigned int size);
void fz_zlib_free(void *ctx, void *ptr);
extern fz_alloc_context fz_alloc_default;
extern fz_locks_context fz_locks_default;
double fz_drand48(fz_context *ctx);
int32_t fz_lrand48(fz_context *ctx);
int32_t fz_mrand48(fz_context *ctx);
double fz_erand48(fz_context *ctx, uint16_t xsubi[3]);
int32_t fz_jrand48(fz_context *ctx, uint16_t xsubi[3]);
int32_t fz_nrand48(fz_context *ctx, uint16_t xsubi[3]);
void fz_lcong48(fz_context *ctx, uint16_t param[7]);
uint16_t *fz_seed48(fz_context *ctx, uint16_t seed16v[3]);
void fz_srand48(fz_context *ctx, int32_t seedval);
void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
#endif

View File

@ -0,0 +1,120 @@
#ifndef MUPDF_FITZ_CRYPT_H
#define MUPDF_FITZ_CRYPT_H
#include "mupdf/fitz/system.h"
/* md5 digests */
typedef struct fz_md5_s fz_md5;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_md5_s
{
unsigned int state[4];
unsigned int count[2];
unsigned char buffer[64];
};
void fz_md5_init(fz_md5 *state);
void fz_md5_update(fz_md5 *state, const unsigned char *input, size_t inlen);
void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
/* sha-256 digests */
typedef struct fz_sha256_s fz_sha256;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_sha256_s
{
unsigned int state[8];
unsigned int count[2];
union {
unsigned char u8[64];
unsigned int u32[16];
} buffer;
};
void fz_sha256_init(fz_sha256 *state);
void fz_sha256_update(fz_sha256 *state, const unsigned char *input, size_t inlen);
void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
/* sha-512 digests */
typedef struct fz_sha512_s fz_sha512;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_sha512_s
{
uint64_t state[8];
unsigned int count[2];
union {
unsigned char u8[128];
uint64_t u64[16];
} buffer;
};
void fz_sha512_init(fz_sha512 *state);
void fz_sha512_update(fz_sha512 *state, const unsigned char *input, size_t inlen);
void fz_sha512_final(fz_sha512 *state, unsigned char digest[64]);
/* sha-384 digests */
typedef struct fz_sha512_s fz_sha384;
void fz_sha384_init(fz_sha384 *state);
void fz_sha384_update(fz_sha384 *state, const unsigned char *input, size_t inlen);
void fz_sha384_final(fz_sha384 *state, unsigned char digest[64]);
/* arc4 crypto */
typedef struct fz_arc4_s fz_arc4;
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_arc4_s
{
unsigned x;
unsigned y;
unsigned char state[256];
};
void fz_arc4_init(fz_arc4 *state, const unsigned char *key, size_t len);
void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, size_t len);
/* AES block cipher implementation from XYSSL */
typedef struct fz_aes_s fz_aes;
#define FZ_AES_DECRYPT 0
#define FZ_AES_ENCRYPT 1
/*
Structure definition is public to enable stack
based allocation. Do not access the members directly.
*/
struct fz_aes_s
{
int nr; /* number of rounds */
unsigned long *rk; /* AES round keys */
unsigned long buf[68]; /* unaligned data */
};
int fz_aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
int fz_aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
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

View File

@ -0,0 +1,294 @@
#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_s 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
};
int fz_lookup_blendmode(const char *name);
char *fz_blendmode_name(int blendmode);
typedef struct fz_device_container_stack_s fz_device_container_stack;
struct fz_device_container_stack_s
{
fz_rect scissor;
int type;
int user;
};
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,
};
struct fz_device_s
{
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 *);
fz_rect d1_rect;
int container_len;
int container_cap;
fz_device_container_stack *container;
};
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);
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))
void fz_close_device(fz_context *ctx, fz_device *dev);
void fz_drop_device(fz_context *ctx, fz_device *dev);
fz_device *fz_keep_device(fz_context *ctx, fz_device *dev);
void fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints);
void fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints);
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.
*/
typedef struct fz_cookie_s fz_cookie;
/*
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.
*/
struct fz_cookie_s
{
int abort;
int progress;
int progress_max; /* -1 for unknown */
int errors;
int incomplete;
};
fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out);
fz_device *fz_new_bbox_device(fz_context *ctx, fz_rect *rectp);
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
};
fz_device *fz_new_draw_device(fz_context *ctx, fz_matrix transform, fz_pixmap *dest);
fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip);
fz_device *fz_new_draw_device_with_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, fz_colorspace *proof_cs);
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 fz_draw_options_s fz_draw_options;
struct fz_draw_options_s
{
int rotate;
int x_resolution;
int y_resolution;
int width;
int height;
fz_colorspace *colorspace;
int alpha;
int graphics;
int text;
};
extern const char *fz_draw_options_usage;
fz_draw_options *fz_parse_draw_options(fz_context *ctx, fz_draw_options *options, const char *string);
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,42 @@
#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_s fz_display_list;
fz_display_list *fz_new_display_list(fz_context *ctx, fz_rect mediabox);
fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
void fz_run_display_list(fz_context *ctx, fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_rect scissor, fz_cookie *cookie);
fz_display_list *fz_keep_display_list(fz_context *ctx, fz_display_list *list);
void fz_drop_display_list(fz_context *ctx, fz_display_list *list);
fz_rect fz_bound_display_list(fz_context *ctx, fz_display_list *list);
fz_image *fz_new_image_from_display_list(fz_context *ctx, float w, float h, fz_display_list *list);
int fz_display_list_is_empty(fz_context *ctx, const fz_display_list *list);
#endif

View File

@ -0,0 +1,458 @@
#ifndef MUPDF_FITZ_DOCUMENT_H
#define MUPDF_FITZ_DOCUMENT_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/geometry.h"
#include "mupdf/fitz/device.h"
#include "mupdf/fitz/transition.h"
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/outline.h"
#include "mupdf/fitz/separation.h"
typedef struct fz_document_s fz_document;
typedef struct fz_document_handler_s fz_document_handler;
typedef struct fz_page_s fz_page;
typedef intptr_t fz_bookmark;
typedef struct fz_location_s
{
int chapter;
int page;
} fz_location;
static inline fz_location fz_make_location(int chapter, int page)
{
fz_location loc = { chapter, page };
return loc;
}
enum
{
/* 6in at 4:3 */
FZ_LAYOUT_KINDLE_W = 260,
FZ_LAYOUT_KINDLE_H = 346,
FZ_LAYOUT_KINDLE_EM = 9,
/* 4.25 x 6.87 in */
FZ_LAYOUT_US_POCKET_W = 306,
FZ_LAYOUT_US_POCKET_H = 495,
FZ_LAYOUT_US_POCKET_EM = 10,
/* 5.5 x 8.5 in */
FZ_LAYOUT_US_TRADE_W = 396,
FZ_LAYOUT_US_TRADE_H = 612,
FZ_LAYOUT_US_TRADE_EM = 11,
/* 110 x 178 mm */
FZ_LAYOUT_UK_A_FORMAT_W = 312,
FZ_LAYOUT_UK_A_FORMAT_H = 504,
FZ_LAYOUT_UK_A_FORMAT_EM = 10,
/* 129 x 198 mm */
FZ_LAYOUT_UK_B_FORMAT_W = 366,
FZ_LAYOUT_UK_B_FORMAT_H = 561,
FZ_LAYOUT_UK_B_FORMAT_EM = 10,
/* 135 x 216 mm */
FZ_LAYOUT_UK_C_FORMAT_W = 382,
FZ_LAYOUT_UK_C_FORMAT_H = 612,
FZ_LAYOUT_UK_C_FORMAT_EM = 11,
/* 148 x 210 mm */
FZ_LAYOUT_A5_W = 420,
FZ_LAYOUT_A5_H = 595,
FZ_LAYOUT_A5_EM = 11,
/* Default to A5 */
FZ_DEFAULT_LAYOUT_W = FZ_LAYOUT_A5_W,
FZ_DEFAULT_LAYOUT_H = FZ_LAYOUT_A5_H,
FZ_DEFAULT_LAYOUT_EM = FZ_LAYOUT_A5_EM,
};
typedef enum
{
FZ_PERMISSION_PRINT = 'p',
FZ_PERMISSION_COPY = 'c',
FZ_PERMISSION_EDIT = 'e',
FZ_PERMISSION_ANNOTATE = 'n',
}
fz_permission;
/*
Type for a function to be called when
the reference count for the fz_document drops to 0. The
implementation should release any resources held by the
document. The actual document pointer will be freed by the
caller.
*/
typedef void (fz_document_drop_fn)(fz_context *ctx, fz_document *doc);
/*
Type for a function to be
called to enquire whether the document needs a password
or not. See fz_needs_password for more information.
*/
typedef int (fz_document_needs_password_fn)(fz_context *ctx, fz_document *doc);
/*
Type for a function to be
called to attempt to authenticate a password. See
fz_authenticate_password for more information.
*/
typedef int (fz_document_authenticate_password_fn)(fz_context *ctx, fz_document *doc, const char *password);
/*
Type for a function to be
called to see if a document grants a certain permission. See
fz_document_has_permission for more information.
*/
typedef int (fz_document_has_permission_fn)(fz_context *ctx, fz_document *doc, fz_permission permission);
/*
Type for a function to be called to
load the outlines for a document. See fz_document_load_outline
for more information.
*/
typedef fz_outline *(fz_document_load_outline_fn)(fz_context *ctx, fz_document *doc);
/*
Type for a function to be called to lay
out a document. See fz_layout_document for more information.
*/
typedef void (fz_document_layout_fn)(fz_context *ctx, fz_document *doc, float w, float h, float em);
/*
Type for a function to be called to
resolve an internal link to a page number. See fz_resolve_link
for more information.
*/
typedef fz_location (fz_document_resolve_link_fn)(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp);
/*
Type for a function to be called to
count the number of chapters in a document. See fz_count_chapters for
more information.
*/
typedef int (fz_document_count_chapters_fn)(fz_context *ctx, fz_document *doc);
/*
Type for a function to be called to
count the number of pages in a document. See fz_count_pages for
more information.
*/
typedef int (fz_document_count_pages_fn)(fz_context *ctx, fz_document *doc, int chapter);
/*
Type for a function to load a given
page from a document. See fz_load_page for more information.
*/
typedef fz_page *(fz_document_load_page_fn)(fz_context *ctx, fz_document *doc, int chapter, int page);
/*
Type for a function to query
a documents metadata. See fz_lookup_metadata for more
information.
*/
typedef int (fz_document_lookup_metadata_fn)(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size);
/*
Return output intent color space if it exists
*/
typedef fz_colorspace* (fz_document_output_intent_fn)(fz_context *ctx, fz_document *doc);
/*
Write document accelerator data
*/
typedef void (fz_document_output_accelerator_fn)(fz_context *ctx, fz_document *doc, fz_output *out);
/*
Type for a function to make
a bookmark. See fz_make_bookmark for more information.
*/
typedef fz_bookmark (fz_document_make_bookmark_fn)(fz_context *ctx, fz_document *doc, fz_location loc);
/*
Type for a function to lookup
a bookmark. See fz_lookup_bookmark for more information.
*/
typedef fz_location (fz_document_lookup_bookmark_fn)(fz_context *ctx, fz_document *doc, fz_bookmark mark);
/*
Type for a function to release all the
resources held by a page. Called automatically when the
reference count for that page reaches zero.
*/
typedef void (fz_page_drop_page_fn)(fz_context *ctx, fz_page *page);
/*
Type for a function to return the
bounding box of a page. See fz_bound_page for more
information.
*/
typedef fz_rect (fz_page_bound_page_fn)(fz_context *ctx, fz_page *page);
/*
Type for a function to run the
contents of a page. See fz_run_page_contents for more
information.
*/
typedef void (fz_page_run_page_fn)(fz_context *ctx, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
/*
Type for a function to load the links
from a page. See fz_load_links for more information.
*/
typedef fz_link *(fz_page_load_links_fn)(fz_context *ctx, fz_page *page);
/*
Type for a function to
obtain the details of how this page should be presented when
in presentation mode. See fz_page_presentation for more
information.
*/
typedef fz_transition *(fz_page_page_presentation_fn)(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
/*
Type for a function to enable/
disable separations on a page. See fz_control_separation for
more information.
*/
typedef void (fz_page_control_separation_fn)(fz_context *ctx, fz_page *page, int separation, int disable);
/*
Type for a function to detect
whether a given separation is enabled or disabled on a page.
See FZ_SEPARATION_DISABLED for more information.
*/
typedef int (fz_page_separation_disabled_fn)(fz_context *ctx, fz_page *page, int separation);
/*
Type for a function to retrieve
details of separations on a page. See fz_get_separations
for more information.
*/
typedef fz_separations *(fz_page_separations_fn)(fz_context *ctx, fz_page *page);
/*
Type for a function to retrieve
whether or not a given page uses overprint.
*/
typedef int (fz_page_uses_overprint_fn)(fz_context *ctx, fz_page *page);
/*
Structure definition is public so other classes can
derive from it. Do not access the members directly.
*/
struct fz_page_s
{
int refs;
int chapter; /* chapter number */
int number; /* page number in chapter */
int incomplete; /* incomplete from progressive loading; don't cache! */
fz_page_drop_page_fn *drop_page;
fz_page_bound_page_fn *bound_page;
fz_page_run_page_fn *run_page_contents;
fz_page_run_page_fn *run_page_annots;
fz_page_run_page_fn *run_page_widgets;
fz_page_load_links_fn *load_links;
fz_page_page_presentation_fn *page_presentation;
fz_page_control_separation_fn *control_separation;
fz_page_separation_disabled_fn *separation_disabled;
fz_page_separations_fn *separations;
fz_page_uses_overprint_fn *overprint;
fz_page **prev, *next; /* linked list of currently open pages */
};
/*
Structure definition is public so other classes can
derive from it. Callers should not access the members
directly, though implementations will need initialize
functions directly.
*/
struct fz_document_s
{
int refs;
fz_document_drop_fn *drop_document;
fz_document_needs_password_fn *needs_password;
fz_document_authenticate_password_fn *authenticate_password;
fz_document_has_permission_fn *has_permission;
fz_document_load_outline_fn *load_outline;
fz_document_layout_fn *layout;
fz_document_make_bookmark_fn *make_bookmark;
fz_document_lookup_bookmark_fn *lookup_bookmark;
fz_document_resolve_link_fn *resolve_link;
fz_document_count_chapters_fn *count_chapters;
fz_document_count_pages_fn *count_pages;
fz_document_load_page_fn *load_page;
fz_document_lookup_metadata_fn *lookup_metadata;
fz_document_output_intent_fn *get_output_intent;
fz_document_output_accelerator_fn *output_accelerator;
int did_layout;
int is_reflowable;
fz_page *open; /* linked list of currently open pages */
};
/*
Function type to open a document from a
file.
filename: file to open
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const char *filename);
/*
Function type to open a
document from a file.
stream: fz_stream to read document data from. Must be
seekable for formats that require it.
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_with_stream_fn)(fz_context *ctx, fz_stream *stream);
/*
Function type to open a document from a
file, with accelerator data.
filename: file to open
accel: accelerator file
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_accel_fn)(fz_context *ctx, const char *filename, const char *accel);
/*
Function type to open a document from a file,
with accelerator data.
stream: fz_stream to read document data from. Must be
seekable for formats that require it.
accel: fz_stream to read accelerator data from. Must be
seekable for formats that require it.
Pointer to opened document. Throws exception in case of error.
*/
typedef fz_document *(fz_document_open_accel_with_stream_fn)(fz_context *ctx, fz_stream *stream, fz_stream *accel);
/*
Recognize a document type from
a magic string.
magic: string to recognise - typically a filename or mime
type.
Returns a number between 0 (not recognized) and 100
(fully recognized) based on how certain the recognizer
is that this is of the required type.
*/
typedef int (fz_document_recognize_fn)(fz_context *ctx, const char *magic);
struct fz_document_handler_s
{
fz_document_recognize_fn *recognize;
fz_document_open_fn *open;
fz_document_open_with_stream_fn *open_with_stream;
const char **extensions;
const char **mimetypes;
fz_document_open_accel_fn *open_accel;
fz_document_open_accel_with_stream_fn *open_accel_with_stream;
};
void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler);
void fz_register_document_handlers(fz_context *ctx);
const fz_document_handler *fz_recognize_document(fz_context *ctx, const char *magic);
fz_document *fz_open_document(fz_context *ctx, const char *filename);
fz_document *fz_open_accelerated_document(fz_context *ctx, const char *filename, const char *accel);
fz_document *fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream);
fz_document *fz_open_accelerated_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream, fz_stream *accel);
int fz_document_supports_accelerator(fz_context *ctx, fz_document *doc);
void fz_save_accelerator(fz_context *ctx, fz_document *doc, const char *accel);
void fz_output_accelerator(fz_context *ctx, fz_document *doc, fz_output *accel);
void *fz_new_document_of_size(fz_context *ctx, int size);
#define fz_new_derived_document(C,M) ((M*)Memento_label(fz_new_document_of_size(C, sizeof(M)), #M))
fz_document *fz_keep_document(fz_context *ctx, fz_document *doc);
void fz_drop_document(fz_context *ctx, fz_document *doc);
int fz_needs_password(fz_context *ctx, fz_document *doc);
int fz_authenticate_password(fz_context *ctx, fz_document *doc, const char *password);
fz_outline *fz_load_outline(fz_context *ctx, fz_document *doc);
int fz_is_document_reflowable(fz_context *ctx, fz_document *doc);
void fz_layout_document(fz_context *ctx, fz_document *doc, float w, float h, float em);
fz_bookmark fz_make_bookmark(fz_context *ctx, fz_document *doc, fz_location loc);
fz_location fz_lookup_bookmark(fz_context *ctx, fz_document *doc, fz_bookmark mark);
int fz_count_pages(fz_context *ctx, fz_document *doc);
fz_location fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp);
fz_location fz_last_page(fz_context *ctx, fz_document *doc);
fz_location fz_next_page(fz_context *ctx, fz_document *doc, fz_location loc);
fz_location fz_previous_page(fz_context *ctx, fz_document *doc, fz_location loc);
fz_location fz_clamp_location(fz_context *ctx, fz_document *doc, fz_location loc);
fz_location fz_location_from_page_number(fz_context *ctx, fz_document *doc, int number);
int fz_page_number_from_location(fz_context *ctx, fz_document *doc, fz_location loc);
fz_page *fz_load_page(fz_context *ctx, fz_document *doc, int number);
int fz_count_chapters(fz_context *ctx, fz_document *doc);
int fz_count_chapter_pages(fz_context *ctx, fz_document *doc, int chapter);
fz_page *fz_load_chapter_page(fz_context *ctx, fz_document *doc, int chapter, int page);
fz_link *fz_load_links(fz_context *ctx, fz_page *page);
fz_page *fz_new_page_of_size(fz_context *ctx, int size);
#define fz_new_derived_page(CTX,TYPE) \
((TYPE *)Memento_label(fz_new_page_of_size(CTX,sizeof(TYPE)),#TYPE))
fz_rect fz_bound_page(fz_context *ctx, fz_page *page);
void fz_run_page(fz_context *ctx, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
void fz_run_page_contents(fz_context *ctx, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
void fz_run_page_annots(fz_context *ctx, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
void fz_run_page_widgets(fz_context *ctx, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
fz_page *fz_keep_page(fz_context *ctx, fz_page *page);
void fz_drop_page(fz_context *ctx, fz_page *page);
fz_transition *fz_page_presentation(fz_context *ctx, fz_page *page, fz_transition *transition, float *duration);
int fz_has_permission(fz_context *ctx, fz_document *doc, fz_permission p);
int fz_lookup_metadata(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size);
#define FZ_META_FORMAT "format"
#define FZ_META_ENCRYPTION "encryption"
#define FZ_META_INFO_AUTHOR "info:Author"
#define FZ_META_INFO_TITLE "info:Title"
fz_colorspace *fz_document_output_intent(fz_context *ctx, fz_document *doc);
fz_separations *fz_page_separations(fz_context *ctx, fz_page *page);
int fz_page_uses_overprint(fz_context *ctx, fz_page *page);
#endif

View File

@ -0,0 +1,48 @@
#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_s fz_jbig2_globals;
typedef struct
{
int64_t offset;
size_t length;
} fz_range;
fz_stream *fz_open_null_filter(fz_context *ctx, fz_stream *chain, int len, int64_t offset);
fz_stream *fz_open_range_filter(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges);
fz_stream *fz_open_endstream_filter(fz_context *ctx, fz_stream *chain, int len, int64_t offset);
fz_stream *fz_open_concat(fz_context *ctx, int max, int pad);
void fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain); /* Ownership of chain is passed in */
fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen);
fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_ahxd(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain);
fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables);
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);
fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits);
fz_stream *fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff);
fz_stream *fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc);
fz_stream *fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals);
fz_jbig2_globals *fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf);
fz_jbig2_globals *fz_keep_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
void fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals);
void fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals);
/* Extra filters for tiff */
fz_stream *fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w);
fz_stream *fz_open_thunder(fz_context *ctx, fz_stream *chain, int w);
#endif

View File

@ -0,0 +1,272 @@
#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"
/* forward declaration for circular dependency */
struct fz_device_s;
/* Various font encoding tables and lookup functions */
extern const char *fz_glyph_name_from_adobe_standard[256];
extern const char *fz_glyph_name_from_iso8859_1[256];
extern const char *fz_glyph_name_from_iso8859_7[256];
extern const char *fz_glyph_name_from_koi8u[256];
extern const char *fz_glyph_name_from_mac_expert[256];
extern const char *fz_glyph_name_from_mac_roman[256];
extern const char *fz_glyph_name_from_win_ansi[256];
extern const char *fz_glyph_name_from_windows_1250[256];
extern const char *fz_glyph_name_from_windows_1251[256];
extern const char *fz_glyph_name_from_windows_1252[256];
extern const unsigned short fz_unicode_from_iso8859_1[256];
extern const unsigned short fz_unicode_from_iso8859_7[256];
extern const unsigned short fz_unicode_from_koi8u[256];
extern const unsigned short fz_unicode_from_pdf_doc_encoding[256];
extern const unsigned short fz_unicode_from_windows_1250[256];
extern const unsigned short fz_unicode_from_windows_1251[256];
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_s fz_font;
/*
* Fonts come in two variants:
* Regular fonts are handled by FreeType.
* Type 3 fonts have callbacks to the interpreter.
*/
void *fz_font_ft_face(fz_context *ctx, fz_font *font);
fz_buffer **fz_font_t3_procs(fz_context *ctx, fz_font *font);
const char *ft_error_string(int err);
int ft_char_index(void *face, int cid);
int ft_name_index(void *face, const char *name);
/* 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;
} fz_font_flags_t;
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;
fz_shaper_data_t *fz_font_shaper_data(fz_context *ctx, fz_font *font);
struct fz_font_s
{
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_s **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_s *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;
/* 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];
};
const char *fz_font_name(fz_context *ctx, fz_font *font);
int fz_font_is_bold(fz_context *ctx, fz_font *font);
int fz_font_is_italic(fz_context *ctx, fz_font *font);
int fz_font_is_serif(fz_context *ctx, fz_font *font);
int fz_font_is_monospaced(fz_context *ctx, fz_font *font);
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);
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);
fz_font *fz_load_system_font(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics);
fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ordering, int serif);
const unsigned char *fz_lookup_builtin_font(fz_context *ctx, const char *name, int bold, int italic, int *len);
const unsigned char *fz_lookup_base14_font(fz_context *ctx, const char *name, int *len);
const unsigned char *fz_lookup_cjk_font(fz_context *ctx, int ordering, int *len, int *index);
const unsigned char *fz_lookup_cjk_font_by_language(fz_context *ctx, const char *lang, int *size, int *subfont);
int fz_lookup_cjk_ordering_by_language(const char *name);
const unsigned char *fz_lookup_noto_font(fz_context *ctx, int script, int lang, int *len, int *subfont);
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);
fz_font *fz_load_fallback_font(fz_context *ctx, int script, int language, int serif, int bold, int italic);
fz_font *fz_new_type3_font(fz_context *ctx, const char *name, fz_matrix matrix);
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);
fz_font *fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox);
fz_font *fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox);
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);
fz_font *fz_keep_font(fz_context *ctx, fz_font *font);
void fz_drop_font(fz_context *ctx, fz_font *font);
void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax);
fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid);
void fz_run_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, struct fz_device_s *dev);
void fz_decouple_type3_font(fz_context *ctx, fz_font *font, void *t3doc);
float fz_advance_glyph(fz_context *ctx, fz_font *font, int glyph, int wmode);
int fz_encode_character(fz_context *ctx, fz_font *font, int unicode);
int fz_encode_character_sc(fz_context *ctx, fz_font *font, int unicode);
int fz_encode_character_by_glyph_name(fz_context *ctx, fz_font *font, const char *glyphname);
int fz_encode_character_with_fallback(fz_context *ctx, fz_font *font, int unicode, int script, int language, fz_font **out_font);
void fz_get_glyph_name(fz_context *ctx, fz_font *font, int glyph, char *buf, int size);
float fz_font_ascender(fz_context *ctx, fz_font *font);
float fz_font_descender(fz_context *ctx, fz_font *font);
void fz_font_digest(fz_context *ctx, fz_font *font, unsigned char digest[16]);
/*
Internal functions for our Harfbuzz integration
to work around the lack of thread safety.
*/
void fz_hb_lock(fz_context *ctx);
void fz_hb_unlock(fz_context *ctx);
#endif

View File

@ -0,0 +1,376 @@
#ifndef MUPDF_FITZ_MATH_H
#define MUPDF_FITZ_MATH_H
#include "mupdf/fitz/system.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)
float fz_atof(const char *s);
int fz_atoi(const char *s);
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 inlines 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 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 int64_t fz_maxi64(int64_t a, int64_t b)
{
return (a > b ? a : b);
}
static inline float fz_clamp(float f, float min, float max)
{
return (f > min ? (f < max ? f : max) : min);
}
static inline int fz_clampi(int i, int min, int max)
{
return (i > min ? (i < max ? i : max) : min);
}
static inline double fz_clampd(double d, double min, double max)
{
return (d > min ? (d < max ? d : max) : min);
}
static inline void *fz_clampp(void *p, void *min, void *max)
{
return (p > min ? (p < max ? p : max) : min);
}
#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 fz_point_s fz_point;
struct fz_point_s
{
float x, y;
};
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.
The relationship between the coordinates are that x0 <= x1 and
y0 <= y1 in all cases except for infinite rectangles. The area
of a rectangle is defined as (x1 - x0) * (y1 - y0). If either
x0 > x1 or y0 > y1 is true for a given rectangle then it is
defined to be infinite.
To check for empty or infinite rectangles use fz_is_empty_rect
and fz_is_infinite_rect.
x0, y0: The top left corner.
x1, y1: The bottom right corner.
*/
typedef struct fz_rect_s fz_rect;
struct fz_rect_s
{
float x0, y0;
float x1, y1;
};
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 fz_irect_s fz_irect;
struct fz_irect_s
{
int x0, y0;
int x1, y1;
};
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).
*/
extern const fz_rect fz_unit_rect;
/*
An empty rectangle with an area equal to zero.
Both the top left and bottom right corner are at (0, 0).
*/
extern const fz_rect fz_empty_rect;
extern const fz_irect fz_empty_irect;
/*
An infinite rectangle with negative area.
The corner (x0, y0) is at (1, 1) while the corner (x1, y1) is
at (-1, -1).
*/
extern const fz_rect fz_infinite_rect;
extern const fz_irect fz_infinite_irect;
/*
Check if rectangle is empty.
An empty rectangle is defined as one whose area is zero.
*/
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.
An infinite rectangle is defined as one where either of the
two relationships between corner coordinates are not true.
*/
static inline int fz_is_infinite_rect(fz_rect r)
{
return (r.x0 > r.x1 || r.y0 > r.y1);
}
/*
Check if an integer rectangle
is infinite.
An infinite rectangle is defined as one where either of the
two relationships between corner coordinates are not true.
*/
static inline int fz_is_infinite_irect(fz_irect r)
{
return (r.x0 > r.x1 || r.y0 > r.y1);
}
/*
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 fz_matrix_s fz_matrix;
struct fz_matrix_s
{
float a, b, c, d, e, f;
};
/*
Identity transform matrix.
*/
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;
}
fz_matrix fz_concat(fz_matrix left, fz_matrix right);
fz_matrix fz_scale(float sx, float sy);
fz_matrix fz_pre_scale(fz_matrix m, float sx, float sy);
fz_matrix fz_post_scale(fz_matrix m, float sx, float sy);
fz_matrix fz_shear(float sx, float sy);
fz_matrix fz_pre_shear(fz_matrix m, float sx, float sy);
fz_matrix fz_rotate(float degrees);
fz_matrix fz_pre_rotate(fz_matrix m, float degrees);
fz_matrix fz_translate(float tx, float ty);
fz_matrix fz_pre_translate(fz_matrix m, float tx, float ty);
fz_matrix fz_transform_page(fz_rect mediabox, float resolution, float rotate);
fz_matrix fz_invert_matrix(fz_matrix matrix);
int fz_try_invert_matrix(fz_matrix *inv, fz_matrix src);
int fz_is_rectilinear(fz_matrix m);
float fz_matrix_expansion(fz_matrix m);
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
fz_irect fz_intersect_irect(fz_irect a, fz_irect b);
fz_rect fz_union_rect(fz_rect a, fz_rect b);
fz_irect fz_irect_from_rect(fz_rect rect);
fz_irect fz_round_rect(fz_rect rect);
fz_rect fz_rect_from_irect(fz_irect bbox);
fz_rect fz_expand_rect(fz_rect b, float expand);
fz_irect fz_expand_irect(fz_irect a, int expand);
fz_rect fz_include_point_in_rect(fz_rect r, fz_point p);
fz_rect fz_translate_rect(fz_rect a, float xoff, float yoff);
fz_irect fz_translate_irect(fz_irect a, int xoff, int yoff);
int fz_contains_rect(fz_rect a, fz_rect b);
fz_point fz_transform_point(fz_point point, fz_matrix m);
fz_point fz_transform_point_xy(float x, float y, fz_matrix m);
fz_point fz_transform_vector(fz_point vector, fz_matrix m);
fz_rect fz_transform_rect(fz_rect rect, fz_matrix m);
fz_point fz_normalize_vector(fz_point p);
fz_matrix fz_gridfit_matrix(int as_tiled, fz_matrix m);
float fz_matrix_max_expansion(fz_matrix m);
typedef struct fz_quad_s fz_quad;
struct fz_quad_s
{
fz_point ul, ur, ll, lr;
};
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;
}
fz_rect fz_rect_from_quad(fz_quad q);
fz_quad fz_transform_quad(fz_quad q, fz_matrix m);
int fz_is_point_inside_quad(fz_point p, fz_quad q);
int fz_is_point_inside_rect(fz_point p, fz_rect r);
int fz_is_point_inside_irect(int x, int y, fz_irect r);
#endif

View File

@ -0,0 +1,20 @@
#ifndef MUPDF_FITZ_GETOPT_H
#define MUPDF_FITZ_GETOPT_H
/*
Simple functions/variables for use in tools.
*/
extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
extern int fz_optind;
extern char *fz_optarg;
/*
Windows unicode versions.
*/
#ifdef _WIN32
extern int fz_getoptw(int nargc, wchar_t * const *nargv, const wchar_t *ostr);
extern int fz_optindw;
extern wchar_t *fz_optargw;
#endif
#endif

View File

@ -0,0 +1,16 @@
#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"
void fz_purge_glyph_cache(fz_context *ctx);
fz_pixmap *fz_render_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, const fz_irect *scissor, int aa);
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);
void fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid);
void fz_dump_glyph_cache_stats(fz_context *ctx);
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,89 @@
#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"
/*
Glyphs represent a run length encoded set of pixels for a 2
dimensional region of a plane.
*/
typedef struct fz_glyph_s fz_glyph;
fz_irect fz_glyph_bbox(fz_context *ctx, fz_glyph *glyph);
int fz_glyph_width(fz_context *ctx, fz_glyph *glyph);
int fz_glyph_height(fz_context *ctx, fz_glyph *glyph);
fz_glyph *fz_new_glyph_from_pixmap(fz_context *ctx, fz_pixmap *pix);
fz_glyph *fz_new_glyph_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
fz_glyph *fz_new_glyph_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
fz_glyph *fz_keep_glyph(fz_context *ctx, fz_glyph *pix);
void fz_drop_glyph(fz_context *ctx, fz_glyph *pix);
/*
Glyphs represent a set of pixels for a 2 dimensional region of a
plane.
x, y: The minimum x and y coord of the region in pixels.
w, h: The width and height of the region in pixels.
samples: The sample data. The sample data is in a compressed format
designed to give reasonable compression, and to be fast to plot from.
The first sizeof(int) * h bytes of the table, when interpreted as
ints gives the offset within the data block of that lines data. An
offset of 0 indicates that that line is completely blank.
The data for individual lines is a sequence of bytes:
00000000 = end of lines data
LLLLLL00 = extend the length given in the next run by the 6 L bits
given here.
LLLLLL01 = A run of length L+1 transparent pixels.
LLLLLE10 = A run of length L+1 solid pixels. If E then this is the
last run on this line.
LLLLLE11 = A run of length L+1 intermediate pixels followed by L+1
bytes of literal pixel data. If E then this is the last run
on this line.
*/
struct fz_glyph_s
{
fz_storable storable;
int x, y, w, h;
fz_pixmap *pixmap;
size_t size;
unsigned char data[1];
};
fz_irect fz_glyph_bbox_no_ctx(fz_glyph *src);
static inline size_t
fz_glyph_size(fz_context *ctx, fz_glyph *glyph)
{
if (glyph == NULL)
return 0;
return sizeof(fz_glyph) + glyph->size + fz_pixmap_size(ctx, glyph->pixmap);
}
fz_path *fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm);
fz_path *fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
fz_glyph *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa);
fz_pixmap *fz_render_ft_glyph_pixmap(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa);
fz_glyph *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model, const fz_irect *scissor, int aa);
fz_pixmap *fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model, const fz_irect *scissor, int aa);
fz_glyph *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, const fz_stroke_state *state, int aa);
fz_pixmap *fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, const fz_stroke_state *state, int aa);
fz_glyph *fz_render_glyph(fz_context *ctx, fz_font*, int gid, fz_matrix *, fz_colorspace *model, const fz_irect *scissor, int alpha, int aa);
fz_glyph *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix *, fz_matrix, const fz_stroke_state *stroke, const fz_irect *scissor, int aa);
fz_pixmap *fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font*, int, fz_matrix *, fz_matrix, const fz_stroke_state *stroke, const fz_irect *scissor, int aa);
#endif

View File

@ -0,0 +1,32 @@
#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"
/*
* 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_s fz_hash_table;
typedef void (fz_hash_table_drop_fn)(fz_context *ctx, void *val);
typedef void (fz_hash_table_for_each_fn)(fz_context *ctx, void *state, void *key, int keylen, void *val);
fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_hash_table_drop_fn *drop_val);
void fz_drop_hash_table(fz_context *ctx, fz_hash_table *table);
void *fz_hash_find(fz_context *ctx, fz_hash_table *table, const void *key);
void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val);
void fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key);
void fz_hash_for_each(fz_context *ctx, fz_hash_table *table, void *state, fz_hash_table_for_each_fn *callback);
#endif

View File

@ -0,0 +1,171 @@
#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_s fz_image;
typedef struct fz_compressed_image_s fz_compressed_image;
typedef struct fz_pixmap_image_s fz_pixmap_image;
fz_pixmap *fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *ctm, int *w, int *h);
void fz_drop_image(fz_context *ctx, fz_image *image);
fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
fz_image *fz_keep_image_store_key(fz_context *ctx, fz_image *image);
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.
*/
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 *);
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))
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);
fz_image *fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask);
fz_image *fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer);
fz_image *fz_new_image_from_file(fz_context *ctx, const char *path);
void fz_drop_image_imp(fz_context *ctx, fz_storable *image);
void fz_drop_image_base(fz_context *ctx, fz_image *image);
fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *image, fz_irect *subarea, int indexed, int l2factor);
fz_pixmap *fz_convert_indexed_pixmap_to_base(fz_context *ctx, const fz_pixmap *src);
fz_pixmap *fz_convert_separation_pixmap_to_base(fz_context *ctx, const fz_pixmap *src);
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_s
{
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 invert_cmyk_jpeg:1;
unsigned int decoded:1;
unsigned int scalable:1;
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];
};
fz_pixmap *fz_load_jpeg(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_jpx(fz_context *ctx, const unsigned char *data, size_t size, fz_colorspace *cs);
fz_pixmap *fz_load_png(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_tiff(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_jxr(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_gif(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_bmp(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_pnm(fz_context *ctx, const unsigned char *data, size_t size);
fz_pixmap *fz_load_jbig2(fz_context *ctx, const unsigned char *data, size_t size);
void fz_load_jpeg_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jpx_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_png_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_tiff_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_gif_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_bmp_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_pnm_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jbig2_info(fz_context *ctx, const unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
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);
void fz_image_resolution(fz_image *image, int *xres, int *yres);
fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg);
void fz_set_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg, fz_pixmap *pix);
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);
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);
#endif

View File

@ -0,0 +1,45 @@
#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"
typedef struct fz_link_s fz_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.
*/
struct fz_link_s
{
int refs;
fz_link *next;
fz_rect rect;
void *doc;
char *uri;
};
fz_link *fz_new_link(fz_context *ctx, fz_rect bbox, void *doc, const char *uri);
fz_link *fz_keep_link(fz_context *ctx, fz_link *link);
int fz_is_external_link(fz_context *ctx, const char *uri);
void fz_drop_link(fz_context *ctx, fz_link *link);
#endif

View File

@ -0,0 +1,49 @@
#ifndef MUPDF_FITZ_OUTLINE_H
#define MUPDF_FITZ_OUTLINE_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
#include "mupdf/fitz/link.h"
#include "mupdf/fitz/output.h"
/* Outline */
/*
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_s fz_outline;
struct fz_outline_s
{
int refs;
char *title;
char *uri;
int page;
float x, y;
fz_outline *next;
fz_outline *down;
int is_open;
};
fz_outline *fz_new_outline(fz_context *ctx);
fz_outline *fz_keep_outline(fz_context *ctx, fz_outline *outline);
void fz_drop_outline(fz_context *ctx, fz_outline *outline);
#endif

View File

@ -0,0 +1,18 @@
#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,
};
fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format, int reuse_images);
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

View File

@ -0,0 +1,153 @@
#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.
*/
typedef struct fz_output_s fz_output;
/*
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);
struct fz_output_s
{
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;
char *bp, *wp, *ep;
};
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);
fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append);
fz_output *fz_new_output_with_buffer(fz_context *ctx, fz_buffer *buf);
fz_output *fz_stdout(fz_context *ctx);
fz_output *fz_stderr(fz_context *ctx);
void fz_set_stdout(fz_context *ctx, fz_output *out);
void fz_set_stderr(fz_context *ctx, fz_output *err);
void fz_write_printf(fz_context *ctx, fz_output *out, const char *fmt, ...);
void fz_write_vprintf(fz_context *ctx, fz_output *out, const char *fmt, va_list ap);
void fz_seek_output(fz_context *ctx, fz_output *out, int64_t off, int whence);
int64_t fz_tell_output(fz_context *ctx, fz_output *out);
void fz_flush_output(fz_context *ctx, fz_output *out);
void fz_close_output(fz_context *, fz_output *);
void fz_drop_output(fz_context *, fz_output *);
fz_stream *fz_stream_from_output(fz_context *, fz_output *);
void fz_write_data(fz_context *ctx, fz_output *out, const void *data, size_t size);
void fz_write_string(fz_context *ctx, fz_output *out, const char *s);
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);
void fz_write_rune(fz_context *ctx, fz_output *out, int rune);
void fz_write_base64(fz_context *ctx, fz_output *out, const unsigned char *data, int size, int newline);
void fz_write_base64_buffer(fz_context *ctx, fz_output *out, fz_buffer *data, int newline);
void fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, va_list args);
size_t fz_vsnprintf(char *buffer, size_t space, const char *fmt, va_list args);
size_t fz_snprintf(char *buffer, size_t space, const char *fmt, ...);
char *fz_asprintf(fz_context *ctx, const char *fmt, ...);
void fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename);
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

View File

@ -0,0 +1,116 @@
#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_s fz_path;
typedef struct fz_stroke_state_s fz_stroke_state;
typedef enum fz_linecap_e
{
FZ_LINECAP_BUTT = 0,
FZ_LINECAP_ROUND = 1,
FZ_LINECAP_SQUARE = 2,
FZ_LINECAP_TRIANGLE = 3
} fz_linecap;
typedef enum fz_linejoin_e
{
FZ_LINEJOIN_MITER = 0,
FZ_LINEJOIN_ROUND = 1,
FZ_LINEJOIN_BEVEL = 2,
FZ_LINEJOIN_MITER_XPS = 3
} fz_linejoin;
struct fz_stroke_state_s
{
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];
};
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;
void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg);
fz_path *fz_new_path(fz_context *ctx);
fz_path *fz_keep_path(fz_context *ctx, const fz_path *path);
void fz_drop_path(fz_context *ctx, const fz_path *path);
void fz_trim_path(fz_context *ctx, fz_path *path);
int fz_packed_path_size(const fz_path *path);
int fz_pack_path(fz_context *ctx, uint8_t *pack, size_t max, const fz_path *path);
fz_path *fz_clone_path(fz_context *ctx, fz_path *path);
fz_point fz_currentpoint(fz_context *ctx, fz_path *path);
void fz_moveto(fz_context *ctx, fz_path *path, float x, float y);
void fz_lineto(fz_context *ctx, fz_path *path, float x, float y);
void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2);
void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2);
void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2);
void fz_closepath(fz_context *ctx, fz_path *path);
void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
fz_rect fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm);
fz_rect fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect rect, const fz_stroke_state *stroke, fz_matrix ctm);
extern const fz_stroke_state fz_default_stroke_state;
fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
#endif

View File

@ -0,0 +1,175 @@
#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 last of which is
always alpha. The data is in premultiplied alpha when rendering, but
non-premultiplied for colorspace conversions and rescaling.
*/
typedef struct fz_overprint_s fz_overprint;
fz_irect fz_pixmap_bbox(fz_context *ctx, const fz_pixmap *pix);
int fz_pixmap_width(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_height(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_x(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_y(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha);
fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_irect bbox, fz_separations *seps, int alpha);
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);
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);
fz_pixmap *fz_new_pixmap_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, const fz_irect *rect);
fz_pixmap *fz_clone_pixmap(fz_context *ctx, fz_pixmap *old);
fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_colorants(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_spots(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_alpha(fz_context *ctx, fz_pixmap *pix);
unsigned char *fz_pixmap_samples(fz_context *ctx, fz_pixmap *pix);
int fz_pixmap_stride(fz_context *ctx, fz_pixmap *pix);
void fz_set_pixmap_resolution(fz_context *ctx, fz_pixmap *pix, int xres, int yres);
void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
void fz_fill_pixmap_with_color(fz_context *ctx, fz_pixmap *pix, fz_colorspace *colorspace, float *color, fz_color_params color_params);
void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_irect r);
void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
void fz_invert_pixmap_luminance(fz_context *ctx, fz_pixmap *pix);
void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
void fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int black, int white);
void fz_invert_pixmap_rect(fz_context *ctx, fz_pixmap *image, fz_irect rect);
void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
fz_pixmap *fz_convert_pixmap(fz_context *ctx, fz_pixmap *pix, fz_colorspace *cs_des, fz_colorspace *prf, fz_default_colorspaces *default_cs, fz_color_params color_params, int keep_alpha);
/*
Pixmaps represent a set of pixels for a 2 dimensional region of a
plane. Each pixel has n components per pixel, the last of which is
always alpha. 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: A simple block of memory w * h * n bytes of memory in which
the components are stored. 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. Subsequent scanlines follow on with no padding.
*/
struct fz_pixmap_s
{
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
};
void fz_drop_pixmap_imp(fz_context *ctx, fz_storable *pix);
void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_irect r, const fz_default_colorspaces *default_cs);
void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray);
size_t fz_pixmap_size(fz_context *ctx, fz_pixmap *pix);
fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, const fz_irect *clip);
typedef struct fz_scale_cache_s fz_scale_cache;
fz_scale_cache *fz_new_scale_cache(fz_context *ctx);
void fz_drop_scale_cache(fz_context *ctx, fz_scale_cache *cache);
fz_pixmap *fz_scale_pixmap_cached(fz_context *ctx, const fz_pixmap *src, float x, float y, float w, float h, const fz_irect *clip, fz_scale_cache *cache_x, fz_scale_cache *cache_y);
void fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor);
fz_irect fz_pixmap_bbox_no_ctx(const fz_pixmap *src);
void fz_decode_tile(fz_context *ctx, fz_pixmap *pix, const float *decode);
void fz_decode_indexed_tile(fz_context *ctx, fz_pixmap *pix, const float *decode, int maxval);
void fz_unpack_tile(fz_context *ctx, fz_pixmap *dst, unsigned char *src, int n, int depth, size_t stride, int scale);
void fz_md5_pixmap(fz_context *ctx, fz_pixmap *pixmap, unsigned char digest[16]);
fz_pixmap *fz_new_pixmap_from_8bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
fz_pixmap *fz_new_pixmap_from_1bpp_data(fz_context *ctx, int x, int y, int w, int h, unsigned char *sp, int span);
#ifdef HAVE_VALGRIND
int fz_valgrind_pixmap(const fz_pixmap *pix);
#else
#define fz_valgrind_pixmap(pix) do {} while (0)
#endif
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);
fz_pixmap *fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, fz_colorspace *prf, fz_color_params color_params, fz_default_colorspaces *default_cs);
#endif

View File

@ -0,0 +1,15 @@
#ifndef MUPDF_FITZ_POOL_H
#define MUPDF_FITZ_POOL_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.h"
typedef struct fz_pool_s fz_pool;
fz_pool *fz_new_pool(fz_context *ctx);
void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size);
char *fz_pool_strdup(fz_context *ctx, fz_pool *pool, const char *s);
size_t fz_pool_size(fz_context *ctx, fz_pool *pool);
void fz_drop_pool(fz_context *ctx, fz_pool *pool);
#endif

View File

@ -0,0 +1,58 @@
#ifndef MUPDF_FITZ_SEPARATION_H
#define MUPDF_FITZ_SEPARATION_H
#include "mupdf/fitz/system.h"
#include "mupdf/fitz/context.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_s 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;
fz_separations *fz_new_separations(fz_context *ctx, int controllable);
fz_separations *fz_keep_separations(fz_context *ctx, fz_separations *sep);
void fz_drop_separations(fz_context *ctx, fz_separations *sep);
void fz_add_separation(fz_context *ctx, fz_separations *sep, const char *name, fz_colorspace *cs, int cs_channel);
void fz_add_separation_equivalents(fz_context *ctx, fz_separations *sep, uint32_t rgba, uint32_t cmyk, const char *name);
void fz_set_separation_behavior(fz_context *ctx, fz_separations *sep, int separation, fz_separation_behavior behavior);
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);
int fz_count_active_separations(fz_context *ctx, const fz_separations *seps);
fz_separations *fz_clone_separations_for_overprint(fz_context *ctx, fz_separations *seps);
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);
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

View File

@ -0,0 +1,130 @@
#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_shade_s
{
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;
fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade);
void fz_drop_shade(fz_context *ctx, fz_shade *shade);
void fz_drop_shade_imp(fz_context *ctx, fz_storable *shade);
fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm);
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);
/*
* Handy routine for processing mesh based shades
*/
typedef struct fz_vertex_s fz_vertex;
struct fz_vertex_s
{
fz_point p;
float c[FZ_MAX_COLORS];
};
/*
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);
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);
#endif

View File

@ -0,0 +1,191 @@
#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"
/*
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_s fz_storable;
typedef struct fz_key_storable_s fz_key_storable;
typedef void (fz_store_drop_fn)(fz_context *, fz_storable *);
struct fz_storable_s {
int refs;
fz_store_drop_fn *drop;
};
struct fz_key_storable_s {
fz_storable storable;
short store_key_refs;
};
#define FZ_INIT_STORABLE(S_,RC,DROP) \
do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
S->drop = (DROP); \
} while (0)
#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)
void *fz_keep_storable(fz_context *, const fz_storable *);
void fz_drop_storable(fz_context *, const fz_storable *);
void *fz_keep_key_storable(fz_context *, const fz_key_storable *);
void fz_drop_key_storable(fz_context *, const fz_key_storable *);
void *fz_keep_key_storable_key(fz_context *, const fz_key_storable *);
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_hash_s
{
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; /* 24 or 28 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 */
typedef struct fz_store_type_s
{
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, int size, void *key);
int (*needs_reap)(fz_context *ctx, void *key);
} fz_store_type;
void fz_new_store_context(fz_context *ctx, size_t max);
void fz_drop_store_context(fz_context *ctx);
fz_store *fz_keep_store_context(fz_context *ctx);
void *fz_store_item(fz_context *ctx, void *key, void *val, size_t itemsize, const fz_store_type *type);
void *fz_find_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
void fz_remove_item(fz_context *ctx, fz_store_drop_fn *drop, void *key, const fz_store_type *type);
void fz_empty_store(fz_context *ctx);
int fz_store_scavenge(fz_context *ctx, size_t size, int *phase);
int fz_store_scavenge_external(fz_context *ctx, size_t size, int *phase);
int fz_shrink_store(fz_context *ctx, unsigned int percent);
typedef int (fz_store_filter_fn)(fz_context *ctx, void *arg, void *key);
void fz_filter_store(fz_context *ctx, fz_store_filter_fn *fn, void *arg, const fz_store_type *type);
void fz_debug_store(fz_context *ctx);
void fz_defer_reap_start(fz_context *ctx);
void fz_defer_reap_end(fz_context *ctx);
#endif

View File

@ -0,0 +1,367 @@
#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"
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_s fz_stream;
fz_stream *fz_open_file(fz_context *ctx, const char *filename);
fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename);
fz_stream *fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len);
fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
fz_stream *fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buf);
void fz_drop_stream(fz_context *ctx, fz_stream *stm);
int64_t fz_tell(fz_context *ctx, fz_stream *stm);
void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence);
size_t fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, size_t len);
size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len);
fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, size_t initial);
fz_buffer *fz_read_file(fz_context *ctx, const char *filename);
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);
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_s
{
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;
};
fz_stream *fz_new_stream(fz_context *ctx, void *state, fz_stream_next_fn *next, fz_stream_drop_fn *drop);
fz_stream *fz_keep_stream(fz_context *ctx, fz_stream *stm);
fz_buffer *fz_read_best(fz_context *ctx, fz_stream *stm, size_t initial, int *truncated);
char *fz_read_line(fz_context *ctx, fz_stream *stm, char *buf, size_t max);
/*
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--;
}
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;
}
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);
}
#endif

View File

@ -0,0 +1,54 @@
#ifndef MUPDF_FITZ_STRING_H
#define MUPDF_FITZ_STRING_H
#include "mupdf/fitz/system.h"
/* The Unicode character used to incoming character whose value is unknown or unrepresentable. */
#define FZ_REPLACEMENT_CHARACTER 0xFFFD
/*
Safe string functions
*/
size_t fz_strnlen(const char *s, size_t maxlen);
char *fz_strsep(char **stringp, const char *delim);
size_t fz_strlcpy(char *dst, const char *src, size_t n);
size_t fz_strlcat(char *dst, const char *src, size_t n);
void *fz_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
void fz_dirname(char *dir, const char *path, size_t dirsize);
char *fz_urldecode(char *url);
void fz_format_output_path(fz_context *ctx, char *path, size_t size, const char *fmt, int page);
char *fz_cleanname(char *name);
int fz_strcasecmp(const char *a, const char *b);
int fz_strncasecmp(const char *a, const char *b, int n);
/*
FZ_UTFMAX: Maximum number of bytes in a decoded rune (maximum length returned by fz_chartorune).
*/
enum { FZ_UTFMAX = 4 };
int fz_chartorune(int *rune, const char *str);
int fz_runetochar(char *str, int rune);
int fz_runelen(int rune);
int fz_utflen(const char *s);
float fz_strtof(const char *s, char **es);
int fz_grisu(float f, char *s, int *exp);
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);
#endif

View File

@ -0,0 +1,191 @@
#ifndef MUPDF_FITZ_STRUCTURED_TEXT_H
#define MUPDF_FITZ_STRUCTURED_TEXT_H
#include "mupdf/fitz/system.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"
/*
Simple text layout (for use with annotation editing primarily).
*/
typedef struct fz_layout_char_s fz_layout_char;
typedef struct fz_layout_line_s fz_layout_line;
typedef struct fz_layout_block_s fz_layout_block;
struct fz_layout_char_s
{
float x, w;
const char *p; /* location in source text of character */
fz_layout_char *next;
};
struct fz_layout_line_s
{
float x, y, h;
const char *p; /* location in source text of start of line */
fz_layout_char *text;
fz_layout_line *next;
};
struct fz_layout_block_s
{
fz_pool *pool;
fz_matrix matrix;
fz_matrix inv_matrix;
fz_layout_line *head, **tailp;
fz_layout_char **text_tailp;
};
fz_layout_block *fz_new_layout(fz_context *ctx);
void fz_drop_layout(fz_context *ctx, fz_layout_block *block);
void fz_add_layout_line(fz_context *ctx, fz_layout_block *block, float x, float y, float h, const char *p);
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_s fz_stext_char;
typedef struct fz_stext_line_s fz_stext_line;
typedef struct fz_stext_block_s fz_stext_block;
typedef struct fz_stext_page_s fz_stext_page;
/*
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.
*/
enum
{
FZ_STEXT_PRESERVE_LIGATURES = 1,
FZ_STEXT_PRESERVE_WHITESPACE = 2,
FZ_STEXT_PRESERVE_IMAGES = 4,
FZ_STEXT_INHIBIT_SPACES = 8,
};
/*
A text page is a list of blocks, together with an overall bounding box.
*/
struct fz_stext_page_s
{
fz_pool *pool;
fz_rect mediabox;
fz_stext_block *first_block, *last_block;
};
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_s
{
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_s
{
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_s
{
int c;
int color; /* sRGB hex color */
fz_point origin;
fz_quad quad;
float size;
fz_font *font;
fz_stext_char *next;
};
extern const char *fz_stext_options_usage;
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);
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);
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);
void fz_print_stext_page_as_xml(fz_context *ctx, fz_output *out, fz_stext_page *page, int id);
void fz_print_stext_page_as_text(fz_context *ctx, fz_output *out, fz_stext_page *page);
int fz_search_stext_page(fz_context *ctx, fz_stext_page *text, const char *needle, fz_quad *quads, int max_quads);
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);
char *fz_copy_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_point b, int crlf);
/*
Options for creating a pixmap and draw device.
*/
typedef struct fz_stext_options_s fz_stext_options;
struct fz_stext_options_s
{
int flags;
};
fz_stext_options *fz_parse_stext_options(fz_context *ctx, fz_stext_options *opts, const char *string);
fz_device *fz_new_stext_device(fz_context *ctx, fz_stext_page *page, const fz_stext_options *options);
#endif

View File

@ -0,0 +1,381 @@
#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 */
#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)
#define fz_jmp_buf sigjmp_buf
#else
#define fz_setjmp(BUF) setjmp(BUF)
#define fz_longjmp(BUF,VAL) longjmp(BUF,VAL)
#define fz_jmp_buf 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
#define hypotf _hypotf
#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
/* inline is standard in C++. For some compilers we can enable it within C too. */
#ifndef __cplusplus
#if defined (__STDC_VERSION_) && (__STDC_VERSION__ >= 199901L) /* C99 */
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) /* MSVC 9 or newer */
#define inline __inline
#elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC 3 or newer */
#define inline __inline
#else /* Unknown or ancient */
#define inline
#endif
#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
#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;
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

View File

@ -0,0 +1,82 @@
#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 fz_text_s fz_text;
typedef struct fz_text_span_s fz_text_span;
typedef struct fz_text_item_s fz_text_item;
struct fz_text_item_s
{
float x, y;
int gid; /* -1 for one gid to many ucs mappings */
int ucs; /* -1 for one ucs to many gid mappings */
};
#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_text_language_e
{
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;
struct fz_text_span_s
{
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;
fz_text_span *next;
};
struct fz_text_s
{
int refs;
fz_text_span *head, *tail;
};
fz_text *fz_new_text(fz_context *ctx);
fz_text *fz_keep_text(fz_context *ctx, const fz_text *text);
void fz_drop_text(fz_context *ctx, const fz_text *text);
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);
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);
fz_rect fz_bound_text(fz_context *ctx, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm);
fz_text_language fz_text_language_from_string(const char *str);
char *fz_string_from_text_language(char str[8], fz_text_language lang);
#endif

View File

@ -0,0 +1,35 @@
#ifndef TRACK_USAGE_H
#define TRACK_USAGE_H
#ifdef TRACK_USAGE
typedef struct track_usage_data_s {
int count;
const char *function;
int line;
const char *desc;
struct track_usage_data_s *next;
} track_usage_data_t;
#define TRACK_LABEL(A) \
do { \
static track_usage_data_t USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, A);\
} while (0)
#define TRACK_FN() \
do { \
static track_usage_data_t USAGE_DATA = { 0 };\
track_usage(&USAGE_DATA, __FILE__, __LINE__, __FUNCTION__);\
} while (0)
void track_usage(track_usage_data_t *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

Some files were not shown because too many files have changed in this diff Show More