Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 4679 → Rev 4680

/contrib/media/updf/android/AndroidManifest.xml
0,0 → 1,23
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.artifex.mupdf"
android:versionCode="1"
android:versionName="1.0">
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-sdk android:minSdkVersion="8" />
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:debuggable="true">
<activity android:name="MuPDFActivity"
android:label="@string/app_name"
android:theme="@style/Theme.NoBackground.NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
/contrib/media/updf/android/ReadMe.txt
0,0 → 1,111
To build/debug android build.
 
1) Download the android sdk, and install it. On windows I unpacked it as:
 
C:\Program Files\android-sdk-windows
 
on Macos as:
 
/Library/android-sdk-mac_x86
 
On windows add: C:/Progra~1/android-sdk-windows/tools to your path.
On linux/macos add the equivalent.
 
2) Download the android ndk, and install in. On windows I unpacked it as:
 
C:\Program Files\android-ndk-r5
 
on Macos as:
 
/Library/android-ndk-r5
 
On windows add: C:/Progra~1/android-ndk-r5 to your path. On linux/macos
add the equivalent.
 
3) On windows, to use the ndk, you *must* be running under cygwin. This means
you need to install Cygwin 1.7 or greater now.
 
In the current release of the ndk (r5), when running under cygwin, there are
bugs to do with the automatic conversion of dependencies from DOS format
paths to cygwin format paths. The 2 fixes can be found in:
 
<http://groups.google.com/group/android-ndk/msg/b385e47e1484c2d4>
 
4) Bring up a shell, and run 'android'. This will bring up a graphical
gui for the sdk. From here you can install the different SDK components
for the different flavours of android. Download them all - bandwidth and disk
space are cheap, right?
 
5) Now go to the Virtual Devices entry on the right hand side. You need to
create yourself an emulator image to use. Click 'New...' on the right hand
side and a window will appear. Fill in the entries as follows:
 
Name: FroyoEm
Target: Android 2.2 - API Level 8
SD card: Size: 1024MiB
Skin: Resolution: 480x756 (756 just fits my macbook screen, but 800 may
be 'more standard')
 
Click 'Create AVD' and wait for a minute or so while it is prepared. Now
you can exit the GUI.
 
6) Now we are ready to build mupdf for Android. Check out a copy of MuPDF
(but you've done that already, cos you're reading this, right?).
 
7) You will also need a copy of mupdf-thirdparty.zip (see the source code
link on http://mupdf.com/). Unpack the contents of this into a 'thirdparty'
directory created within the mupdf directory (i.e. at the same level as
fitz, pdf, android etc).
 
8) Finally, you will need a copy of a 'generated' directory. This is not
currently available to download. The easiest way to obtain this is to do
a standard windows or linux build of mupdf, which generates the required
files as part of the build process.
 
9) Change into the android directory, and edit local.properties into your
favourite editor. Change the sdk path there as appropriate. This should be
the only bit of localisation you need to do.
 
10) Change into the android directory (note, the android directory, NOT
the android/jni directory!), and execute (in a Cygwin window on Windows!):
 
ndk-build
 
This should build the native code portion. Then execute:
 
ant debug
 
or on windows under cygwin:
 
ant.bat debug
 
This should build the java wrapper.
 
11) Now start the emulator by executing:
 
emulator -avd FroyoEm
 
This will take a while to full start up (be patient).
 
12) We now need to give the demo file something to chew on, so let's copy
a file into the SD card image of the emulator (this should only need to be
done once). With the emulator running type:
 
adb push ../../MyTests/pdf_reference17.pdf /mnt/sdcard/Download/test.pdf
 
(where obviously ../../MyTests/pdf_reference17.pdf is altered for your
machine). (adb lives in <sdk>/platform-tools if it's not on your path).
 
13) With the emulator running (see step 11), execute
 
ant install
 
('ant.bat install' on Windows) and that will copy MuPDF into the emulator
where you can run it from the launchpad screen.
 
14) To see debug messages from the emulator (including stdout/stderr from
our app), execute:
 
adb logcat
 
Good luck!
/contrib/media/updf/android/build.properties
0,0 → 1,17
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
 
# This file is only used by the Ant script.
 
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
 
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.
 
/contrib/media/updf/android/build.sh
0,0 → 1,0
ndk-build && ant.bat install
/contrib/media/updf/android/build.xml
0,0 → 1,84
<?xml version="1.0" encoding="UTF-8"?>
<project name="MuPDF" default="help">
 
<!-- The local.properties file is created and updated by the 'android'
tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
 
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
Here are some properties you may want to change/update:
 
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
 
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
 
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
 
-->
<property file="build.properties" />
 
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
 
<!-- Custom Android task to deal with the project target, and import the
proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
</path>
 
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
 
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
 
[This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir}]
<target name="-post-compile">
</target>
-->
 
 
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
 
The rules file is imported from
<SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
 
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
 
</project>
/contrib/media/updf/android/default.properties
0,0 → 1,11
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
 
# Project target.
target=android-8
/contrib/media/updf/android/jni/Android.mk
0,0 → 1,22
LOCAL_PATH := $(call my-dir)
TOP_LOCAL_PATH := $(LOCAL_PATH)
 
MUPDF_ROOT := ..
 
include $(TOP_LOCAL_PATH)/Core.mk
include $(TOP_LOCAL_PATH)/ThirdParty.mk
 
include $(CLEAR_VARS)
 
LOCAL_C_INCLUDES := \
$(MUPDF_ROOT)/draw \
$(MUPDF_ROOT)/fitz \
$(MUPDF_ROOT)/pdf
LOCAL_CFLAGS :=
LOCAL_MODULE := mupdf
LOCAL_SRC_FILES := mupdf.c
LOCAL_STATIC_LIBRARIES := mupdfcore mupdfthirdparty
 
LOCAL_LDLIBS := -lm -llog -ljnigraphics
 
include $(BUILD_SHARED_LIBRARY)
/contrib/media/updf/android/jni/Application.mk
0,0 → 1,3
# The ARMv7 is significanly faster due to the use of the hardware FPU
APP_ABI := armeabi armeabi-v7a
APP_OPTIM := debug
/contrib/media/updf/android/jni/Core.mk
0,0 → 1,99
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
MY_ROOT := ../..
 
LOCAL_C_INCLUDES := \
../thirdparty/jbig2dec \
../thirdparty/openjpeg-1.4/libopenjpeg \
../thirdparty/jpeg-8c \
../thirdparty/zlib-1.2.5 \
../thirdparty/freetype-2.4.4/include \
../draw \
../fitz \
../pdf \
../scripts \
..
 
LOCAL_MODULE := mupdfcore
LOCAL_SRC_FILES := \
$(MY_ROOT)/fitz/base_error.c \
$(MY_ROOT)/fitz/base_geometry.c \
$(MY_ROOT)/fitz/base_getopt.c \
$(MY_ROOT)/fitz/base_hash.c \
$(MY_ROOT)/fitz/base_memory.c \
$(MY_ROOT)/fitz/base_object.c \
$(MY_ROOT)/fitz/base_string.c \
$(MY_ROOT)/fitz/base_time.c \
$(MY_ROOT)/fitz/crypt_aes.c \
$(MY_ROOT)/fitz/crypt_arc4.c \
$(MY_ROOT)/fitz/crypt_md5.c \
$(MY_ROOT)/fitz/crypt_sha2.c \
$(MY_ROOT)/fitz/dev_bbox.c \
$(MY_ROOT)/fitz/dev_list.c \
$(MY_ROOT)/fitz/dev_null.c \
$(MY_ROOT)/fitz/dev_text.c \
$(MY_ROOT)/fitz/dev_trace.c \
$(MY_ROOT)/fitz/filt_basic.c \
$(MY_ROOT)/fitz/filt_dctd.c \
$(MY_ROOT)/fitz/filt_faxd.c \
$(MY_ROOT)/fitz/filt_flate.c \
$(MY_ROOT)/fitz/filt_jbig2d.c \
$(MY_ROOT)/fitz/filt_jpxd.c \
$(MY_ROOT)/fitz/filt_lzwd.c \
$(MY_ROOT)/fitz/filt_predict.c \
$(MY_ROOT)/fitz/obj_print.c \
$(MY_ROOT)/fitz/res_colorspace.c \
$(MY_ROOT)/fitz/res_font.c \
$(MY_ROOT)/fitz/res_path.c \
$(MY_ROOT)/fitz/res_pixmap.c \
$(MY_ROOT)/fitz/res_shade.c \
$(MY_ROOT)/fitz/res_text.c \
$(MY_ROOT)/fitz/stm_buffer.c \
$(MY_ROOT)/fitz/stm_open.c \
$(MY_ROOT)/fitz/stm_read.c \
$(MY_ROOT)/draw/arch_arm.c \
$(MY_ROOT)/draw/arch_port.c \
$(MY_ROOT)/draw/draw_affine.c \
$(MY_ROOT)/draw/draw_blend.c \
$(MY_ROOT)/draw/draw_device.c \
$(MY_ROOT)/draw/draw_edge.c \
$(MY_ROOT)/draw/draw_glyph.c \
$(MY_ROOT)/draw/draw_mesh.c \
$(MY_ROOT)/draw/draw_paint.c \
$(MY_ROOT)/draw/draw_path.c \
$(MY_ROOT)/draw/draw_scale.c \
$(MY_ROOT)/draw/draw_unpack.c \
$(MY_ROOT)/pdf/pdf_annot.c \
$(MY_ROOT)/pdf/pdf_cmap.c \
$(MY_ROOT)/pdf/pdf_cmap_load.c \
$(MY_ROOT)/pdf/pdf_cmap_parse.c \
$(MY_ROOT)/pdf/pdf_cmap_table.c \
$(MY_ROOT)/pdf/pdf_colorspace.c \
$(MY_ROOT)/pdf/pdf_crypt.c \
$(MY_ROOT)/pdf/pdf_encoding.c \
$(MY_ROOT)/pdf/pdf_font.c \
$(MY_ROOT)/pdf/pdf_fontfile.c \
$(MY_ROOT)/pdf/pdf_function.c \
$(MY_ROOT)/pdf/pdf_image.c \
$(MY_ROOT)/pdf/pdf_interpret.c \
$(MY_ROOT)/pdf/pdf_lex.c \
$(MY_ROOT)/pdf/pdf_metrics.c \
$(MY_ROOT)/pdf/pdf_nametree.c \
$(MY_ROOT)/pdf/pdf_outline.c \
$(MY_ROOT)/pdf/pdf_page.c \
$(MY_ROOT)/pdf/pdf_parse.c \
$(MY_ROOT)/pdf/pdf_pattern.c \
$(MY_ROOT)/pdf/pdf_repair.c \
$(MY_ROOT)/pdf/pdf_shade.c \
$(MY_ROOT)/pdf/pdf_store.c \
$(MY_ROOT)/pdf/pdf_stream.c \
$(MY_ROOT)/pdf/pdf_type3.c \
$(MY_ROOT)/pdf/pdf_unicode.c \
$(MY_ROOT)/pdf/pdf_xobject.c \
$(MY_ROOT)/pdf/pdf_xref.c
 
LOCAL_LDLIBS := -lm -llog -ljnigraphics
 
include $(BUILD_STATIC_LIBRARY)
/contrib/media/updf/android/jni/ThirdParty.mk
0,0 → 1,153
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
MY_ROOT := ../..
 
LOCAL_C_INCLUDES := \
../thirdparty/jbig2dec \
../thirdparty/openjpeg-1.4/libopenjpeg \
../thirdparty/jpeg-8c \
../thirdparty/zlib-1.2.5 \
../thirdparty/freetype-2.4.4/include \
../scripts
 
LOCAL_CFLAGS := \
-DFT2_BUILD_LIBRARY -DDARWIN_NO_CARBON -DHAVE_STDINT_H
 
LOCAL_MODULE := mupdfthirdparty
LOCAL_SRC_FILES := \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_arith.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_arith_int.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_arith_iaid.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_huffman.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_segment.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_page.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_symbol_dict.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_text.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_generic.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_refinement.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_mmr.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_image.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_metadata.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/bio.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/cio.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/dwt.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/event.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/image.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/j2k.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/j2k_lib.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/jp2.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/jpt.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/mct.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/mqc.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/openjpeg.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/pi.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/raw.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/t1.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/t2.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/tcd.c \
$(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/tgt.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jaricom.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcapimin.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcapistd.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcarith.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jccoefct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jccolor.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcdctmgr.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jchuff.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcinit.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcmainct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcmarker.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcmaster.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcomapi.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcparam.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcprepct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jcsample.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jctrans.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdapimin.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdapistd.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdarith.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdatadst.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdatasrc.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdcoefct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdcolor.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jddctmgr.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdhuff.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdinput.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdmainct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdmarker.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdmaster.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdmerge.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdpostct.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdsample.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jdtrans.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jerror.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jfdctflt.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jfdctfst.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jfdctint.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jidctflt.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jidctfst.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jidctint.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jquant1.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jquant2.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jutils.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jmemmgr.c \
$(MY_ROOT)/thirdparty/jpeg-8c/jmemansi.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/adler32.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/compress.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/crc32.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/deflate.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/gzclose.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/gzlib.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/gzread.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/gzwrite.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/infback.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/inffast.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/inflate.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/inftrees.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/trees.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/uncompr.c \
$(MY_ROOT)/thirdparty/zlib-1.2.5/zutil.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/autofit/autofit.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftbase.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftbbox.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftbdf.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftbitmap.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftdebug.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftgasp.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftglyph.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftgxval.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftinit.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftlcdfil.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftmm.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftotval.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftpfr.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftstroke.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftsynth.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftsystem.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/fttype1.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftwinfnt.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftxf86.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/base/ftpatent.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/bdf/bdf.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/cache/ftcache.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/cff/cff.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/cid/type1cid.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/gzip/ftgzip.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/lzw/ftlzw.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/pcf/pcf.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/pfr/pfr.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/psaux/psaux.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/pshinter/pshinter.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/psnames/psnames.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/raster/raster.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/smooth/smooth.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/sfnt/sfnt.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/truetype/truetype.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/type1/type1.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/type42/type42.c \
$(MY_ROOT)/thirdparty/freetype-2.4.4/src/winfonts/winfnt.c
 
include $(BUILD_STATIC_LIBRARY)
/contrib/media/updf/android/jni/mupdf.c
0,0 → 1,212
#include <jni.h>
#include <time.h>
#include <android/log.h>
#include <android/bitmap.h>
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
#include "fitz.h"
#include "mupdf.h"
 
#define LOG_TAG "libmupdf"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
 
/* Set to 1 to enable debug log traces. */
#define DEBUG 0
 
/* Globals */
fz_colorspace *colorspace;
fz_glyph_cache *glyphcache;
pdf_xref *xref;
int pagenum = 1;
int resolution = 160;
float pageWidth = 100;
float pageHeight = 100;
fz_display_list *currentPageList;
fz_rect currentMediabox;
int currentRotate;
 
JNIEXPORT int JNICALL
Java_com_artifex_mupdf_MuPDFCore_openFile(JNIEnv * env, jobject thiz, jstring jfilename)
{
const char *filename;
char *password = "";
int accelerate = 1;
fz_error error;
int pages;
 
filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
if (filename == NULL)
{
LOGE("Failed to get filename");
return 0;
}
 
if (accelerate)
fz_accelerate();
glyphcache = fz_new_glyph_cache();
colorspace = fz_device_rgb;
 
LOGE("Opening document...");
error = pdf_open_xref(&xref, filename, password);
if (error)
{
LOGE("Cannot open document: '%s'\n", filename);
return 0;
}
 
LOGE("Loading page tree...");
error = pdf_load_page_tree(xref);
if (error)
{
LOGE("Cannot load page tree: '%s'\n", filename);
return 0;
}
pages = pdf_count_pages(xref);
LOGE("Done! %d pages", pages);
 
return pages;
}
 
JNIEXPORT void JNICALL
Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(JNIEnv *env, jobject thiz, int page)
{
float zoom;
fz_matrix ctm;
fz_bbox bbox;
fz_error error;
fz_device *dev;
pdf_page *currentPage;
 
/* In the event of an error, ensure we give a non-empty page */
pageWidth = 100;
pageHeight = 100;
 
LOGE("Goto page %d...", page);
if (currentPageList != NULL)
{
fz_free_display_list(currentPageList);
currentPageList = NULL;
}
pagenum = page;
error = pdf_load_page(&currentPage, xref, pagenum);
if (error)
return;
zoom = resolution / 72;
currentMediabox = currentPage->mediabox;
currentRotate = currentPage->rotate;
ctm = fz_translate(0, -currentMediabox.y1);
ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
ctm = fz_concat(ctm, fz_rotate(currentRotate));
bbox = fz_round_rect(fz_transform_rect(ctm, currentMediabox));
pageWidth = bbox.x1-bbox.x0;
pageHeight = bbox.y1-bbox.y0;
/* Render to list */
currentPageList = fz_new_display_list();
dev = fz_new_list_device(currentPageList);
error = pdf_run_page(xref, currentPage, dev, fz_identity);
pdf_free_page(currentPage);
if (error)
LOGE("cannot make displaylist from page %d", pagenum);
fz_free_device(dev);
}
 
JNIEXPORT float JNICALL
Java_com_artifex_mupdf_MuPDFCore_getPageWidth(JNIEnv *env, jobject thiz)
{
LOGE("PageWidth=%g", pageWidth);
return pageWidth;
}
 
JNIEXPORT float JNICALL
Java_com_artifex_mupdf_MuPDFCore_getPageHeight(JNIEnv *env, jobject thiz)
{
LOGE("PageHeight=%g", pageHeight);
return pageHeight;
}
 
JNIEXPORT jboolean JNICALL
Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bitmap,
int pageW, int pageH, int patchX, int patchY, int patchW, int patchH)
{
AndroidBitmapInfo info;
void *pixels;
int ret;
fz_error error;
fz_device *dev;
float zoom;
fz_matrix ctm;
fz_bbox bbox;
fz_pixmap *pix;
float xscale, yscale;
fz_bbox rect;
 
LOGI("In native method\n");
if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return 0;
}
 
LOGI("Checking format\n");
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return 0;
}
 
LOGI("locking pixels\n");
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return 0;
}
 
/* Call mupdf to render display list to screen */
LOGE("Rendering page=%dx%d patch=[%d,%d,%d,%d]",
pageW, pageH, patchX, patchY, patchW, patchH);
 
rect.x0 = patchX;
rect.y0 = patchY;
rect.x1 = patchX + patchW;
rect.y1 = patchY + patchH;
pix = fz_new_pixmap_with_rect_and_data(colorspace, rect, pixels);
if (currentPageList == NULL)
{
fz_clear_pixmap_with_color(pix, 0xd0);
return 0;
}
fz_clear_pixmap_with_color(pix, 0xff);
 
zoom = resolution / 72;
ctm = fz_translate(-currentMediabox.x0, -currentMediabox.y1);
ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
ctm = fz_concat(ctm, fz_rotate(currentRotate));
bbox = fz_round_rect(fz_transform_rect(ctm,currentMediabox));
/* Now, adjust ctm so that it would give the correct page width
* heights. */
xscale = (float)pageW/(float)(bbox.x1-bbox.x0);
yscale = (float)pageH/(float)(bbox.y1-bbox.y0);
ctm = fz_concat(ctm, fz_scale(xscale, yscale));
bbox = fz_round_rect(fz_transform_rect(ctm,currentMediabox));
dev = fz_new_draw_device(glyphcache, pix);
fz_execute_display_list(currentPageList, dev, ctm, bbox);
fz_free_device(dev);
fz_drop_pixmap(pix);
LOGE("Rendered");
 
AndroidBitmap_unlockPixels(env, bitmap);
 
return 1;
}
 
JNIEXPORT void JNICALL
Java_com_artifex_mupdf_MuPDFCore_destroying(JNIEnv * env, jobject thiz)
{
fz_free_display_list(currentPageList);
currentPageList = NULL;
pdf_free_xref(xref);
xref = NULL;
fz_free_glyph_cache(glyphcache);
glyphcache = NULL;
}
/contrib/media/updf/android/local.properties
0,0 → 1,2
#sdk.dir=/Library/android-sdk-mac_x86
sdk.dir=C:\\Program Files\\android-sdk-windows
/contrib/media/updf/android/res/drawable-hdpi/icon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/updf/android/res/drawable-ldpi/icon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/updf/android/res/drawable-mdpi/icon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/updf/android/res/layout/main.xml
0,0 → 1,8
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</LinearLayout>
 
/contrib/media/updf/android/res/values/strings.xml
0,0 → 1,4
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MuPDF</string>
</resources>
/contrib/media/updf/android/res/values/theme.xml
0,0 → 1,7
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.NoBackground.NoTitle" parent="android:Theme">
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
/contrib/media/updf/android/src/com/artifex/mupdf/MuPDFActivity.java
0,0 → 1,162
package com.artifex.mupdf;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.LinearLayout.*;
import java.io.File;
 
import com.artifex.mupdf.PixmapView;
 
public class MuPDFActivity extends Activity
{
/* The core rendering instance */
private MuPDFCore core;
 
private MuPDFCore openFile()
{
String storageState = Environment.getExternalStorageState();
File path, file;
MuPDFCore core;
 
if (Environment.MEDIA_MOUNTED.equals(storageState))
{
System.out.println("Media mounted read/write");
}
else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(storageState))
{
System.out.println("Media mounted read only");
}
else
{
System.out.println("No media at all! Bale!\n");
return null;
}
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
file = new File(path, "test.pdf");
System.out.println("Trying to open "+file.toString());
try
{
core = new MuPDFCore(file.toString());
}
catch (Exception e)
{
System.out.println(e);
return null;
}
return core;
}
 
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
PixmapView pixmapView;
 
if (core == null) {
core = (MuPDFCore)getLastNonConfigurationInstance();
}
if (core == null) {
core = openFile();
}
if (core == null)
{
/* FIXME: Error handling here! */
return;
}
 
pixmapView = new PixmapView(this, core);
super.onCreate(savedInstanceState);
 
/* Now create the UI */
RelativeLayout layout;
LinearLayout bar;
MyButtonHandler bh = new MyButtonHandler(pixmapView);
 
bar = new LinearLayout(this);
bar.setOrientation(LinearLayout.HORIZONTAL);
bh.buttonStart = new Button(this);
bh.buttonStart.setText("<<");
bh.buttonStart.setOnClickListener(bh);
bar.addView(bh.buttonStart);
bh.buttonPrev = new Button(this);
bh.buttonPrev.setText("<");
bh.buttonPrev.setOnClickListener(bh);
bar.addView(bh.buttonPrev);
bh.buttonNext = new Button(this);
bh.buttonNext.setText(">");
bh.buttonNext.setOnClickListener(bh);
bar.addView(bh.buttonNext);
bh.buttonEnd = new Button(this);
bh.buttonEnd.setText(">>");
bh.buttonEnd.setOnClickListener(bh);
bar.addView(bh.buttonEnd);
 
layout = new RelativeLayout(this);
layout.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
layout.setGravity(Gravity.FILL);
 
RelativeLayout.LayoutParams barParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
barParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
bar.setId(100);
layout.addView(bar, barParams);
 
RelativeLayout.LayoutParams pixmapParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
pixmapParams.addRule(RelativeLayout.ABOVE,100);
layout.addView(pixmapView, pixmapParams);
 
setContentView(layout);
}
 
public Object onRetainNonConfigurationInstance()
{
MuPDFCore mycore = core;
core = null;
return mycore;
}
 
public void onDestroy()
{
if (core != null)
core.onDestroy();
core = null;
super.onDestroy();
}
 
private class MyButtonHandler implements OnClickListener
{
Button buttonStart;
Button buttonPrev;
Button buttonNext;
Button buttonEnd;
PixmapView pixmapView;
 
public MyButtonHandler(PixmapView pixmapView)
{
this.pixmapView = pixmapView;
}
 
public void onClick(View v)
{
if (v == buttonStart)
pixmapView.changePage(Integer.MIN_VALUE);
else if (v == buttonPrev)
pixmapView.changePage(-1);
else if (v == buttonNext)
pixmapView.changePage(+1);
else if (v == buttonEnd)
pixmapView.changePage(Integer.MAX_VALUE);
}
}
}
/contrib/media/updf/android/src/com/artifex/mupdf/MuPDFCore.java
0,0 → 1,54
package com.artifex.mupdf;
import android.graphics.*;
 
public class MuPDFCore
{
/* load our native library */
static {
System.loadLibrary("mupdf");
}
 
/* Readable members */
public int pageNum;
public int numPages;
public float pageWidth;
public float pageHeight;
 
/* The native functions */
private static native int openFile(String filename);
private static native void gotoPageInternal(int localActionPageNum);
private static native float getPageWidth();
private static native float getPageHeight();
public static native void drawPage(Bitmap bitmap,
int pageW, int pageH,
int patchX, int patchY,
int patchW, int patchH);
public static native void destroying();
 
public MuPDFCore(String filename) throws Exception
{
numPages = openFile(filename);
if (numPages <= 0)
{
throw new Exception("Failed to open "+filename);
}
pageNum = 0;
}
 
/* Shim function */
public void gotoPage(int page)
{
if (page > numPages-1)
page = numPages-1;
else if (page < 0)
page = 0;
gotoPageInternal(page);
this.pageNum = page;
this.pageWidth = getPageWidth();
this.pageHeight = getPageHeight();
}
 
public void onDestroy() {
destroying();
}
}
/contrib/media/updf/android/src/com/artifex/mupdf/PixmapView.java
0,0 → 1,579
package com.artifex.mupdf;
 
import android.app.*;
import android.os.*;
import android.content.*;
import android.content.res.*;
import android.graphics.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import java.net.*;
import java.io.*;
 
public class PixmapView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private MuPDFThread thread = null;
private boolean threadStarted = false;
private MuPDFCore core;
 
/* Constructor */
public PixmapView(Context context, MuPDFCore core)
{
super(context);
System.out.println("PixmapView construct");
this.core = core;
holder = getHolder();
holder.addCallback(this);
thread = new MuPDFThread(holder, core);
setFocusable(true); // need to get the key events
}
 
/* load our native library */
static {
System.loadLibrary("mupdf");
}
 
/* Handlers for keys - so we can actually do stuff */
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (thread.onKeyDown(keyCode, event))
return true;
return super.onKeyDown(keyCode, event);
}
 
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (thread.onKeyUp(keyCode, event))
return true;
return super.onKeyUp(keyCode, event);
}
 
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (thread.onTouchEvent(event))
return true;
return super.onTouchEvent(event);
}
 
public void changePage(int delta)
{
thread.changePage(delta);
}
 
/* Handlers for SurfaceHolder callbacks; these are called when the
* surface is created/destroyed/changed. We need to ensure that we only
* draw into the surface between the created and destroyed calls.
* Therefore, we start/stop the thread that actually runs MuPDF on
* creation/destruction. */
public void surfaceCreated(SurfaceHolder holder)
{
}
 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
thread.newScreenSize(width, height);
if (!threadStarted)
{
threadStarted = true;
thread.setRunning(true);
thread.start();
}
}
 
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
System.out.println("Surface destroyed 1 this="+this);
thread.setRunning(false);
System.out.println("Surface destroyed 2");
while (retry)
{
try
{
thread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
threadStarted = false;
System.out.println("Surface destroyed 3");
}
 
class MuPDFThread extends Thread
{
private SurfaceHolder holder;
private boolean running = false;
private int keycode = -1;
private int screenWidth;
private int screenHeight;
private int screenGeneration;
private Bitmap bitmap;
private MuPDFCore core;
 
/* The following variables deal with the size of the current page;
* specifically, its position on the screen, its raw size, its
* current scale, and its current scaled size (in terms of whole
* pixels).
*/
private int pageOriginX;
private int pageOriginY;
private float pageScale;
private int pageWidth;
private int pageHeight;
 
/* The following variables deal with the multitouch handling */
private final int NONE = 0;
private final int DRAG = 1;
private final int ZOOM = 2;
private int touchMode = NONE;
private float touchInitialSpacing;
private float touchDragStartX;
private float touchDragStartY;
private float touchInitialOriginX;
private float touchInitialOriginY;
private float touchInitialScale;
private PointF touchZoomMidpoint;
 
/* The following control the inner loop; other events etc cause
* action to be set. The inner loop runs around a tight loop
* performing the action requested of it.
*/
private boolean wakeMe = false;
private int action;
private final int SLEEP = 0;
private final int REDRAW = 1;
private final int DIE = 2;
private final int GOTOPAGE = 3;
private int actionPageNum;
 
/* Members for blitting, declared here to avoid causing gcs */
private Rect srcRect;
private RectF dstRect;
 
public MuPDFThread(SurfaceHolder holder, MuPDFCore core)
{
this.holder = holder;
this.core = core;
touchZoomMidpoint = new PointF(0,0);
srcRect = new Rect(0,0,0,0);
dstRect = new RectF(0,0,0,0);
}
 
public void setRunning(boolean running)
{
this.running = running;
if (!running)
{
System.out.println("killing 1");
synchronized(this)
{
System.out.println("killing 2");
action = DIE;
if (wakeMe)
{
wakeMe = false;
System.out.println("killing 3");
this.notify();
System.out.println("killing 4");
}
}
}
}
 
public void newScreenSize(int width, int height)
{
this.screenWidth = width;
this.screenHeight = height;
this.screenGeneration++;
}
 
public boolean onKeyDown(int keyCode, KeyEvent msg)
{
keycode = keyCode;
return false;
}
 
public boolean onKeyUp(int keyCode, KeyEvent msg)
{
return false;
}
 
public synchronized void changePage(int delta)
{
action = GOTOPAGE;
if (delta == Integer.MIN_VALUE)
actionPageNum = 0;
else if (delta == Integer.MAX_VALUE)
actionPageNum = core.numPages-1;
else
{
actionPageNum += delta;
if (actionPageNum < 0)
actionPageNum = 0;
if (actionPageNum > core.numPages-1)
actionPageNum = core.numPages-1;
}
if (wakeMe)
{
wakeMe = false;
this.notify();
}
}
 
private float spacing(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x*x+y*y);
}
 
private void midpoint(PointF point, MotionEvent event)
{
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x/2, y/2);
}
 
private synchronized void forceRedraw()
{
if (wakeMe)
{
wakeMe = false;
this.notify();
}
action = REDRAW;
}
 
public synchronized void setPageOriginTo(int x, int y)
{
/* Adjust the coordinates so that the page always covers the
* centre of the screen. */
if (x + pageWidth < screenWidth/2)
{
x = screenWidth/2 - pageWidth;
}
else if (x > screenWidth/2)
{
x = screenWidth/2;
}
if (y + pageHeight < screenHeight/2)
{
y = screenHeight/2 - pageHeight;
}
else if (y > screenHeight/2)
{
y = screenHeight/2;
}
if ((x != pageOriginX) || (y != pageOriginY))
{
pageOriginX = x;
pageOriginY = y;
}
forceRedraw();
}
 
public void setPageScaleTo(float scale, PointF midpoint)
{
float x, y;
/* Convert midpoint (in screen coords) to page coords */
x = (midpoint.x - pageOriginX)/pageScale;
y = (midpoint.y - pageOriginY)/pageScale;
/* Find new scaled page sizes */
synchronized(this)
{
pageWidth = (int)(core.pageWidth*scale+0.5);
if (pageWidth < screenWidth/2)
{
scale = screenWidth/2/core.pageWidth;
pageWidth = (int)(core.pageWidth*scale+0.5);
}
pageHeight = (int)(core.pageHeight*scale+0.5);
if (pageHeight < screenHeight/2)
{
scale = screenHeight/2/core.pageHeight;
pageWidth = (int)(core.pageWidth *scale+0.5);
pageHeight = (int)(core.pageHeight*scale+0.5);
}
pageScale = scale;
/* Now given this new scale, calculate page origins so that
* x and y are at midpoint */
float xscale = (float)pageWidth /core.pageWidth;
float yscale = (float)pageHeight/core.pageHeight;
setPageOriginTo((int)(midpoint.x - x*xscale + 0.5),
(int)(midpoint.y - y*yscale + 0.5));
}
}
 
public void scalePageToScreen()
{
float scaleX, scaleY;
scaleX = (float)screenWidth /core.pageWidth;
scaleY = (float)screenHeight/core.pageHeight;
synchronized(this)
{
if (scaleX < scaleY)
pageScale = scaleX;
else
pageScale = scaleY;
pageWidth = (int)(core.pageWidth * pageScale + 0.5);
pageHeight = (int)(core.pageHeight * pageScale + 0.5);
pageOriginX = (screenWidth - pageWidth)/2;
pageOriginY = (screenHeight - pageHeight)/2;
forceRedraw();
}
System.out.println("scalePageToScreen: Raw="+
core.pageWidth+"x"+core.pageHeight+" scaled="+
pageWidth+","+pageHeight+" pageScale="+
pageScale);
}
 
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
boolean done = false;
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
touchMode = DRAG;
touchDragStartX = event.getX();
touchDragStartY = event.getY();
touchInitialOriginX = pageOriginX;
touchInitialOriginY = pageOriginY;
System.out.println("Starting dragging from: "+touchDragStartX+","+touchDragStartY+" ("+pageOriginX+","+pageOriginY+")");
done = true;
break;
case MotionEvent.ACTION_POINTER_DOWN:
touchInitialSpacing = spacing(event);
if (touchInitialSpacing > 10f)
{
System.out.println("Started zooming: spacing="+touchInitialSpacing);
touchInitialScale = pageScale;
touchMode = ZOOM;
done = true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (touchMode != NONE)
{
System.out.println("Released!");
touchMode = NONE;
done = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (touchMode == DRAG)
{
float x = touchInitialOriginX+event.getX()-touchDragStartX;
float y = touchInitialOriginY+event.getY()-touchDragStartY;
System.out.println("Dragged to "+x+","+y);
setPageOriginTo((int)(x+0.5),(int)(y+0.5));
done = true;
}
else if (touchMode == ZOOM)
{
float newSpacing = spacing(event);
if (newSpacing > 10f)
{
float newScale = touchInitialScale*newSpacing/touchInitialSpacing;
System.out.println("Zoomed to "+newSpacing);
midpoint(touchZoomMidpoint,event);
setPageScaleTo(newScale,touchZoomMidpoint);
done = true;
}
}
}
return done;
}
 
public void run()
{
boolean redraw = false;
int patchW = 0;
int patchH = 0;
int patchX = 0;
int patchY = 0;
int localPageW = 0;
int localPageH = 0;
int localScreenGeneration = screenGeneration;
int localAction;
int localActionPageNum = core.pageNum;
 
/* Set up our default action */
action = GOTOPAGE;
actionPageNum = core.pageNum;
while (action != DIE)
{
synchronized(this)
{
while (action == SLEEP)
{
wakeMe = true;
try
{
System.out.println("Render thread sleeping");
this.wait();
System.out.println("Render thread woken");
}
catch (java.lang.InterruptedException e)
{
System.out.println("Render thread exception:"+e);
}
}
 
/* Now we do as little as we can get away with while
* synchronised. In general this means copying any action
* or global variables into local ones so that when we
* unsynchronoise, other people can alter them again.
*/
switch (action)
{
case DIE:
System.out.println("Woken to die!");
break;
case GOTOPAGE:
localActionPageNum = actionPageNum;
break;
case REDRAW:
/* Figure out what area of the page we want to
* redraw (in local variables, in docspace).
* We'll always draw a screensized lump, unless
* that's too big. */
System.out.println("page="+pageWidth+","+pageHeight+" ("+core.pageWidth+","+core.pageHeight+"@"+pageScale+") @ "+pageOriginX+","+pageOriginY);
localPageW = pageWidth;
localPageH = pageHeight;
patchW = pageWidth;
patchH = pageHeight;
patchX = -pageOriginX;
patchY = -pageOriginY;
if (patchX < 0)
patchX = 0;
if (patchW > screenWidth)
patchW = screenWidth;
srcRect.left = 0;
if (patchX+patchW > pageWidth)
{
srcRect.left += patchX+patchW-pageWidth;
patchX = pageWidth-patchW;
}
if (patchY < 0)
patchY = 0;
if (patchH > screenHeight)
patchH = screenHeight;
srcRect.top = 0;
if (patchY+patchH > pageHeight)
{
srcRect.top += patchY+patchH-pageHeight;
patchY = pageHeight-patchH;
}
dstRect.left = pageOriginX;
if (dstRect.left < 0)
dstRect.left = 0;
dstRect.top = pageOriginY;
if (dstRect.top < 0)
dstRect.top = 0;
dstRect.right = dstRect.left + patchW;
srcRect.right = srcRect.left + patchW;
if (srcRect.right > screenWidth)
{
dstRect.right -= srcRect.right-screenWidth;
srcRect.right = screenWidth;
}
if (dstRect.right > screenWidth)
{
srcRect.right -= dstRect.right-screenWidth;
dstRect.right = screenWidth;
}
dstRect.bottom = dstRect.top + patchH;
srcRect.bottom = srcRect.top + patchH;
if (srcRect.bottom > screenHeight)
{
dstRect.bottom -=srcRect.bottom-screenHeight;
srcRect.bottom = screenHeight;
}
if (dstRect.bottom > screenHeight)
{
srcRect.bottom -=dstRect.bottom-screenHeight;
dstRect.bottom = screenHeight;
}
System.out.println("patch=["+patchX+","+patchY+","+patchW+","+patchH+"]");
break;
}
localAction = action;
if (action != DIE)
action = SLEEP;
}
 
/* In the redraw case:
* pW, pH, pX, pY, localPageW, localPageH are now all set
* in local variables, and we are safe from the global vars
* being altered in calls from other threads. This is all
* the information we need to actually do our render.
*/
switch (localAction)
{
case GOTOPAGE:
core.gotoPage(localActionPageNum);
scalePageToScreen();
action = REDRAW;
break;
case REDRAW:
if ((bitmap == null) ||
(bitmap.getWidth() != patchW) ||
(bitmap.getHeight() != patchH))
{
/* make bitmap of required size */
bitmap = Bitmap.createBitmap(patchW, patchH, Bitmap.Config.ARGB_8888);
}
System.out.println("Calling redraw native method");
core.drawPage(bitmap, localPageW, localPageH, patchX, patchY, patchW, patchH);
System.out.println("Called native method");
{
Canvas c = null;
try
{
c = holder.lockCanvas(null);
synchronized(holder)
{
if (localScreenGeneration == screenGeneration)
{
doDraw(c);
}
else
{
/* Someone has changed the screen
* under us! Better redraw again...
*/
action = REDRAW;
}
}
}
finally
{
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
}
}
}
 
protected void doDraw(Canvas canvas)
{
if ((canvas == null) || (bitmap == null))
return;
/* Clear the screen */
canvas.drawRGB(128,128,128);
/* Draw our bitmap on top */
System.out.println("Blitting bitmap from "+srcRect.left+","+srcRect.top+","+srcRect.right+","+srcRect.bottom+" to "+dstRect.left+","+dstRect.top+","+dstRect.right+","+dstRect.bottom);
canvas.drawBitmap(bitmap, srcRect, dstRect, (Paint)null);
}
}
}