summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2013-06-19 15:29:44 +0200
committerTor Andersson <tor.andersson@artifex.com>2013-06-20 16:45:35 +0200
commit0a927854a10e1e6b9770a81e2e1d9f3093631757 (patch)
tree3d65d820d9fdba2d0d394d99c36290c851b78ca0 /platform
parent1ae8f19179c5f0f8c6352b3c7855465325d5449a (diff)
downloadmupdf-0a927854a10e1e6b9770a81e2e1d9f3093631757.tar.xz
Rearrange source files.
Diffstat (limited to 'platform')
-rw-r--r--platform/android/AndroidManifest.xml86
-rw-r--r--platform/android/ClassStructure.txt187
-rw-r--r--platform/android/Icons.txt2
-rw-r--r--platform/android/ReadMe.txt198
-rw-r--r--platform/android/build.sh1
-rw-r--r--platform/android/build.xml85
-rw-r--r--platform/android/jni/Android.mk35
-rw-r--r--platform/android/jni/Application.mk48
-rw-r--r--platform/android/jni/Core.mk162
-rw-r--r--platform/android/jni/Core2.mk45
-rw-r--r--platform/android/jni/ThirdParty.mk132
-rw-r--r--platform/android/jni/mupdf.c2389
-rw-r--r--platform/android/local.properties.sample8
-rw-r--r--platform/android/project.properties11
-rw-r--r--platform/android/res/animator/info.xml20
-rw-r--r--platform/android/res/drawable-hdpi/icon.pngbin0 -> 4791 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_annot.pngbin0 -> 311 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_annotation.pngbin0 -> 480 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_arrow_left.pngbin0 -> 204 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_arrow_right.pngbin0 -> 208 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_cancel.pngbin0 -> 204 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_check.pngbin0 -> 213 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_clipboard.pngbin0 -> 1309 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_dir.pngbin0 -> 157 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_doc.pngbin0 -> 1262 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_highlight.pngbin0 -> 378 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_link.pngbin0 -> 342 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_list.pngbin0 -> 2821 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_magnifying_glass.pngbin0 -> 323 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_more.pngbin0 -> 533 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_pen.pngbin0 -> 257 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_print.pngbin0 -> 1248 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_reflow.pngbin0 -> 220 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_select.pngbin0 -> 247 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_strike.pngbin0 -> 449 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_trash.pngbin0 -> 246 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_underline.pngbin0 -> 403 bytes
-rw-r--r--platform/android/res/drawable-ldpi/ic_updir.pngbin0 -> 268 bytes
-rw-r--r--platform/android/res/drawable-ldpi/icon.pngbin0 -> 2158 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_annot.pngbin0 -> 418 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_annotation.pngbin0 -> 601 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_arrow_left.pngbin0 -> 225 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_arrow_right.pngbin0 -> 233 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_arrow_up.pngbin0 -> 297 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_cancel.pngbin0 -> 224 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_check.pngbin0 -> 251 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_clipboard.pngbin0 -> 1345 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_dir.pngbin0 -> 165 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_doc.pngbin0 -> 1277 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_highlight.pngbin0 -> 524 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_link.pngbin0 -> 374 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_list.pngbin0 -> 2791 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_magnifying_glass.pngbin0 -> 386 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_more.pngbin0 -> 671 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_pen.pngbin0 -> 282 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_print.pngbin0 -> 1250 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_reflow.pngbin0 -> 234 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_select.pngbin0 -> 280 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_strike.pngbin0 -> 622 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_trash.pngbin0 -> 291 bytes
-rw-r--r--platform/android/res/drawable-mdpi/ic_underline.pngbin0 -> 565 bytes
-rw-r--r--platform/android/res/drawable-mdpi/icon.pngbin0 -> 3009 bytes
-rw-r--r--platform/android/res/drawable-xhdpi/icon.pngbin0 -> 6413 bytes
-rw-r--r--platform/android/res/drawable/busy.xml10
-rw-r--r--platform/android/res/drawable/button.xml23
-rw-r--r--platform/android/res/drawable/darkdenim3.pngbin0 -> 22532 bytes
-rw-r--r--platform/android/res/drawable/page_num.xml9
-rw-r--r--platform/android/res/drawable/search.xml37
-rw-r--r--platform/android/res/drawable/seek_progress.xml6
-rw-r--r--platform/android/res/drawable/seek_thumb.xml7
-rw-r--r--platform/android/res/drawable/tiled_background.xml4
-rw-r--r--platform/android/res/layout/buttons.xml385
-rw-r--r--platform/android/res/layout/main.xml5
-rw-r--r--platform/android/res/layout/outline_entry.xml27
-rw-r--r--platform/android/res/layout/picker_entry.xml25
-rw-r--r--platform/android/res/layout/print_dialog.xml9
-rw-r--r--platform/android/res/layout/textentry.xml8
-rw-r--r--platform/android/res/values-ar/strings.xml54
-rw-r--r--platform/android/res/values-ca/strings.xml54
-rw-r--r--platform/android/res/values-cs/strings.xml54
-rw-r--r--platform/android/res/values-da/strings.xml54
-rw-r--r--platform/android/res/values-de/strings.xml54
-rw-r--r--platform/android/res/values-el/strings.xml54
-rw-r--r--platform/android/res/values-es/strings.xml54
-rw-r--r--platform/android/res/values-et/strings.xml54
-rw-r--r--platform/android/res/values-fi/strings.xml54
-rw-r--r--platform/android/res/values-fr/strings.xml54
-rw-r--r--platform/android/res/values-hi/strings.xml54
-rw-r--r--platform/android/res/values-hu/strings.xml54
-rw-r--r--platform/android/res/values-in/strings.xml54
-rw-r--r--platform/android/res/values-it/strings.xml54
-rw-r--r--platform/android/res/values-iw/strings.xml54
-rw-r--r--platform/android/res/values-ja/strings.xml54
-rw-r--r--platform/android/res/values-ko/strings.xml54
-rw-r--r--platform/android/res/values-lt/strings.xml54
-rw-r--r--platform/android/res/values-ms/strings.xml54
-rw-r--r--platform/android/res/values-nl/strings.xml54
-rw-r--r--platform/android/res/values-no/strings.xml54
-rw-r--r--platform/android/res/values-pl/strings.xml54
-rw-r--r--platform/android/res/values-pt/strings.xml54
-rw-r--r--platform/android/res/values-ru/strings.xml54
-rw-r--r--platform/android/res/values-sk/strings.xml54
-rw-r--r--platform/android/res/values-sv/strings.xml54
-rw-r--r--platform/android/res/values-th/strings.xml54
-rw-r--r--platform/android/res/values-tl/strings.xml54
-rw-r--r--platform/android/res/values-tr/strings.xml54
-rw-r--r--platform/android/res/values-zh-rTW/strings.xml54
-rw-r--r--platform/android/res/values-zh/strings.xml54
-rw-r--r--platform/android/res/values/colors.xml16
-rw-r--r--platform/android/res/values/strings.xml56
-rw-r--r--platform/android/res/values/styles.xml5
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/Annotation.java18
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/ArrayDeque.java855
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/AsyncTask.java670
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java25
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/ChoosePDFActivity.java195
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/ChoosePDFAdapter.java66
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/ChoosePDFItem.java15
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/Deque.java554
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/LinkInfo.java14
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/LinkInfoExternal.java14
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/LinkInfoInternal.java14
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/LinkInfoRemote.java18
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/LinkInfoVisitor.java7
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java1090
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFAlert.java21
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFAlertInternal.java30
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java300
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java72
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java502
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java261
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java43
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java176
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/MuPDFView.java32
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/OutlineActivity.java31
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/OutlineActivityData.java17
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/OutlineAdapter.java46
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/OutlineItem.java14
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/PageView.java704
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/PrintDialogActivity.java145
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/ReaderView.java803
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/SafeAnimatorInflater.java37
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/SearchTask.java128
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/SearchTaskResult.java24
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/TextChar.java12
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/TextWord.java17
-rw-r--r--platform/android/src/com/artifex/mupdfdemo/WidgetType.java8
-rw-r--r--platform/debian/changelog41
-rw-r--r--platform/debian/compat1
-rw-r--r--platform/debian/control38
-rw-r--r--platform/debian/copyright63
-rw-r--r--platform/debian/dirs3
-rw-r--r--platform/debian/libmupdf-dev.install3
-rw-r--r--platform/debian/mupdf-tools.docs1
-rw-r--r--platform/debian/mupdf-tools.install2
-rw-r--r--platform/debian/mupdf-tools.manpages2
-rw-r--r--platform/debian/mupdf.applications7
-rw-r--r--platform/debian/mupdf.desktop15
-rw-r--r--platform/debian/mupdf.docs1
-rw-r--r--platform/debian/mupdf.install5
-rw-r--r--platform/debian/mupdf.manpages1
-rw-r--r--platform/debian/mupdf.menu8
-rw-r--r--platform/debian/mupdf.mime2
-rw-r--r--platform/debian/mupdf.pc12
-rw-r--r--platform/debian/mupdf.pngbin0 -> 3009 bytes
-rw-r--r--platform/debian/mupdf.xpm497
-rwxr-xr-xplatform/debian/rules49
-rw-r--r--platform/ios/About.xpsbin0 -> 76673 bytes
-rw-r--r--platform/ios/Default-568h@2x.pngbin0 -> 18594 bytes
-rw-r--r--platform/ios/Icon-72.pngbin0 -> 4080 bytes
-rw-r--r--platform/ios/Icon-72@2x.pngbin0 -> 9264 bytes
-rw-r--r--platform/ios/Icon.pngbin0 -> 3062 bytes
-rw-r--r--platform/ios/Icon@2x.pngbin0 -> 7891 bytes
-rw-r--r--platform/ios/Info.plist135
-rw-r--r--platform/ios/MuPDF.xcodeproj/project.pbxproj357
-rw-r--r--platform/ios/build_libs.sh37
-rw-r--r--platform/ios/iTunesArtwork.pngbin0 -> 72576 bytes
-rw-r--r--platform/ios/main.m1661
-rw-r--r--platform/ios/x_alt_blue.pngbin0 -> 344 bytes
-rw-r--r--platform/ios/x_alt_blue@2x.pngbin0 -> 534 bytes
-rw-r--r--platform/win32/README.txt1
-rw-r--r--platform/win32/generate.bat45
-rw-r--r--platform/win32/generated.vcproj830
-rw-r--r--platform/win32/libmupdf-nov8.vcproj220
-rw-r--r--platform/win32/libmupdf-v8.vcproj232
-rw-r--r--platform/win32/libmupdf.vcproj1003
-rw-r--r--platform/win32/libthirdparty.vcproj1108
-rw-r--r--platform/win32/mudraw.vcproj246
-rw-r--r--platform/win32/mujstest-v8.vcproj433
-rw-r--r--platform/win32/mupdf-v8.vcproj437
-rw-r--r--platform/win32/mupdf.sln166
-rw-r--r--platform/win32/mupdf.vcproj429
-rw-r--r--platform/win32/mutool.vcproj266
-rw-r--r--platform/winrt/README.txt39
-rw-r--r--platform/winrt/generate.bat45
-rw-r--r--platform/winrt/generated.vcxproj319
-rw-r--r--platform/winrt/generated.vcxproj.filters568
-rw-r--r--platform/winrt/libmupdf-nov8_winRT.vcxproj297
-rw-r--r--platform/winrt/libmupdf-nov8_winRT.vcxproj.filters13
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj430
-rw-r--r--platform/winrt/libmupdf_winRT.vcxproj.filters399
-rw-r--r--platform/winrt/libthirdparty_winRT.vcxproj524
-rw-r--r--platform/winrt/libthirdparty_winRT.vcxproj.filters684
-rw-r--r--platform/winrt/mupdf.sln266
-rw-r--r--platform/winrt/mupdf_cpp/App.xaml20
-rw-r--r--platform/winrt/mupdf_cpp/App.xaml.cpp125
-rw-r--r--platform/winrt/mupdf_cpp/App.xaml.h24
-rw-r--r--platform/winrt/mupdf_cpp/Assets/Logo.Scale-100.pngbin0 -> 14183 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/Logo.Scale-140.pngbin0 -> 19150 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/Logo.Scale-180.pngbin0 -> 24211 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/Logo.Scale-80.pngbin0 -> 11656 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-100.pngbin0 -> 5816 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-140.pngbin0 -> 7512 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-180.pngbin0 -> 9262 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/WideLogo.scale-100.pngbin0 -> 30014 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/WideLogo.scale-140.pngbin0 -> 51342 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/WideLogo.scale-180.pngbin0 -> 68929 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/WideLogo.scale-80.pngbin0 -> 22486 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/mupdf_smallogo.pngbin0 -> 4299 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Assets/mupdf_splash.pngbin0 -> 28390 bytes
-rw-r--r--platform/winrt/mupdf_cpp/Common/StandardStyles.xaml1889
-rw-r--r--platform/winrt/mupdf_cpp/DocumentPage.cpp15
-rw-r--r--platform/winrt/mupdf_cpp/DocumentPage.h195
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml276
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.cpp1479
-rw-r--r--platform/winrt/mupdf_cpp/MainPage.xaml.h177
-rw-r--r--platform/winrt/mupdf_cpp/Package.appxmanifest37
-rw-r--r--platform/winrt/mupdf_cpp/RectList.cpp9
-rw-r--r--platform/winrt/mupdf_cpp/RectList.h153
-rw-r--r--platform/winrt/mupdf_cpp/mupdf_cpp.rcbin0 -> 2664 bytes
-rw-r--r--platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj269
-rw-r--r--platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj.filters72
-rw-r--r--platform/winrt/mupdf_cpp/pch.cpp6
-rw-r--r--platform/winrt/mupdf_cpp/pch.h9
-rw-r--r--platform/winrt/mupdfwinrt/Cache.cpp114
-rw-r--r--platform/winrt/mupdfwinrt/Cache.h34
-rw-r--r--platform/winrt/mupdfwinrt/ContentItem.cpp11
-rw-r--r--platform/winrt/mupdfwinrt/ContentItem.h58
-rw-r--r--platform/winrt/mupdfwinrt/Links.cpp12
-rw-r--r--platform/winrt/mupdfwinrt/Links.h88
-rw-r--r--platform/winrt/mupdfwinrt/muctx.cpp569
-rw-r--r--platform/winrt/mupdfwinrt/muctx.h99
-rw-r--r--platform/winrt/mupdfwinrt/mudocument.cpp320
-rw-r--r--platform/winrt/mupdfwinrt/mudocument.h50
-rw-r--r--platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj248
-rw-r--r--platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj.filters28
-rw-r--r--platform/winrt/mupdfwinrt/pch.cpp6
-rw-r--r--platform/winrt/mupdfwinrt/pch.h6
-rw-r--r--platform/winrt/mupdfwinrt/utils.cpp28
-rw-r--r--platform/winrt/mupdfwinrt/utils.h7
-rw-r--r--platform/x11/jstest_main.c424
-rw-r--r--platform/x11/mupdf.icobin0 -> 15086 bytes
-rw-r--r--platform/x11/pdfapp.c1545
-rw-r--r--platform/x11/pdfapp.h149
-rw-r--r--platform/x11/win_main.c1163
-rw-r--r--platform/x11/win_res.rc82
-rw-r--r--platform/x11/x11_image.c703
-rw-r--r--platform/x11/x11_main.c993
258 files changed, 36126 insertions, 0 deletions
diff --git a/platform/android/AndroidManifest.xml b/platform/android/AndroidManifest.xml
new file mode 100644
index 00000000..040663e4
--- /dev/null
+++ b/platform/android/AndroidManifest.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.artifex.mupdfdemo"
+ android:versionCode="50"
+ android:versionName="@string/version"
+ android:installLocation="auto">
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <supports-screens
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:largeScreens="true"
+ android:anyDensity="true" />
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/icon"
+ android:hardwareAccelerated="true">
+ <activity
+ android:name="ChoosePDFActivity"
+ android:theme="@android:style/Theme.Light"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="MuPDFActivity"
+ android:theme="@style/AppBaseTheme"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:mimeType="application/vnd.ms-xpsdocument"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:mimeType="application/pdf"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:mimeType="application/x-cbz"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="file"/>
+ <data android:mimeType="*/*"/>
+ <data android:pathPattern=".*\\.xps"/>
+ <data android:host="*"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="file"/>
+ <data android:mimeType="*/*"/>
+ <data android:pathPattern=".*\\.pdf"/>
+ <data android:host="*"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="file"/>
+ <data android:mimeType="*/*"/>
+ <data android:pathPattern=".*\\.cbz"/>
+ <data android:host="*"/>
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="OutlineActivity"
+ android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
+ android:label="@string/outline_title">
+ </activity>
+ <activity
+ android:name="PrintDialogActivity"
+ android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
+ android:label="@string/print">
+ </activity>
+ </application>
+</manifest>
diff --git a/platform/android/ClassStructure.txt b/platform/android/ClassStructure.txt
new file mode 100644
index 00000000..39939674
--- /dev/null
+++ b/platform/android/ClassStructure.txt
@@ -0,0 +1,187 @@
+MuPDFActivity
+~~~~~~~~~~~~~
+
+MuPDFActivity is the main activity used when displaying and interacting with a
+document. This class is responsible for creating the view hierarchy and the
+menus.
+
+
+Main view classes
+~~~~~~~~~~~~~~~~~
+
+ReaderView
+~~~~~~~~~~
+MuPDF uses Android's standard Adapter/AdapterView paradigm, where a subclass of
+BaseAdapter supplies multiple views that have their motion on screen
+choreographed by a subclass of AdapterView. There are several standard
+AdapterView subclasses, but none support zooming into a specific subview and
+then panning within it, so MuPDF has its own AdapterView subclass, namely
+ReaderView. The class is intended to be general purpose and usable within any
+document-viewing application. During page viewing, ReaderView handles all touch
+events, recognises gestures and positions the displayed document pages
+accordingly. ReaderView needs to handle positioning slightly differently
+depending on whether MuPDF is reflowing text or not, and so it has two slightly
+different modes of operation.
+
+MuPDFReaderView
+~~~~~~~~~~~~~~~
+MuPDFReaderView subclasses ReaderView, so as to provide some of the
+page-positioning behaviour that is specific to MuPDF. It overrides some of the
+gesture recognition methods of ReaderView, so that it can perform special
+handling of (e.g.) tapping on the side of the screen for page progression, and
+tapping on links or form fields. It also handles the disabling of scrolling
+during text-selection and annotation-drawing, and it performs the setup
+operations needed by the individual page views as each newly appears.
+
+MuPDFView
+~~~~~~~~~
+Document viewing uses different View subclasses to display the individual pages
+depending on whether reflowing text or displaying pages unaltered. MuPDFView is
+the common interface to the two view subclasses.
+
+PageView
+~~~~~~~~
+PageView is the main View class used for non-reflow display of a page. Like
+ReaderView, it is intended to be, as much as is possible, independent of the
+specifics of MuPDF and usable in general document display apps. It is a
+subclass of ViewGroup because page displays are built from several layers. The
+lowest layer is a rendering of the page at a resolution that matches the screen
+exactly when maximally zoomed out so that the page fits the screen. As the user
+zooms in, this layer maintains a visible appearance of the page, but one that
+becomes more blurred as zooming in progresses. A second layer provides a higher
+resolution rendering of just the area of the page that is visible on screen,
+and at a resolution that matches the screen. As the user pans, this layer is
+updated on a background thread, so parts of the blurred layer will temporarily
+become visible, but only momentarily later to be replaced by the high-quality
+rendering. There is one further layer that is used to draw transparent shapes
+for highlighting and the like.
+
+MuPDFPageView
+~~~~~~~~~~~~~
+MuPDFPageView is a subclass of PageView, which handles some of the specifics of
+MuPDF's behaviour, such as taps on links and form fields, text selection, and
+annotation drawing. It also handles its parent class's bitmap rendering calls.
+This is the class used to display pages in non-reflow mode. It implements the
+MuPDFView interface.
+
+MuPDFReflowView
+~~~~~~~~~~~~~~~
+This is the class used to display pages in reflow mode. Like MuPDFPageView it
+implements the MuPDFView interface. It is a subclass of WebView, and achieves
+reflowing by loading an HTML version of the page, which the MuPDF core
+constructs.
+
+MuPDFPageAdapter and MuPDFReflowAdapter
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As with any AdapterView subclass, ReaderView needs an Adapter subclass to
+supply, on demand, the subviews for the pages currently displayed. These are
+the two Adapter subclasses, supplying the subviews as MuPDFPageView and
+MuPDFReflowView objects respectively. The former is a little more complex than
+the latter, since it caches the sizes of the pages corresponding to the views
+it supplies. It does so, so that page views, on their second and subsequent
+appearances, can take on their correct size immediately. (The determining of
+page size is not a completely trivial operation and is performed on a
+background thread, as is all interaction with the core MuPDF library).
+
+
+C library wrapper
+~~~~~~~~~~~~~~~~~
+
+MuPDFCore
+~~~~~~~~~
+This class is the interface to the MuPDF C library. It is used to render bitmap
+versions of the page for display in the view classes mentioned above. It also
+provides for interaction with objects within the page, such as the individual
+text objects and annotations. Many of the methods take too long an execution
+time to be run on the UI thread, hence they need to be run in the background,
+and because even the fast methods have to be synchronised with the slower
+methods, (almost) all methods should be called in the background. There are a
+few non synchronised ones that have special purposes.
+
+
+Link handling
+~~~~~~~~~~~~~
+There are three types of PDF links, each entailing different information and
+requiring different handling. There are five classes involved in their
+representation.
+
+LinkInfo is the base class representing any one of the three
+
+LinkInfoExternal, LinkInfoInternal and LinkInfoRemote are the three subclasses
+representing the specific cases.
+
+LinkInfoVisitor is a class implementing a common Java paradigm which allows
+case analysis on the three different types of link, executing different methods
+for each.
+
+BitmapHolder
+~~~~~~~~~~~~
+BitmapHolder is the solution to a problem in allocating the Bitmaps to which
+rendering is performed by background tasks. Renderings for the purpose of
+update have to be passed a Bitmap with the current page state. During frenetic
+page flicking a large number of rendering tasks can be queued, each holding
+reference to a Bitmap. Rather than pass the Bitmap directly, we pass a
+BitmapHolder containing a reference to the Bitmap. When a page view transitions
+off screen, the BitmapHolder's reference to the Bitmap can be nulled to release
+it.
+
+SearchTask and SearchTaskResult
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+SearchTask encapsulates the process of searching for a text string within a
+document. The class uses an AsyncTask internally to perform the search in the
+background and reports the result by calling onTextFound. A SearchTaskResult
+object is used to return the result of the search.
+
+SafeAnimatorInflator
+~~~~~~~~~~~~~~~~~~~~
+This class is a simple wrapper around AnimatorInflator. AnimatorInflator
+doesn't exist in some of the Android API levels MuPDF supports, and the wrapper
+allows for a test of API-level before the point at which the class would be
+loaded.
+
+MuPDFAlert and MuPDFAlertInternal
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This class represents the information issued by a javascript app.alert call.
+MuPDFAlertInternal represents the same information, but with Java enums
+replaced by ints, which are easier to return from JNI code.
+
+TextChar and TextWord
+~~~~~~~~~~~~~~~~~~~~~
+TextChar is used when processing the individual characters of the page. Each
+TextChar object contains the character and the rectangular area of the page at
+which it appears. TextWord is used to gather TextChars into words.
+
+Annotation
+~~~~~~~~~~
+This class represents the type and position on page of a PDF annotation.
+
+Other activities
+~~~~~~~~~~~~~~~~
+The app has three activities other than document-viewing.
+
+ChoosePDFActivity
+~~~~~~~~~~~~~~~~~
+ChoosePDFActivity allows the user to navigate local disc directories and view a
+list of loadable files, from which one can be chosen. It derives off
+ListActivity, and so displays the files in a standard ListView. ChoosePDFItem
+represents the various types of list entry: up-one, directory or file.
+ChoosePDFAdapter populates the list view.
+
+OutlineActivity
+~~~~~~~~~~~~~~~
+OutlineActivity displays a PDF document's outline as a list of selectable
+section titles. OutlineActivityData represents the current state of the
+activity. OutlineItem represents the individual items, and OutlineAdapter
+populates the list view.
+
+PrintDialogActivity
+~~~~~~~~~~~~~~~~~~~
+This activity allows the user to print documents via Google Cloud Print.
+
+
+Copied system classes
+~~~~~~~~~~~~~~~~~~~~~
+AsyncTask has had improvements made to it since issuing at the lowest android
+API level we support, and so we include the improved version as part of the
+MuPDF app. We also include Deque and ArrayDeque, which are used my AsyncTask.
+
diff --git a/platform/android/Icons.txt b/platform/android/Icons.txt
new file mode 100644
index 00000000..9d0082bf
--- /dev/null
+++ b/platform/android/Icons.txt
@@ -0,0 +1,2 @@
+The icons are from http://somerandomdude.com/work/iconic/
+They are covered by the CC-BY-SA license: http://creativecommons.org/licenses/by-sa/3.0/us/
diff --git a/platform/android/ReadMe.txt b/platform/android/ReadMe.txt
new file mode 100644
index 00000000..17e60e73
--- /dev/null
+++ b/platform/android/ReadMe.txt
@@ -0,0 +1,198 @@
+To build/debug android build.
+
+1) Download the android sdk, and install it. These instructions have been
+written with r14 (the latest version at time of writing) of the SDK in mind;
+other versions may give problems. On windows r14 unpacked as:
+
+ C:\Program Files (x86)\Android\android-sdk
+
+on Macos an older version installed as:
+
+ /Library/android-sdk-mac_x86
+
+on Linux install it as:
+
+ mkdir ~/android-sdk
+ cd ~/android-sdk
+ tar ~/Downloads/android-sdk_r20.0.3-linux.tgz
+
+Whatever directory it unpacks to, ensure that both the 'tools' and
+'platform-tools' directories inside it have been added to your PATH.
+
+2) Download the android ndk, and unpack it. These instructions were written
+with NDK r6b (the latest version at the time of writing) in mind, but the
+build has now been tweaked to work with r8b. Other versions may give problems.
+On windows I unpacked it as:
+
+ C:\android-ndk-r8b
+
+on Macos an older version unpacked as:
+
+ /Library/android-ndk-r5
+
+on Linux as:
+
+ mkdir ~/android-ndk
+ cd ~/android-ndk
+ tar jxvf ~/Downloads/android-ndk-r8b-linux-x86.tar.bz2
+
+It is very important that you should unpack it to a directory with no
+spaces in the name! (Don't be tempted to put it in C:\Program Files etc)
+
+Ensure that that directory is also added to your PATH.
+
+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 version r5 of the ndk, when running under cygwin, there were ]
+[ 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> ]
+[ ]
+[ Use the latest version and there should not be a problem. ]
+
+4) If the SDK has not popped up a window already, bring up a shell, and run
+'android' (or android.bat on cygwin/windows). You should now have a window
+with 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? Make sure you get at least
+the API level 11 as this is the current dependency for mupdf.
+
+5) In new versions of the GUI there is a 'Tools' menu from which you can
+select 'Manage AVDs...'. In old versions, 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
+ CPU/ABI: ARM (armeabi) (If this option exists)
+ SD card: Size: 1024MiB
+ Skin: Resolution: 480x756 (756 just fits my macbook screen, but 800 may
+ be 'more standard')
+
+Click 'Create AVD' (on old versions you may have to wait for a minute or
+so while it is prepared. Now you can exit the GUI.
+
+6) You will need a copy of the JDK installed. See
+<http://www.oracle.com/technetwork/java/javase/downloads/>. When this
+installs, ensure that JAVA_HOME is set to point to the installation
+directory.
+
+7) You will need a copy of Apache ANT installed.
+See <http://ant.apache.org/>. Ensure that ANT_HOME is set to point to
+the top level directory, and that ANT_HOME/bin is on the PATH.
+
+8) 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?).
+
+9) You will also need a copy of mupdf's thirdparty libraries. If you are
+using git, make sure to do a git submodule update --init from the top of
+the build tree. Older versions packaged this source code in a .zip-file
+(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).
+
+10) Finally, you will need a copy of a 'generated' directory. This is not
+currently available to download.
+
+The normal mupdf build process involves running some code on the host
+(the machine on which you are compiling), rather than the target (the
+machine/device on which you eventually want to run mupdf). This code
+repacks various bits of information (fonts, CMAPs etc) into a more
+compact and usable form.
+
+Unfortunately, the android SDK does not provide a compiler for the host
+machine, so we cannot run this step automatically as part of the android
+build. You will need to generate it by running a different build, such
+as the windows or linux native builds.
+
+We do not make a snapshot of the generated directory available to
+download as the contents of this directory change frequently, and we'd
+have to keep multiple versions on the website. We assume that anyone
+capable of building for android is capable of doing a normal hosted
+build.
+
+On windows (where you are using cygwin), or on linux/macos, this can be
+as simple as running 'make generate' in the top level directory.
+
+11) Change into mupdf's android directory. Copy the
+android/local.properties.sample file to be android/local.properties and
+change the sdk path there as appropriate. This should be the only bit of
+localisation you need to do.
+
+12) 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.
+
+If this dies with an error in thirdparty/jbig2/os_types.h load this
+file into an editor, and change line 43 from:
+
+ #else
+
+to
+
+ #elif !defined(HAVE_STDINT_H)
+
+and this should solve the problem.
+
+13) Then execute:
+
+ ant debug
+
+or on windows under cygwin:
+
+ ant.bat debug
+
+This should build the java wrapper.
+
+14) Now start the emulator by executing:
+
+ emulator -avd FroyoEm
+
+This will take a while to full start up (be patient).
+
+15) 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, and under Windows, should start c:/ even if invoked from cygwin)
+(adb lives in <sdk>/platform-tools if it's not on your path).
+
+16) With the emulator running (see step 14), execute
+
+ ant debug install
+
+('ant.bat debug install' on Windows) and that will copy MuPDF into the
+emulator where you can run it from the launchpad screen.
+
+17) To see debug messages from the emulator (including stdout/stderr from
+our app), execute:
+
+ adb logcat
+
+Good luck!
+
+Forms support
+~~~~~~~~~~~~~
+
+To build with PDF forms support, the only change is to the ndk-build stage.
+Run:
+
+ V8_BUILD=yes ndk-build
+
+The build will need v8 headers and libraries to be present in the thirdparty
+directory. The files assumed are:
+
+ thirdparty/v8-3.9/android/libv8_base.a
+ thirdparty/v8-3.9/android/libv8_snapshot.a
+ thirdparty/v8-3.9/include/v8.h
+ thirdparty/v8-3.9/include/v8stdint.h
+
diff --git a/platform/android/build.sh b/platform/android/build.sh
new file mode 100644
index 00000000..36ad883f
--- /dev/null
+++ b/platform/android/build.sh
@@ -0,0 +1 @@
+ndk-build && ant.bat install
diff --git a/platform/android/build.xml b/platform/android/build.xml
new file mode 100644
index 00000000..7cb2cdf8
--- /dev/null
+++ b/platform/android/build.xml
@@ -0,0 +1,85 @@
+<?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. -->
+ <loadproperties srcFile="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ 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'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ 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="ant.properties" />
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'"
+ unless="sdk.dir"
+ />
+
+
+<!-- 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>
+-->
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/platform/android/jni/Android.mk b/platform/android/jni/Android.mk
new file mode 100644
index 00000000..2391e161
--- /dev/null
+++ b/platform/android/jni/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH := $(call my-dir)
+TOP_LOCAL_PATH := $(LOCAL_PATH)
+
+MUPDF_ROOT := ..
+
+ifdef NDK_PROFILER
+include android-ndk-profiler.mk
+endif
+
+include $(TOP_LOCAL_PATH)/Core2.mk
+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 mupdfcore2 mupdfthirdparty
+ifdef NDK_PROFILER
+LOCAL_CFLAGS += -pg -DNDK_PROFILER
+LOCAL_STATIC_LIBRARIES += andprof
+else
+endif
+
+LOCAL_LDLIBS := -lm -llog -ljnigraphics
+ifdef V8_BUILD
+LOCAL_LDLIBS += -L$(MUPDF_ROOT)/thirdparty/v8-3.9/android -lv8_$(TARGET_ARCH_ABI)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/platform/android/jni/Application.mk b/platform/android/jni/Application.mk
new file mode 100644
index 00000000..8eb9c3b9
--- /dev/null
+++ b/platform/android/jni/Application.mk
@@ -0,0 +1,48 @@
+# When we build for google play, we build 4 different apk's, each with
+# a different version, by uncommenting one of the pairs of lines below.
+# Suppose our base version is X:
+
+# Version X: armeabi
+#APP_PLATFORM=android-8
+#APP_ABI := armeabi
+
+# Version X+1: armeabi-v7a (Much faster due to the availability of hardware
+# FP, but cannot be run in the emulator).
+APP_PLATFORM=android-8
+APP_ABI := armeabi-v7a
+
+# Version X+2: x86 (Requires android-9, so a change needs to be made in
+# AndroidManifest.xml too)
+#APP_PLATFORM=android-9
+#APP_ABI := x86
+
+# Version X+3: mips (Requires android-9, so a change needs to be made in
+# AndroidManifest.xml too)
+#APP_PLATFORM=android-9
+#APP_ABI := mips
+
+ifdef NDK_PROFILER
+# The profiler doesn't seem to receive ticks when run on release code.
+# Accordingly, we need to build as debug - but this turns optimisations
+# off, which is less than ideal. We COULD force them back on by using
+# APP_CFLAGS = -O2, but this then triggers bugs in the compiler when it
+# builds a couple of our source files. Accordingly, we have moved
+# those files into Core2, and we have some flag hackery to make just that
+# module without optimisation.
+APP_OPTIM := debug
+APP_CFLAGS :=
+else
+APP_OPTIM := release
+endif
+ifdef V8_BUILD
+APP_STL := stlport_static
+endif
+ifdef MEMENTO
+APP_CFLAGS += -DMEMENTO -DMEMENTO_LEAKONLY
+endif
+
+# If the ndk is r8b then workaround bug by uncommenting the following line
+#NDK_TOOLCHAIN_VERSION=4.4.3
+
+# If the ndk is newer than r8c, try using clang.
+#NDK_TOOLCHAIN_VERSION=clang3.1
diff --git a/platform/android/jni/Core.mk b/platform/android/jni/Core.mk
new file mode 100644
index 00000000..f53f679a
--- /dev/null
+++ b/platform/android/jni/Core.mk
@@ -0,0 +1,162 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+MY_ROOT := ../..
+
+V8 := v8-3.9
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB -DARCH_ARM_CAN_LOAD_UNALIGNED
+ifdef NDK_PROFILER
+LOCAL_CFLAGS += -pg -DNDK_PROFILER -O2
+endif
+endif
+LOCAL_CFLAGS += -DAA_BITS=8
+ifdef MEMENTO
+LOCAL_CFLAGS += -DMEMENTO -DMEMENTO_LEAKONLY
+endif
+
+LOCAL_C_INCLUDES := \
+ ../thirdparty/jbig2dec \
+ ../thirdparty/openjpeg/src/lib/openjp2 \
+ ../thirdparty/jpeg \
+ ../thirdparty/zlib \
+ ../thirdparty/freetype/include \
+ ../draw \
+ ../fitz \
+ ../pdf \
+ ../xps \
+ ../cbz \
+ ../ucdn \
+ ../scripts \
+ ..
+ifdef V8_BUILD
+LOCAL_C_INCLUDES += ../thirdparty/$(V8)/include
+endif
+
+LOCAL_MODULE := mupdfcore
+LOCAL_SRC_FILES := \
+ $(MY_ROOT)/fitz/base_context.c \
+ $(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_string.c \
+ $(MY_ROOT)/fitz/base_time.c \
+ $(MY_ROOT)/fitz/base_xml.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_trace.c \
+ $(MY_ROOT)/fitz/doc_document.c \
+ $(MY_ROOT)/fitz/doc_link.c \
+ $(MY_ROOT)/fitz/doc_outline.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_lzwd.c \
+ $(MY_ROOT)/fitz/filt_predict.c \
+ $(MY_ROOT)/fitz/image_jpx.c \
+ $(MY_ROOT)/fitz/image_jpeg.c \
+ $(MY_ROOT)/fitz/image_png.c \
+ $(MY_ROOT)/fitz/image_tiff.c \
+ $(MY_ROOT)/fitz/res_colorspace.c \
+ $(MY_ROOT)/fitz/res_font.c \
+ $(MY_ROOT)/fitz/res_func.c \
+ $(MY_ROOT)/fitz/res_image.c \
+ $(MY_ROOT)/fitz/res_path.c \
+ $(MY_ROOT)/fitz/res_pixmap.c \
+ $(MY_ROOT)/fitz/res_store.c \
+ $(MY_ROOT)/fitz/res_text.c \
+ $(MY_ROOT)/fitz/stm_buffer.c \
+ $(MY_ROOT)/fitz/stm_comp_buf.c \
+ $(MY_ROOT)/fitz/stm_open.c \
+ $(MY_ROOT)/fitz/stm_output.c \
+ $(MY_ROOT)/fitz/stm_read.c \
+ $(MY_ROOT)/fitz/text_extract.c \
+ $(MY_ROOT)/fitz/text_output.c \
+ $(MY_ROOT)/fitz/text_paragraph.c \
+ $(MY_ROOT)/fitz/text_search.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_simple_scale.c \
+ $(MY_ROOT)/draw/draw_unpack.c \
+ $(MY_ROOT)/ucdn/ucdn.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_device.c \
+ $(MY_ROOT)/pdf/pdf_encoding.c \
+ $(MY_ROOT)/pdf/pdf_event.c \
+ $(MY_ROOT)/pdf/pdf_field.c \
+ $(MY_ROOT)/pdf/pdf_font.c \
+ $(MY_ROOT)/pdf/pdf_fontfile.c \
+ $(MY_ROOT)/pdf/pdf_form.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_object.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_stream.c \
+ $(MY_ROOT)/pdf/pdf_store.c \
+ $(MY_ROOT)/pdf/pdf_type3.c \
+ $(MY_ROOT)/pdf/pdf_unicode.c \
+ $(MY_ROOT)/pdf/pdf_write.c \
+ $(MY_ROOT)/pdf/pdf_xobject.c \
+ $(MY_ROOT)/pdf/pdf_xref.c \
+ $(MY_ROOT)/pdf/pdf_xref_aux.c \
+ $(MY_ROOT)/xps/xps_common.c \
+ $(MY_ROOT)/xps/xps_doc.c \
+ $(MY_ROOT)/xps/xps_glyphs.c \
+ $(MY_ROOT)/xps/xps_gradient.c \
+ $(MY_ROOT)/xps/xps_image.c \
+ $(MY_ROOT)/xps/xps_outline.c \
+ $(MY_ROOT)/xps/xps_path.c \
+ $(MY_ROOT)/xps/xps_resource.c \
+ $(MY_ROOT)/xps/xps_tile.c \
+ $(MY_ROOT)/xps/xps_util.c \
+ $(MY_ROOT)/xps/xps_zip.c \
+ $(MY_ROOT)/cbz/mucbz.c \
+ $(MY_ROOT)/image/muimage.c
+ifdef MEMENTO
+ LOCAL_SRC_FILES += $(MY_ROOT)/fitz/memento.c
+endif
+ifdef V8_BUILD
+LOCAL_SRC_FILES += \
+ $(MY_ROOT)/pdf/pdf_js.c \
+ $(MY_ROOT)/pdf/pdf_jsimp_cpp.c \
+ $(MY_ROOT)/pdf/pdf_jsimp_v8.cpp
+else
+LOCAL_SRC_FILES += \
+ $(MY_ROOT)/pdf/pdf_js_none.c
+endif
+
+LOCAL_LDLIBS := -lm -llog -ljnigraphics
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/platform/android/jni/Core2.mk b/platform/android/jni/Core2.mk
new file mode 100644
index 00000000..b08751fe
--- /dev/null
+++ b/platform/android/jni/Core2.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+MY_ROOT := ../..
+
+V8 := v8-3.9
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB -DARCH_ARM_CAN_LOAD_UNALIGNED
+ifdef NDK_PROFILER
+LOCAL_CFLAGS += -pg -DNDK_PROFILER -O0
+NDK_APP_CFLAGS :=
+endif
+endif
+LOCAL_CFLAGS += -DAA_BITS=8
+ifdef MEMENTO
+LOCAL_CFLAGS += -DMEMENTO -DMEMENTO_LEAKONLY
+endif
+
+LOCAL_C_INCLUDES := \
+ ../thirdparty/jbig2dec \
+ ../thirdparty/openjpeg/src/lib/openjp2 \
+ ../thirdparty/jpeg \
+ ../thirdparty/zlib \
+ ../thirdparty/freetype/include \
+ ../draw \
+ ../fitz \
+ ../pdf \
+ ../xps \
+ ../cbz \
+ ../ucdn \
+ ../scripts \
+ ..
+ifdef V8_BUILD
+LOCAL_C_INCLUDES += ../thirdparty/$(V8)/include
+endif
+
+LOCAL_MODULE := mupdfcore2
+LOCAL_SRC_FILES := \
+ $(MY_ROOT)/fitz/res_shade.c
+
+LOCAL_LDLIBS := -lm -llog -ljnigraphics
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/platform/android/jni/ThirdParty.mk b/platform/android/jni/ThirdParty.mk
new file mode 100644
index 00000000..1a104b4b
--- /dev/null
+++ b/platform/android/jni/ThirdParty.mk
@@ -0,0 +1,132 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+MY_ROOT := ../..
+
+LOCAL_C_INCLUDES := \
+ ../thirdparty/jbig2dec \
+ ../thirdparty/openjpeg/src/lib/openjp2 \
+ ../thirdparty/jpeg \
+ ../thirdparty/zlib \
+ ../thirdparty/freetype/include \
+ ../scripts
+
+LOCAL_CFLAGS := \
+ -DFT2_BUILD_LIBRARY -DDARWIN_NO_CARBON -DHAVE_STDINT_H \
+ -DOPJ_HAVE_STDINT_H \
+ '-DFT_CONFIG_MODULES_H="slimftmodules.h"' \
+ '-DFT_CONFIG_OPTIONS_H="slimftoptions.h"'
+ifdef NDK_PROFILER
+LOCAL_CFLAGS += -pg -DNDK_PROFILER -O2
+endif
+ifdef MEMENTO
+LOCAL_CFLAGS += -DMEMENTO -DMEMENTO_LEAKONLY
+endif
+
+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_iaid.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_arith_int.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_generic.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_halftone.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_huffman.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_image.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_metadata.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_mmr.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_page.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_refinement.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_segment.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_symbol_dict.c \
+ $(MY_ROOT)/thirdparty/jbig2dec/jbig2_text.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/bio.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/cidx_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/cio.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/dwt.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/event.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/function_list.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/image.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/invert.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/j2k.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/jp2.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/mct.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/mqc.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/openjpeg.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/opj_clock.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/phix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/pi.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/ppix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/raw.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/t1.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/t1_generate_luts.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/t2.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/tcd.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/tgt.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/thix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg/src/lib/openjp2/tpix_manager.c \
+ $(MY_ROOT)/thirdparty/jpeg/jaricom.c \
+ $(MY_ROOT)/thirdparty/jpeg/jcomapi.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdapimin.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdapistd.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdarith.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdatadst.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdatasrc.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdcoefct.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdcolor.c \
+ $(MY_ROOT)/thirdparty/jpeg/jddctmgr.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdhuff.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdinput.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdmainct.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdmarker.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdmaster.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdmerge.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdpostct.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdsample.c \
+ $(MY_ROOT)/thirdparty/jpeg/jdtrans.c \
+ $(MY_ROOT)/thirdparty/jpeg/jerror.c \
+ $(MY_ROOT)/thirdparty/jpeg/jfdctflt.c \
+ $(MY_ROOT)/thirdparty/jpeg/jfdctfst.c \
+ $(MY_ROOT)/thirdparty/jpeg/jfdctint.c \
+ $(MY_ROOT)/thirdparty/jpeg/jidctflt.c \
+ $(MY_ROOT)/thirdparty/jpeg/jidctfst.c \
+ $(MY_ROOT)/thirdparty/jpeg/jidctint.c \
+ $(MY_ROOT)/thirdparty/jpeg/jmemmgr.c \
+ $(MY_ROOT)/thirdparty/jpeg/jmemnobs.c \
+ $(MY_ROOT)/thirdparty/jpeg/jquant1.c \
+ $(MY_ROOT)/thirdparty/jpeg/jquant2.c \
+ $(MY_ROOT)/thirdparty/jpeg/jutils.c \
+ $(MY_ROOT)/thirdparty/zlib/adler32.c \
+ $(MY_ROOT)/thirdparty/zlib/compress.c \
+ $(MY_ROOT)/thirdparty/zlib/crc32.c \
+ $(MY_ROOT)/thirdparty/zlib/deflate.c \
+ $(MY_ROOT)/thirdparty/zlib/inffast.c \
+ $(MY_ROOT)/thirdparty/zlib/inflate.c \
+ $(MY_ROOT)/thirdparty/zlib/inftrees.c \
+ $(MY_ROOT)/thirdparty/zlib/trees.c \
+ $(MY_ROOT)/thirdparty/zlib/uncompr.c \
+ $(MY_ROOT)/thirdparty/zlib/zutil.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftbase.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftbbox.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftbitmap.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftgasp.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftglyph.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftinit.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftstroke.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftsynth.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftsystem.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/fttype1.c \
+ $(MY_ROOT)/thirdparty/freetype/src/base/ftxf86.c \
+ $(MY_ROOT)/thirdparty/freetype/src/cff/cff.c \
+ $(MY_ROOT)/thirdparty/freetype/src/cid/type1cid.c \
+ $(MY_ROOT)/thirdparty/freetype/src/psaux/psaux.c \
+ $(MY_ROOT)/thirdparty/freetype/src/pshinter/pshinter.c \
+ $(MY_ROOT)/thirdparty/freetype/src/psnames/psnames.c \
+ $(MY_ROOT)/thirdparty/freetype/src/raster/raster.c \
+ $(MY_ROOT)/thirdparty/freetype/src/smooth/smooth.c \
+ $(MY_ROOT)/thirdparty/freetype/src/sfnt/sfnt.c \
+ $(MY_ROOT)/thirdparty/freetype/src/truetype/truetype.c \
+ $(MY_ROOT)/thirdparty/freetype/src/type1/type1.c
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/platform/android/jni/mupdf.c b/platform/android/jni/mupdf.c
new file mode 100644
index 00000000..bb827778
--- /dev/null
+++ b/platform/android/jni/mupdf.c
@@ -0,0 +1,2389 @@
+#include <jni.h>
+#include <time.h>
+#include <pthread.h>
+#include <android/log.h>
+#include <android/bitmap.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef NDK_PROFILER
+#include "prof.h"
+#endif
+
+#include "mupdf/fitz.h"
+#include "mupdf/pdf.h"
+
+#define JNI_FN(A) Java_com_artifex_mupdfdemo_ ## A
+#define PACKAGENAME "com/artifex/mupdfdemo"
+
+#define LOG_TAG "libmupdf"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGT(...) __android_log_print(ANDROID_LOG_INFO,"alert",__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
+
+/* Enable to log rendering times (render each frame 100 times and time) */
+#undef TIME_DISPLAY_LIST
+
+#define MAX_SEARCH_HITS (500)
+#define NUM_CACHE (3)
+#define STRIKE_HEIGHT (0.375f)
+#define UNDERLINE_HEIGHT (0.075f)
+#define LINE_THICKNESS (0.07f)
+#define INK_THICKNESS (4.0f)
+#define SMALL_FLOAT (0.00001)
+
+enum
+{
+ NONE,
+ TEXT,
+ LISTBOX,
+ COMBOBOX
+};
+
+typedef struct rect_node_s rect_node;
+
+struct rect_node_s
+{
+ fz_rect rect;
+ rect_node *next;
+};
+
+typedef struct
+{
+ int number;
+ int width;
+ int height;
+ fz_rect media_box;
+ fz_page *page;
+ rect_node *changed_rects;
+ rect_node *hq_changed_rects;
+ fz_display_list *page_list;
+ fz_display_list *annot_list;
+} page_cache;
+
+typedef struct globals_s globals;
+
+struct globals_s
+{
+ fz_colorspace *colorspace;
+ fz_document *doc;
+ int resolution;
+ fz_context *ctx;
+ fz_rect *hit_bbox;
+ int current;
+ char *current_path;
+
+ page_cache pages[NUM_CACHE];
+
+ int alerts_initialised;
+ // fin_lock and fin_lock2 are used during shutdown. The two waiting tasks
+ // show_alert and waitForAlertInternal respectively take these locks while
+ // waiting. During shutdown, the conditions are signaled and then the fin_locks
+ // are taken momentarily to ensure the blocked threads leave the controlled
+ // area of code before the mutexes and condition variables are destroyed.
+ pthread_mutex_t fin_lock;
+ pthread_mutex_t fin_lock2;
+ // alert_lock is the main lock guarding the variables directly below.
+ pthread_mutex_t alert_lock;
+ // Flag indicating if the alert system is active. When not active, both
+ // show_alert and waitForAlertInternal return immediately.
+ int alerts_active;
+ // Pointer to the alert struct passed in by show_alert, and valid while
+ // show_alert is blocked.
+ pdf_alert_event *current_alert;
+ // Flag and condition varibles to signal a request is present and a reply
+ // is present, respectively. The condition variables alone are not sufficient
+ // because of the pthreads permit spurious signals.
+ int alert_request;
+ int alert_reply;
+ pthread_cond_t alert_request_cond;
+ pthread_cond_t alert_reply_cond;
+
+ // For the buffer reading mode, we need to implement stream reading, which
+ // needs access to the following.
+ JNIEnv *env;
+ jclass thiz;
+};
+
+static jfieldID global_fid;
+static jfieldID buffer_fid;
+
+static void drop_changed_rects(fz_context *ctx, rect_node **nodePtr)
+{
+ rect_node *node = *nodePtr;
+ while (node)
+ {
+ rect_node *tnode = node;
+ node = node->next;
+ fz_free(ctx, tnode);
+ }
+
+ *nodePtr = NULL;
+}
+
+static void drop_page_cache(globals *glo, page_cache *pc)
+{
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+
+ LOGI("Drop page %d", pc->number);
+ fz_drop_display_list(ctx, pc->page_list);
+ pc->page_list = NULL;
+ fz_drop_display_list(ctx, pc->annot_list);
+ pc->annot_list = NULL;
+ fz_free_page(doc, pc->page);
+ pc->page = NULL;
+ drop_changed_rects(ctx, &pc->changed_rects);
+ drop_changed_rects(ctx, &pc->hq_changed_rects);
+}
+
+static void dump_annotation_display_lists(globals *glo)
+{
+ fz_context *ctx = glo->ctx;
+ int i;
+
+ for (i = 0; i < NUM_CACHE; i++) {
+ fz_drop_display_list(ctx, glo->pages[i].annot_list);
+ glo->pages[i].annot_list = NULL;
+ }
+}
+
+static void show_alert(globals *glo, pdf_alert_event *alert)
+{
+ pthread_mutex_lock(&glo->fin_lock2);
+ pthread_mutex_lock(&glo->alert_lock);
+
+ LOGT("Enter show_alert: %s", alert->title);
+ alert->button_pressed = 0;
+
+ if (glo->alerts_active)
+ {
+ glo->current_alert = alert;
+ glo->alert_request = 1;
+ pthread_cond_signal(&glo->alert_request_cond);
+
+ while (glo->alerts_active && !glo->alert_reply)
+ pthread_cond_wait(&glo->alert_reply_cond, &glo->alert_lock);
+ glo->alert_reply = 0;
+ glo->current_alert = NULL;
+ }
+
+ LOGT("Exit show_alert");
+
+ pthread_mutex_unlock(&glo->alert_lock);
+ pthread_mutex_unlock(&glo->fin_lock2);
+}
+
+static void event_cb(pdf_doc_event *event, void *data)
+{
+ globals *glo = (globals *)data;
+
+ switch (event->type)
+ {
+ case PDF_DOCUMENT_EVENT_ALERT:
+ show_alert(glo, pdf_access_alert_event(event));
+ break;
+ }
+}
+
+static void alerts_init(globals *glo)
+{
+ pdf_document *idoc = pdf_specifics(glo->doc);
+
+ if (!idoc || glo->alerts_initialised)
+ return;
+
+ glo->alerts_active = 0;
+ glo->alert_request = 0;
+ glo->alert_reply = 0;
+ pthread_mutex_init(&glo->fin_lock, NULL);
+ pthread_mutex_init(&glo->fin_lock2, NULL);
+ pthread_mutex_init(&glo->alert_lock, NULL);
+ pthread_cond_init(&glo->alert_request_cond, NULL);
+ pthread_cond_init(&glo->alert_reply_cond, NULL);
+
+ pdf_set_doc_event_callback(idoc, event_cb, glo);
+ LOGT("alert_init");
+ glo->alerts_initialised = 1;
+}
+
+static void alerts_fin(globals *glo)
+{
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ if (!glo->alerts_initialised)
+ return;
+
+ LOGT("Enter alerts_fin");
+ if (idoc)
+ pdf_set_doc_event_callback(idoc, NULL, NULL);
+
+ // Set alerts_active false and wake up show_alert and waitForAlertInternal,
+ pthread_mutex_lock(&glo->alert_lock);
+ glo->current_alert = NULL;
+ glo->alerts_active = 0;
+ pthread_cond_signal(&glo->alert_request_cond);
+ pthread_cond_signal(&glo->alert_reply_cond);
+ pthread_mutex_unlock(&glo->alert_lock);
+
+ // Wait for the fin_locks.
+ pthread_mutex_lock(&glo->fin_lock);
+ pthread_mutex_unlock(&glo->fin_lock);
+ pthread_mutex_lock(&glo->fin_lock2);
+ pthread_mutex_unlock(&glo->fin_lock2);
+
+ pthread_cond_destroy(&glo->alert_reply_cond);
+ pthread_cond_destroy(&glo->alert_request_cond);
+ pthread_mutex_destroy(&glo->alert_lock);
+ pthread_mutex_destroy(&glo->fin_lock2);
+ pthread_mutex_destroy(&glo->fin_lock);
+ LOGT("Exit alerts_fin");
+ glo->alerts_initialised = 0;
+}
+
+static globals *get_globals(JNIEnv *env, jobject thiz)
+{
+ globals *glo = (globals *)(void *)((*env)->GetLongField(env, thiz, global_fid));
+ if (glo != NULL)
+ {
+ glo->env = env;
+ glo->thiz = thiz;
+ }
+ return glo;
+}
+
+JNIEXPORT jlong JNICALL
+JNI_FN(MuPDFCore_openFile)(JNIEnv * env, jobject thiz, jstring jfilename)
+{
+ const char *filename;
+ globals *glo;
+ fz_context *ctx;
+ jclass clazz;
+
+#ifdef NDK_PROFILER
+ monstartup("libmupdf.so");
+#endif
+
+ clazz = (*env)->GetObjectClass(env, thiz);
+ global_fid = (*env)->GetFieldID(env, clazz, "globals", "J");
+
+ glo = calloc(1, sizeof(*glo));
+ if (glo == NULL)
+ return 0;
+ glo->resolution = 160;
+ glo->alerts_initialised = 0;
+
+ filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
+ if (filename == NULL)
+ {
+ LOGE("Failed to get filename");
+ free(glo);
+ return 0;
+ }
+
+ /* 128 MB store for low memory devices. Tweak as necessary. */
+ glo->ctx = ctx = fz_new_context(NULL, NULL, 128 << 20);
+ if (!ctx)
+ {
+ LOGE("Failed to initialise context");
+ (*env)->ReleaseStringUTFChars(env, jfilename, filename);
+ free(glo);
+ return 0;
+ }
+
+ glo->doc = NULL;
+ fz_try(ctx)
+ {
+ glo->colorspace = fz_device_rgb(ctx);
+
+ LOGE("Opening document...");
+ fz_try(ctx)
+ {
+ glo->current_path = fz_strdup(ctx, (char *)filename);
+ glo->doc = fz_open_document(ctx, (char *)filename);
+ alerts_init(glo);
+ }
+ fz_catch(ctx)
+ {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot open document: '%s'", filename);
+ }
+ LOGE("Done!");
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Failed: %s", ctx->error->message);
+ fz_close_document(glo->doc);
+ glo->doc = NULL;
+ fz_free_context(ctx);
+ glo->ctx = NULL;
+ free(glo);
+ glo = NULL;
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jfilename, filename);
+
+ return (jlong)(void *)glo;
+}
+
+static int bufferStreamRead(fz_stream *stream, unsigned char *buf, int len)
+{
+ globals *glo = (globals *)stream->state;
+ JNIEnv *env = glo->env;
+ jbyteArray array = (jbyteArray)(void *)((*env)->GetObjectField(env, glo->thiz, buffer_fid));
+ int arrayLength = (*env)->GetArrayLength(env, array);
+
+ if (stream->pos > arrayLength)
+ stream->pos = arrayLength;
+ if (stream->pos < 0)
+ stream->pos = 0;
+ if (len + stream->pos > arrayLength)
+ len = arrayLength - stream->pos;
+
+ (*env)->GetByteArrayRegion(env, array, stream->pos, len, buf);
+ (*env)->DeleteLocalRef(env, array);
+ return len;
+}
+
+static void bufferStreamClose(fz_context *ctx, void *state)
+{
+ /* Nothing to do */
+}
+
+static void bufferStreamSeek(fz_stream *stream, int offset, int whence)
+{
+ globals *glo = (globals *)stream->state;
+ JNIEnv *env = glo->env;
+ jbyteArray array = (jbyteArray)(void *)((*env)->GetObjectField(env, glo->thiz, buffer_fid));
+ int arrayLength = (*env)->GetArrayLength(env, array);
+
+ (*env)->DeleteLocalRef(env, array);
+
+ if (whence == 0) /* SEEK_SET */
+ stream->pos = offset;
+ else if (whence == 1) /* SEEK_CUR */
+ stream->pos += offset;
+ else if (whence == 2) /* SEEK_END */
+ stream->pos = arrayLength + offset;
+
+ if (stream->pos > arrayLength)
+ stream->pos = arrayLength;
+ if (stream->pos < 0)
+ stream->pos = 0;
+
+ stream->rp = stream->bp;
+ stream->wp = stream->bp;
+}
+
+JNIEXPORT jlong JNICALL
+JNI_FN(MuPDFCore_openBuffer)(JNIEnv * env, jobject thiz)
+{
+ globals *glo;
+ fz_context *ctx;
+ jclass clazz;
+ fz_stream *stream;
+
+#ifdef NDK_PROFILER
+ monstartup("libmupdf.so");
+#endif
+
+ clazz = (*env)->GetObjectClass(env, thiz);
+ global_fid = (*env)->GetFieldID(env, clazz, "globals", "J");
+
+ glo = calloc(1, sizeof(*glo));
+ if (glo == NULL)
+ return 0;
+ glo->resolution = 160;
+ glo->alerts_initialised = 0;
+ glo->env = env;
+ glo->thiz = thiz;
+ buffer_fid = (*env)->GetFieldID(env, clazz, "fileBuffer", "[B");
+
+ /* 128 MB store for low memory devices. Tweak as necessary. */
+ glo->ctx = ctx = fz_new_context(NULL, NULL, 128 << 20);
+ if (!ctx)
+ {
+ LOGE("Failed to initialise context");
+ free(glo);
+ return 0;
+ }
+
+ glo->doc = NULL;
+ fz_try(ctx)
+ {
+ stream = fz_new_stream(ctx, glo, bufferStreamRead, bufferStreamClose);
+ stream->seek = bufferStreamSeek;
+
+ glo->colorspace = fz_device_rgb(ctx);
+
+ LOGE("Opening document...");
+ fz_try(ctx)
+ {
+ glo->current_path = NULL;
+ glo->doc = fz_open_document_with_stream(ctx, "", stream);
+ alerts_init(glo);
+ }
+ fz_catch(ctx)
+ {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot open memory document");
+ }
+ LOGE("Done!");
+ }
+ fz_always(ctx)
+ {
+ fz_close(stream);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Failed: %s", ctx->error->message);
+ fz_close_document(glo->doc);
+ glo->doc = NULL;
+ fz_free_context(ctx);
+ glo->ctx = NULL;
+ free(glo);
+ glo = NULL;
+ }
+
+ return (jlong)(void *)glo;
+}
+
+JNIEXPORT int JNICALL
+JNI_FN(MuPDFCore_countPagesInternal)(JNIEnv *env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ int count = 0;
+
+ fz_try(ctx)
+ {
+ count = fz_count_pages(glo->doc);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("exception while counting pages: %s", ctx->error->message);
+ }
+ return count;
+}
+
+JNIEXPORT jstring JNICALL
+JNI_FN(MuPDFCore_fileFormatInternal)(JNIEnv * env, jobject thiz)
+{
+ char info[64];
+ globals *glo = get_globals(env, thiz);
+
+ fz_meta(glo->doc, FZ_META_FORMAT_INFO, info, sizeof(info));
+
+ return (*env)->NewStringUTF(env, info);
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_gotoPageInternal)(JNIEnv *env, jobject thiz, int page)
+{
+ int i;
+ int furthest;
+ int furthest_dist = -1;
+ float zoom;
+ fz_matrix ctm;
+ fz_irect bbox;
+ page_cache *pc;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+
+ for (i = 0; i < NUM_CACHE; i++)
+ {
+ if (glo->pages[i].page != NULL && glo->pages[i].number == page)
+ {
+ /* The page is already cached */
+ glo->current = i;
+ return;
+ }
+
+ if (glo->pages[i].page == NULL)
+ {
+ /* cache record unused, and so a good one to use */
+ furthest = i;
+ furthest_dist = INT_MAX;
+ }
+ else
+ {
+ int dist = abs(glo->pages[i].number - page);
+
+ /* Further away - less likely to be needed again */
+ if (dist > furthest_dist)
+ {
+ furthest_dist = dist;
+ furthest = i;
+ }
+ }
+ }
+
+ glo->current = furthest;
+ pc = &glo->pages[glo->current];
+
+ drop_page_cache(glo, pc);
+
+ /* In the event of an error, ensure we give a non-empty page */
+ pc->width = 100;
+ pc->height = 100;
+
+ pc->number = page;
+ LOGE("Goto page %d...", page);
+ fz_try(ctx)
+ {
+ fz_rect rect;
+ LOGI("Load page %d", pc->number);
+ pc->page = fz_load_page(glo->doc, pc->number);
+ zoom = glo->resolution / 72;
+ fz_bound_page(glo->doc, pc->page, &pc->media_box);
+ fz_scale(&ctm, zoom, zoom);
+ rect = pc->media_box;
+ fz_round_rect(&bbox, fz_transform_rect(&rect, &ctm));
+ pc->width = bbox.x1-bbox.x0;
+ pc->height = bbox.y1-bbox.y0;
+ }
+ fz_catch(ctx)
+ {
+ LOGE("cannot make displaylist from page %d", pc->number);
+ }
+}
+
+JNIEXPORT float JNICALL
+JNI_FN(MuPDFCore_getPageWidth)(JNIEnv *env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ LOGE("PageWidth=%d", glo->pages[glo->current].width);
+ return glo->pages[glo->current].width;
+}
+
+JNIEXPORT float JNICALL
+JNI_FN(MuPDFCore_getPageHeight)(JNIEnv *env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ LOGE("PageHeight=%d", glo->pages[glo->current].height);
+ return glo->pages[glo->current].height;
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_javascriptSupported)(JNIEnv *env, jobject thiz)
+{
+ return fz_javascript_supported();
+}
+
+static void update_changed_rects(globals *glo, page_cache *pc, pdf_document *idoc)
+{
+ fz_annot *annot;
+
+ pdf_update_page(idoc, (pdf_page *)pc->page);
+ while ((annot = (fz_annot *)pdf_poll_changed_annot(idoc, (pdf_page *)pc->page)) != NULL)
+ {
+ /* FIXME: We bound the annot twice here */
+ rect_node *node = fz_malloc_struct(glo->ctx, rect_node);
+ fz_bound_annot(glo->doc, annot, &node->rect);
+ node->next = pc->changed_rects;
+ pc->changed_rects = node;
+
+ node = fz_malloc_struct(glo->ctx, rect_node);
+ fz_bound_annot(glo->doc, annot, &node->rect);
+ node->next = pc->hq_changed_rects;
+ pc->hq_changed_rects = node;
+ }
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(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_device *dev = NULL;
+ float zoom;
+ fz_matrix ctm;
+ fz_irect bbox;
+ fz_rect rect;
+ fz_pixmap *pix = NULL;
+ float xscale, yscale;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ page_cache *pc = &glo->pages[glo->current];
+ int hq = (patchW < pageW || patchH < pageH);
+ fz_matrix scale;
+
+ if (pc->page == NULL)
+ return 0;
+
+ fz_var(pix);
+ fz_var(dev);
+
+ 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(%d)=%dx%d patch=[%d,%d,%d,%d]",
+ pc->number, pageW, pageH, patchX, patchY, patchW, patchH);
+
+ fz_try(ctx)
+ {
+ pdf_document *idoc = pdf_specifics(doc);
+
+ if (idoc)
+ {
+ /* Update the changed-rects for both hq patch and main bitmap */
+ update_changed_rects(glo, pc, idoc);
+
+ /* Then drop the changed-rects for the bitmap we're about to
+ render because we are rendering the entire area */
+ drop_changed_rects(ctx, hq ? &pc->hq_changed_rects : &pc->changed_rects);
+ }
+
+ if (pc->page_list == NULL)
+ {
+ /* Render to list */
+ pc->page_list = fz_new_display_list(ctx);
+ dev = fz_new_list_device(ctx, pc->page_list);
+ fz_run_page_contents(doc, pc->page, dev, &fz_identity, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ if (pc->annot_list == NULL)
+ {
+ fz_annot *annot;
+ pc->annot_list = fz_new_display_list(ctx);
+ dev = fz_new_list_device(ctx, pc->annot_list);
+ for (annot = fz_first_annot(doc, pc->page); annot; annot = fz_next_annot(doc, annot))
+ fz_run_annot(doc, pc->page, annot, dev, &fz_identity, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ bbox.x0 = patchX;
+ bbox.y0 = patchY;
+ bbox.x1 = patchX + patchW;
+ bbox.y1 = patchY + patchH;
+ pix = fz_new_pixmap_with_bbox_and_data(ctx, glo->colorspace, &bbox, pixels);
+ if (pc->page_list == NULL && pc->annot_list == NULL)
+ {
+ fz_clear_pixmap_with_value(ctx, pix, 0xd0);
+ break;
+ }
+ fz_clear_pixmap_with_value(ctx, pix, 0xff);
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+ rect = pc->media_box;
+ fz_round_rect(&bbox, fz_transform_rect(&rect, &ctm));
+ /* 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);
+ fz_concat(&ctm, &ctm, fz_scale(&scale, xscale, yscale));
+ rect = pc->media_box;
+ fz_transform_rect(&rect, &ctm);
+ dev = fz_new_draw_device(ctx, pix);
+#ifdef TIME_DISPLAY_LIST
+ {
+ clock_t time;
+ int i;
+
+ LOGE("Executing display list");
+ time = clock();
+ for (i=0; i<100;i++) {
+#endif
+ if (pc->page_list)
+ fz_run_display_list(pc->page_list, dev, &ctm, &rect, NULL);
+ if (pc->annot_list)
+ fz_run_display_list(pc->annot_list, dev, &ctm, &rect, NULL);
+#ifdef TIME_DISPLAY_LIST
+ }
+ time = clock() - time;
+ LOGE("100 renders in %d (%d per sec)", time, CLOCKS_PER_SEC);
+ }
+#endif
+ fz_free_device(dev);
+ dev = NULL;
+ fz_drop_pixmap(ctx, pix);
+ LOGE("Rendered");
+ }
+ fz_always(ctx)
+ {
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Render failed");
+ }
+
+ AndroidBitmap_unlockPixels(env, bitmap);
+
+ return 1;
+}
+
+static char *widget_type_string(int t)
+{
+ switch(t)
+ {
+ case PDF_WIDGET_TYPE_PUSHBUTTON: return "pushbutton";
+ case PDF_WIDGET_TYPE_CHECKBOX: return "checkbox";
+ case PDF_WIDGET_TYPE_RADIOBUTTON: return "radiobutton";
+ case PDF_WIDGET_TYPE_TEXT: return "text";
+ case PDF_WIDGET_TYPE_LISTBOX: return "listbox";
+ case PDF_WIDGET_TYPE_COMBOBOX: return "combobox";
+ default: return "non-widget";
+ }
+}
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap, int page,
+ int pageW, int pageH, int patchX, int patchY, int patchW, int patchH)
+{
+ AndroidBitmapInfo info;
+ void *pixels;
+ int ret;
+ fz_device *dev = NULL;
+ float zoom;
+ fz_matrix ctm;
+ fz_irect bbox;
+ fz_rect rect;
+ fz_pixmap *pix = NULL;
+ float xscale, yscale;
+ pdf_document *idoc;
+ page_cache *pc = NULL;
+ int hq = (patchW < pageW || patchH < pageH);
+ int i;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ rect_node *crect;
+ fz_matrix scale;
+
+ for (i = 0; i < NUM_CACHE; i++)
+ {
+ if (glo->pages[i].page != NULL && glo->pages[i].number == page)
+ {
+ pc = &glo->pages[i];
+ break;
+ }
+ }
+
+ if (pc == NULL)
+ {
+ /* Without a cached page object we cannot perform a partial update so
+ render the entire bitmap instead */
+ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, page);
+ return JNI_FN(MuPDFCore_drawPage)(env, thiz, bitmap, pageW, pageH, patchX, patchY, patchW, patchH);
+ }
+
+ idoc = pdf_specifics(doc);
+
+ fz_var(pix);
+ fz_var(dev);
+
+ 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(%d)=%dx%d patch=[%d,%d,%d,%d]",
+ pc->number, pageW, pageH, patchX, patchY, patchW, patchH);
+
+ fz_try(ctx)
+ {
+ fz_annot *annot;
+
+ if (idoc)
+ {
+ /* Update the changed-rects for both hq patch and main bitmap */
+ update_changed_rects(glo, pc, idoc);
+ }
+
+ if (pc->page_list == NULL)
+ {
+ /* Render to list */
+ pc->page_list = fz_new_display_list(ctx);
+ dev = fz_new_list_device(ctx, pc->page_list);
+ fz_run_page_contents(doc, pc->page, dev, &fz_identity, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+
+ if (pc->annot_list == NULL) {
+ pc->annot_list = fz_new_display_list(ctx);
+ dev = fz_new_list_device(ctx, pc->annot_list);
+ for (annot = fz_first_annot(doc, pc->page); annot; annot = fz_next_annot(doc, annot))
+ fz_run_annot(doc, pc->page, annot, dev, &fz_identity, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+
+ bbox.x0 = patchX;
+ bbox.y0 = patchY;
+ bbox.x1 = patchX + patchW;
+ bbox.y1 = patchY + patchH;
+ pix = fz_new_pixmap_with_bbox_and_data(ctx, glo->colorspace, &bbox, pixels);
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+ rect = pc->media_box;
+ fz_round_rect(&bbox, fz_transform_rect(&rect, &ctm));
+ /* 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);
+ fz_concat(&ctm, &ctm, fz_scale(&scale, xscale, yscale));
+ rect = pc->media_box;
+ fz_transform_rect(&rect, &ctm);
+
+ LOGI("Start partial update");
+ for (crect = hq ? pc->hq_changed_rects : pc->changed_rects; crect; crect = crect->next)
+ {
+ fz_irect abox;
+ fz_rect arect = crect->rect;
+ fz_intersect_rect(fz_transform_rect(&arect, &ctm), &rect);
+ fz_round_rect(&abox, &arect);
+
+ LOGI("Update rectangle (%d, %d, %d, %d)", abox.x0, abox.y0, abox.x1, abox.y1);
+ if (!fz_is_empty_irect(&abox))
+ {
+ LOGI("And it isn't empty");
+ fz_clear_pixmap_rect_with_value(ctx, pix, 0xff, &abox);
+ dev = fz_new_draw_device_with_bbox(ctx, pix, &abox);
+ if (pc->page_list)
+ fz_run_display_list(pc->page_list, dev, &ctm, &arect, NULL);
+ if (pc->annot_list)
+ fz_run_display_list(pc->annot_list, dev, &ctm, &arect, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ }
+ LOGI("End partial update");
+
+ /* Drop the changed rects we've just rendered */
+ drop_changed_rects(ctx, hq ? &pc->hq_changed_rects : &pc->changed_rects);
+
+ LOGE("Rendered");
+ }
+ fz_always(ctx)
+ {
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Render failed");
+ }
+
+ fz_drop_pixmap(ctx, pix);
+ AndroidBitmap_unlockPixels(env, bitmap);
+
+ return 1;
+}
+
+static int
+charat(fz_text_page *page, int idx)
+{
+ fz_char_and_box cab;
+ return fz_text_char_at(&cab, page, idx)->c;
+}
+
+static fz_rect
+bboxcharat(fz_text_page *page, int idx)
+{
+ fz_char_and_box cab;
+ return fz_text_char_at(&cab, page, idx)->bbox;
+}
+
+static int
+textlen(fz_text_page *page)
+{
+ int len = 0;
+ int block_num;
+
+ for (block_num = 0; block_num < page->len; block_num++)
+ {
+ fz_text_block *block;
+ fz_text_line *line;
+
+ if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT)
+ continue;
+ block = page->blocks[block_num].u.text;
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ fz_text_span *span;
+
+ for (span = line->first_span; span; span = span->next)
+ {
+ len += span->len;
+ }
+ len++; /* pseudo-newline */
+ }
+ }
+ return len;
+}
+
+static int
+countOutlineItems(fz_outline *outline)
+{
+ int count = 0;
+
+ while (outline)
+ {
+ if (outline->dest.kind == FZ_LINK_GOTO
+ && outline->dest.ld.gotor.page >= 0
+ && outline->title)
+ count++;
+
+ count += countOutlineItems(outline->down);
+ outline = outline->next;
+ }
+
+ return count;
+}
+
+static int
+fillInOutlineItems(JNIEnv * env, jclass olClass, jmethodID ctor, jobjectArray arr, int pos, fz_outline *outline, int level)
+{
+ while (outline)
+ {
+ if (outline->dest.kind == FZ_LINK_GOTO)
+ {
+ int page = outline->dest.ld.gotor.page;
+ if (page >= 0 && outline->title)
+ {
+ jobject ol;
+ jstring title = (*env)->NewStringUTF(env, outline->title);
+ if (title == NULL) return -1;
+ ol = (*env)->NewObject(env, olClass, ctor, level, title, page);
+ if (ol == NULL) return -1;
+ (*env)->SetObjectArrayElement(env, arr, pos, ol);
+ (*env)->DeleteLocalRef(env, ol);
+ (*env)->DeleteLocalRef(env, title);
+ pos++;
+ }
+ }
+ pos = fillInOutlineItems(env, olClass, ctor, arr, pos, outline->down, level+1);
+ if (pos < 0) return -1;
+ outline = outline->next;
+ }
+
+ return pos;
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_needsPasswordInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+
+ return fz_needs_password(glo->doc) ? JNI_TRUE : JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_authenticatePasswordInternal)(JNIEnv *env, jobject thiz, jstring password)
+{
+ const char *pw;
+ int result;
+ globals *glo = get_globals(env, thiz);
+
+ pw = (*env)->GetStringUTFChars(env, password, NULL);
+ if (pw == NULL)
+ return JNI_FALSE;
+
+ result = fz_authenticate_password(glo->doc, (char *)pw);
+ (*env)->ReleaseStringUTFChars(env, password, pw);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_hasOutlineInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_outline *outline = fz_load_outline(glo->doc);
+
+ fz_free_outline(glo->ctx, outline);
+ return (outline == NULL) ? JNI_FALSE : JNI_TRUE;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getOutlineInternal)(JNIEnv * env, jobject thiz)
+{
+ jclass olClass;
+ jmethodID ctor;
+ jobjectArray arr;
+ jobject ol;
+ fz_outline *outline;
+ int nItems;
+ globals *glo = get_globals(env, thiz);
+ jobjectArray ret;
+
+ olClass = (*env)->FindClass(env, PACKAGENAME "/OutlineItem");
+ if (olClass == NULL) return NULL;
+ ctor = (*env)->GetMethodID(env, olClass, "<init>", "(ILjava/lang/String;I)V");
+ if (ctor == NULL) return NULL;
+
+ outline = fz_load_outline(glo->doc);
+ nItems = countOutlineItems(outline);
+
+ arr = (*env)->NewObjectArray(env,
+ nItems,
+ olClass,
+ NULL);
+ if (arr == NULL) return NULL;
+
+ ret = fillInOutlineItems(env, olClass, ctor, arr, 0, outline, 0) > 0
+ ? arr
+ :NULL;
+ fz_free_outline(glo->ctx, outline);
+ return ret;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_searchPage)(JNIEnv * env, jobject thiz, jstring jtext)
+{
+ jclass rectClass;
+ jmethodID ctor;
+ jobjectArray arr;
+ jobject rect;
+ fz_text_sheet *sheet = NULL;
+ fz_text_page *text = NULL;
+ fz_device *dev = NULL;
+ float zoom;
+ fz_matrix ctm;
+ int pos;
+ int len;
+ int i, n;
+ int hit_count = 0;
+ const char *str;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ page_cache *pc = &glo->pages[glo->current];
+
+ rectClass = (*env)->FindClass(env, "android/graphics/RectF");
+ if (rectClass == NULL) return NULL;
+ ctor = (*env)->GetMethodID(env, rectClass, "<init>", "(FFFF)V");
+ if (ctor == NULL) return NULL;
+ str = (*env)->GetStringUTFChars(env, jtext, NULL);
+ if (str == NULL) return NULL;
+
+ fz_var(sheet);
+ fz_var(text);
+ fz_var(dev);
+
+ fz_try(ctx)
+ {
+ if (glo->hit_bbox == NULL)
+ glo->hit_bbox = fz_malloc_array(ctx, MAX_SEARCH_HITS, sizeof(*glo->hit_bbox));
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+ sheet = fz_new_text_sheet(ctx);
+ text = fz_new_text_page(ctx);
+ dev = fz_new_text_device(ctx, sheet, text);
+ fz_run_page(doc, pc->page, dev, &ctm, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+
+ hit_count = fz_search_text_page(ctx, text, str, glo->hit_bbox, MAX_SEARCH_HITS);
+ }
+ fz_always(ctx)
+ {
+ fz_free_text_page(ctx, text);
+ fz_free_text_sheet(ctx, sheet);
+ fz_free_device(dev);
+ }
+ fz_catch(ctx)
+ {
+ jclass cls;
+ (*env)->ReleaseStringUTFChars(env, jtext, str);
+ cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage");
+ (*env)->DeleteLocalRef(env, cls);
+
+ return NULL;
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jtext, str);
+
+ arr = (*env)->NewObjectArray(env,
+ hit_count,
+ rectClass,
+ NULL);
+ if (arr == NULL) return NULL;
+
+ for (i = 0; i < hit_count; i++) {
+ rect = (*env)->NewObject(env, rectClass, ctor,
+ (float) (glo->hit_bbox[i].x0),
+ (float) (glo->hit_bbox[i].y0),
+ (float) (glo->hit_bbox[i].x1),
+ (float) (glo->hit_bbox[i].y1));
+ if (rect == NULL)
+ return NULL;
+ (*env)->SetObjectArrayElement(env, arr, i, rect);
+ (*env)->DeleteLocalRef(env, rect);
+ }
+
+ return arr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_text)(JNIEnv * env, jobject thiz)
+{
+ jclass textCharClass;
+ jclass textSpanClass;
+ jclass textLineClass;
+ jclass textBlockClass;
+ jmethodID ctor;
+ jobjectArray barr = NULL;
+ fz_text_sheet *sheet = NULL;
+ fz_text_page *text = NULL;
+ fz_device *dev = NULL;
+ float zoom;
+ fz_matrix ctm;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ page_cache *pc = &glo->pages[glo->current];
+
+ textCharClass = (*env)->FindClass(env, PACKAGENAME "/TextChar");
+ if (textCharClass == NULL) return NULL;
+ textSpanClass = (*env)->FindClass(env, "[L" PACKAGENAME "/TextChar;");
+ if (textSpanClass == NULL) return NULL;
+ textLineClass = (*env)->FindClass(env, "[[L" PACKAGENAME "/TextChar;");
+ if (textLineClass == NULL) return NULL;
+ textBlockClass = (*env)->FindClass(env, "[[[L" PACKAGENAME "/TextChar;");
+ if (textBlockClass == NULL) return NULL;
+ ctor = (*env)->GetMethodID(env, textCharClass, "<init>", "(FFFFC)V");
+ if (ctor == NULL) return NULL;
+
+ fz_var(sheet);
+ fz_var(text);
+ fz_var(dev);
+
+ fz_try(ctx)
+ {
+ int b, l, s, c;
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+ sheet = fz_new_text_sheet(ctx);
+ text = fz_new_text_page(ctx);
+ dev = fz_new_text_device(ctx, sheet, text);
+ fz_run_page(doc, pc->page, dev, &ctm, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+
+ barr = (*env)->NewObjectArray(env, text->len, textBlockClass, NULL);
+ if (barr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
+
+ for (b = 0; b < text->len; b++)
+ {
+ fz_text_block *block;
+ jobjectArray *larr;
+
+ if (text->blocks[b].type != FZ_PAGE_BLOCK_TEXT)
+ continue;
+ block = text->blocks[b].u.text;
+ larr = (*env)->NewObjectArray(env, block->len, textLineClass, NULL);
+ if (larr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
+
+ for (l = 0; l < block->len; l++)
+ {
+ fz_text_line *line = &block->lines[l];
+ jobjectArray *sarr;
+ fz_text_span *span;
+ int len = 0;
+
+ for (span = line->first_span; span; span = span->next)
+ len++;
+
+ sarr = (*env)->NewObjectArray(env, len, textSpanClass, NULL);
+ if (sarr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
+
+ for (s=0, span = line->first_span; span; s++, span = span->next)
+ {
+ jobjectArray *carr = (*env)->NewObjectArray(env, span->len, textCharClass, NULL);
+ if (carr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
+
+ for (c = 0; c < span->len; c++)
+ {
+ fz_text_char *ch = &span->text[c];
+ fz_rect bbox;
+ fz_text_char_bbox(&bbox, span, c);
+ jobject cobj = (*env)->NewObject(env, textCharClass, ctor, bbox.x0, bbox.y0, bbox.x1, bbox.y1, ch->c);
+ if (cobj == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectfailed");
+
+ (*env)->SetObjectArrayElement(env, carr, c, cobj);
+ (*env)->DeleteLocalRef(env, cobj);
+ }
+
+ (*env)->SetObjectArrayElement(env, sarr, s, carr);
+ (*env)->DeleteLocalRef(env, carr);
+ }
+
+ (*env)->SetObjectArrayElement(env, larr, l, sarr);
+ (*env)->DeleteLocalRef(env, sarr);
+ }
+
+ (*env)->SetObjectArrayElement(env, barr, b, larr);
+ (*env)->DeleteLocalRef(env, larr);
+ }
+ }
+ fz_always(ctx)
+ {
+ fz_free_text_page(ctx, text);
+ fz_free_text_sheet(ctx, sheet);
+ fz_free_device(dev);
+ }
+ fz_catch(ctx)
+ {
+ jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_text");
+ (*env)->DeleteLocalRef(env, cls);
+
+ return NULL;
+ }
+
+ return barr;
+}
+
+JNIEXPORT jbyteArray JNICALL
+JNI_FN(MuPDFCore_textAsHtml)(JNIEnv * env, jobject thiz)
+{
+ fz_text_sheet *sheet = NULL;
+ fz_text_page *text = NULL;
+ fz_device *dev = NULL;
+ fz_matrix ctm;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ page_cache *pc = &glo->pages[glo->current];
+ jbyteArray bArray = NULL;
+ fz_buffer *buf = NULL;
+ fz_output *out = NULL;
+
+ fz_var(sheet);
+ fz_var(text);
+ fz_var(dev);
+
+ fz_try(ctx)
+ {
+ int b, l, s, c;
+
+ ctm = fz_identity;
+ sheet = fz_new_text_sheet(ctx);
+ text = fz_new_text_page(ctx);
+ dev = fz_new_text_device(ctx, sheet, text);
+ fz_run_page(doc, pc->page, dev, &ctm, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+
+ fz_analyze_text(ctx, sheet, text);
+
+ buf = fz_new_buffer(ctx, 256);
+ out = fz_new_output_with_buffer(ctx, buf);
+ fz_printf(out, "<html>\n");
+ fz_printf(out, "<style>\n");
+ fz_printf(out, "body{margin:0;}\n");
+ fz_printf(out, "div.page{background-color:white;}\n");
+ fz_printf(out, "div.block{margin:0pt;padding:0pt;}\n");
+ fz_printf(out, "div.metaline{display:table;width:100%%}\n");
+ fz_printf(out, "div.line{display:table-row;}\n");
+ fz_printf(out, "div.cell{display:table-cell;padding-left:0.25em;padding-right:0.25em}\n");
+ //fz_printf(out, "p{margin:0;padding:0;}\n");
+ fz_printf(out, "</style>\n");
+ fz_printf(out, "<body style=\"margin:0\"><div style=\"padding:10px\" id=\"content\">");
+ fz_print_text_page_html(ctx, out, text);
+ fz_printf(out, "</div></body>\n");
+ fz_printf(out, "<style>\n");
+ fz_print_text_sheet(ctx, out, sheet);
+ fz_printf(out, "</style>\n</html>\n");
+ fz_close_output(out);
+ out = NULL;
+
+ bArray = (*env)->NewByteArray(env, buf->len);
+ if (bArray == NULL)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to make byteArray");
+ (*env)->SetByteArrayRegion(env, bArray, 0, buf->len, buf->data);
+
+ }
+ fz_always(ctx)
+ {
+ fz_free_text_page(ctx, text);
+ fz_free_text_sheet(ctx, sheet);
+ fz_free_device(dev);
+ fz_close_output(out);
+ fz_drop_buffer(ctx, buf);
+ }
+ fz_catch(ctx)
+ {
+ jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_textAsHtml");
+ (*env)->DeleteLocalRef(env, cls);
+
+ return NULL;
+ }
+
+ return bArray;
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_addMarkupAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray points, fz_annot_type type)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ pdf_document *idoc = pdf_specifics(doc);
+ page_cache *pc = &glo->pages[glo->current];
+ jclass pt_cls;
+ jfieldID x_fid, y_fid;
+ int i, n;
+ fz_point *pts = NULL;
+ float color[3];
+ float alpha;
+ float line_height;
+ float line_thickness;
+
+ if (idoc == NULL)
+ return;
+
+ switch (type)
+ {
+ case FZ_ANNOT_HIGHLIGHT:
+ color[0] = 1.0;
+ color[1] = 1.0;
+ color[2] = 0.0;
+ alpha = 0.5;
+ line_thickness = 1.0;
+ line_height = 0.5;
+ break;
+ case FZ_ANNOT_UNDERLINE:
+ color[0] = 0.0;
+ color[1] = 0.0;
+ color[2] = 1.0;
+ alpha = 1.0;
+ line_thickness = LINE_THICKNESS;
+ line_height = UNDERLINE_HEIGHT;
+ break;
+ case FZ_ANNOT_STRIKEOUT:
+ color[0] = 1.0;
+ color[1] = 0.0;
+ color[2] = 0.0;
+ alpha = 1.0;
+ line_thickness = LINE_THICKNESS;
+ line_height = STRIKE_HEIGHT;
+ break;
+ default:
+ return;
+ }
+
+ fz_var(pts);
+ fz_try(ctx)
+ {
+ fz_annot *annot;
+ fz_matrix ctm;
+
+ float zoom = glo->resolution / 72;
+ zoom = 1.0 / zoom;
+ fz_scale(&ctm, zoom, zoom);
+ pt_cls = (*env)->FindClass(env, "android.graphics.PointF");
+ if (pt_cls == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "FindClass");
+ x_fid = (*env)->GetFieldID(env, pt_cls, "x", "F");
+ if (x_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(x)");
+ y_fid = (*env)->GetFieldID(env, pt_cls, "y", "F");
+ if (y_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(y)");
+
+ n = (*env)->GetArrayLength(env, points);
+
+ pts = fz_malloc_array(ctx, n, sizeof(fz_point));
+
+ for (i = 0; i < n; i++)
+ {
+ jobject opt = (*env)->GetObjectArrayElement(env, points, i);
+ pts[i].x = opt ? (*env)->GetFloatField(env, opt, x_fid) : 0.0f;
+ pts[i].y = opt ? (*env)->GetFloatField(env, opt, y_fid) : 0.0f;
+ fz_transform_point(&pts[i], &ctm);
+ }
+
+ annot = (fz_annot *)pdf_create_annot(idoc, (pdf_page *)pc->page, type);
+
+ pdf_set_markup_annot_quadpoints(idoc, (pdf_annot *)annot, pts, n);
+ pdf_set_markup_appearance(idoc, (pdf_annot *)annot, color, alpha, line_thickness, line_height);
+
+ dump_annotation_display_lists(glo);
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, pts);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("addStrikeOutAnnotation: %s failed", ctx->error->message);
+ jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage");
+ (*env)->DeleteLocalRef(env, cls);
+ }
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray arcs)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ pdf_document *idoc = pdf_specifics(doc);
+ page_cache *pc = &glo->pages[glo->current];
+ jclass pt_cls;
+ jfieldID x_fid, y_fid;
+ int i, j, k, n;
+ fz_point *pts = NULL;
+ int *counts = NULL;
+ int total = 0;
+ float color[3];
+
+ if (idoc == NULL)
+ return;
+
+ color[0] = 1.0;
+ color[1] = 0.0;
+ color[2] = 0.0;
+
+ fz_var(pts);
+ fz_var(counts);
+ fz_try(ctx)
+ {
+ fz_annot *annot;
+ fz_matrix ctm;
+
+ float zoom = glo->resolution / 72;
+ zoom = 1.0 / zoom;
+ fz_scale(&ctm, zoom, zoom);
+ pt_cls = (*env)->FindClass(env, "android.graphics.PointF");
+ if (pt_cls == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "FindClass");
+ x_fid = (*env)->GetFieldID(env, pt_cls, "x", "F");
+ if (x_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(x)");
+ y_fid = (*env)->GetFieldID(env, pt_cls, "y", "F");
+ if (y_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(y)");
+
+ n = (*env)->GetArrayLength(env, arcs);
+
+ counts = fz_malloc_array(ctx, n, sizeof(int));
+
+ for (i = 0; i < n; i++)
+ {
+ jobjectArray arc = (jobjectArray)(*env)->GetObjectArrayElement(env, arcs, i);
+ int count = (*env)->GetArrayLength(env, arc);
+
+ counts[i] = count;
+ total += count;
+ }
+
+ pts = fz_malloc_array(ctx, total, sizeof(fz_point));
+
+ k = 0;
+ for (i = 0; i < n; i++)
+ {
+ jobjectArray arc = (jobjectArray)(*env)->GetObjectArrayElement(env, arcs, i);
+ int count = counts[i];
+
+ for (j = 0; j < count; j++)
+ {
+ jobject pt = (*env)->GetObjectArrayElement(env, arc, j);
+
+ pts[k].x = pt ? (*env)->GetFloatField(env, pt, x_fid) : 0.0f;
+ pts[k].y = pt ? (*env)->GetFloatField(env, pt, y_fid) : 0.0f;
+ fz_transform_point(&pts[k], &ctm);
+ k++;
+ }
+ }
+
+ annot = (fz_annot *)pdf_create_annot(idoc, (pdf_page *)pc->page, FZ_ANNOT_INK);
+
+ pdf_set_ink_annot_list(idoc, (pdf_annot *)annot, pts, counts, n, color, INK_THICKNESS);
+
+ dump_annotation_display_lists(glo);
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, pts);
+ fz_free(ctx, counts);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("addInkAnnotation: %s failed", ctx->error->message);
+ jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage");
+ (*env)->DeleteLocalRef(env, cls);
+ }
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_deleteAnnotationInternal)(JNIEnv * env, jobject thiz, int annot_index)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_document *doc = glo->doc;
+ pdf_document *idoc = pdf_specifics(doc);
+ page_cache *pc = &glo->pages[glo->current];
+ fz_annot *annot;
+ int i;
+
+ if (idoc == NULL)
+ return;
+
+ fz_try(ctx)
+ {
+ annot = fz_first_annot(glo->doc, pc->page);
+ for (i = 0; i < annot_index && annot; i++)
+ annot = fz_next_annot(glo->doc, annot);
+
+ if (annot)
+ {
+ pdf_delete_annot(idoc, (pdf_page *)pc->page, (pdf_annot *)annot);
+ dump_annotation_display_lists(glo);
+ }
+ }
+ fz_catch(ctx)
+ {
+ LOGE("deleteAnnotationInternal: %s", ctx->error->message);
+ }
+}
+
+/* Close the document, at least enough to be able to save over it. This
+ * may be called again later, so must be idempotent. */
+static void close_doc(globals *glo)
+{
+ int i;
+
+ fz_free(glo->ctx, glo->hit_bbox);
+ glo->hit_bbox = NULL;
+
+ for (i = 0; i < NUM_CACHE; i++)
+ drop_page_cache(glo, &glo->pages[i]);
+
+ alerts_fin(glo);
+
+ fz_close_document(glo->doc);
+ glo->doc = NULL;
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_destroying)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+
+ if (glo == NULL)
+ return;
+ LOGI("Destroying");
+ fz_free(glo->ctx, glo->current_path);
+ glo->current_path = NULL;
+ close_doc(glo);
+ fz_free_context(glo->ctx);
+ glo->ctx = NULL;
+ free(glo);
+#ifdef MEMENTO
+ LOGI("Destroying dump start");
+ Memento_listBlocks();
+ Memento_stats();
+ LOGI("Destroying dump end");
+#endif
+#ifdef NDK_PROFILER
+ // Apparently we should really be writing to whatever path we get
+ // from calling getFilesDir() in the java part, which supposedly
+ // gives /sdcard/data/data/com.artifex.MuPDF/gmon.out, but that's
+ // unfriendly.
+ setenv("CPUPROFILE", "/sdcard/gmon.out", 1);
+ moncleanup();
+#endif
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getPageLinksInternal)(JNIEnv * env, jobject thiz, int pageNumber)
+{
+ jclass linkInfoClass;
+ jclass linkInfoInternalClass;
+ jclass linkInfoExternalClass;
+ jclass linkInfoRemoteClass;
+ jmethodID ctorInternal;
+ jmethodID ctorExternal;
+ jmethodID ctorRemote;
+ jobjectArray arr;
+ jobject linkInfo;
+ fz_matrix ctm;
+ float zoom;
+ fz_link *list;
+ fz_link *link;
+ int count;
+ page_cache *pc;
+ globals *glo = get_globals(env, thiz);
+
+ linkInfoClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfo");
+ if (linkInfoClass == NULL) return NULL;
+ linkInfoInternalClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoInternal");
+ if (linkInfoInternalClass == NULL) return NULL;
+ linkInfoExternalClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoExternal");
+ if (linkInfoExternalClass == NULL) return NULL;
+ linkInfoRemoteClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoRemote");
+ if (linkInfoRemoteClass == NULL) return NULL;
+ ctorInternal = (*env)->GetMethodID(env, linkInfoInternalClass, "<init>", "(FFFFI)V");
+ if (ctorInternal == NULL) return NULL;
+ ctorExternal = (*env)->GetMethodID(env, linkInfoExternalClass, "<init>", "(FFFFLjava/lang/String;)V");
+ if (ctorExternal == NULL) return NULL;
+ ctorRemote = (*env)->GetMethodID(env, linkInfoRemoteClass, "<init>", "(FFFFLjava/lang/String;IZ)V");
+ if (ctorRemote == NULL) return NULL;
+
+ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
+ pc = &glo->pages[glo->current];
+ if (pc->page == NULL || pc->number != pageNumber)
+ return NULL;
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+
+ list = fz_load_links(glo->doc, pc->page);
+ count = 0;
+ for (link = list; link; link = link->next)
+ {
+ switch (link->dest.kind)
+ {
+ case FZ_LINK_GOTO:
+ case FZ_LINK_GOTOR:
+ case FZ_LINK_URI:
+ count++ ;
+ }
+ }
+
+ arr = (*env)->NewObjectArray(env, count, linkInfoClass, NULL);
+ if (arr == NULL)
+ {
+ fz_drop_link(glo->ctx, list);
+ return NULL;
+ }
+
+ count = 0;
+ for (link = list; link; link = link->next)
+ {
+ fz_rect rect = link->rect;
+ fz_transform_rect(&rect, &ctm);
+
+ switch (link->dest.kind)
+ {
+ case FZ_LINK_GOTO:
+ {
+ linkInfo = (*env)->NewObject(env, linkInfoInternalClass, ctorInternal,
+ (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
+ link->dest.ld.gotor.page);
+ break;
+ }
+
+ case FZ_LINK_GOTOR:
+ {
+ jstring juri = (*env)->NewStringUTF(env, link->dest.ld.gotor.file_spec);
+ linkInfo = (*env)->NewObject(env, linkInfoRemoteClass, ctorRemote,
+ (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
+ juri, link->dest.ld.gotor.page, link->dest.ld.gotor.new_window ? JNI_TRUE : JNI_FALSE);
+ break;
+ }
+
+ case FZ_LINK_URI:
+ {
+ jstring juri = (*env)->NewStringUTF(env, link->dest.ld.uri.uri);
+ linkInfo = (*env)->NewObject(env, linkInfoExternalClass, ctorExternal,
+ (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
+ juri);
+ break;
+ }
+
+ default:
+ continue;
+ }
+
+ if (linkInfo == NULL)
+ {
+ fz_drop_link(glo->ctx, list);
+ return NULL;
+ }
+ (*env)->SetObjectArrayElement(env, arr, count, linkInfo);
+ (*env)->DeleteLocalRef(env, linkInfo);
+ count++;
+ }
+ fz_drop_link(glo->ctx, list);
+
+ return arr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getWidgetAreasInternal)(JNIEnv * env, jobject thiz, int pageNumber)
+{
+ jclass rectFClass;
+ jmethodID ctor;
+ jobjectArray arr;
+ jobject rectF;
+ pdf_document *idoc;
+ pdf_widget *widget;
+ fz_matrix ctm;
+ float zoom;
+ int count;
+ page_cache *pc;
+ globals *glo = get_globals(env, thiz);
+
+ rectFClass = (*env)->FindClass(env, "android/graphics/RectF");
+ if (rectFClass == NULL) return NULL;
+ ctor = (*env)->GetMethodID(env, rectFClass, "<init>", "(FFFF)V");
+ if (ctor == NULL) return NULL;
+
+ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
+ pc = &glo->pages[glo->current];
+ if (pc->number != pageNumber || pc->page == NULL)
+ return NULL;
+
+ idoc = pdf_specifics(glo->doc);
+ if (idoc == NULL)
+ return NULL;
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+
+ count = 0;
+ for (widget = pdf_first_widget(idoc, (pdf_page *)pc->page); widget; widget = pdf_next_widget(widget))
+ count ++;
+
+ arr = (*env)->NewObjectArray(env, count, rectFClass, NULL);
+ if (arr == NULL) return NULL;
+
+ count = 0;
+ for (widget = pdf_first_widget(idoc, (pdf_page *)pc->page); widget; widget = pdf_next_widget(widget))
+ {
+ fz_rect rect;
+ pdf_bound_widget(widget, &rect);
+ fz_transform_rect(&rect, &ctm);
+
+ rectF = (*env)->NewObject(env, rectFClass, ctor,
+ (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1);
+ if (rectF == NULL) return NULL;
+ (*env)->SetObjectArrayElement(env, arr, count, rectF);
+ (*env)->DeleteLocalRef(env, rectF);
+
+ count ++;
+ }
+
+ return arr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getAnnotationsInternal)(JNIEnv * env, jobject thiz, int pageNumber)
+{
+ jclass annotClass;
+ jmethodID ctor;
+ jobjectArray arr;
+ jobject jannot;
+ fz_annot *annot;
+ fz_matrix ctm;
+ float zoom;
+ int count;
+ page_cache *pc;
+ globals *glo = get_globals(env, thiz);
+
+ annotClass = (*env)->FindClass(env, PACKAGENAME "/Annotation");
+ if (annotClass == NULL) return NULL;
+ ctor = (*env)->GetMethodID(env, annotClass, "<init>", "(FFFFI)V");
+ if (ctor == NULL) return NULL;
+
+ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
+ pc = &glo->pages[glo->current];
+ if (pc->number != pageNumber || pc->page == NULL)
+ return NULL;
+
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+
+ count = 0;
+ for (annot = fz_first_annot(glo->doc, pc->page); annot; annot = fz_next_annot(glo->doc, annot))
+ count ++;
+
+ arr = (*env)->NewObjectArray(env, count, annotClass, NULL);
+ if (arr == NULL) return NULL;
+
+ count = 0;
+ for (annot = fz_first_annot(glo->doc, pc->page); annot; annot = fz_next_annot(glo->doc, annot))
+ {
+ fz_rect rect;
+ fz_annot_type type = pdf_annot_type((pdf_annot *)annot);
+ fz_bound_annot(glo->doc, annot, &rect);
+ fz_transform_rect(&rect, &ctm);
+
+ jannot = (*env)->NewObject(env, annotClass, ctor,
+ (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1, type);
+ if (jannot == NULL) return NULL;
+ (*env)->SetObjectArrayElement(env, arr, count, jannot);
+ (*env)->DeleteLocalRef(env, jannot);
+
+ count ++;
+ }
+
+ return arr;
+}
+
+JNIEXPORT int JNICALL
+JNI_FN(MuPDFCore_passClickEventInternal)(JNIEnv * env, jobject thiz, int pageNumber, float x, float y)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_matrix ctm;
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ float zoom;
+ fz_point p;
+ pdf_ui_event event;
+ int changed = 0;
+ page_cache *pc;
+
+ if (idoc == NULL)
+ return 0;
+
+ JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
+ pc = &glo->pages[glo->current];
+ if (pc->number != pageNumber || pc->page == NULL)
+ return 0;
+
+ p.x = x;
+ p.y = y;
+
+ /* Ultimately we should probably return a pointer to a java structure
+ * with the link details in, but for now, page number will suffice.
+ */
+ zoom = glo->resolution / 72;
+ fz_scale(&ctm, zoom, zoom);
+ fz_invert_matrix(&ctm, &ctm);
+
+ fz_transform_point(&p, &ctm);
+
+ fz_try(ctx)
+ {
+ event.etype = PDF_EVENT_TYPE_POINTER;
+ event.event.pointer.pt = p;
+ event.event.pointer.ptype = PDF_POINTER_DOWN;
+ changed = pdf_pass_event(idoc, (pdf_page *)pc->page, &event);
+ event.event.pointer.ptype = PDF_POINTER_UP;
+ changed |= pdf_pass_event(idoc, (pdf_page *)pc->page, &event);
+ if (changed) {
+ dump_annotation_display_lists(glo);
+ }
+ }
+ fz_catch(ctx)
+ {
+ LOGE("passClickEvent: %s", ctx->error->message);
+ }
+
+ return changed;
+}
+
+JNIEXPORT jstring JNICALL
+JNI_FN(MuPDFCore_getFocusedWidgetTextInternal)(JNIEnv * env, jobject thiz)
+{
+ char *text = "";
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+
+ fz_try(ctx)
+ {
+ pdf_document *idoc = pdf_specifics(glo->doc);
+
+ if (idoc)
+ {
+ pdf_widget *focus = pdf_focused_widget(idoc);
+
+ if (focus)
+ text = pdf_text_widget_text(idoc, focus);
+ }
+ }
+ fz_catch(ctx)
+ {
+ LOGE("getFocusedWidgetText failed: %s", ctx->error->message);
+ }
+
+ return (*env)->NewStringUTF(env, text);
+}
+
+JNIEXPORT int JNICALL
+JNI_FN(MuPDFCore_setFocusedWidgetTextInternal)(JNIEnv * env, jobject thiz, jstring jtext)
+{
+ const char *text;
+ int result = 0;
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+
+ text = (*env)->GetStringUTFChars(env, jtext, NULL);
+ if (text == NULL)
+ {
+ LOGE("Failed to get text");
+ return 0;
+ }
+
+ fz_try(ctx)
+ {
+ pdf_document *idoc = pdf_specifics(glo->doc);
+
+ if (idoc)
+ {
+ pdf_widget *focus = pdf_focused_widget(idoc);
+
+ if (focus)
+ {
+ result = pdf_text_widget_set_text(idoc, focus, (char *)text);
+ dump_annotation_display_lists(glo);
+ }
+ }
+ }
+ fz_catch(ctx)
+ {
+ LOGE("setFocusedWidgetText failed: %s", ctx->error->message);
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jtext, text);
+
+ return result;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getFocusedWidgetChoiceOptions)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ pdf_widget *focus;
+ int type;
+ int nopts, i;
+ char **opts = NULL;
+ jclass stringClass;
+ jobjectArray arr;
+
+ if (idoc == NULL)
+ return NULL;
+
+ focus = pdf_focused_widget(idoc);
+ if (focus == NULL)
+ return NULL;
+
+ type = pdf_widget_get_type(focus);
+ if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
+ return NULL;
+
+ fz_var(opts);
+ fz_try(ctx)
+ {
+ nopts = pdf_choice_widget_options(idoc, focus, NULL);
+ opts = fz_malloc(ctx, nopts * sizeof(*opts));
+ (void)pdf_choice_widget_options(idoc, focus, opts);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, opts);
+ LOGE("Failed in getFocuseedWidgetChoiceOptions");
+ return NULL;
+ }
+
+ stringClass = (*env)->FindClass(env, "java/lang/String");
+
+ arr = (*env)->NewObjectArray(env, nopts, stringClass, NULL);
+
+ for (i = 0; i < nopts; i++)
+ {
+ jstring s = (*env)->NewStringUTF(env, opts[i]);
+ if (s != NULL)
+ (*env)->SetObjectArrayElement(env, arr, i, s);
+
+ (*env)->DeleteLocalRef(env, s);
+ }
+
+ fz_free(ctx, opts);
+
+ return arr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+JNI_FN(MuPDFCore_getFocusedWidgetChoiceSelected)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ pdf_widget *focus;
+ int type;
+ int nsel, i;
+ char **sel = NULL;
+ jclass stringClass;
+ jobjectArray arr;
+
+ if (idoc == NULL)
+ return NULL;
+
+ focus = pdf_focused_widget(idoc);
+ if (focus == NULL)
+ return NULL;
+
+ type = pdf_widget_get_type(focus);
+ if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
+ return NULL;
+
+ fz_var(sel);
+ fz_try(ctx)
+ {
+ nsel = pdf_choice_widget_value(idoc, focus, NULL);
+ sel = fz_malloc(ctx, nsel * sizeof(*sel));
+ (void)pdf_choice_widget_value(idoc, focus, sel);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, sel);
+ LOGE("Failed in getFocuseedWidgetChoiceOptions");
+ return NULL;
+ }
+
+ stringClass = (*env)->FindClass(env, "java/lang/String");
+
+ arr = (*env)->NewObjectArray(env, nsel, stringClass, NULL);
+
+ for (i = 0; i < nsel; i++)
+ {
+ jstring s = (*env)->NewStringUTF(env, sel[i]);
+ if (s != NULL)
+ (*env)->SetObjectArrayElement(env, arr, i, s);
+
+ (*env)->DeleteLocalRef(env, s);
+ }
+
+ fz_free(ctx, sel);
+
+ return arr;
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_setFocusedWidgetChoiceSelectedInternal)(JNIEnv * env, jobject thiz, jobjectArray arr)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ pdf_widget *focus;
+ int type;
+ int nsel, i;
+ char **sel = NULL;
+ jstring *objs = NULL;
+
+ if (idoc == NULL)
+ return;
+
+ focus = pdf_focused_widget(idoc);
+ if (focus == NULL)
+ return;
+
+ type = pdf_widget_get_type(focus);
+ if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
+ return;
+
+ nsel = (*env)->GetArrayLength(env, arr);
+
+ sel = calloc(nsel, sizeof(*sel));
+ objs = calloc(nsel, sizeof(*objs));
+ if (objs == NULL || sel == NULL)
+ {
+ free(sel);
+ free(objs);
+ LOGE("Failed in setFocusWidgetChoiceSelected");
+ return;
+ }
+
+ for (i = 0; i < nsel; i++)
+ {
+ objs[i] = (jstring)(*env)->GetObjectArrayElement(env, arr, i);
+ sel[i] = (char *)(*env)->GetStringUTFChars(env, objs[i], NULL);
+ }
+
+ fz_try(ctx)
+ {
+ pdf_choice_widget_set_value(idoc, focus, nsel, sel);
+ dump_annotation_display_lists(glo);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Failed in setFocusWidgetChoiceSelected");
+ }
+
+ for (i = 0; i < nsel; i++)
+ (*env)->ReleaseStringUTFChars(env, objs[i], sel[i]);
+
+ free(sel);
+ free(objs);
+}
+
+JNIEXPORT int JNICALL
+JNI_FN(MuPDFCore_getFocusedWidgetTypeInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ pdf_document *idoc = pdf_specifics(glo->doc);
+ pdf_widget *focus;
+
+ if (idoc == NULL)
+ return NONE;
+
+ focus = pdf_focused_widget(idoc);
+
+ if (focus == NULL)
+ return NONE;
+
+ switch (pdf_widget_get_type(focus))
+ {
+ case PDF_WIDGET_TYPE_TEXT: return TEXT;
+ case PDF_WIDGET_TYPE_LISTBOX: return LISTBOX;
+ case PDF_WIDGET_TYPE_COMBOBOX: return COMBOBOX;
+ }
+
+ return NONE;
+}
+
+JNIEXPORT jobject JNICALL
+JNI_FN(MuPDFCore_waitForAlertInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ jclass alertClass;
+ jmethodID ctor;
+ jstring title;
+ jstring message;
+ int alert_present;
+ pdf_alert_event alert;
+
+ LOGT("Enter waitForAlert");
+ pthread_mutex_lock(&glo->fin_lock);
+ pthread_mutex_lock(&glo->alert_lock);
+
+ while (glo->alerts_active && !glo->alert_request)
+ pthread_cond_wait(&glo->alert_request_cond, &glo->alert_lock);
+ glo->alert_request = 0;
+
+ alert_present = (glo->alerts_active && glo->current_alert);
+
+ if (alert_present)
+ alert = *glo->current_alert;
+
+ pthread_mutex_unlock(&glo->alert_lock);
+ pthread_mutex_unlock(&glo->fin_lock);
+ LOGT("Exit waitForAlert %d", alert_present);
+
+ if (!alert_present)
+ return NULL;
+
+ alertClass = (*env)->FindClass(env, PACKAGENAME "/MuPDFAlertInternal");
+ if (alertClass == NULL)
+ return NULL;
+
+ ctor = (*env)->GetMethodID(env, alertClass, "<init>", "(Ljava/lang/String;IILjava/lang/String;I)V");
+ if (ctor == NULL)
+ return NULL;
+
+ title = (*env)->NewStringUTF(env, alert.title);
+ if (title == NULL)
+ return NULL;
+
+ message = (*env)->NewStringUTF(env, alert.message);
+ if (message == NULL)
+ return NULL;
+
+ return (*env)->NewObject(env, alertClass, ctor, message, alert.icon_type, alert.button_group_type, title, alert.button_pressed);
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_replyToAlertInternal)(JNIEnv * env, jobject thiz, jobject alert)
+{
+ globals *glo = get_globals(env, thiz);
+ jclass alertClass;
+ jfieldID field;
+ int button_pressed;
+
+ alertClass = (*env)->FindClass(env, PACKAGENAME "/MuPDFAlertInternal");
+ if (alertClass == NULL)
+ return;
+
+ field = (*env)->GetFieldID(env, alertClass, "buttonPressed", "I");
+ if (field == NULL)
+ return;
+
+ button_pressed = (*env)->GetIntField(env, alert, field);
+
+ LOGT("Enter replyToAlert");
+ pthread_mutex_lock(&glo->alert_lock);
+
+ if (glo->alerts_active && glo->current_alert)
+ {
+ // Fill in button_pressed and signal reply received.
+ glo->current_alert->button_pressed = button_pressed;
+ glo->alert_reply = 1;
+ pthread_cond_signal(&glo->alert_reply_cond);
+ }
+
+ pthread_mutex_unlock(&glo->alert_lock);
+ LOGT("Exit replyToAlert");
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_startAlertsInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+
+ if (!glo->alerts_initialised)
+ return;
+
+ LOGT("Enter startAlerts");
+ pthread_mutex_lock(&glo->alert_lock);
+
+ glo->alert_reply = 0;
+ glo->alert_request = 0;
+ glo->alerts_active = 1;
+ glo->current_alert = NULL;
+
+ pthread_mutex_unlock(&glo->alert_lock);
+ LOGT("Exit startAlerts");
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_stopAlertsInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+
+ if (!glo->alerts_initialised)
+ return;
+
+ LOGT("Enter stopAlerts");
+ pthread_mutex_lock(&glo->alert_lock);
+
+ glo->alert_reply = 0;
+ glo->alert_request = 0;
+ glo->alerts_active = 0;
+ glo->current_alert = NULL;
+ pthread_cond_signal(&glo->alert_reply_cond);
+ pthread_cond_signal(&glo->alert_request_cond);
+
+ pthread_mutex_unlock(&glo->alert_lock);
+ LOGT("Exit stopAleerts");
+}
+
+JNIEXPORT jboolean JNICALL
+JNI_FN(MuPDFCore_hasChangesInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ pdf_document *idoc = pdf_specifics(glo->doc);
+
+ return (idoc && pdf_has_unsaved_changes(idoc)) ? JNI_TRUE : JNI_FALSE;
+}
+
+static char *tmp_path(char *path)
+{
+ int f;
+ char *buf = malloc(strlen(path) + 6 + 1);
+ if (!buf)
+ return NULL;
+
+ strcpy(buf, path);
+ strcat(buf, "XXXXXX");
+
+ f = mkstemp(buf);
+
+ if (f >= 0)
+ {
+ close(f);
+ return buf;
+ }
+ else
+ {
+ free(buf);
+ return NULL;
+ }
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_saveInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+
+ if (glo->doc && glo->current_path)
+ {
+ char *tmp;
+ fz_write_options opts;
+ opts.do_ascii = 1;
+ opts.do_expand = 0;
+ opts.do_garbage = 1;
+ opts.do_linear = 0;
+
+ tmp = tmp_path(glo->current_path);
+ if (tmp)
+ {
+ int written;
+
+ fz_var(written);
+ fz_try(ctx)
+ {
+ fz_write_document(glo->doc, tmp, &opts);
+ written = 1;
+ }
+ fz_catch(ctx)
+ {
+ written = 0;
+ }
+
+ if (written)
+ {
+ close_doc(glo);
+ rename(tmp, glo->current_path);
+ }
+
+ free(tmp);
+ }
+ }
+}
+
+JNIEXPORT void JNICALL
+JNI_FN(MuPDFCore_dumpMemoryInternal)(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+
+#ifdef MEMENTO
+ LOGE("dumpMemoryInternal start");
+ Memento_listNewBlocks();
+ Memento_stats();
+ LOGE("dumpMemoryInternal end");
+#endif
+}
diff --git a/platform/android/local.properties.sample b/platform/android/local.properties.sample
new file mode 100644
index 00000000..557fbc14
--- /dev/null
+++ b/platform/android/local.properties.sample
@@ -0,0 +1,8 @@
+# Uncomment and edit the appropriate line below.
+# Resave this file as local.properties.
+
+# For MacOS/Linux you want a line such as:
+#sdk.dir=/Library/android-sdk-mac_x86
+
+# For Windows/Cygwin you want something like the following:
+#sdk.dir=C:\\Program Files (x86)\\Android\\android-sdk
diff --git a/platform/android/project.properties b/platform/android/project.properties
new file mode 100644
index 00000000..d79abae1
--- /dev/null
+++ b/platform/android/project.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,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-11
diff --git a/platform/android/res/animator/info.xml b/platform/android/res/animator/info.xml
new file mode 100644
index 00000000..9085a9ee
--- /dev/null
+++ b/platform/android/res/animator/info.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:ordering="sequentially" >
+
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:duration="200" />
+
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueTo="1.0"
+ android:duration="800" />
+
+ <objectAnimator
+ android:propertyName="alpha"
+ android:valueTo="0.0"
+ android:duration="400" />
+</set>
diff --git a/platform/android/res/drawable-hdpi/icon.png b/platform/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..4f47347d
--- /dev/null
+++ b/platform/android/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_annot.png b/platform/android/res/drawable-ldpi/ic_annot.png
new file mode 100644
index 00000000..c4f1df07
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_annot.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_annotation.png b/platform/android/res/drawable-ldpi/ic_annotation.png
new file mode 100644
index 00000000..1f4e6d48
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_annotation.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_arrow_left.png b/platform/android/res/drawable-ldpi/ic_arrow_left.png
new file mode 100644
index 00000000..d49c7438
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_arrow_left.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_arrow_right.png b/platform/android/res/drawable-ldpi/ic_arrow_right.png
new file mode 100644
index 00000000..e76d0cb0
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_arrow_right.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_cancel.png b/platform/android/res/drawable-ldpi/ic_cancel.png
new file mode 100644
index 00000000..6912e1ed
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_cancel.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_check.png b/platform/android/res/drawable-ldpi/ic_check.png
new file mode 100644
index 00000000..fb789c8d
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_check.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_clipboard.png b/platform/android/res/drawable-ldpi/ic_clipboard.png
new file mode 100644
index 00000000..3023c6eb
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_clipboard.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_dir.png b/platform/android/res/drawable-ldpi/ic_dir.png
new file mode 100644
index 00000000..2236f2f8
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_dir.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_doc.png b/platform/android/res/drawable-ldpi/ic_doc.png
new file mode 100644
index 00000000..407ed5d4
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_doc.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_highlight.png b/platform/android/res/drawable-ldpi/ic_highlight.png
new file mode 100644
index 00000000..3d6d29b9
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_highlight.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_link.png b/platform/android/res/drawable-ldpi/ic_link.png
new file mode 100644
index 00000000..a447b87d
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_link.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_list.png b/platform/android/res/drawable-ldpi/ic_list.png
new file mode 100644
index 00000000..4a2dde6d
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_list.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_magnifying_glass.png b/platform/android/res/drawable-ldpi/ic_magnifying_glass.png
new file mode 100644
index 00000000..a3c8f598
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_magnifying_glass.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_more.png b/platform/android/res/drawable-ldpi/ic_more.png
new file mode 100644
index 00000000..68988a56
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_more.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_pen.png b/platform/android/res/drawable-ldpi/ic_pen.png
new file mode 100644
index 00000000..7b7de296
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_pen.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_print.png b/platform/android/res/drawable-ldpi/ic_print.png
new file mode 100644
index 00000000..f191fc85
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_print.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_reflow.png b/platform/android/res/drawable-ldpi/ic_reflow.png
new file mode 100644
index 00000000..e9e8b052
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_reflow.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_select.png b/platform/android/res/drawable-ldpi/ic_select.png
new file mode 100644
index 00000000..81af6738
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_select.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_strike.png b/platform/android/res/drawable-ldpi/ic_strike.png
new file mode 100644
index 00000000..fc39409f
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_strike.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_trash.png b/platform/android/res/drawable-ldpi/ic_trash.png
new file mode 100644
index 00000000..465d1245
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_trash.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_underline.png b/platform/android/res/drawable-ldpi/ic_underline.png
new file mode 100644
index 00000000..0a5be3d4
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_underline.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/ic_updir.png b/platform/android/res/drawable-ldpi/ic_updir.png
new file mode 100644
index 00000000..b923e429
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/ic_updir.png
Binary files differ
diff --git a/platform/android/res/drawable-ldpi/icon.png b/platform/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..82655e72
--- /dev/null
+++ b/platform/android/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_annot.png b/platform/android/res/drawable-mdpi/ic_annot.png
new file mode 100644
index 00000000..0b4bfd92
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_annot.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_annotation.png b/platform/android/res/drawable-mdpi/ic_annotation.png
new file mode 100644
index 00000000..6f81c4a0
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_annotation.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_arrow_left.png b/platform/android/res/drawable-mdpi/ic_arrow_left.png
new file mode 100644
index 00000000..16a31b21
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_arrow_left.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_arrow_right.png b/platform/android/res/drawable-mdpi/ic_arrow_right.png
new file mode 100644
index 00000000..cc34067e
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_arrow_right.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_arrow_up.png b/platform/android/res/drawable-mdpi/ic_arrow_up.png
new file mode 100644
index 00000000..de2726ce
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_arrow_up.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_cancel.png b/platform/android/res/drawable-mdpi/ic_cancel.png
new file mode 100644
index 00000000..0b794b4d
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_cancel.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_check.png b/platform/android/res/drawable-mdpi/ic_check.png
new file mode 100644
index 00000000..527aaeb9
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_check.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_clipboard.png b/platform/android/res/drawable-mdpi/ic_clipboard.png
new file mode 100644
index 00000000..c05deffd
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_clipboard.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_dir.png b/platform/android/res/drawable-mdpi/ic_dir.png
new file mode 100644
index 00000000..e15200c5
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_dir.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_doc.png b/platform/android/res/drawable-mdpi/ic_doc.png
new file mode 100644
index 00000000..1eb722be
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_doc.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_highlight.png b/platform/android/res/drawable-mdpi/ic_highlight.png
new file mode 100644
index 00000000..2a8fe4db
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_highlight.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_link.png b/platform/android/res/drawable-mdpi/ic_link.png
new file mode 100644
index 00000000..7f7ac170
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_link.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_list.png b/platform/android/res/drawable-mdpi/ic_list.png
new file mode 100644
index 00000000..e4f3164c
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_list.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_magnifying_glass.png b/platform/android/res/drawable-mdpi/ic_magnifying_glass.png
new file mode 100644
index 00000000..389cebd5
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_magnifying_glass.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_more.png b/platform/android/res/drawable-mdpi/ic_more.png
new file mode 100644
index 00000000..2b662ab3
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_more.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_pen.png b/platform/android/res/drawable-mdpi/ic_pen.png
new file mode 100644
index 00000000..db805373
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_pen.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_print.png b/platform/android/res/drawable-mdpi/ic_print.png
new file mode 100644
index 00000000..58105463
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_print.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_reflow.png b/platform/android/res/drawable-mdpi/ic_reflow.png
new file mode 100644
index 00000000..84bd5418
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_reflow.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_select.png b/platform/android/res/drawable-mdpi/ic_select.png
new file mode 100644
index 00000000..9eaf6924
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_select.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_strike.png b/platform/android/res/drawable-mdpi/ic_strike.png
new file mode 100644
index 00000000..b15e9324
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_strike.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_trash.png b/platform/android/res/drawable-mdpi/ic_trash.png
new file mode 100644
index 00000000..3006fec3
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_trash.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/ic_underline.png b/platform/android/res/drawable-mdpi/ic_underline.png
new file mode 100644
index 00000000..5d4dd5a4
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/ic_underline.png
Binary files differ
diff --git a/platform/android/res/drawable-mdpi/icon.png b/platform/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..e05de27c
--- /dev/null
+++ b/platform/android/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/platform/android/res/drawable-xhdpi/icon.png b/platform/android/res/drawable-xhdpi/icon.png
new file mode 100644
index 00000000..0995b78e
--- /dev/null
+++ b/platform/android/res/drawable-xhdpi/icon.png
Binary files differ
diff --git a/platform/android/res/drawable/busy.xml b/platform/android/res/drawable/busy.xml
new file mode 100644
index 00000000..f7f42a44
--- /dev/null
+++ b/platform/android/res/drawable/busy.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="12dp" />
+ <padding android:left="16dp"
+ android:right="16dp"
+ android:top="16dp"
+ android:bottom="16dp" />
+ <solid android:color="@color/busy_indicator" />
+</shape>
diff --git a/platform/android/res/drawable/button.xml b/platform/android/res/drawable/button.xml
new file mode 100644
index 00000000..0a9bcd51
--- /dev/null
+++ b/platform/android/res/drawable/button.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <shape>
+ <solid android:color="@color/button_pressed" />
+ <padding android:left="8dp" android:top="8dp" android:right="8dp" android:bottom="8dp" />
+ </shape>
+ </item>
+ <item android:state_focused="true">
+ <shape>
+ <solid android:color="@color/button_normal" />
+ <stroke android:width="4dp" android:color="@color/button_pressed" />
+ <padding android:left="8dp" android:top="8dp" android:right="8dp" android:bottom="8dp" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <solid android:color="@color/button_normal" />
+ <padding android:left="8dp" android:top="8dp" android:right="8dp" android:bottom="8dp" />
+ </shape>
+ </item>
+</selector>
diff --git a/platform/android/res/drawable/darkdenim3.png b/platform/android/res/drawable/darkdenim3.png
new file mode 100644
index 00000000..be532f6d
--- /dev/null
+++ b/platform/android/res/drawable/darkdenim3.png
Binary files differ
diff --git a/platform/android/res/drawable/page_num.xml b/platform/android/res/drawable/page_num.xml
new file mode 100644
index 00000000..8d50df85
--- /dev/null
+++ b/platform/android/res/drawable/page_num.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <padding android:left="8dp"
+ android:right="8dp"
+ android:top="1dp"
+ android:bottom="2dp" />
+ <solid android:color="@color/page_indicator" />
+</shape>
diff --git a/platform/android/res/drawable/search.xml b/platform/android/res/drawable/search.xml
new file mode 100644
index 00000000..4fc58830
--- /dev/null
+++ b/platform/android/res/drawable/search.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/text_pressed" />
+ <stroke android:width="4dp" android:color="@color/text_border_pressed" />
+ <padding
+ android:left="12dp"
+ android:right="12dp"
+ android:top="8dp"
+ android:bottom="8dp" />
+ </shape>
+ </item>
+ <item android:state_focused="true">
+ <shape>
+ <solid android:color="@color/text_normal" />
+ <stroke android:width="4dp" android:color="@color/text_border_focused" />
+ <padding
+ android:left="12dp"
+ android:right="12dp"
+ android:top="8dp"
+ android:bottom="8dp" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <solid android:color="@color/text_normal" />
+ <stroke android:width="4dp" android:color="@color/text_border_normal" />
+ <padding
+ android:left="12dp"
+ android:right="12dp"
+ android:top="8dp"
+ android:bottom="8dp" />
+ </shape>
+ </item>
+</selector>
diff --git a/platform/android/res/drawable/seek_progress.xml b/platform/android/res/drawable/seek_progress.xml
new file mode 100644
index 00000000..328139c2
--- /dev/null
+++ b/platform/android/res/drawable/seek_progress.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="line" >
+ <stroke android:width="6dp" android:color="@color/seek_progress" />
+</shape>
diff --git a/platform/android/res/drawable/seek_thumb.xml b/platform/android/res/drawable/seek_thumb.xml
new file mode 100644
index 00000000..e3a9bad4
--- /dev/null
+++ b/platform/android/res/drawable/seek_thumb.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval" >
+ <size android:width="28dp" android:height="28dp" />
+ <solid android:color="@color/seek_thumb" />
+</shape>
diff --git a/platform/android/res/drawable/tiled_background.xml b/platform/android/res/drawable/tiled_background.xml
new file mode 100644
index 00000000..60e08f3c
--- /dev/null
+++ b/platform/android/res/drawable/tiled_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/darkdenim3"
+ android:tileMode="repeat" />
diff --git a/platform/android/res/layout/buttons.xml b/platform/android/res/layout/buttons.xml
new file mode 100644
index 00000000..98eddc22
--- /dev/null
+++ b/platform/android/res/layout/buttons.xml
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <ViewAnimator
+ android:id="@+id/switcher"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true" >
+
+ <RelativeLayout
+ android:id="@+id/topBar0Main"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <TextView
+ android:id="@+id/docNameText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/linkButton"
+ android:layout_alignParentLeft="true"
+ android:paddingLeft="16dp"
+ android:singleLine="true"
+ android:textColor="#FFFFFF"
+ android:textStyle="bold"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageButton
+ android:id="@+id/linkButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/reflowButton"
+ android:contentDescription="@string/toggle_links"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_link" />
+
+ <ImageButton
+ android:id="@+id/reflowButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/outlineButton"
+ android:contentDescription="@string/toggle_reflow_mode"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_reflow" />
+
+ <ImageButton
+ android:id="@+id/outlineButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/searchButton"
+ android:contentDescription="@string/outline_title"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_list" />
+
+ <ImageButton
+ android:id="@+id/searchButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/moreButton"
+ android:contentDescription="@string/search_document"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_magnifying_glass" />
+
+ <ImageButton
+ android:id="@+id/moreButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/more"
+ android:background="@drawable/button"
+ android:onClick="OnMoreButtonClick"
+ android:src="@drawable/ic_more" />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/topBar1Search"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <ImageButton
+ android:id="@+id/cancelSearch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ android:contentDescription="@string/cancel"
+ android:background="@drawable/button"
+ android:onClick="OnCancelSearchButtonClick"
+ android:src="@drawable/ic_cancel" />
+
+ <EditText
+ android:id="@+id/searchText"
+ android:background="@drawable/search"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/cancelSearch"
+ android:layout_toLeftOf="@+id/searchBack"
+ android:inputType="text"
+ android:hint="@string/search"
+ android:singleLine="true" />
+
+ <ImageButton
+ android:id="@+id/searchBack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/searchForward"
+ android:contentDescription="@string/search_backwards"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_arrow_left" />
+
+ <ImageButton
+ android:id="@+id/searchForward"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/search_forwards"
+ android:background="@drawable/button"
+ android:src="@drawable/ic_arrow_right" />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/topBar2Annot"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <ImageButton
+ android:id="@+id/cancelAnnotButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ android:contentDescription="@string/cancel"
+ android:background="@drawable/button"
+ android:onClick="OnCancelAnnotButtonClick"
+ android:src="@drawable/ic_cancel" />
+
+ <ImageButton
+ android:id="@+id/highlightButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/underlineButton"
+ android:contentDescription="@string/highlight"
+ android:background="@drawable/button"
+ android:onClick="OnHighlightButtonClick"
+ android:src="@drawable/ic_highlight" />
+
+ <ImageButton
+ android:id="@+id/underlineButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/strikeOutButton"
+ android:contentDescription="@string/underline"
+ android:background="@drawable/button"
+ android:onClick="OnUnderlineButtonClick"
+ android:src="@drawable/ic_underline" />
+
+ <ImageButton
+ android:id="@+id/strikeOutButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/inkButton"
+ android:contentDescription="@string/strike_out"
+ android:background="@drawable/button"
+ android:onClick="OnStrikeOutButtonClick"
+ android:src="@drawable/ic_strike" />
+
+ <ImageButton
+ android:id="@+id/inkButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/ink"
+ android:background="@drawable/button"
+ android:onClick="OnInkButtonClick"
+ android:src="@drawable/ic_pen" />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/topBar3Delete"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <ImageButton
+ android:id="@+id/cancelDeleteButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ android:contentDescription="@string/cancel"
+ android:background="@drawable/button"
+ android:onClick="OnCancelDeleteButtonClick"
+ android:src="@drawable/ic_cancel" />
+
+ <TextView
+ android:id="@+id/deleteLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/cancelDeleteButton"
+ android:layout_toLeftOf="@+id/deleteButton"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textColor="#FFFFFF"
+ android:textStyle="bold"
+ android:text="@string/delete"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageButton
+ android:id="@+id/deleteButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/delete"
+ android:background="@drawable/button"
+ android:onClick="OnDeleteButtonClick"
+ android:src="@drawable/ic_trash" />
+
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/topBar4More"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <ImageButton
+ android:id="@+id/cancelMoreButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ android:contentDescription="@string/cancel"
+ android:background="@drawable/button"
+ android:onClick="OnCancelMoreButtonClick"
+ android:src="@drawable/ic_cancel" />
+
+ <ImageButton
+ android:id="@+id/printButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/copyTextButton"
+ android:contentDescription="@string/print"
+ android:background="@drawable/button"
+ android:onClick="OnPrintButtonClick"
+ android:src="@drawable/ic_print" />
+
+ <ImageButton
+ android:id="@+id/copyTextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/editAnnotButton"
+ android:layout_alignWithParentIfMissing="true"
+ android:contentDescription="@string/copy_text_to_the_clipboard"
+ android:background="@drawable/button"
+ android:onClick="OnCopyTextButtonClick"
+ android:src="@drawable/ic_clipboard" />
+
+ <ImageButton
+ android:id="@+id/editAnnotButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/edit_annotations"
+ android:background="@drawable/button"
+ android:onClick="OnEditAnnotButtonClick"
+ android:src="@drawable/ic_annotation" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/topBar5Accept"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/toolbar" >
+
+ <ImageButton
+ android:id="@+id/cancelAcceptButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ android:contentDescription="@string/cancel"
+ android:background="@drawable/button"
+ android:onClick="OnCancelAcceptButtonClick"
+ android:src="@drawable/ic_cancel" />
+
+ <TextView
+ android:id="@+id/annotType"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/cancelAcceptButton"
+ android:layout_toLeftOf="@+id/acceptButton"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textColor="#FFFFFF"
+ android:textStyle="bold"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageButton
+ android:id="@+id/acceptButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@string/accept"
+ android:background="@drawable/button"
+ android:onClick="OnAcceptButtonClick"
+ android:src="@drawable/ic_check" />
+ </RelativeLayout>
+ </ViewAnimator>
+
+ <RelativeLayout
+ android:id="@+id/lowerButtons"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true" >
+
+ <SeekBar
+ android:id="@+id/pageSlider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:layout_margin="0dp"
+ android:thumb="@drawable/seek_thumb"
+ android:progressDrawable="@drawable/seek_progress"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="12dp"
+ android:paddingBottom="8dp"
+ android:background="@color/toolbar"
+ />
+
+ <TextView
+ android:id="@+id/pageNumber"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/pageSlider"
+ android:layout_centerHorizontal="true"
+ android:layout_marginBottom="16dp"
+ android:background="@drawable/page_num"
+ android:textColor="#FFFFFF"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </RelativeLayout>
+
+ <TextView
+ android:id="@+id/info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/pageSlider"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:background="@drawable/page_num"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="#FFFFFF" />
+</RelativeLayout>
diff --git a/platform/android/res/layout/main.xml b/platform/android/res/layout/main.xml
new file mode 100644
index 00000000..50b4746b
--- /dev/null
+++ b/platform/android/res/layout/main.xml
@@ -0,0 +1,5 @@
+<?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" />
diff --git a/platform/android/res/layout/outline_entry.xml b/platform/android/res/layout/outline_entry.xml
new file mode 100644
index 00000000..ea7912e4
--- /dev/null
+++ b/platform/android/res/layout/outline_entry.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@+id/page"
+ android:singleLine="true"
+ android:layout_centerVertical="true"
+ android:paddingLeft="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/page"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/title"
+ android:layout_alignBottom="@+id/title"
+ android:layout_alignParentRight="true"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</RelativeLayout>
diff --git a/platform/android/res/layout/picker_entry.xml b/platform/android/res/layout/picker_entry.xml
new file mode 100644
index 00000000..673a4724
--- /dev/null
+++ b/platform/android/res/layout/picker_entry.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="8dp" >
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true" />
+
+ <TextView
+ android:id="@+id/name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@+id/icon"
+ android:paddingBottom="8dp"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
+ android:paddingTop="8dp"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</RelativeLayout>
diff --git a/platform/android/res/layout/print_dialog.xml b/platform/android/res/layout/print_dialog.xml
new file mode 100644
index 00000000..1d54d22f
--- /dev/null
+++ b/platform/android/res/layout/print_dialog.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <WebView android:id="@+id/webview"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"/>
+</RelativeLayout>
diff --git a/platform/android/res/layout/textentry.xml b/platform/android/res/layout/textentry.xml
new file mode 100644
index 00000000..08823df8
--- /dev/null
+++ b/platform/android/res/layout/textentry.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
+ android:singleLine="false"
+ android:minLines="3"
+ android:inputType="textMultiLine"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+</EditText>
diff --git a/platform/android/res/values-ar/strings.xml b/platform/android/res/values-ar/strings.xml
new file mode 100644
index 00000000..f16d5ba9
--- /dev/null
+++ b/platform/android/res/values-ar/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">قبول</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">إلغاء</string>
+ <string name="cannot_open_buffer">تعذر فتح المخزن المؤقت</string>
+ <string name="cannot_open_document">تعذر فتح المستند</string>
+ <string name="cannot_open_document_Reason">تعذر فتح المستند: %1$s</string>
+ <string name="cannot_open_file_Path">تعذر فتح الملف: %1$s</string>
+ <string name="choose_value">اختر قيمة</string>
+ <string name="copied_to_clipboard">تم النسخ إلى الحافظة</string>
+ <string name="copy">نسخ</string>
+ <string name="copy_text">نسخ النص</string>
+ <string name="copy_text_to_the_clipboard">نسخ النص إلى الحافظة</string>
+ <string name="delete">حذف</string>
+ <string name="dismiss">تجاهل</string>
+ <string name="document_has_changes_save_them_">يحتوي المستند على تغييرات. هل تريد حفظها؟</string>
+ <string name="draw_annotation">سحب تعليق توضيحي</string>
+ <string name="edit_annotations">تعديل التعليقات التوضيحية</string>
+ <string name="enter_password">أدخل كلمة المرور</string>
+ <string name="entering_reflow_mode">دخول إلى وضع إعادة التدفق</string>
+ <string name="fill_out_text_field">تعبئة حقل النص</string>
+ <string name="format_currently_not_supported">التنسيق غير مدعوم حاليًا</string>
+ <string name="highlight">تظليل</string>
+ <string name="ink">حبر</string>
+ <string name="leaving_reflow_mode">خروج من وضع إعادة التدفق</string>
+ <string name="more">المزيد</string>
+ <string name="no">لا</string>
+ <string name="no_further_occurrences_found">لم يتم العثور على متكررات أخرى</string>
+ <string name="no_media_hint">مشاركة وسائط التخزين مع حاسوب شخصي قد يمنع الوصول إليها</string>
+ <string name="no_media_warning">وسائط التخزين غير موجودة</string>
+ <string name="no_text_selected">لم يتم تحديد نص</string>
+ <string name="not_supported">غير مدعوم</string>
+ <string name="nothing_to_save">لا يوجد شيء لحفظه</string>
+ <string name="okay">موافق</string>
+ <string name="outline_title">جدول المحتويات</string>
+ <string name="parent_directory">[أعلى مستوى واحد]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">طباعة</string>
+ <string name="print_failed">فشلت الطباعة</string>
+ <string name="save">حفظ</string>
+ <string name="search">بحث</string>
+ <string name="search_backwards">بحث إلى الخلف</string>
+ <string name="search_document">بحث في المستند</string>
+ <string name="search_forwards">بحث إلى الأمام</string>
+ <string name="searching_">جاري البحث في&amp;#8230;</string>
+ <string name="select">تحديد</string>
+ <string name="select_text">تحديد النص</string>
+ <string name="strike_out">شطب</string>
+ <string name="text_not_found">لم يتم العثور على النص</string>
+ <string name="toggle_links">تظليل وتمكين الروابط</string>
+ <string name="underline">تسطير</string>
+ <string name="yes">نعم</string>
+</resources>
diff --git a/platform/android/res/values-ca/strings.xml b/platform/android/res/values-ca/strings.xml
new file mode 100644
index 00000000..ef72886e
--- /dev/null
+++ b/platform/android/res/values-ca/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Acceptar</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Cancel·lar</string>
+ <string name="cannot_open_buffer">No es pot obrir el buffer</string>
+ <string name="cannot_open_document">No es pot obrir el document</string>
+ <string name="cannot_open_document_Reason">No es pot obrir el document: %1$s</string>
+ <string name="cannot_open_file_Path">No es pot obrir l\'arxiu: %1$s</string>
+ <string name="choose_value">Tria el valor</string>
+ <string name="copied_to_clipboard">Copiat al portapapers</string>
+ <string name="copy">Copiar</string>
+ <string name="copy_text">copiar text</string>
+ <string name="copy_text_to_the_clipboard">Copiar text al portapapers</string>
+ <string name="delete">Esborrar</string>
+ <string name="dismiss">Descartar</string>
+ <string name="document_has_changes_save_them_">El document té canvis. Desar?</string>
+ <string name="draw_annotation">Dibuixar anotació</string>
+ <string name="edit_annotations">Editar anotacions</string>
+ <string name="enter_password">Introduir contrasenya</string>
+ <string name="entering_reflow_mode">Entrant en modo de reflux</string>
+ <string name="fill_out_text_field">Emplena el camp de text</string>
+ <string name="format_currently_not_supported">Format no suportat actualment</string>
+ <string name="highlight">Destacar</string>
+ <string name="ink">Tinta</string>
+ <string name="leaving_reflow_mode">Abandonant modo de reflux</string>
+ <string name="more">Més</string>
+ <string name="no">No</string>
+ <string name="no_further_occurrences_found">No hi ha més coincidències</string>
+ <string name="no_media_hint">Compartir el mitjà d\'emmagatzematge amb un PC pot fer que sigui inaccessible</string>
+ <string name="no_media_warning">Mitjà d\'emmagatzematge no present</string>
+ <string name="no_text_selected">No s\'ha seleccionat text</string>
+ <string name="not_supported">No compatible</string>
+ <string name="nothing_to_save">No hi ha gens que guardar</string>
+ <string name="okay">Acceptar</string>
+ <string name="outline_title">Índex</string>
+ <string name="parent_directory">[Pujar un nivell]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Imprimir</string>
+ <string name="print_failed">Fallada al imprimir</string>
+ <string name="save">Desar</string>
+ <string name="search">Buscar</string>
+ <string name="search_backwards">Buscar cap a enrere</string>
+ <string name="search_document">Buscar document</string>
+ <string name="search_forwards">Buscar cap a davant</string>
+ <string name="searching_">Buscant…</string>
+ <string name="select">Seleccionar</string>
+ <string name="select_text">Seleccionar text</string>
+ <string name="strike_out">Ratllat</string>
+ <string name="text_not_found">Text no trobat</string>
+ <string name="toggle_links">Ressaltar i habilitar enllaços</string>
+ <string name="underline">Subratllat</string>
+ <string name="yes">Sí</string>
+</resources>
diff --git a/platform/android/res/values-cs/strings.xml b/platform/android/res/values-cs/strings.xml
new file mode 100644
index 00000000..6c870391
--- /dev/null
+++ b/platform/android/res/values-cs/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Přijmout</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Zrušit</string>
+ <string name="cannot_open_buffer">Nelze otevřít vyrovnávací paměť</string>
+ <string name="cannot_open_document">Nelze otevřít dokument</string>
+ <string name="cannot_open_document_Reason">Nelze otevřít dokument: %1$s</string>
+ <string name="cannot_open_file_Path">Nelze otevřít soubor: %1$s</string>
+ <string name="choose_value">Zvolte hodnotu</string>
+ <string name="copied_to_clipboard">Kopírováno do schránky</string>
+ <string name="copy">Kopírovat</string>
+ <string name="copy_text">kopírovat text</string>
+ <string name="copy_text_to_the_clipboard">Kopírovat text do schránky</string>
+ <string name="delete">Smazat</string>
+ <string name="dismiss">Odmítnout</string>
+ <string name="document_has_changes_save_them_">Dokument byl změněn. Uložit?</string>
+ <string name="draw_annotation">Vložit anotaci</string>
+ <string name="edit_annotations">Upravit anotace</string>
+ <string name="enter_password">Zadat heslo</string>
+ <string name="entering_reflow_mode">Vstup do režimu přeformátování řádků</string>
+ <string name="fill_out_text_field">Vyplnit textové pole</string>
+ <string name="format_currently_not_supported">Formát aktuálně nepodporován</string>
+ <string name="highlight">Zvýraznit</string>
+ <string name="ink">Inkoust</string>
+ <string name="leaving_reflow_mode">Odchod z režimu přeformátování řádků</string>
+ <string name="more">Více</string>
+ <string name="no">Ne</string>
+ <string name="no_further_occurrences_found">Nenalezeny další výskyty</string>
+ <string name="no_media_hint">Při sdílení s PC může být paměťové médium nedostupné</string>
+ <string name="no_media_warning">Paměťové médim nenalezeno</string>
+ <string name="no_text_selected">Nevybrán žádný text</string>
+ <string name="not_supported">Nepodporováno</string>
+ <string name="nothing_to_save">Nic k uložení</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Obsah</string>
+ <string name="parent_directory">[Nahoru o jednu úroveň]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Tisk</string>
+ <string name="print_failed">Tisk selhal</string>
+ <string name="save">Uložit</string>
+ <string name="search">Hledat</string>
+ <string name="search_backwards">Hledat zpět</string>
+ <string name="search_document">Prohledat dokument</string>
+ <string name="search_forwards">Hledat vpřed</string>
+ <string name="searching_">Hledání&amp;#8230;</string>
+ <string name="select">Vybrat</string>
+ <string name="select_text">Vybrat text</string>
+ <string name="strike_out">Přeškrtnout</string>
+ <string name="text_not_found">Text nenalezen</string>
+ <string name="toggle_links">Zvýraznit a aktivovat odkazy</string>
+ <string name="underline">Podtrhnout</string>
+ <string name="yes">Ano</string>
+</resources>
diff --git a/platform/android/res/values-da/strings.xml b/platform/android/res/values-da/strings.xml
new file mode 100644
index 00000000..b7de1fdc
--- /dev/null
+++ b/platform/android/res/values-da/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Accepter</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Annuller</string>
+ <string name="cannot_open_buffer">Buffer kan ikke åbnes</string>
+ <string name="cannot_open_document">Dokument kan ikke åbnes</string>
+ <string name="cannot_open_document_Reason">Kan ikke åbne dokumentet: %1$s</string>
+ <string name="cannot_open_file_Path">Kan ikke åbne filen: %1$s</string>
+ <string name="choose_value">Vælg værdi</string>
+ <string name="copied_to_clipboard">Kopieret til udklipsholder</string>
+ <string name="copy">Kopier</string>
+ <string name="copy_text">kopier tekst</string>
+ <string name="copy_text_to_the_clipboard">kopier tekst til udklipsholder</string>
+ <string name="delete">Slet</string>
+ <string name="dismiss">Afvis</string>
+ <string name="document_has_changes_save_them_">Dokumentet er ændret. Gem ændringer?</string>
+ <string name="draw_annotation">Lav anmærkning</string>
+ <string name="edit_annotations">Rediger anmærkninger</string>
+ <string name="enter_password">Indtast adgangskode</string>
+ <string name="entering_reflow_mode">Går over til konverteringstilstand</string>
+ <string name="fill_out_text_field">Udfyld tekstfelt</string>
+ <string name="format_currently_not_supported">Format ikke understøttet i øjeblikket</string>
+ <string name="highlight">Fremhæv</string>
+ <string name="ink">Ink</string>
+ <string name="leaving_reflow_mode">Forlader konverteringstilstand</string>
+ <string name="more">Mere</string>
+ <string name="no">Nej</string>
+ <string name="no_further_occurrences_found">Der blev ikke fundet flere tilfælde</string>
+ <string name="no_media_hint">Deles lagermediet med en PC, kan det gøre det utilgængeligt</string>
+ <string name="no_media_warning">Lagermedie ikke fundet</string>
+ <string name="no_text_selected">Ingen tekst valgt</string>
+ <string name="not_supported">Ikke understøttet</string>
+ <string name="nothing_to_save">Intet at gemme</string>
+ <string name="okay">Okay</string>
+ <string name="outline_title">Indholdsfortegnelse</string>
+ <string name="parent_directory">[Et niveau op]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Udskriv</string>
+ <string name="print_failed">Udskrivning mislykket</string>
+ <string name="save">Gem</string>
+ <string name="search">Søg</string>
+ <string name="search_backwards">Søg bagud</string>
+ <string name="search_document">Søg i dokument</string>
+ <string name="search_forwards">Søg fremad</string>
+ <string name="searching_">Søger&amp;#8230;</string>
+ <string name="select">Vælg</string>
+ <string name="select_text">Vælg tekst</string>
+ <string name="strike_out">Gennemstreget</string>
+ <string name="text_not_found">Tekst ikke fundet</string>
+ <string name="toggle_links">Fremhæv og aktiver links</string>
+ <string name="underline">Understreg</string>
+ <string name="yes">Ja</string>
+</resources>
diff --git a/platform/android/res/values-de/strings.xml b/platform/android/res/values-de/strings.xml
new file mode 100644
index 00000000..2e69d369
--- /dev/null
+++ b/platform/android/res/values-de/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Akzeptieren</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Abbrechen</string>
+ <string name="cannot_open_buffer">Zwischenspeicher kann nicht geöffnet werden</string>
+ <string name="cannot_open_document">Dokument kann nicht geöffnet werden</string>
+ <string name="cannot_open_document_Reason">Dokument kann nicht geöffnet werden: %1$s</string>
+ <string name="cannot_open_file_Path">Datei kann nicht geöffnet werden: %1$s</string>
+ <string name="choose_value">Wert auswählen</string>
+ <string name="copied_to_clipboard">In die Zwischenanlage kopiert</string>
+ <string name="copy">Kopieren</string>
+ <string name="copy_text">Text kopieren</string>
+ <string name="copy_text_to_the_clipboard">Text in Zwischenablage kopieren</string>
+ <string name="delete">Entfernen</string>
+ <string name="dismiss">Verwerfen</string>
+ <string name="document_has_changes_save_them_">Das Dokument wurde verändert. Sollen die Änderungen gespeichert werden?</string>
+ <string name="draw_annotation">Kommentar einfügen</string>
+ <string name="edit_annotations">Kommentar bearbeiten</string>
+ <string name="enter_password">Passwort eingeben</string>
+ <string name="entering_reflow_mode">Anpassungsmodus wird gestartet</string>
+ <string name="fill_out_text_field">Textfeld ausfüllen</string>
+ <string name="format_currently_not_supported">Format wird momentan nicht unterstützt</string>
+ <string name="highlight">Markieren</string>
+ <string name="ink">Farbe</string>
+ <string name="leaving_reflow_mode">Anpassungsmodus wird beendet</string>
+ <string name="more">Mehr</string>
+ <string name="no">Nein</string>
+ <string name="no_further_occurrences_found">Keine weiteren Treffer</string>
+ <string name="no_media_hint">Die Freigabe des Speichermediums für einen PC kann es unzugänglich machen</string>
+ <string name="no_media_warning">Speichermedium nicht vorhanden</string>
+ <string name="no_text_selected">Kein Text ausgewählt</string>
+ <string name="not_supported">Nicht unterstützt</string>
+ <string name="nothing_to_save">Nichts zum Speichern</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Inhaltsverzeichnis</string>
+ <string name="parent_directory">[Eine Ebene nach oben]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Drucken</string>
+ <string name="print_failed">Fehler beim Drucken</string>
+ <string name="save">Speichern</string>
+ <string name="search">Suchen</string>
+ <string name="search_backwards">Rückwärts suchen</string>
+ <string name="search_document">Dokument durchsuchen</string>
+ <string name="search_forwards">Vorwärts suchen</string>
+ <string name="searching_">Suche…</string>
+ <string name="select">Auswählen</string>
+ <string name="select_text">Text auswählen</string>
+ <string name="strike_out">Durchstreichen</string>
+ <string name="text_not_found">Text konnte nicht gefunden werden</string>
+ <string name="toggle_links">Markiere und aktiviere Verknüpfungen</string>
+ <string name="underline">Unterstreichen</string>
+ <string name="yes">Ja</string>
+</resources>
diff --git a/platform/android/res/values-el/strings.xml b/platform/android/res/values-el/strings.xml
new file mode 100644
index 00000000..f994f287
--- /dev/null
+++ b/platform/android/res/values-el/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Αποδοχή</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Ακύρωση</string>
+ <string name="cannot_open_buffer">Αδυναμία ανοίγματος buffer </string>
+ <string name="cannot_open_document">Αδυναμία ανοίγματος εγγράφου</string>
+ <string name="cannot_open_document_Reason">Αδυναμία ανοίγματος εγγράφου: %1$s</string>
+ <string name="cannot_open_file_Path">Αδυναμία ανοίγματος αρχείου: %1$s</string>
+ <string name="choose_value">Επιλογή τιμής</string>
+ <string name="copied_to_clipboard">Αντιγράφηκε στο πρόχειρο</string>
+ <string name="copy">Αντιγραφή</string>
+ <string name="copy_text">αντιγραφή κειμένου</string>
+ <string name="copy_text_to_the_clipboard">Αντιγραφή κειμένου στο πρόχειρο</string>
+ <string name="delete">Διαγραφή</string>
+ <string name="dismiss">Ματαίωση</string>
+ <string name="document_has_changes_save_them_">Το έγγραφο έχει αλλαγές. Να αποθηκευτούν;</string>
+ <string name="draw_annotation">Σχεδίαση σχολίου</string>
+ <string name="edit_annotations">Επεξεργασία σχολίων</string>
+ <string name="enter_password">Πληκτρολογήστε κωδικό πρόσβασης</string>
+ <string name="entering_reflow_mode">Είσοδος σε λειτουργία δυναμικής προσαρμογής</string>
+ <string name="fill_out_text_field">Συμπλήρωση πεδίου κειμένου</string>
+ <string name="format_currently_not_supported">Αυτή η μορφή δεν υποστηρίζεται τη δεδομένη στιγμή</string>
+ <string name="highlight">Επισήμανση</string>
+ <string name="ink">Γραφή</string>
+ <string name="leaving_reflow_mode">Έξοδος από λειτουργία δυναμικής προσαρμογής</string>
+ <string name="more">Περισσότερο</string>
+ <string name="no">Όχι</string>
+ <string name="no_further_occurrences_found">Δεν βρέθηκαν άλλες εμφανίσεις</string>
+ <string name="no_media_hint">Η κοινή χρήση του αποθηκευτικού μέσου με έναν υπολογιστή μπορεί να το καταστήσει μη προσβάσιμο</string>
+ <string name="no_media_warning">Δεν υπάρχει αποθηκευτικό μέσο</string>
+ <string name="no_text_selected">Δεν έχει επιλεγεί κείμενο</string>
+ <string name="not_supported">Δεν υποστηρίζεται</string>
+ <string name="nothing_to_save">Δεν υπάρχει περιεχόμενο για αποθήκευση</string>
+ <string name="okay">ΟΚ</string>
+ <string name="outline_title">Πίνακας περιεχομένων</string>
+ <string name="parent_directory">[Ένα επίπεδο επάνω]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Εκτύπωση</string>
+ <string name="print_failed">Η εκτύπωση απέτυχε</string>
+ <string name="save">Αποθήκευση</string>
+ <string name="search">Αναζήτηση</string>
+ <string name="search_backwards">Αναζήτηση προς τα πίσω</string>
+ <string name="search_document">Αναζήτηση εγγράφου</string>
+ <string name="search_forwards">Αναζήτηση προς τα μπροστά</string>
+ <string name="searching_">Αναζήτηση&amp;#8230;</string>
+ <string name="select">Επιλογή</string>
+ <string name="select_text">Επιλογή κειμένου</string>
+ <string name="strike_out">Διακριτή διαγραφή</string>
+ <string name="text_not_found">Δεν βρέθηκε το κείμενο</string>
+ <string name="toggle_links">Επισήμανση και ενεργοποίηση συνδέσεων</string>
+ <string name="underline">Υπογράμμιση</string>
+ <string name="yes">Ναι</string>
+</resources>
diff --git a/platform/android/res/values-es/strings.xml b/platform/android/res/values-es/strings.xml
new file mode 100644
index 00000000..0e28a909
--- /dev/null
+++ b/platform/android/res/values-es/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Aceptar</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Cancelar</string>
+ <string name="cannot_open_buffer">No se puede abrir el búfer</string>
+ <string name="cannot_open_document">No se puede abrir el documento</string>
+ <string name="cannot_open_document_Reason">No se puede abrir el documento:%1$s</string>
+ <string name="cannot_open_file_Path">No se puede abrir el archivo: %1$s</string>
+ <string name="choose_value">Elegir valor</string>
+ <string name="copied_to_clipboard">Copiado al portapapeles</string>
+ <string name="copy">Copiar</string>
+ <string name="copy_text">copiar texto</string>
+ <string name="copy_text_to_the_clipboard">Copiar texto al portapapeles</string>
+ <string name="delete">Borrar</string>
+ <string name="dismiss">Ignorar</string>
+ <string name="document_has_changes_save_them_">El documento tiene cambios. ¿Guardar?</string>
+ <string name="draw_annotation">Dibujar anotación</string>
+ <string name="edit_annotations">Editar anotaicones</string>
+ <string name="enter_password">Introducir contraseña</string>
+ <string name="entering_reflow_mode">Entrando en el modo de redistribución</string>
+ <string name="fill_out_text_field">Rellenar el campo de texto</string>
+ <string name="format_currently_not_supported">Formato actualmente no soportado</string>
+ <string name="highlight">Resaltar</string>
+ <string name="ink">Tinta</string>
+ <string name="leaving_reflow_mode">Saliendo del modo de redistribución</string>
+ <string name="more">Más</string>
+ <string name="no">No</string>
+ <string name="no_further_occurrences_found">No se han encontrado más casos</string>
+ <string name="no_media_hint">Compartir el medio de almacenamiento con un PC puede hacerlo inaccesible</string>
+ <string name="no_media_warning">Medio de almacenimiento no presente</string>
+ <string name="no_text_selected">Texto no seleccionado</string>
+ <string name="not_supported">No aceptado</string>
+ <string name="nothing_to_save">Nada que guardar</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Tabla de contenidos</string>
+ <string name="parent_directory">[Subir un nivel]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Imprimir</string>
+ <string name="print_failed">No se ha imprimido</string>
+ <string name="save">Guardar</string>
+ <string name="search">Buscar</string>
+ <string name="search_backwards">Buscar hacia atrás</string>
+ <string name="search_document">Buscar documento</string>
+ <string name="search_forwards">Buscar hacia adelante</string>
+ <string name="searching_">Buscando&amp;#8230;</string>
+ <string name="select">Seleccionar</string>
+ <string name="select_text">Seleccionar texto</string>
+ <string name="strike_out">Tachar</string>
+ <string name="text_not_found">Texto no encontrado</string>
+ <string name="toggle_links">Resaltar y activar</string>
+ <string name="underline">Subrayar</string>
+ <string name="yes">Sí</string>
+</resources>
diff --git a/platform/android/res/values-et/strings.xml b/platform/android/res/values-et/strings.xml
new file mode 100644
index 00000000..fddd25a8
--- /dev/null
+++ b/platform/android/res/values-et/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Nõustu</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Tühista</string>
+ <string name="cannot_open_buffer">Ei saa avada puhvrit</string>
+ <string name="cannot_open_document">Ei saa avada dokumenti</string>
+ <string name="cannot_open_document_Reason">Ei saa avada dokumenti: %1$s</string>
+ <string name="cannot_open_file_Path">Ei saa avada faili: %1$s</string>
+ <string name="choose_value">Vali väärtus</string>
+ <string name="copied_to_clipboard">Kopeeritud lõikelauale</string>
+ <string name="copy">Kopeeri</string>
+ <string name="copy_text">kopeeri tekst</string>
+ <string name="copy_text_to_the_clipboard">Kopeeri tekst lõikelauale</string>
+ <string name="delete">Kustuta</string>
+ <string name="dismiss">Lõpeta</string>
+ <string name="document_has_changes_save_them_">Dokumendis on tehtud muudatusi. Kas salvestada need?</string>
+ <string name="draw_annotation">Tee marginaal</string>
+ <string name="edit_annotations">Redigeeri marginaale</string>
+ <string name="enter_password">Sisesta salasõna</string>
+ <string name="entering_reflow_mode">Sisenen ümberpaigutamise režiimi</string>
+ <string name="fill_out_text_field">Täida tekstiväli</string>
+ <string name="format_currently_not_supported">Vormingul puudub hetkel tugi</string>
+ <string name="highlight">Tõsta esile</string>
+ <string name="ink">Tint</string>
+ <string name="leaving_reflow_mode">Lahkun ümberpaigutamise režiimist</string>
+ <string name="more">Veel</string>
+ <string name="no">Ei</string>
+ <string name="no_further_occurrences_found">Ei leitud rohkem juhtumeid</string>
+ <string name="no_media_hint">Salvestuskandja jagamine arvutiga võib selle juurdepääsmatuks muuta</string>
+ <string name="no_media_warning">Salvestuskandja puudub</string>
+ <string name="no_text_selected">Teksti ei ole valitud</string>
+ <string name="not_supported">Puudub tugi</string>
+ <string name="nothing_to_save">Ei ole midagi salvestada</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Sisukord</string>
+ <string name="parent_directory">[Taseme võrra üles]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s%3$s</string>
+ <string name="print">Prindi</string>
+ <string name="print_failed">Printimine ebaõnnestus</string>
+ <string name="save">Salvesta</string>
+ <string name="search">Otsi</string>
+ <string name="search_backwards">Otsi tagasisuunas</string>
+ <string name="search_document">Otsi dokumendist</string>
+ <string name="search_forwards">Otsi edasisuunas</string>
+ <string name="searching_">Otsin&amp;#8230;</string>
+ <string name="select">Vali</string>
+ <string name="select_text">Vali tekst</string>
+ <string name="strike_out">Läbikriipsutus</string>
+ <string name="text_not_found">Teksti ei leitud</string>
+ <string name="toggle_links">Tõsta lingid esile ja luba need</string>
+ <string name="underline">Jooni alla</string>
+ <string name="yes">Jah</string>
+</resources>
diff --git a/platform/android/res/values-fi/strings.xml b/platform/android/res/values-fi/strings.xml
new file mode 100644
index 00000000..ae13e724
--- /dev/null
+++ b/platform/android/res/values-fi/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Hyväksy</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Peruuta</string>
+ <string name="cannot_open_buffer">Puskuria ei voi avata</string>
+ <string name="cannot_open_document">Tiedostoa ei voi avata</string>
+ <string name="cannot_open_document_Reason">Ei voi avata tiedostoa: %1$s</string>
+ <string name="cannot_open_file_Path">Ei voi avata tiedostoa: %1$s</string>
+ <string name="choose_value">Valitse arvo</string>
+ <string name="copied_to_clipboard">Kopioitu leikepöydälle</string>
+ <string name="copy">Kopioi</string>
+ <string name="copy_text">kopio teksti</string>
+ <string name="copy_text_to_the_clipboard">Kopioi teksti leikepöydälle</string>
+ <string name="delete">Poista</string>
+ <string name="dismiss">Hylkää</string>
+ <string name="document_has_changes_save_them_">Tiedostossa on muutoksia. Haluatko tallentaa muutokset?</string>
+ <string name="draw_annotation">Piirrä huomautus</string>
+ <string name="edit_annotations">Muokkaa huomautuksia</string>
+ <string name="enter_password">Anna salasana</string>
+ <string name="entering_reflow_mode">Siirrytään takaisinmuuntotilaan</string>
+ <string name="fill_out_text_field">Täytä tekstikenttä</string>
+ <string name="format_currently_not_supported">Muotoa ei tällä hetkellä tueta</string>
+ <string name="highlight">Korosta</string>
+ <string name="ink">Muste</string>
+ <string name="leaving_reflow_mode">Poistutaan takaisinmuuntotilasta</string>
+ <string name="more">Lisää</string>
+ <string name="no">Ei</string>
+ <string name="no_further_occurrences_found">Muita esiintymiä ei löydy</string>
+ <string name="no_media_hint">Tallennustietovälineen jakaminen tietokoneen kanssa voi estää sen käyttämisen</string>
+ <string name="no_media_warning">Tallennustietoväline ei ole käytössä</string>
+ <string name="no_text_selected">Ei valittua tekstiä</string>
+ <string name="not_supported">Ei tuettu</string>
+ <string name="nothing_to_save">Ei mitään tallennettavaa</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Sisällys</string>
+ <string name="parent_directory">[Yksi taso ylöspäin]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Tulosta</string>
+ <string name="print_failed">Tulostus ei onnistunut</string>
+ <string name="save">Tallenna</string>
+ <string name="search">Haku</string>
+ <string name="search_backwards">Hae taaksepäin</string>
+ <string name="search_document">Hae tiedostosta</string>
+ <string name="search_forwards">Hae eteenpäin</string>
+ <string name="searching_">Haetaan &amp;#8230;</string>
+ <string name="select">Valitse</string>
+ <string name="select_text">Valitse teksti</string>
+ <string name="strike_out">Yliviivaa</string>
+ <string name="text_not_found">Tekstiä ei löydy</string>
+ <string name="toggle_links">Korosta ja ota käyttöön linkit</string>
+ <string name="underline">Alleviivaa</string>
+ <string name="yes">Kyllä</string>
+</resources>
diff --git a/platform/android/res/values-fr/strings.xml b/platform/android/res/values-fr/strings.xml
new file mode 100644
index 00000000..967707b9
--- /dev/null
+++ b/platform/android/res/values-fr/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Accepter</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Annuler</string>
+ <string name="cannot_open_buffer">Impossible d\'ouvrir le buffer</string>
+ <string name="cannot_open_document">Impossible d\'ouvrir le document</string>
+ <string name="cannot_open_document_Reason">Impossible d\'ouvrir le document : %1$s</string>
+ <string name="cannot_open_file_Path">Impossible d\'ouvrir le fichier : %1$s</string>
+ <string name="choose_value">Choisir la valeur</string>
+ <string name="copied_to_clipboard">Copié dans le presse-papier</string>
+ <string name="copy">Copier</string>
+ <string name="copy_text">copier le texte</string>
+ <string name="copy_text_to_the_clipboard">Copier le texte sur le presse-papier</string>
+ <string name="delete">Supprimer</string>
+ <string name="dismiss">Ignorer</string>
+ <string name="document_has_changes_save_them_">Des modifications ont été effectuées au document. Les sauvegarder ?</string>
+ <string name="draw_annotation">Dessiner une note</string>
+ <string name="edit_annotations">Éditer une note</string>
+ <string name="enter_password">Introduire le mot de passe</string>
+ <string name="entering_reflow_mode">Entrer en mode refusion</string>
+ <string name="fill_out_text_field">Remplir le champ du texte</string>
+ <string name="format_currently_not_supported">Format non compatible pour l\'instant</string>
+ <string name="highlight">Surligner</string>
+ <string name="ink">Encre</string>
+ <string name="leaving_reflow_mode">Quitter le mode refusion</string>
+ <string name="more">Plus</string>
+ <string name="no">Non</string>
+ <string name="no_further_occurrences_found">Aucune occurrence trouvée</string>
+ <string name="no_media_hint">Sauvegarder le support de stockage avec un PC peut le rendre inaccessible</string>
+ <string name="no_media_warning">Support de stockage absent</string>
+ <string name="no_text_selected">Aucun texte sélectionné</string>
+ <string name="not_supported">Non compatible</string>
+ <string name="nothing_to_save">Rien à sauvegarder</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Table des matières</string>
+ <string name="parent_directory">[Niveau supérieur]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s : %3$s</string>
+ <string name="print">Imprimer</string>
+ <string name="print_failed">L\'impression a échoué</string>
+ <string name="save">Sauvegarder</string>
+ <string name="search">Rechercher</string>
+ <string name="search_backwards">Rechercher en arrière</string>
+ <string name="search_document">Rechercher document</string>
+ <string name="search_forwards">Rechercher en avant</string>
+ <string name="searching_">Chercher&amp;#8230 ;</string>
+ <string name="select">Sélectionner</string>
+ <string name="select_text">Sélectionner le texte</string>
+ <string name="strike_out">Rayer</string>
+ <string name="text_not_found">Texte introuvable</string>
+ <string name="toggle_links">Surligner et autoriser les liens</string>
+ <string name="underline">Souligner</string>
+ <string name="yes">Oui</string>
+</resources>
diff --git a/platform/android/res/values-hi/strings.xml b/platform/android/res/values-hi/strings.xml
new file mode 100644
index 00000000..4d09a972
--- /dev/null
+++ b/platform/android/res/values-hi/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">स्वीकार करें</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">रद्द करें</string>
+ <string name="cannot_open_buffer">बफ़र खोल नहीं सके</string>
+ <string name="cannot_open_document">दस्तावेज़ खोल नहीं सके</string>
+ <string name="cannot_open_document_Reason">दस्तावेज़ नहीं खोल सके: %1$s</string>
+ <string name="cannot_open_file_Path">फ़ाइल खोल नहीं सके: %1$s</string>
+ <string name="choose_value">मान चुनें</string>
+ <string name="copied_to_clipboard">क्लिपबोर्ड में कॉप कर दिया गया</string>
+ <string name="copy">कॉपी करें</string>
+ <string name="copy_text">पाठ कॉपी करें</string>
+ <string name="copy_text_to_the_clipboard">पाठ को क्लिपबोर्ड में कॉपी करें</string>
+ <string name="delete">हटाएँ</string>
+ <string name="dismiss">खारिज करें</string>
+ <string name="document_has_changes_save_them_">दस्तावेज़ में परिवर्तन हैं। उन्हें सहेजें?</string>
+ <string name="draw_annotation">एनोटेशन बनाएँ</string>
+ <string name="edit_annotations">एनोटेशनों को संपादित करें</string>
+ <string name="enter_password">पासवर्ड दर्ज करें</string>
+ <string name="entering_reflow_mode">रीफ़्लो मोड में प्रवेश कर रहे हैं</string>
+ <string name="fill_out_text_field">पाठ फ़ील्ड को भरें</string>
+ <string name="format_currently_not_supported">इस समय इस फ़ॉर्मेट को समर्थन नहीं प्राप्त है</string>
+ <string name="highlight">हाइलाइट करें</string>
+ <string name="ink">स्याही</string>
+ <string name="leaving_reflow_mode">रीफ़्लो मोड को छोड़ रहे हैं</string>
+ <string name="more">और भी</string>
+ <string name="no">नहीं</string>
+ <string name="no_further_occurrences_found">यह और कहीं नहीं मिला</string>
+ <string name="no_media_hint">संग्रह माध्यम को पीसी के साथ साझा करने से उस तक पहुँचना मुश्किल हो सकता है</string>
+ <string name="no_media_warning">संग्रह माध्यम मौजूद नहीं है</string>
+ <string name="no_text_selected">कोई भी पाठ नहीं चुना गया है</string>
+ <string name="not_supported">असमर्थित</string>
+ <string name="nothing_to_save">सहेजने के लिए कुछ नहीं है</string>
+ <string name="okay">ठीक है</string>
+ <string name="outline_title">विषय सूची</string>
+ <string name="parent_directory">[एक स्तर ऊपर]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s:%3$s</string>
+ <string name="print">मुद्रित करें</string>
+ <string name="print_failed">मुद्रण विफल हुआ</string>
+ <string name="save">सहेजें</string>
+ <string name="search">खोजें</string>
+ <string name="search_backwards">पीछे की ओर खोजें</string>
+ <string name="search_document">दस्तावेज़ में खोजें</string>
+ <string name="search_forwards">आगे की ओर खोजें</string>
+ <string name="searching_">&amp;#8230 को खोज रहे हैं;</string>
+ <string name="select">चुनें</string>
+ <string name="select_text">पाठ चुनें</string>
+ <string name="strike_out">काटें</string>
+ <string name="text_not_found">पाठ नहीं मिला</string>
+ <string name="toggle_links">लिंकों को हाइलाइट और सक्षम करें</string>
+ <string name="underline">रेखांकित करें</string>
+ <string name="yes">हाँ</string>
+</resources>
diff --git a/platform/android/res/values-hu/strings.xml b/platform/android/res/values-hu/strings.xml
new file mode 100644
index 00000000..1533b65a
--- /dev/null
+++ b/platform/android/res/values-hu/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Elfogadás</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Mégse</string>
+ <string name="cannot_open_buffer">A puffert nem lehet megnyitni</string>
+ <string name="cannot_open_document">A dokumentumot nem lehet megnyitni</string>
+ <string name="cannot_open_document_Reason">A dokumentumot nem lehet megnyitni: %1$s</string>
+ <string name="cannot_open_file_Path">A fájlt nem lehet megnyitni: %1$s</string>
+ <string name="choose_value">Érték kiválasztása</string>
+ <string name="copied_to_clipboard">A vágólapra másolva</string>
+ <string name="copy">Másolás</string>
+ <string name="copy_text">szöveg másolása</string>
+ <string name="copy_text_to_the_clipboard">Szöveg másolása a vágólapra</string>
+ <string name="delete">Törlés</string>
+ <string name="dismiss">Bezárás</string>
+ <string name="document_has_changes_save_them_">A dokumentum módosítva lett. Menti a változtatásokat?</string>
+ <string name="draw_annotation">Jegyzet rajzolása</string>
+ <string name="edit_annotations">Jegyzetek szerkesztése</string>
+ <string name="enter_password">Jelszó megadása</string>
+ <string name="entering_reflow_mode">Belépés az újrarendezési módba</string>
+ <string name="fill_out_text_field">Szövegmező kitöltése</string>
+ <string name="format_currently_not_supported">A formátum jelenleg nem támogatott</string>
+ <string name="highlight">Kiemelés</string>
+ <string name="ink">Kézírás</string>
+ <string name="leaving_reflow_mode">Kilépés az újrarendezési módból</string>
+ <string name="more">Több</string>
+ <string name="no">Nem</string>
+ <string name="no_further_occurrences_found">Nincsenek további találatok</string>
+ <string name="no_media_hint">Az adathordozó a PC-vel való megosztás esetén elérhetetlenné válhat</string>
+ <string name="no_media_warning">Nincs jelen adathordozó</string>
+ <string name="no_text_selected">Nincs kijelölt szöveg</string>
+ <string name="not_supported">Nem támogatott</string>
+ <string name="nothing_to_save">Nem kell semmit menteni</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Tartalomjegyzék</string>
+ <string name="parent_directory">[Egy szinttel feljebb]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Nyomtatás</string>
+ <string name="print_failed">Nyomtatás sikertelen</string>
+ <string name="save">Mentés</string>
+ <string name="search">Keresés</string>
+ <string name="search_backwards">Keresés visszafelé</string>
+ <string name="search_document">Dokumentum keresése</string>
+ <string name="search_forwards">Keresés előrefelé</string>
+ <string name="searching_">Keresés:&amp;#8230;</string>
+ <string name="select">Kijelölés</string>
+ <string name="select_text">Szöveg kijelölése</string>
+ <string name="strike_out">Áthúzás</string>
+ <string name="text_not_found">Szöveg nem található</string>
+ <string name="toggle_links">Kiemelés és linkek engedélyezése</string>
+ <string name="underline">Aláhúzás</string>
+ <string name="yes">Igen</string>
+</resources>
diff --git a/platform/android/res/values-in/strings.xml b/platform/android/res/values-in/strings.xml
new file mode 100644
index 00000000..f90d1b3b
--- /dev/null
+++ b/platform/android/res/values-in/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Terima</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Batal</string>
+ <string name="cannot_open_buffer">Tidak bisa membuka penyangga</string>
+ <string name="cannot_open_document">Tidak bisa membuka dokumen</string>
+ <string name="cannot_open_document_Reason">Tidak bisa membuka dokumen: %1$s</string>
+ <string name="cannot_open_file_Path">Tidak bisa membuka berkas: %1$s</string>
+ <string name="choose_value">Pilih nilai</string>
+ <string name="copied_to_clipboard">Disalin ke papan klip</string>
+ <string name="copy">Salin</string>
+ <string name="copy_text">Salin teks</string>
+ <string name="copy_text_to_the_clipboard">Salin teks ke papan klip</string>
+ <string name="delete">Hapus</string>
+ <string name="dismiss">Hilangkan</string>
+ <string name="document_has_changes_save_them_">Dokumen telah berubah. Simpan perubahan?</string>
+ <string name="draw_annotation">Gambar anotasi</string>
+ <string name="edit_annotations">Sunting anotasi</string>
+ <string name="enter_password">Masukkan kata sandi</string>
+ <string name="entering_reflow_mode">Masuk mode alir-ulang</string>
+ <string name="fill_out_text_field">Isi bidang teks</string>
+ <string name="format_currently_not_supported">Format ini tidak didukung</string>
+ <string name="highlight">Sorotan</string>
+ <string name="ink">Tinta</string>
+ <string name="leaving_reflow_mode">Tinggalkan mode alir-ulang</string>
+ <string name="more">Selengkapnya</string>
+ <string name="no">Tidak</string>
+ <string name="no_further_occurrences_found">Tidak ditemukan kejadian lain</string>
+ <string name="no_media_hint">Berbagi media penyimpanan dengan PC dapat membuatnya tidak bisa diakses</string>
+ <string name="no_media_warning">Media penyimpanan tidak ada</string>
+ <string name="no_text_selected">Tidak ada teks yang dipilih</string>
+ <string name="not_supported">Tidak didukung</string>
+ <string name="nothing_to_save">Tidak ada yang disimpan</string>
+ <string name="okay">Oke</string>
+ <string name="outline_title">Daftar Isi</string>
+ <string name="parent_directory">[Naik satu tingkat]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Cetak</string>
+ <string name="print_failed">Pencetakan gagal</string>
+ <string name="save">Simpan</string>
+ <string name="search">Cari</string>
+ <string name="search_backwards">Cari mundur</string>
+ <string name="search_document">Cari dokumen</string>
+ <string name="search_forwards">Cari maju</string>
+ <string name="searching_">Mencari…</string>
+ <string name="select">Pilih</string>
+ <string name="select_text">Pilih teks</string>
+ <string name="strike_out">Gagal</string>
+ <string name="text_not_found">Teks tidak ditemukan</string>
+ <string name="toggle_links">Sorot dan aktifkan tautan</string>
+ <string name="underline">Garis bawah</string>
+ <string name="yes">Ya</string>
+</resources>
diff --git a/platform/android/res/values-it/strings.xml b/platform/android/res/values-it/strings.xml
new file mode 100644
index 00000000..25cf56dd
--- /dev/null
+++ b/platform/android/res/values-it/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Accetta</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Annulla</string>
+ <string name="cannot_open_buffer">Impossibile aprire buffering</string>
+ <string name="cannot_open_document">Impossibile aprire documento</string>
+ <string name="cannot_open_document_Reason">Impossibile aprire documento: %1$s</string>
+ <string name="cannot_open_file_Path">Impossibile aprire file: %1$s</string>
+ <string name="choose_value">Scegli valore</string>
+ <string name="copied_to_clipboard">Copiato negli appunti</string>
+ <string name="copy">Copia</string>
+ <string name="copy_text">copia testo</string>
+ <string name="copy_text_to_the_clipboard">Copia testo negli appunti</string>
+ <string name="delete">Elimina</string>
+ <string name="dismiss">Ignora</string>
+ <string name="document_has_changes_save_them_">Il documento contiene modifiche. Salvare?</string>
+ <string name="draw_annotation">Disegna annotazione</string>
+ <string name="edit_annotations">Modifica annotazione</string>
+ <string name="enter_password">Inserisci password</string>
+ <string name="entering_reflow_mode">Inserimento modalità di adattamento dinamico del contenuto</string>
+ <string name="fill_out_text_field">Riempi il campo di testo</string>
+ <string name="format_currently_not_supported">Formato attualmente non supportato</string>
+ <string name="highlight">Evidenzia</string>
+ <string name="ink">Inchiostro</string>
+ <string name="leaving_reflow_mode">Abbandono della modalità di adattamento dinamico del contenuto</string>
+ <string name="more">Altro</string>
+ <string name="no">No</string>
+ <string name="no_further_occurrences_found">Nessun\'altra occorrenza trovata</string>
+ <string name="no_media_hint">La condivisione del supporto di archiviazione con un PC può renderlo inaccessibile</string>
+ <string name="no_media_warning">Supporto di archiviazione non presente</string>
+ <string name="no_text_selected">Nessun testo selezionato</string>
+ <string name="not_supported">Non supportato</string>
+ <string name="nothing_to_save">Niente da salvare</string>
+ <string name="okay">Ok</string>
+ <string name="outline_title">Sommario</string>
+ <string name="parent_directory">[Su di un livello]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Stampa</string>
+ <string name="print_failed">Stampa non riuscita</string>
+ <string name="save">Salva</string>
+ <string name="search">Cerca</string>
+ <string name="search_backwards">Cerca indietro</string>
+ <string name="search_document">Cerca documento</string>
+ <string name="search_forwards">Cerca avanti</string>
+ <string name="searching_">Ricerca...</string>
+ <string name="select">Seleziona</string>
+ <string name="select_text">Seleziona testo</string>
+ <string name="strike_out">Barrato</string>
+ <string name="text_not_found">Testo non trovato</string>
+ <string name="toggle_links">Evidenzia e abilita link</string>
+ <string name="underline">Sottolinea</string>
+ <string name="yes">Sì</string>
+</resources>
diff --git a/platform/android/res/values-iw/strings.xml b/platform/android/res/values-iw/strings.xml
new file mode 100644
index 00000000..d259ae76
--- /dev/null
+++ b/platform/android/res/values-iw/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">קבל</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">בטל</string>
+ <string name="cannot_open_buffer">אין אפשרות לפתוח מאגר</string>
+ <string name="cannot_open_document">אין אפשרות לפתוח מסמך</string>
+ <string name="cannot_open_document_Reason">אין אפשרות לפתוח מסמך: %1$s</string>
+ <string name="cannot_open_file_Path">אין אפשרות לפתוח קובץ: %1$s</string>
+ <string name="choose_value">בחר ערך</string>
+ <string name="copied_to_clipboard">הועתק ללוח</string>
+ <string name="copy">העתק</string>
+ <string name="copy_text">העתק טקסט</string>
+ <string name="copy_text_to_the_clipboard">העתק טקסט ללוח</string>
+ <string name="delete">מחק</string>
+ <string name="dismiss">התעלם</string>
+ <string name="document_has_changes_save_them_">קיימים שינויים במסמך. לשמור אותם?</string>
+ <string name="draw_annotation">רשום ביאור</string>
+ <string name="edit_annotations">ערוך ביאורים</string>
+ <string name="enter_password">הזן סיסמה</string>
+ <string name="entering_reflow_mode">כניסה למצב הזרמה מחדש</string>
+ <string name="fill_out_text_field">מלא את שדה הטקסט</string>
+ <string name="format_currently_not_supported">תבנית לא נתמכת כעת</string>
+ <string name="highlight">הבלטה</string>
+ <string name="ink">דיו</string>
+ <string name="leaving_reflow_mode">יציאה ממצב הזרמה מחדש</string>
+ <string name="more">עוד</string>
+ <string name="no">לא</string>
+ <string name="no_further_occurrences_found">לא עוד</string>
+ <string name="no_media_hint">שיתוף מדיית האחסון עם מחשב עשויה להפוך אותה לבלתי נגישה</string>
+ <string name="no_media_warning">מדיית אחסון לא קיימת</string>
+ <string name="no_text_selected">לא נבחר טקסט</string>
+ <string name="not_supported">לא נתמך</string>
+ <string name="nothing_to_save">אין מה לשמור</string>
+ <string name="okay">בסדר</string>
+ <string name="outline_title">תוכן העניינים</string>
+ <string name="parent_directory">[למעלה ברמה אחת]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">הדפס</string>
+ <string name="print_failed">ההדפסה נכשלה</string>
+ <string name="save">שמור</string>
+ <string name="search">חפש</string>
+ <string name="search_backwards">חפש אחורה</string>
+ <string name="search_document">חפש במסמך</string>
+ <string name="search_forwards">חפש קדימה</string>
+ <string name="searching_">מחפש&amp;#8230;</string>
+ <string name="select">בחר ערך</string>
+ <string name="select_text">בחר טקסט</string>
+ <string name="strike_out">הדגש</string>
+ <string name="text_not_found">לא נמצא טקסט</string>
+ <string name="toggle_links">הבלט ואפשר קישורים</string>
+ <string name="underline">קו תחתון</string>
+ <string name="yes">כן</string>
+</resources>
diff --git a/platform/android/res/values-ja/strings.xml b/platform/android/res/values-ja/strings.xml
new file mode 100644
index 00000000..8ceb5e09
--- /dev/null
+++ b/platform/android/res/values-ja/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">承諾する</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">キャンセル</string>
+ <string name="cannot_open_buffer">バッファーを開けません</string>
+ <string name="cannot_open_document">ドキュメントを開けません</string>
+ <string name="cannot_open_document_Reason">次のドキュメントを開けません:%1$s</string>
+ <string name="cannot_open_file_Path">次のファイルを開けません: %1$s</string>
+ <string name="choose_value">バリューを選択してください</string>
+ <string name="copied_to_clipboard">クリップボードにコピーされました</string>
+ <string name="copy">コピー</string>
+ <string name="copy_text">テキストをコピー</string>
+ <string name="copy_text_to_the_clipboard">テキストをクリップボードにコピー</string>
+ <string name="delete">削除</string>
+ <string name="dismiss">却下</string>
+ <string name="document_has_changes_save_them_">ドキュメントは変更されました。保存しますか?</string>
+ <string name="draw_annotation">注釈を挿入する</string>
+ <string name="edit_annotations">注釈を編集する</string>
+ <string name="enter_password">パスワードを入力する</string>
+ <string name="entering_reflow_mode">リフローモードを開始する</string>
+ <string name="fill_out_text_field">テキストフィールドに書き込む</string>
+ <string name="format_currently_not_supported">このフォーマットは現在サポートされていません</string>
+ <string name="highlight">ハイライト</string>
+ <string name="ink">インク</string>
+ <string name="leaving_reflow_mode">リフローモードを終了する</string>
+ <string name="more">もっと</string>
+ <string name="no">いいえ</string>
+ <string name="no_further_occurrences_found">他にオカレンスは見つかりませんでした</string>
+ <string name="no_media_hint">記憶媒体をPCとシェアするとアクセスできなくなる可能性があります</string>
+ <string name="no_media_warning">記憶媒体が見つかりません</string>
+ <string name="no_text_selected">テキストが選択されていません</string>
+ <string name="not_supported">サポートされていません</string>
+ <string name="nothing_to_save">保存するものがありません</string>
+ <string name="okay">了解</string>
+ <string name="outline_title">目次</string>
+ <string name="parent_directory">[一つ上位のレベル]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">印刷</string>
+ <string name="print_failed">印刷に失敗しました</string>
+ <string name="save">保存</string>
+ <string name="search">検索</string>
+ <string name="search_backwards">逆方向検索</string>
+ <string name="search_document">ドキュメントを検索する</string>
+ <string name="search_forwards">順方向検索</string>
+ <string name="searching_">検索中</string>
+ <string name="select">選択</string>
+ <string name="select_text">テキストを選択する</string>
+ <string name="strike_out">取り消し線を引く</string>
+ <string name="text_not_found">テキストが見つかりません</string>
+ <string name="toggle_links">ハイライトしてリンクを有効にする</string>
+ <string name="underline">下線を引く</string>
+ <string name="yes">はい</string>
+</resources>
diff --git a/platform/android/res/values-ko/strings.xml b/platform/android/res/values-ko/strings.xml
new file mode 100644
index 00000000..b52a2f5a
--- /dev/null
+++ b/platform/android/res/values-ko/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">수락</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">취소</string>
+ <string name="cannot_open_buffer">버퍼 열 수 없음</string>
+ <string name="cannot_open_document">문서 열 수 없음</string>
+ <string name="cannot_open_document_Reason">문서 열 수 없음: %1$s</string>
+ <string name="cannot_open_file_Path">파일 열 수 없음: %1$s</string>
+ <string name="choose_value">값 선택</string>
+ <string name="copied_to_clipboard">클립보드로 복사됨</string>
+ <string name="copy">복사</string>
+ <string name="copy_text">텍스트 복사</string>
+ <string name="copy_text_to_the_clipboard">클립보드로 텍스트 복사</string>
+ <string name="delete">삭제</string>
+ <string name="dismiss">무시</string>
+ <string name="document_has_changes_save_them_">문서에 변경사항이 있습니다. 저장?</string>
+ <string name="draw_annotation">주석달기</string>
+ <string name="edit_annotations">주석 편집</string>
+ <string name="enter_password">패스워드 입력</string>
+ <string name="entering_reflow_mode">리플로우 모드 시작</string>
+ <string name="fill_out_text_field">텍스트 입력란에 기입하십시오.</string>
+ <string name="format_currently_not_supported">현재 지원되지 않는 포맷</string>
+ <string name="highlight">주요기능</string>
+ <string name="ink">잉크</string>
+ <string name="leaving_reflow_mode">리플로우 모드 해제</string>
+ <string name="more">기타</string>
+ <string name="no">아니오</string>
+ <string name="no_further_occurrences_found">발견된 추가 발생 없음</string>
+ <string name="no_media_hint">PC와 스토리지 미디어를 공유하면 액세스할 수 없습니다.</string>
+ <string name="no_media_warning">스토리지 미디어 없음</string>
+ <string name="no_text_selected">선택된 텍스트 없음</string>
+ <string name="not_supported">지원 안됨</string>
+ <string name="nothing_to_save">저장 대상 없음</string>
+ <string name="okay">확인</string>
+ <string name="outline_title">목차</string>
+ <string name="parent_directory">[레벨 한 단계 상승]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">인쇄</string>
+ <string name="print_failed">인쇄 실패</string>
+ <string name="save">저장</string>
+ <string name="search">검색</string>
+ <string name="search_backwards">뒤로 검색</string>
+ <string name="search_document">문서 검색</string>
+ <string name="search_forwards">앞으로 검색</string>
+ <string name="searching_">검색 중&amp;#8230;</string>
+ <string name="select">선택</string>
+ <string name="select_text">텍스트 선택</string>
+ <string name="strike_out">삭제</string>
+ <string name="text_not_found">발견된 텍스트 없음</string>
+ <string name="toggle_links">하이라이트 및 링크 활성화</string>
+ <string name="underline">밑줄</string>
+ <string name="yes">예</string>
+</resources>
diff --git a/platform/android/res/values-lt/strings.xml b/platform/android/res/values-lt/strings.xml
new file mode 100644
index 00000000..f66ba305
--- /dev/null
+++ b/platform/android/res/values-lt/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Priimti</string>
+ <string name="app_name">„MuPDF“</string>
+ <string name="cancel">Atšaukti</string>
+ <string name="cannot_open_buffer">Nepavyksta atverti buferinės atmintinės</string>
+ <string name="cannot_open_document">Nepavyksta atverti dokumento</string>
+ <string name="cannot_open_document_Reason">Nepavyksta atverti dokumento: %1$s</string>
+ <string name="cannot_open_file_Path">Nepavyksta atverti failo: %1$s</string>
+ <string name="choose_value">Pasirinkti vertę</string>
+ <string name="copied_to_clipboard">Nukopijuota į iškarpinę</string>
+ <string name="copy">Kopijuoti</string>
+ <string name="copy_text">kopijuoti tekstą</string>
+ <string name="copy_text_to_the_clipboard">Kopijuoti tekstą į iškarpinę</string>
+ <string name="delete">Naikinti</string>
+ <string name="dismiss">Atmesti</string>
+ <string name="document_has_changes_save_them_">Dokumente yra pakeitimų. Ar juos įrašyti?</string>
+ <string name="draw_annotation">Braižyti anotaciją</string>
+ <string name="edit_annotations">Redaguoti anotacijas</string>
+ <string name="enter_password">Įvesti slaptažodį</string>
+ <string name="entering_reflow_mode">Pereinama į pertvarkymo režimą</string>
+ <string name="fill_out_text_field">Užpildyti teksto lauką</string>
+ <string name="format_currently_not_supported">Formatas šiuo metu nedera</string>
+ <string name="highlight">Pažymėti</string>
+ <string name="ink">Rašalas</string>
+ <string name="leaving_reflow_mode">Išeinama iš pertvarkymo režimo</string>
+ <string name="more">Daugiau</string>
+ <string name="no">Ne</string>
+ <string name="no_further_occurrences_found">Daugiau įrašų nerasta</string>
+ <string name="no_media_hint">Pabendrinus laikmeną su kompiuteriu, ji gali tapti nebepasiekiama</string>
+ <string name="no_media_warning">Laikmenos nėra</string>
+ <string name="no_text_selected">Neparinktas tekstas</string>
+ <string name="not_supported">Nedera</string>
+ <string name="nothing_to_save">Nėra ką įrašyti</string>
+ <string name="okay">Gerai</string>
+ <string name="outline_title">Turinys</string>
+ <string name="parent_directory">[Vienu lygiu aukštyn]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Spausdinti</string>
+ <string name="print_failed">Išspausdinti nepavyko</string>
+ <string name="save">Įrašyti</string>
+ <string name="search">Ieškoti</string>
+ <string name="search_backwards">Ieškoti atgal</string>
+ <string name="search_document">Ieškoti dokumente</string>
+ <string name="search_forwards">Ieškoti pirmyn</string>
+ <string name="searching_">Ieškoma&amp;#8230;</string>
+ <string name="select">Pasirinkti</string>
+ <string name="select_text">Pasirinkti tekstą</string>
+ <string name="strike_out">Išbraukti</string>
+ <string name="text_not_found">Teksto nerasta</string>
+ <string name="toggle_links">Pažymėti ir įjungti nuorodas</string>
+ <string name="underline">Pabraukti</string>
+ <string name="yes">Taip</string>
+</resources>
diff --git a/platform/android/res/values-ms/strings.xml b/platform/android/res/values-ms/strings.xml
new file mode 100644
index 00000000..64541e6f
--- /dev/null
+++ b/platform/android/res/values-ms/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Terima</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Batal</string>
+ <string name="cannot_open_buffer">Tidak boleh membuka penimbal</string>
+ <string name="cannot_open_document">Tidak boleh membuka dokumen</string>
+ <string name="cannot_open_document_Reason">Tidak boleh membuka dokumen: %1$s</string>
+ <string name="cannot_open_file_Path">Tidak boleh membuka fail: %1$s</string>
+ <string name="choose_value">Pilih nilai</string>
+ <string name="copied_to_clipboard">Disalin ke papan klip</string>
+ <string name="copy">Salin</string>
+ <string name="copy_text">salin teks</string>
+ <string name="copy_text_to_the_clipboard">Salin teks ke papan klip</string>
+ <string name="delete">Padam</string>
+ <string name="dismiss">Singkir</string>
+ <string name="document_has_changes_save_them_">Dokumen mempunyai perubahan. Simpankannya?</string>
+ <string name="draw_annotation">Lakarkan catatan</string>
+ <string name="edit_annotations">Suntingkan catatan</string>
+ <string name="enter_password">Masukkan kata laluan</string>
+ <string name="entering_reflow_mode">Memasuki mod penyusunan semula</string>
+ <string name="fill_out_text_field">Mengisi medan teks</string>
+ <string name="format_currently_not_supported">Format buat masa ini tidak disokong</string>
+ <string name="highlight">Serlahkan</string>
+ <string name="ink">Dakwat</string>
+ <string name="leaving_reflow_mode">Meninggalkan mod penyusunan semula</string>
+ <string name="more">Lagi</string>
+ <string name="no">Tidak</string>
+ <string name="no_further_occurrences_found">Tiada kejadian lanjut ditemui</string>
+ <string name="no_media_hint">Berkongsi media storan dengan PC boleh menjadikannya tidak dapat dicapai</string>
+ <string name="no_media_warning">Media storan tidak wujud</string>
+ <string name="no_text_selected">Tiada teks dipilih</string>
+ <string name="not_supported">Tidak disokong</string>
+ <string name="nothing_to_save">Tiada apa untuk disimpan</string>
+ <string name="okay">Okey</string>
+ <string name="outline_title">Jadual Kandungan</string>
+ <string name="parent_directory">[Naik satu tahap]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Cetak</string>
+ <string name="print_failed">Gagal dicetak</string>
+ <string name="save">Simpan</string>
+ <string name="search">Carian</string>
+ <string name="search_backwards">Carian ke belakang</string>
+ <string name="search_document">Carian dokumen</string>
+ <string name="search_forwards">Carian ke depan</string>
+ <string name="searching_">Mencari&amp;#8230;</string>
+ <string name="select">Pilih</string>
+ <string name="select_text">Pilih teks</string>
+ <string name="strike_out">Mansuhkan</string>
+ <string name="text_not_found">Teks tidak ditemui</string>
+ <string name="toggle_links">Serlahkan dan dayakan pautan</string>
+ <string name="underline">Gariskan</string>
+ <string name="yes">Ya</string>
+</resources>
diff --git a/platform/android/res/values-nl/strings.xml b/platform/android/res/values-nl/strings.xml
new file mode 100644
index 00000000..21945c86
--- /dev/null
+++ b/platform/android/res/values-nl/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Accepteren</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Annuleren</string>
+ <string name="cannot_open_buffer">Buffer kan niet geopend worden</string>
+ <string name="cannot_open_document">Document kan niet geopend worden</string>
+ <string name="cannot_open_document_Reason">Document kan niet geopend worden: %1$s</string>
+ <string name="cannot_open_file_Path">Bestand kan niet geopend worden : %1$s</string>
+ <string name="choose_value">Kies waarde</string>
+ <string name="copied_to_clipboard">Gekopieerd naar klembord</string>
+ <string name="copy">Kopiëren</string>
+ <string name="copy_text">tekst kopiëren</string>
+ <string name="copy_text_to_the_clipboard">Tekst kopiëren naar klembord</string>
+ <string name="delete">Verwijderen</string>
+ <string name="dismiss">Afwijzen</string>
+ <string name="document_has_changes_save_them_">Het document is gewijzigd. Opslaan?</string>
+ <string name="draw_annotation">Opmerking tekenen</string>
+ <string name="edit_annotations">Opmerkingen bewerken</string>
+ <string name="enter_password">Voer wachtwoord in</string>
+ <string name="entering_reflow_mode">Conversiemodus wordt geopend</string>
+ <string name="fill_out_text_field">Vul het tekstveld in</string>
+ <string name="format_currently_not_supported">Formaat wordt momenteel niet ondersteund</string>
+ <string name="highlight">Markeren</string>
+ <string name="ink">Inkten</string>
+ <string name="leaving_reflow_mode">Conversiemodus wordt beëindigd</string>
+ <string name="more">Meer</string>
+ <string name="no">Nee</string>
+ <string name="no_further_occurrences_found">Geen andere resultaten gevonden</string>
+ <string name="no_media_hint">Het opslagmedium kan ontoegankelijk worden als het met een pc wordt gedeeld</string>
+ <string name="no_media_warning">Geen opslagmedium aanwezig</string>
+ <string name="no_text_selected">Geen tekst geselecteerd</string>
+ <string name="not_supported">Niet ondersteund</string>
+ <string name="nothing_to_save">Niets om op te slaan</string>
+ <string name="okay">Oké</string>
+ <string name="outline_title">Inhoudsopgave</string>
+ <string name="parent_directory">[Een niveau hoger]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Afdrukken</string>
+ <string name="print_failed">Afdrukken mislukt</string>
+ <string name="save">Opslaan</string>
+ <string name="search">Zoeken</string>
+ <string name="search_backwards">Achterstevoren zoeken</string>
+ <string name="search_document">Document doorzoeken</string>
+ <string name="search_forwards">Vooruit zoeken</string>
+ <string name="searching_">Aan het zoeken …</string>
+ <string name="select">Selecteren</string>
+ <string name="select_text">Tekst selecteren</string>
+ <string name="strike_out">Doorhalen</string>
+ <string name="text_not_found">Tekst niet gevonden</string>
+ <string name="toggle_links">Markeren en koppelingen inschakelen</string>
+ <string name="underline">Onderstrepen</string>
+ <string name="yes">Ja</string>
+</resources>
diff --git a/platform/android/res/values-no/strings.xml b/platform/android/res/values-no/strings.xml
new file mode 100644
index 00000000..31bd6bf0
--- /dev/null
+++ b/platform/android/res/values-no/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Aksepter</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Avbryt</string>
+ <string name="cannot_open_buffer">Kan ikke åpne buffer</string>
+ <string name="cannot_open_document">Kan ikke åpne dukumentet</string>
+ <string name="cannot_open_document_Reason">Kan ikke åpne dokumentet: %1$s</string>
+ <string name="cannot_open_file_Path">Kan ikke åpne filen: %1$s</string>
+ <string name="choose_value">Velg verdi</string>
+ <string name="copied_to_clipboard">Kopiert til utklippstavlen</string>
+ <string name="copy">Kopier</string>
+ <string name="copy_text">kopier tekst</string>
+ <string name="copy_text_to_the_clipboard">Kopier teksten til utklippstavlen</string>
+ <string name="delete">Slett</string>
+ <string name="dismiss">Avvis</string>
+ <string name="document_has_changes_save_them_">Det er endringer i dokumentet. Lagre dem?</string>
+ <string name="draw_annotation">Lag merknad</string>
+ <string name="edit_annotations">Rediger merknader</string>
+ <string name="enter_password">Skriv inn passord</string>
+ <string name="entering_reflow_mode">Bytter til konverteringsmodus</string>
+ <string name="fill_out_text_field">Fyll ut tekstfeltet</string>
+ <string name="format_currently_not_supported">Formatet er ikke støttet for øyeblikket</string>
+ <string name="highlight">Uthev</string>
+ <string name="ink">Håndskrift</string>
+ <string name="leaving_reflow_mode">Går ut av konverteringsmodus</string>
+ <string name="more">Mer</string>
+ <string name="no">Nei</string>
+ <string name="no_further_occurrences_found">Ingen flere hendelser funnet</string>
+ <string name="no_media_hint">Deling av lagringsmedia med en PC kan gjøre det utilgjengelig</string>
+ <string name="no_media_warning">Lagringsmedia ikke til stede</string>
+ <string name="no_text_selected">Ingen tekst er valgt</string>
+ <string name="not_supported">Ikke støttet</string>
+ <string name="nothing_to_save">Ingenting å lagre</string>
+ <string name="okay">Ok</string>
+ <string name="outline_title">Innholdsfortegnelse</string>
+ <string name="parent_directory">[OPP ett nivå]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s%3$s</string>
+ <string name="print">Skriv ut</string>
+ <string name="print_failed">Kunne ikke skrive ut</string>
+ <string name="save">Lagre</string>
+ <string name="search">Søk</string>
+ <string name="search_backwards">Søk bakover</string>
+ <string name="search_document">Søk i dokument</string>
+ <string name="search_forwards">Søk framover</string>
+ <string name="searching_">Søker&amp;#8230;</string>
+ <string name="select">Velg</string>
+ <string name="select_text">Valgt tekst</string>
+ <string name="strike_out">Gjennomstreking</string>
+ <string name="text_not_found">Teksten ble ikke funnet</string>
+ <string name="toggle_links">Uthev og aktiver koblinger</string>
+ <string name="underline">Understrek</string>
+ <string name="yes">Ja</string>
+</resources>
diff --git a/platform/android/res/values-pl/strings.xml b/platform/android/res/values-pl/strings.xml
new file mode 100644
index 00000000..42511e42
--- /dev/null
+++ b/platform/android/res/values-pl/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Zaakceptuj</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Anuluj</string>
+ <string name="cannot_open_buffer">Nie można otworzyć bufora</string>
+ <string name="cannot_open_document">Nie można otworzyć dokumentu</string>
+ <string name="cannot_open_document_Reason">Nie można otworzyć dokumentu: %1$s</string>
+ <string name="cannot_open_file_Path">Nie można otworzyć pliku: %1$s</string>
+ <string name="choose_value">Wybierz wartość</string>
+ <string name="copied_to_clipboard">Skopiowano do schowka</string>
+ <string name="copy">Kopiuj</string>
+ <string name="copy_text">kopiuj tekst</string>
+ <string name="copy_text_to_the_clipboard">Kopiuj tekst do schowka</string>
+ <string name="delete">Usuń</string>
+ <string name="dismiss">Odrzuć</string>
+ <string name="document_has_changes_save_them_">W dokumencie dokonano zmian. Czy chcesz je zapisać?</string>
+ <string name="draw_annotation">Sporządź notatkę</string>
+ <string name="edit_annotations">Edytuj notatki</string>
+ <string name="enter_password">Wprowadź hasło</string>
+ <string name="entering_reflow_mode">Włączanie trybu zawijania tekstu</string>
+ <string name="fill_out_text_field">Wypełnij pole tekstowe</string>
+ <string name="format_currently_not_supported">Format obecnie nieobsługiwany</string>
+ <string name="highlight">Podświetl</string>
+ <string name="ink">Atrament</string>
+ <string name="leaving_reflow_mode">Wyłączanie trybu zawijania tekstu</string>
+ <string name="more">Więcej</string>
+ <string name="no">Nie</string>
+ <string name="no_further_occurrences_found">Nie znaleziono więcej wystąpień</string>
+ <string name="no_media_hint">Współdzielenie nośnika danych z komputerem PC może sprawić, że będzie niedostępny</string>
+ <string name="no_media_warning">Nośnik danych niedostępny</string>
+ <string name="no_text_selected">Nie wybrano tekstu</string>
+ <string name="not_supported">Nieobsługiwany</string>
+ <string name="nothing_to_save">Nie ma nic do zapisania</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Spis treści</string>
+ <string name="parent_directory">[W górę o jeden poziom]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Drukuj</string>
+ <string name="print_failed">Drukowanie nieudane</string>
+ <string name="save">Zapisz</string>
+ <string name="search">Szukaj</string>
+ <string name="search_backwards">Szukaj z tyłu</string>
+ <string name="search_document">Szukaj w dokumencie</string>
+ <string name="search_forwards">Szukaj z przodu</string>
+ <string name="searching_">Wyszukiwanie&amp;#8230;</string>
+ <string name="select">Wybierz</string>
+ <string name="select_text">Wybierz tekst</string>
+ <string name="strike_out">Przekreślenie</string>
+ <string name="text_not_found">Nie znaleziono tekstu</string>
+ <string name="toggle_links">Podświetl i aktywuj linki</string>
+ <string name="underline">Podkreślenie</string>
+ <string name="yes">Tak</string>
+</resources>
diff --git a/platform/android/res/values-pt/strings.xml b/platform/android/res/values-pt/strings.xml
new file mode 100644
index 00000000..15f86283
--- /dev/null
+++ b/platform/android/res/values-pt/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Aceitar</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Cancelar</string>
+ <string name="cannot_open_buffer">Não é possível abrir a memória intermédia</string>
+ <string name="cannot_open_document">Não é possível abrir o documento</string>
+ <string name="cannot_open_document_Reason">Não é possível abrir o documento: %1$s</string>
+ <string name="cannot_open_file_Path">Não é possível abrir o ficheiro: %1$s</string>
+ <string name="choose_value">Escolha um valor</string>
+ <string name="copied_to_clipboard">Copiado para a área de transferência</string>
+ <string name="copy">Copiar</string>
+ <string name="copy_text">copiar o texto</string>
+ <string name="copy_text_to_the_clipboard">Copiar o texto para a área de transferência</string>
+ <string name="delete">Eliminar</string>
+ <string name="dismiss">Desistir</string>
+ <string name="document_has_changes_save_them_">Há alterações ao documento. Deseja guardá-las?</string>
+ <string name="draw_annotation">Adicionar anotação</string>
+ <string name="edit_annotations">Editar anotações</string>
+ <string name="enter_password">Escrever a palavra-passe</string>
+ <string name="entering_reflow_mode">A entrar no modo de refluxo</string>
+ <string name="fill_out_text_field">Preencher o campo de texto</string>
+ <string name="format_currently_not_supported">Esse formato não é atualmente suportado</string>
+ <string name="highlight">Destacar</string>
+ <string name="ink">Tinta</string>
+ <string name="leaving_reflow_mode">A sair do modo de refluxo</string>
+ <string name="more">Mais</string>
+ <string name="no">Não</string>
+ <string name="no_further_occurrences_found">Não foram encontradas mais ocorrências</string>
+ <string name="no_media_hint">Partilhar o dispositivo de armazenamento com um PC poderá torná-lo inacessível</string>
+ <string name="no_media_warning">O dispositivo de armazenamento não está presente</string>
+ <string name="no_text_selected">Não há texto selecionado</string>
+ <string name="not_supported">Não suportado</string>
+ <string name="nothing_to_save">Não há nada para guardar</string>
+ <string name="okay">Okay</string>
+ <string name="outline_title">Índice</string>
+ <string name="parent_directory">[subir um nível]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s: %3$s</string>
+ <string name="print">Imprimir</string>
+ <string name="print_failed">Falha na Impressão</string>
+ <string name="save">Guardar</string>
+ <string name="search">Pesquisar</string>
+ <string name="search_backwards">Pesquisar para trás</string>
+ <string name="search_document">Pesquisar no documento</string>
+ <string name="search_forwards">Pesquisar para a frente</string>
+ <string name="searching_">A pesquisar&amp;#8230;</string>
+ <string name="select">Selecionar</string>
+ <string name="select_text">Selecionar o texto</string>
+ <string name="strike_out">Rasurado</string>
+ <string name="text_not_found">Texto não encontrado</string>
+ <string name="toggle_links">Destacar e permitir links</string>
+ <string name="underline">Sublinhado</string>
+ <string name="yes">Sim</string>
+</resources>
diff --git a/platform/android/res/values-ru/strings.xml b/platform/android/res/values-ru/strings.xml
new file mode 100644
index 00000000..7cc35187
--- /dev/null
+++ b/platform/android/res/values-ru/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Принять</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Отмена</string>
+ <string name="cannot_open_buffer">Невозможно открыть буфер</string>
+ <string name="cannot_open_document">Невозможно открыть документ</string>
+ <string name="cannot_open_document_Reason">Невозможно открыть документ: %1$s</string>
+ <string name="cannot_open_file_Path">Невозможно открыть файл: %1$s</string>
+ <string name="choose_value">Выберите значение</string>
+ <string name="copied_to_clipboard">Скопировано в буфер</string>
+ <string name="copy">Копировать</string>
+ <string name="copy_text">копировать текст</string>
+ <string name="copy_text_to_the_clipboard">Копировать текст в буфер</string>
+ <string name="delete">Удалить</string>
+ <string name="dismiss">Пропустить</string>
+ <string name="document_has_changes_save_them_">Документ был изменен. Сохранить изменения?</string>
+ <string name="draw_annotation">Создать аннтоацию</string>
+ <string name="edit_annotations">Редактировать аннотации</string>
+ <string name="enter_password">Введите пароль</string>
+ <string name="entering_reflow_mode">Переход в режим Reflow</string>
+ <string name="fill_out_text_field">Заполните текстовое поле</string>
+ <string name="format_currently_not_supported">Формат не поддерживается</string>
+ <string name="highlight">Выделить</string>
+ <string name="ink">Чернила</string>
+ <string name="leaving_reflow_mode">Выход из режима Reflow</string>
+ <string name="more">Еще</string>
+ <string name="no">Нет</string>
+ <string name="no_further_occurrences_found">Других ошибок не зафиксировано</string>
+ <string name="no_media_hint">Подключение компьютеров к хранилищу данных может привести к потере доступа к хранилищу</string>
+ <string name="no_media_warning">Хранилище данных отсутствует</string>
+ <string name="no_text_selected">Текст не выбран</string>
+ <string name="not_supported">Не поддерживается</string>
+ <string name="nothing_to_save">Не выбраны файлы для сохранения</string>
+ <string name="okay">ОК</string>
+ <string name="outline_title">Содержание</string>
+ <string name="parent_directory">[Вверх на один уровень]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Печать</string>
+ <string name="print_failed">Печать не выполнена</string>
+ <string name="save">Сохранить</string>
+ <string name="search">Поиск</string>
+ <string name="search_backwards">Искать в предыдущей части документа</string>
+ <string name="search_document">Искать в документе</string>
+ <string name="search_forwards">Искать в остальной части документа</string>
+ <string name="searching_">Поиск&amp;#8230;</string>
+ <string name="select">Выбор</string>
+ <string name="select_text">Выбрать текст</string>
+ <string name="strike_out">Зачеркнуть</string>
+ <string name="text_not_found">Текст не найден</string>
+ <string name="toggle_links">Выделить и включить ссылки</string>
+ <string name="underline">Подчеркнуть</string>
+ <string name="yes">Да</string>
+</resources>
diff --git a/platform/android/res/values-sk/strings.xml b/platform/android/res/values-sk/strings.xml
new file mode 100644
index 00000000..e11737ef
--- /dev/null
+++ b/platform/android/res/values-sk/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Prijať</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Zrušiť</string>
+ <string name="cannot_open_buffer">Buffer sa nedá otvoriť</string>
+ <string name="cannot_open_document">Dokument sa nedá otvoriť</string>
+ <string name="cannot_open_document_Reason">Nedá sa otvoriť dokument: %1$s</string>
+ <string name="cannot_open_file_Path">Nedá sa otvoriť súbor: %1$s</string>
+ <string name="choose_value">Vyberte si hodnotu</string>
+ <string name="copied_to_clipboard">Skopírované do vyrovnávacej pamäti</string>
+ <string name="copy">Kopírovať</string>
+ <string name="copy_text">kopírovať text</string>
+ <string name="copy_text_to_the_clipboard">Kopírovať text do vyrovnávacej pamäti</string>
+ <string name="delete">Zmazať</string>
+ <string name="dismiss">Zrušiť</string>
+ <string name="document_has_changes_save_them_">Dokument bol zmený. Uložiť zmeny?</string>
+ <string name="draw_annotation">Zostaviť anotáciu</string>
+ <string name="edit_annotations">Upraviť anotácie</string>
+ <string name="enter_password">Zadať heslo</string>
+ <string name="entering_reflow_mode">Vstupujem do režimu opätovného nalievania</string>
+ <string name="fill_out_text_field">Vyplniť textové pole</string>
+ <string name="format_currently_not_supported">Tento formát momentálne nepodporujem</string>
+ <string name="highlight">Zvýrazniť</string>
+ <string name="ink">Atrament</string>
+ <string name="leaving_reflow_mode">Vystupujem z režimu opätovného nalievania</string>
+ <string name="more">Viac</string>
+ <string name="no">Nie</string>
+ <string name="no_further_occurrences_found">Viac príkladov sa nenašlo</string>
+ <string name="no_media_hint">Zdieľanie úložného média s PC môže znemožniť prístup</string>
+ <string name="no_media_warning">Nie je tu úložné médium</string>
+ <string name="no_text_selected">Žiadny text nie je vybraný</string>
+ <string name="not_supported">Nepodporované</string>
+ <string name="nothing_to_save">Niet čo uložiť</string>
+ <string name="okay">Dobre</string>
+ <string name="outline_title">Obsah</string>
+ <string name="parent_directory">[O úroveň vyššie]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Tlačiť</string>
+ <string name="print_failed">Tlačenie zlyhalo</string>
+ <string name="save">Uložiť</string>
+ <string name="search">Hľadať</string>
+ <string name="search_backwards">Hľadať spätne</string>
+ <string name="search_document">Hľadať v dokumente</string>
+ <string name="search_forwards">Hľadať dopredu</string>
+ <string name="searching_">Hľadám&amp;#8230;</string>
+ <string name="select">Vybrať</string>
+ <string name="select_text">Vybrať text</string>
+ <string name="strike_out">Preškrtnúť</string>
+ <string name="text_not_found">Text sa nenašiel</string>
+ <string name="toggle_links">Zvýrazniť a zapnúť linky</string>
+ <string name="underline">Podčiarknúť</string>
+ <string name="yes">Áno</string>
+</resources>
diff --git a/platform/android/res/values-sv/strings.xml b/platform/android/res/values-sv/strings.xml
new file mode 100644
index 00000000..61d14d05
--- /dev/null
+++ b/platform/android/res/values-sv/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Acceptera</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Avbryt</string>
+ <string name="cannot_open_buffer">Kan inte öppna buffer</string>
+ <string name="cannot_open_document">Kan inte öppna dokument</string>
+ <string name="cannot_open_document_Reason">Kan inte öppna dokument: %1$s</string>
+ <string name="cannot_open_file_Path">Kan inte öppna fil: %1$s</string>
+ <string name="choose_value">Välj värde</string>
+ <string name="copied_to_clipboard">Kopierat till klippbordet</string>
+ <string name="copy">Kopiera</string>
+ <string name="copy_text">kopiera text</string>
+ <string name="copy_text_to_the_clipboard">Kopiera text till klippbordet</string>
+ <string name="delete">Ta bort</string>
+ <string name="dismiss">Avfärda</string>
+ <string name="document_has_changes_save_them_">Dokumentet har ändrats. Spara ändringar?</string>
+ <string name="draw_annotation">Rita annotation</string>
+ <string name="edit_annotations">Ändra annotation</string>
+ <string name="enter_password">Fyll i lösenord</string>
+ <string name="entering_reflow_mode">Aktiverar reflow-läge</string>
+ <string name="fill_out_text_field">Fyll i textfält</string>
+ <string name="format_currently_not_supported">Formatat stöds inte för närvarande</string>
+ <string name="highlight">Markera</string>
+ <string name="ink">Bläck</string>
+ <string name="leaving_reflow_mode">Lämnar reflow-läge</string>
+ <string name="more">Mer</string>
+ <string name="no">Nej</string>
+ <string name="no_further_occurrences_found">Inga flera förekomster hittades</string>
+ <string name="no_media_hint">Att dela lagringsmediet med en PC kan göra den oåtkomlig</string>
+ <string name="no_media_warning">Lagringsmedia finns inte</string>
+ <string name="no_text_selected">Ingen text har valts</string>
+ <string name="not_supported">Stöds ej</string>
+ <string name="nothing_to_save">Inget att spara</string>
+ <string name="okay">OK</string>
+ <string name="outline_title">Innehållsförteckning</string>
+ <string name="parent_directory">[Upp en nivå]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Skriv ut</string>
+ <string name="print_failed">Utskrift misslyckades</string>
+ <string name="save">Spara</string>
+ <string name="search">Sök</string>
+ <string name="search_backwards">Sök bakåt</string>
+ <string name="search_document">Sök dokument</string>
+ <string name="search_forwards">Sök framåt</string>
+ <string name="searching_">Letar&amp;#8230;</string>
+ <string name="select">Välj</string>
+ <string name="select_text">Välj text</string>
+ <string name="strike_out">Stryk</string>
+ <string name="text_not_found">Text hittades ej</string>
+ <string name="toggle_links">Markera och aktivera länkar</string>
+ <string name="underline">Understryk</string>
+ <string name="yes">Ja</string>
+</resources>
diff --git a/platform/android/res/values-th/strings.xml b/platform/android/res/values-th/strings.xml
new file mode 100644
index 00000000..e6827125
--- /dev/null
+++ b/platform/android/res/values-th/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">ยอมรับ</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">ยกเลิก</string>
+ <string name="cannot_open_buffer">ไม่สามารถเปิดบัฟเฟอร์</string>
+ <string name="cannot_open_document">ไม่สามารถเปิดเอกสาร</string>
+ <string name="cannot_open_document_Reason">ไม่สามารถเปิดเอกสาร: %1$s</string>
+ <string name="cannot_open_file_Path">ไม่สามารถเปิดไฟล์: %1$s</string>
+ <string name="choose_value">เลือกค่า</string>
+ <string name="copied_to_clipboard">คัดลอกไปที่คลิปบอร์ดแล้ว</string>
+ <string name="copy">คัดลอก</string>
+ <string name="copy_text">คัดลอกข้อความ</string>
+ <string name="copy_text_to_the_clipboard">คัดลอกข้อความไปที่คลิปบอร์ด</string>
+ <string name="delete">ลบ</string>
+ <string name="dismiss">เลิกใช้</string>
+ <string name="document_has_changes_save_them_">เอกสารมีการเปลี่ยนแปลง ต้องการบันทึกหรือไม่</string>
+ <string name="draw_annotation">เขียนคำอธิบายประกอบ</string>
+ <string name="edit_annotations">แก้ไขคำอธิบายประกอบ</string>
+ <string name="enter_password">ป้อนรหัสผ่าน</string>
+ <string name="entering_reflow_mode">เข้าสู่โหมดเรียงหน้ากระดาษใหม่</string>
+ <string name="fill_out_text_field">เติมในช่องข้อความ</string>
+ <string name="format_currently_not_supported">ไม่รองรับรูปแบบในขณะนี้</string>
+ <string name="highlight">ไฮไลท์</string>
+ <string name="ink">หมึก</string>
+ <string name="leaving_reflow_mode">ออกจากโหมดเรียงหน้ากระดาษใหม่</string>
+ <string name="more">เพิ่มเติม</string>
+ <string name="no">ไม่</string>
+ <string name="no_further_occurrences_found">ไม่พบเหตุการณ์ที่เกิดขึ้นเพิ่มเติม</string>
+ <string name="no_media_hint">การแบ่งปันสื่อจัดเก็บข้อมูลกับพีซีสามารถทำให้สื่อจัดเก็บข้อมูลไม่สามารถเข้าถึงได้</string>
+ <string name="no_media_warning">สื่อเก็บข้อมูลไม่ปรากฏ</string>
+ <string name="no_text_selected">ไม่มีข้อความที่เลือก</string>
+ <string name="not_supported">ไม่รองรับ</string>
+ <string name="nothing_to_save">ไม่มีอะไรให้บันทึก</string>
+ <string name="okay">ตกลง</string>
+ <string name="outline_title">สารบัญ</string>
+ <string name="parent_directory">[ขึ้นหนึ่งระดับ]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">พิมพ์</string>
+ <string name="print_failed">พิมพ์ล้มเหลว</string>
+ <string name="save">บันทึก</string>
+ <string name="search">ค้นหา</string>
+ <string name="search_backwards">ค้นหาย้อนกลับ</string>
+ <string name="search_document">ค้นหาเอกสาร</string>
+ <string name="search_forwards">ค้นหาไปข้างหน้า</string>
+ <string name="searching_">กำลังค้นหา&amp;#8230;</string>
+ <string name="select">เลือก</string>
+ <string name="select_text">เลือกข้อความ</string>
+ <string name="strike_out">ขีดทับ</string>
+ <string name="text_not_found">ไม่พบข้อความ</string>
+ <string name="toggle_links">ไฮไลท์และเปิดใช้งานลิงก์</string>
+ <string name="underline">ขีดเส้นใต้</string>
+ <string name="yes">ใช่</string>
+</resources>
diff --git a/platform/android/res/values-tl/strings.xml b/platform/android/res/values-tl/strings.xml
new file mode 100644
index 00000000..39611fcb
--- /dev/null
+++ b/platform/android/res/values-tl/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Tanggapin</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">Kanselahin</string>
+ <string name="cannot_open_buffer">Hindi mabuksan ang buffer</string>
+ <string name="cannot_open_document">Hindi mabuksan ang dokumento</string>
+ <string name="cannot_open_document_Reason">Hindi mabuksan ang dokumentong: %1$s</string>
+ <string name="cannot_open_file_Path">Hindi mabuksan ang file na: %1$s</string>
+ <string name="choose_value">Pumili ng halaga</string>
+ <string name="copied_to_clipboard">Kinopya sa clipboard</string>
+ <string name="copy">Kopyahin</string>
+ <string name="copy_text">kopyahin ang teksto</string>
+ <string name="copy_text_to_the_clipboard">Kopyahin ang teksto sa clipboard</string>
+ <string name="delete">Alisin</string>
+ <string name="dismiss">Umalis</string>
+ <string name="document_has_changes_save_them_">May mga pagbabago sa dokumento. I-save ang mga ito?</string>
+ <string name="draw_annotation">Gumuhit ng anotasyon</string>
+ <string name="edit_annotations">I-edit ang mga anotasyon</string>
+ <string name="enter_password">Ilagay ang password</string>
+ <string name="entering_reflow_mode">Pumapasok sa reflow mode</string>
+ <string name="fill_out_text_field">Punan ang puwang para sa teksto</string>
+ <string name="format_currently_not_supported">Ang format ay kasalukuyang hindi gumagana dito</string>
+ <string name="highlight">I-highlight</string>
+ <string name="ink">Lagdaan (Ink)</string>
+ <string name="leaving_reflow_mode">Umaalis sa reflow mode</string>
+ <string name="more">Higit pa</string>
+ <string name="no">Hindi</string>
+ <string name="no_further_occurrences_found">Walang nahanap na karagdagang paglitaw</string>
+ <string name="no_media_hint">Ang pagbabahagi ng storage media sa isang PC ay gagawin itong hindi magagamit</string>
+ <string name="no_media_warning">Walang storage media</string>
+ <string name="no_text_selected">Walang piniling teksto</string>
+ <string name="not_supported">Hindi gumagana dito</string>
+ <string name="nothing_to_save">Walang ise-save</string>
+ <string name="okay">Okay</string>
+ <string name="outline_title">Talaan ng Nilalaman</string>
+ <string name="parent_directory">[Umakyat ng isang antas]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">I-print</string>
+ <string name="print_failed">Hindi nai-print</string>
+ <string name="save">I-save</string>
+ <string name="search">Maghanap</string>
+ <string name="search_backwards">Maghanap pabalik</string>
+ <string name="search_document">Maghanap sa dokumento</string>
+ <string name="search_forwards">Maghanap nang pasulong</string>
+ <string name="searching_">Hinahanap ang&amp;#8230;</string>
+ <string name="select">Piliin</string>
+ <string name="select_text">Piliin ang teksto</string>
+ <string name="strike_out">Guhitan ang teksto (strike-out)</string>
+ <string name="text_not_found">Hindi nahanap ang teksto</string>
+ <string name="toggle_links">I-highlight at paganahin ang mga link</string>
+ <string name="underline">Guhitan</string>
+ <string name="yes">Oo</string>
+</resources>
diff --git a/platform/android/res/values-tr/strings.xml b/platform/android/res/values-tr/strings.xml
new file mode 100644
index 00000000..c64ab7ce
--- /dev/null
+++ b/platform/android/res/values-tr/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">Kabul et</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">İptal et</string>
+ <string name="cannot_open_buffer">Arabellek açılamıyor</string>
+ <string name="cannot_open_document">Belge açılamıyor</string>
+ <string name="cannot_open_document_Reason">Belge açılamıyor: %1$s</string>
+ <string name="cannot_open_file_Path">Dosya açılamıyor: %1$s</string>
+ <string name="choose_value">Değeri seç</string>
+ <string name="copied_to_clipboard">Panoya kopyalandı</string>
+ <string name="copy">Kopyala</string>
+ <string name="copy_text">metni kopyala</string>
+ <string name="copy_text_to_the_clipboard">Metni panoya kopyala</string>
+ <string name="delete">Sil</string>
+ <string name="dismiss">Bırak</string>
+ <string name="document_has_changes_save_them_">Belgede değişiklikler var. Kaydetmek istiyor musunuz?</string>
+ <string name="draw_annotation">Ek açıklama çiz</string>
+ <string name="edit_annotations">Ek açıklamalar düzenle</string>
+ <string name="enter_password">Şifreyi gir</string>
+ <string name="entering_reflow_mode">Yeniden akma moduna giriyor</string>
+ <string name="fill_out_text_field">Metin alanını doldurun</string>
+ <string name="format_currently_not_supported">Bu format şu an için desteklenmiyor</string>
+ <string name="highlight">Vurgula</string>
+ <string name="ink">Mürekkep</string>
+ <string name="leaving_reflow_mode">Yeniden akma modundan çıkılıyor</string>
+ <string name="more">Daha fazla</string>
+ <string name="no">Hayır</string>
+ <string name="no_further_occurrences_found">Daha fazla öğe bulunamadı</string>
+ <string name="no_media_hint">Depolama ortamının bilgisayar ile paylaşımı onu erişilmez yapabilir</string>
+ <string name="no_media_warning">Depolama ortamı bulunmuyor</string>
+ <string name="no_text_selected">Seçili metin bulunmuyor</string>
+ <string name="not_supported">Desteklenmiyor</string>
+ <string name="nothing_to_save">Kaydedecek bir şey yok</string>
+ <string name="okay">Tamam</string>
+ <string name="outline_title">İçindekiler Tablosu</string>
+ <string name="parent_directory">[Bir seviye üste çık]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="print">Yazdır</string>
+ <string name="print_failed">Yazdırma başarısız oldu</string>
+ <string name="save">Kaydet</string>
+ <string name="search">Ara</string>
+ <string name="search_backwards">Geriye doğru ara</string>
+ <string name="search_document">Belge ara</string>
+ <string name="search_forwards">İleriye doğru ara</string>
+ <string name="searching_">Aranıyor&amp;#8230;</string>
+ <string name="select">Seç</string>
+ <string name="select_text">Metin seç</string>
+ <string name="strike_out">Üstünü çiz</string>
+ <string name="text_not_found">Metin bulunamadı</string>
+ <string name="toggle_links">Bağlantıları vurgula ve etkinleştir</string>
+ <string name="underline">Altını çiz</string>
+ <string name="yes">Evet</string>
+</resources>
diff --git a/platform/android/res/values-zh-rTW/strings.xml b/platform/android/res/values-zh-rTW/strings.xml
new file mode 100644
index 00000000..4cd89709
--- /dev/null
+++ b/platform/android/res/values-zh-rTW/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">同意</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">取消</string>
+ <string name="cannot_open_buffer">未能開啟緩衝</string>
+ <string name="cannot_open_document">未能開啟文件</string>
+ <string name="cannot_open_document_Reason">未能開啟文件: %1$s</string>
+ <string name="cannot_open_file_Path">未能開啟檔案%1$s</string>
+ <string name="choose_value">選擇數值</string>
+ <string name="copied_to_clipboard">複製至剪貼簿</string>
+ <string name="copy">複製</string>
+ <string name="copy_text">複製文字</string>
+ <string name="copy_text_to_the_clipboard">複製文字至剪貼簿</string>
+ <string name="delete">刪除</string>
+ <string name="dismiss">取消</string>
+ <string name="document_has_changes_save_them_">你需要儲存已編輯的文件嗎?</string>
+ <string name="draw_annotation">繪畫註釋</string>
+ <string name="edit_annotations">編輯註釋</string>
+ <string name="enter_password">輸入密碼</string>
+ <string name="entering_reflow_mode">根據螢幕大小顯示</string>
+ <string name="fill_out_text_field">填寫文字欄</string>
+ <string name="format_currently_not_supported">暫時不支援此格式</string>
+ <string name="highlight">標示重點</string>
+ <string name="ink">墨水</string>
+ <string name="leaving_reflow_mode">不根據螢幕大小顯示</string>
+ <string name="more">更多</string>
+ <string name="no">沒有</string>
+ <string name="no_further_occurrences_found">沒有相符項目</string>
+ <string name="no_media_hint">未能與電腦分享存放裝置</string>
+ <string name="no_media_warning">沒有存放裝置</string>
+ <string name="no_text_selected">沒有選擇文字</string>
+ <string name="not_supported">不支援</string>
+ <string name="nothing_to_save">沒有資料儲存</string>
+ <string name="okay">完成</string>
+ <string name="outline_title">目錄</string>
+ <string name="parent_directory">[升一級]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s%3$s</string>
+ <string name="print">列印</string>
+ <string name="print_failed">列印失敗</string>
+ <string name="save">儲存</string>
+ <string name="search">搜尋</string>
+ <string name="search_backwards">往後搜尋</string>
+ <string name="search_document">搜尋文件</string>
+ <string name="search_forwards">往前搜尋</string>
+ <string name="searching_">搜尋中&amp;#8230;</string>
+ <string name="select">選擇</string>
+ <string name="select_text">選擇文字</string>
+ <string name="strike_out">刪除線</string>
+ <string name="text_not_found">未能找到文字</string>
+ <string name="toggle_links">標示及允許連結</string>
+ <string name="underline">在下面劃線</string>
+ <string name="yes">是</string>
+</resources>
diff --git a/platform/android/res/values-zh/strings.xml b/platform/android/res/values-zh/strings.xml
new file mode 100644
index 00000000..60fcbb82
--- /dev/null
+++ b/platform/android/res/values-zh/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="accept">接受</string>
+ <string name="app_name">MuPDF</string>
+ <string name="cancel">取消</string>
+ <string name="cannot_open_buffer">无法打开缓冲器</string>
+ <string name="cannot_open_document">无法打开文档</string>
+ <string name="cannot_open_document_Reason">无法打开文档: %1$s</string>
+ <string name="cannot_open_file_Path">无法打开文件:%1$s</string>
+ <string name="choose_value">选择值</string>
+ <string name="copied_to_clipboard">已复制到剪贴板</string>
+ <string name="copy">复制</string>
+ <string name="copy_text">复制文本</string>
+ <string name="copy_text_to_the_clipboard">将文本复制到剪贴板</string>
+ <string name="delete">删除</string>
+ <string name="dismiss">解除</string>
+ <string name="document_has_changes_save_them_">文档已变更,保存变更吗?</string>
+ <string name="draw_annotation">作批注</string>
+ <string name="edit_annotations">编辑批注</string>
+ <string name="enter_password">输入密码</string>
+ <string name="entering_reflow_mode">输入重排模式</string>
+ <string name="fill_out_text_field">填充文本字段</string>
+ <string name="format_currently_not_supported">当前不支持此格式</string>
+ <string name="highlight">高亮</string>
+ <string name="ink">墨迹</string>
+ <string name="leaving_reflow_mode">正在离开重排模式</string>
+ <string name="more">更多</string>
+ <string name="no">否</string>
+ <string name="no_further_occurrences_found">未发现更多实例。</string>
+ <string name="no_media_hint">存储介质在设备和 PC 上共同使用,会导致该存储介质在设备上无法被访问</string>
+ <string name="no_media_warning">没有存储介质</string>
+ <string name="no_text_selected">未选择文本</string>
+ <string name="not_supported">不被支持</string>
+ <string name="nothing_to_save">没有要保存的内容</string>
+ <string name="okay">确定</string>
+ <string name="outline_title">目录</string>
+ <string name="parent_directory">[向上一级]</string>
+ <string name="picker_title_App_Ver_Dir">%1$s%2$s:%3$s</string>
+ <string name="print">打印</string>
+ <string name="print_failed">未能打印</string>
+ <string name="save">保存</string>
+ <string name="search">搜索</string>
+ <string name="search_backwards">向后搜索</string>
+ <string name="search_document">搜索文档</string>
+ <string name="search_forwards">向前搜索</string>
+ <string name="searching_">正在搜索…</string>
+ <string name="select">选择</string>
+ <string name="select_text">选择文本</string>
+ <string name="strike_out">删除线</string>
+ <string name="text_not_found">未发现文本</string>
+ <string name="toggle_links">高亮并启用墨迹</string>
+ <string name="underline">下划线</string>
+ <string name="yes">是</string>
+</resources>
diff --git a/platform/android/res/values/colors.xml b/platform/android/res/values/colors.xml
new file mode 100644
index 00000000..ecd1519d
--- /dev/null
+++ b/platform/android/res/values/colors.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="canvas">#404040</color>
+ <color name="toolbar">#C0000000</color>
+ <color name="page_indicator">#C0202020</color>
+ <color name="busy_indicator">#C0202020</color>
+ <color name="button_normal">#00000000</color>
+ <color name="button_pressed">#FF2572AC</color>
+ <color name="text_normal">#FFFFFF</color>
+ <color name="text_pressed">#FFFFFF</color>
+ <color name="text_border_normal">#000000</color>
+ <color name="text_border_pressed">#2572AC</color>
+ <color name="text_border_focused">#000000</color>
+ <color name="seek_thumb">#2572AC</color>
+ <color name="seek_progress">#FFFFFF</color>
+</resources>
diff --git a/platform/android/res/values/strings.xml b/platform/android/res/values/strings.xml
new file mode 100644
index 00000000..2928db14
--- /dev/null
+++ b/platform/android/res/values/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">MuPDF</string>
+ <string name="version">1.2 (Build 50/armv7a)</string>
+ <string name="no_media_warning">Storage media not present</string>
+ <string name="no_media_hint">Sharing the storage media with a PC can make it inaccessible</string>
+ <string name="cancel">Cancel</string>
+ <string name="search_backwards">Search backwards</string>
+ <string name="search_forwards">Search forwards</string>
+ <string name="search_document">Search document</string>
+ <string name="picker_title_App_Ver_Dir">%1$s %2$s: %3$s</string>
+ <string name="outline_title">Table of Contents</string>
+ <string name="enter_password">Enter password</string>
+ <string name="text_not_found">Text not found</string>
+ <string name="searching_">Searching&#8230;</string>
+ <string name="toggle_links">Highlight and enable links</string>
+ <string name="no_further_occurrences_found">No further occurrences found</string>
+ <string name="select">Select</string>
+ <string name="search">Search</string>
+ <string name="copy">Copy</string>
+ <string name="strike_out">Strike-out</string>
+ <string name="delete">Delete</string>
+ <string name="highlight">Highlight</string>
+ <string name="underline">Underline</string>
+ <string name="edit_annotations">Edit annotations</string>
+ <string name="ink">Ink</string>
+ <string name="save">Save</string>
+ <string name="print">Print</string>
+ <string name="dismiss">Dismiss</string>
+ <string name="parent_directory">[Up one level]</string>
+ <string name="yes">Yes</string>
+ <string name="no">No</string>
+ <string name="entering_reflow_mode">Entering reflow mode</string>
+ <string name="leaving_reflow_mode">Leaving reflow mode</string>
+ <string name="print_failed">Print failed</string>
+ <string name="select_text">Select text</string>
+ <string name="copied_to_clipboard">Copied to clipboard</string>
+ <string name="no_text_selected">No text selected</string>
+ <string name="draw_annotation">Draw annotation</string>
+ <string name="nothing_to_save">Nothing to save</string>
+ <string name="document_has_changes_save_them_">Document has changes. Save them?</string>
+ <string name="cannot_open_document">Cannot open document</string>
+ <string name="cannot_open_document_Reason">Cannot open document: %1$s</string>
+ <string name="cannot_open_file_Path">Cannot open file: %1$s</string>
+ <string name="cannot_open_buffer">Cannot open buffer</string>
+ <string name="fill_out_text_field">Fill out text field</string>
+ <string name="okay">Okay</string>
+ <string name="choose_value">Choose value</string>
+ <string name="not_supported">Not supported</string>
+ <string name="copy_text_to_the_clipboard">Copy text to the clipboard</string>
+ <string name="more">More</string>
+ <string name="accept">Accept</string>
+ <string name="copy_text">copy text</string>
+ <string name="format_currently_not_supported">Format currently not supported</string>
+ <string name="toggle_reflow_mode">Toggle reflow mode</string>
+</resources>
diff --git a/platform/android/res/values/styles.xml b/platform/android/res/values/styles.xml
new file mode 100644
index 00000000..ade851dd
--- /dev/null
+++ b/platform/android/res/values/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+ <style name="AppBaseTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
+ <item name="android:windowBackground">@drawable/tiled_background</item>
+ </style>
+</resources>
diff --git a/platform/android/src/com/artifex/mupdfdemo/Annotation.java b/platform/android/src/com/artifex/mupdfdemo/Annotation.java
new file mode 100644
index 00000000..cf915524
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/Annotation.java
@@ -0,0 +1,18 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.RectF;
+
+public class Annotation extends RectF {
+ enum Type {
+ TEXT, LINK, FREETEXT, LINE, SQUARE, CIRCLE, POLYGON, POLYLINE, HIGHLIGHT,
+ UNDERLINE, SQUIGGLY, STRIKEOUT, STAMP, CARET, INK, POPUP, FILEATTACHMENT,
+ SOUND, MOVIE, WIDGET, SCREEN, PRINTERMARK, TRAPNET, WATERMARK, A3D, UNKNOWN
+ }
+
+ public final Type type;
+
+ public Annotation(float x0, float y0, float x1, float y1, int _type) {
+ super(x0, y0, x1, y1);
+ type = _type == -1 ? Type.UNKNOWN : Type.values()[_type];
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/ArrayDeque.java b/platform/android/src/com/artifex/mupdfdemo/ArrayDeque.java
new file mode 100644
index 00000000..4f06ea41
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/ArrayDeque.java
@@ -0,0 +1,855 @@
+/*
+ * Written by Josh Bloch of Google Inc. and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
+ */
+
+package com.artifex.mupdfdemo;
+
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Stack;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * Resizable-array implementation of the {@link Deque} interface. Array
+ * deques have no capacity restrictions; they grow as necessary to support
+ * usage. They are not thread-safe; in the absence of external
+ * synchronization, they do not support concurrent access by multiple threads.
+ * Null elements are prohibited. This class is likely to be faster than
+ * {@link Stack} when used as a stack, and faster than {@link LinkedList}
+ * when used as a queue.
+ *
+ * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
+ * Exceptions include {@link #remove(Object) remove}, {@link
+ * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
+ * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
+ * iterator.remove()}, and the bulk operations, all of which run in linear
+ * time.
+ *
+ * <p>The iterators returned by this class's <tt>iterator</tt> method are
+ * <i>fail-fast</i>: If the deque is modified at any time after the iterator
+ * is created, in any way except through the iterator's own <tt>remove</tt>
+ * method, the iterator will generally throw a {@link
+ * ConcurrentModificationException}. Thus, in the face of concurrent
+ * modification, the iterator fails quickly and cleanly, rather than risking
+ * arbitrary, non-deterministic behavior at an undetermined time in the
+ * future.
+ *
+ * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
+ * as it is, generally speaking, impossible to make any hard guarantees in the
+ * presence of unsynchronized concurrent modification. Fail-fast iterators
+ * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
+ * Therefore, it would be wrong to write a program that depended on this
+ * exception for its correctness: <i>the fail-fast behavior of iterators
+ * should be used only to detect bugs.</i>
+ *
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
+ *
+ * @author Josh Bloch and Doug Lea
+ * @since 1.6
+ * @param <E> the type of elements held in this collection
+ */
+public class ArrayDeque<E> extends AbstractCollection<E>
+ implements Deque<E>, Cloneable, java.io.Serializable
+{
+ /**
+ * The array in which the elements of the deque are stored.
+ * The capacity of the deque is the length of this array, which is
+ * always a power of two. The array is never allowed to become
+ * full, except transiently within an addX method where it is
+ * resized (see doubleCapacity) immediately upon becoming full,
+ * thus avoiding head and tail wrapping around to equal each
+ * other. We also guarantee that all array cells not holding
+ * deque elements are always null.
+ */
+ private transient Object[] elements;
+
+ /**
+ * The index of the element at the head of the deque (which is the
+ * element that would be removed by remove() or pop()); or an
+ * arbitrary number equal to tail if the deque is empty.
+ */
+ private transient int head;
+
+ /**
+ * The index at which the next element would be added to the tail
+ * of the deque (via addLast(E), add(E), or push(E)).
+ */
+ private transient int tail;
+
+ /**
+ * The minimum capacity that we'll use for a newly created deque.
+ * Must be a power of 2.
+ */
+ private static final int MIN_INITIAL_CAPACITY = 8;
+
+ // ****** Array allocation and resizing utilities ******
+
+ /**
+ * Allocate empty array to hold the given number of elements.
+ *
+ * @param numElements the number of elements to hold
+ */
+ private void allocateElements(int numElements) {
+ int initialCapacity = MIN_INITIAL_CAPACITY;
+ // Find the best power of two to hold elements.
+ // Tests "<=" because arrays aren't kept full.
+ if (numElements >= initialCapacity) {
+ initialCapacity = numElements;
+ initialCapacity |= (initialCapacity >>> 1);
+ initialCapacity |= (initialCapacity >>> 2);
+ initialCapacity |= (initialCapacity >>> 4);
+ initialCapacity |= (initialCapacity >>> 8);
+ initialCapacity |= (initialCapacity >>> 16);
+ initialCapacity++;
+
+ if (initialCapacity < 0) // Too many elements, must back off
+ initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
+ }
+ elements = new Object[initialCapacity];
+ }
+
+ /**
+ * Double the capacity of this deque. Call only when full, i.e.,
+ * when head and tail have wrapped around to become equal.
+ */
+ private void doubleCapacity() {
+ // assert head == tail;
+ int p = head;
+ int n = elements.length;
+ int r = n - p; // number of elements to the right of p
+ int newCapacity = n << 1;
+ if (newCapacity < 0)
+ throw new IllegalStateException("Sorry, deque too big");
+ Object[] a = new Object[newCapacity];
+ System.arraycopy(elements, p, a, 0, r);
+ System.arraycopy(elements, 0, a, r, p);
+ elements = a;
+ head = 0;
+ tail = n;
+ }
+
+ /**
+ * Copies the elements from our element array into the specified array,
+ * in order (from first to last element in the deque). It is assumed
+ * that the array is large enough to hold all elements in the deque.
+ *
+ * @return its argument
+ */
+ private <T> T[] copyElements(T[] a) {
+ if (head < tail) {
+ System.arraycopy(elements, head, a, 0, size());
+ } else if (head > tail) {
+ int headPortionLen = elements.length - head;
+ System.arraycopy(elements, head, a, 0, headPortionLen);
+ System.arraycopy(elements, 0, a, headPortionLen, tail);
+ }
+ return a;
+ }
+
+ /**
+ * Constructs an empty array deque with an initial capacity
+ * sufficient to hold 16 elements.
+ */
+ public ArrayDeque() {
+ elements = new Object[16];
+ }
+
+ /**
+ * Constructs an empty array deque with an initial capacity
+ * sufficient to hold the specified number of elements.
+ *
+ * @param numElements lower bound on initial capacity of the deque
+ */
+ public ArrayDeque(int numElements) {
+ allocateElements(numElements);
+ }
+
+ /**
+ * Constructs a deque containing the elements of the specified
+ * collection, in the order they are returned by the collection's
+ * iterator. (The first element returned by the collection's
+ * iterator becomes the first element, or <i>front</i> of the
+ * deque.)
+ *
+ * @param c the collection whose elements are to be placed into the deque
+ * @throws NullPointerException if the specified collection is null
+ */
+ public ArrayDeque(Collection<? extends E> c) {
+ allocateElements(c.size());
+ addAll(c);
+ }
+
+ // The main insertion and extraction methods are addFirst,
+ // addLast, pollFirst, pollLast. The other methods are defined in
+ // terms of these.
+
+ /**
+ * Inserts the specified element at the front of this deque.
+ *
+ * @param e the element to add
+ * @throws NullPointerException if the specified element is null
+ */
+ public void addFirst(E e) {
+ if (e == null)
+ throw new NullPointerException("e == null");
+ elements[head = (head - 1) & (elements.length - 1)] = e;
+ if (head == tail)
+ doubleCapacity();
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #add}.
+ *
+ * @param e the element to add
+ * @throws NullPointerException if the specified element is null
+ */
+ public void addLast(E e) {
+ if (e == null)
+ throw new NullPointerException("e == null");
+ elements[tail] = e;
+ if ( (tail = (tail + 1) & (elements.length - 1)) == head)
+ doubleCapacity();
+ }
+
+ /**
+ * Inserts the specified element at the front of this deque.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offerFirst(E e) {
+ addFirst(e);
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offerLast(E e) {
+ addLast(e);
+ return true;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E removeFirst() {
+ E x = pollFirst();
+ if (x == null)
+ throw new NoSuchElementException();
+ return x;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E removeLast() {
+ E x = pollLast();
+ if (x == null)
+ throw new NoSuchElementException();
+ return x;
+ }
+
+ public E pollFirst() {
+ int h = head;
+ @SuppressWarnings("unchecked") E result = (E) elements[h];
+ // Element is null if deque empty
+ if (result == null)
+ return null;
+ elements[h] = null; // Must null out slot
+ head = (h + 1) & (elements.length - 1);
+ return result;
+ }
+
+ public E pollLast() {
+ int t = (tail - 1) & (elements.length - 1);
+ @SuppressWarnings("unchecked") E result = (E) elements[t];
+ if (result == null)
+ return null;
+ elements[t] = null;
+ tail = t;
+ return result;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E getFirst() {
+ @SuppressWarnings("unchecked") E result = (E) elements[head];
+ if (result == null)
+ throw new NoSuchElementException();
+ return result;
+ }
+
+ /**
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E getLast() {
+ @SuppressWarnings("unchecked")
+ E result = (E) elements[(tail - 1) & (elements.length - 1)];
+ if (result == null)
+ throw new NoSuchElementException();
+ return result;
+ }
+
+ public E peekFirst() {
+ @SuppressWarnings("unchecked") E result = (E) elements[head];
+ // elements[head] is null if deque empty
+ return result;
+ }
+
+ public E peekLast() {
+ @SuppressWarnings("unchecked")
+ E result = (E) elements[(tail - 1) & (elements.length - 1)];
+ return result;
+ }
+
+ /**
+ * Removes the first occurrence of the specified element in this
+ * deque (when traversing the deque from head to tail).
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if the deque contained the specified element
+ */
+ public boolean removeFirstOccurrence(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = head;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x)) {
+ delete(i);
+ return true;
+ }
+ i = (i + 1) & mask;
+ }
+ return false;
+ }
+
+ /**
+ * Removes the last occurrence of the specified element in this
+ * deque (when traversing the deque from head to tail).
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the last element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if the deque contained the specified element
+ */
+ public boolean removeLastOccurrence(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = (tail - 1) & mask;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x)) {
+ delete(i);
+ return true;
+ }
+ i = (i - 1) & mask;
+ }
+ return false;
+ }
+
+ // *** Queue methods ***
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #addLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Collection#add})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean add(E e) {
+ addLast(e);
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the end of this deque.
+ *
+ * <p>This method is equivalent to {@link #offerLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Queue#offer})
+ * @throws NullPointerException if the specified element is null
+ */
+ public boolean offer(E e) {
+ return offerLast(e);
+ }
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque.
+ *
+ * This method differs from {@link #poll poll} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #removeFirst}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E remove() {
+ return removeFirst();
+ }
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque), or returns
+ * <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ public E poll() {
+ return pollFirst();
+ }
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque. This method differs from {@link #peek peek} only in
+ * that it throws an exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #getFirst}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E element() {
+ return getFirst();
+ }
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque, or returns <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #peekFirst}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ public E peek() {
+ return peekFirst();
+ }
+
+ // *** Stack methods ***
+
+ /**
+ * Pushes an element onto the stack represented by this deque. In other
+ * words, inserts the element at the front of this deque.
+ *
+ * <p>This method is equivalent to {@link #addFirst}.
+ *
+ * @param e the element to push
+ * @throws NullPointerException if the specified element is null
+ */
+ public void push(E e) {
+ addFirst(e);
+ }
+
+ /**
+ * Pops an element from the stack represented by this deque. In other
+ * words, removes and returns the first element of this deque.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the element at the front of this deque (which is the top
+ * of the stack represented by this deque)
+ * @throws NoSuchElementException {@inheritDoc}
+ */
+ public E pop() {
+ return removeFirst();
+ }
+
+ private void checkInvariants() {
+ // assert elements[tail] == null;
+ // assert head == tail ? elements[head] == null :
+ // (elements[head] != null &&
+ // elements[(tail - 1) & (elements.length - 1)] != null);
+ // assert elements[(head - 1) & (elements.length - 1)] == null;
+ }
+
+ /**
+ * Removes the element at the specified position in the elements array,
+ * adjusting head and tail as necessary. This can result in motion of
+ * elements backwards or forwards in the array.
+ *
+ * <p>This method is called delete rather than remove to emphasize
+ * that its semantics differ from those of {@link List#remove(int)}.
+ *
+ * @return true if elements moved backwards
+ */
+ private boolean delete(int i) {
+ //checkInvariants();
+ final Object[] elements = this.elements;
+ final int mask = elements.length - 1;
+ final int h = head;
+ final int t = tail;
+ final int front = (i - h) & mask;
+ final int back = (t - i) & mask;
+
+ // Invariant: head <= i < tail mod circularity
+ if (front >= ((t - h) & mask))
+ throw new ConcurrentModificationException();
+
+ // Optimize for least element motion
+ if (front < back) {
+ if (h <= i) {
+ System.arraycopy(elements, h, elements, h + 1, front);
+ } else { // Wrap around
+ System.arraycopy(elements, 0, elements, 1, i);
+ elements[0] = elements[mask];
+ System.arraycopy(elements, h, elements, h + 1, mask - h);
+ }
+ elements[h] = null;
+ head = (h + 1) & mask;
+ return false;
+ } else {
+ if (i < t) { // Copy the null tail as well
+ System.arraycopy(elements, i + 1, elements, i, back);
+ tail = t - 1;
+ } else { // Wrap around
+ System.arraycopy(elements, i + 1, elements, i, mask - i);
+ elements[mask] = elements[0];
+ System.arraycopy(elements, 1, elements, 0, t);
+ tail = (t - 1) & mask;
+ }
+ return true;
+ }
+ }
+
+ // *** Collection Methods ***
+
+ /**
+ * Returns the number of elements in this deque.
+ *
+ * @return the number of elements in this deque
+ */
+ public int size() {
+ return (tail - head) & (elements.length - 1);
+ }
+
+ /**
+ * Returns <tt>true</tt> if this deque contains no elements.
+ *
+ * @return <tt>true</tt> if this deque contains no elements
+ */
+ public boolean isEmpty() {
+ return head == tail;
+ }
+
+ /**
+ * Returns an iterator over the elements in this deque. The elements
+ * will be ordered from first (head) to last (tail). This is the same
+ * order that elements would be dequeued (via successive calls to
+ * {@link #remove} or popped (via successive calls to {@link #pop}).
+ *
+ * @return an iterator over the elements in this deque
+ */
+ public Iterator<E> iterator() {
+ return new DeqIterator();
+ }
+
+ public Iterator<E> descendingIterator() {
+ return new DescendingIterator();
+ }
+
+ private class DeqIterator implements Iterator<E> {
+ /**
+ * Index of element to be returned by subsequent call to next.
+ */
+ private int cursor = head;
+
+ /**
+ * Tail recorded at construction (also in remove), to stop
+ * iterator and also to check for comodification.
+ */
+ private int fence = tail;
+
+ /**
+ * Index of element returned by most recent call to next.
+ * Reset to -1 if element is deleted by a call to remove.
+ */
+ private int lastRet = -1;
+
+ public boolean hasNext() {
+ return cursor != fence;
+ }
+
+ public E next() {
+ if (cursor == fence)
+ throw new NoSuchElementException();
+ @SuppressWarnings("unchecked") E result = (E) elements[cursor];
+ // This check doesn't catch all possible comodifications,
+ // but does catch the ones that corrupt traversal
+ if (tail != fence || result == null)
+ throw new ConcurrentModificationException();
+ lastRet = cursor;
+ cursor = (cursor + 1) & (elements.length - 1);
+ return result;
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ if (delete(lastRet)) { // if left-shifted, undo increment in next()
+ cursor = (cursor - 1) & (elements.length - 1);
+ fence = tail;
+ }
+ lastRet = -1;
+ }
+ }
+
+ private class DescendingIterator implements Iterator<E> {
+ /*
+ * This class is nearly a mirror-image of DeqIterator, using
+ * tail instead of head for initial cursor, and head instead of
+ * tail for fence.
+ */
+ private int cursor = tail;
+ private int fence = head;
+ private int lastRet = -1;
+
+ public boolean hasNext() {
+ return cursor != fence;
+ }
+
+ public E next() {
+ if (cursor == fence)
+ throw new NoSuchElementException();
+ cursor = (cursor - 1) & (elements.length - 1);
+ @SuppressWarnings("unchecked") E result = (E) elements[cursor];
+ if (head != fence || result == null)
+ throw new ConcurrentModificationException();
+ lastRet = cursor;
+ return result;
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ if (!delete(lastRet)) {
+ cursor = (cursor + 1) & (elements.length - 1);
+ fence = head;
+ }
+ lastRet = -1;
+ }
+ }
+
+ /**
+ * Returns <tt>true</tt> if this deque contains the specified element.
+ * More formally, returns <tt>true</tt> if and only if this deque contains
+ * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+ *
+ * @param o object to be checked for containment in this deque
+ * @return <tt>true</tt> if this deque contains the specified element
+ */
+ public boolean contains(Object o) {
+ if (o == null)
+ return false;
+ int mask = elements.length - 1;
+ int i = head;
+ Object x;
+ while ( (x = elements[i]) != null) {
+ if (o.equals(x))
+ return true;
+ i = (i + 1) & mask;
+ }
+ return false;
+ }
+
+ /**
+ * Removes a single instance of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>o.equals(e)</tt> (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * <p>This method is equivalent to {@link #removeFirstOccurrence}.
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if this deque contained the specified element
+ */
+ public boolean remove(Object o) {
+ return removeFirstOccurrence(o);
+ }
+
+ /**
+ * Removes all of the elements from this deque.
+ * The deque will be empty after this call returns.
+ */
+ public void clear() {
+ int h = head;
+ int t = tail;
+ if (h != t) { // clear all cells
+ head = tail = 0;
+ int i = h;
+ int mask = elements.length - 1;
+ do {
+ elements[i] = null;
+ i = (i + 1) & mask;
+ } while (i != t);
+ }
+ }
+
+ /**
+ * Returns an array containing all of the elements in this deque
+ * in proper sequence (from first to last element).
+ *
+ * <p>The returned array will be "safe" in that no references to it are
+ * maintained by this deque. (In other words, this method must allocate
+ * a new array). The caller is thus free to modify the returned array.
+ *
+ * <p>This method acts as bridge between array-based and collection-based
+ * APIs.
+ *
+ * @return an array containing all of the elements in this deque
+ */
+ public Object[] toArray() {
+ return copyElements(new Object[size()]);
+ }
+
+ /**
+ * Returns an array containing all of the elements in this deque in
+ * proper sequence (from first to last element); the runtime type of the
+ * returned array is that of the specified array. If the deque fits in
+ * the specified array, it is returned therein. Otherwise, a new array
+ * is allocated with the runtime type of the specified array and the
+ * size of this deque.
+ *
+ * <p>If this deque fits in the specified array with room to spare
+ * (i.e., the array has more elements than this deque), the element in
+ * the array immediately following the end of the deque is set to
+ * <tt>null</tt>.
+ *
+ * <p>Like the {@link #toArray()} method, this method acts as bridge between
+ * array-based and collection-based APIs. Further, this method allows
+ * precise control over the runtime type of the output array, and may,
+ * under certain circumstances, be used to save allocation costs.
+ *
+ * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
+ * The following code can be used to dump the deque into a newly
+ * allocated array of <tt>String</tt>:
+ *
+ * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+ *
+ * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+ * <tt>toArray()</tt>.
+ *
+ * @param a the array into which the elements of the deque are to
+ * be stored, if it is big enough; otherwise, a new array of the
+ * same runtime type is allocated for this purpose
+ * @return an array containing all of the elements in this deque
+ * @throws ArrayStoreException if the runtime type of the specified array
+ * is not a supertype of the runtime type of every element in
+ * this deque
+ * @throws NullPointerException if the specified array is null
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T[] toArray(T[] a) {
+ int size = size();
+ if (a.length < size)
+ a = (T[])java.lang.reflect.Array.newInstance(
+ a.getClass().getComponentType(), size);
+ copyElements(a);
+ if (a.length > size)
+ a[size] = null;
+ return a;
+ }
+
+ // *** Object methods ***
+
+ /**
+ * Returns a copy of this deque.
+ *
+ * @return a copy of this deque
+ */
+ public ArrayDeque<E> clone() {
+ try {
+ @SuppressWarnings("unchecked")
+ ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
+ result.elements = Arrays.copyOf(elements, elements.length);
+ return result;
+
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Appease the serialization gods.
+ */
+ private static final long serialVersionUID = 2340985798034038923L;
+
+ /**
+ * Serialize this deque.
+ *
+ * @serialData The current size (<tt>int</tt>) of the deque,
+ * followed by all of its elements (each an object reference) in
+ * first-to-last order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ s.defaultWriteObject();
+
+ // Write out size
+ s.writeInt(size());
+
+ // Write out elements in order.
+ int mask = elements.length - 1;
+ for (int i = head; i != tail; i = (i + 1) & mask)
+ s.writeObject(elements[i]);
+ }
+
+ /**
+ * Deserialize this deque.
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+
+ // Read in size and allocate array
+ int size = s.readInt();
+ allocateElements(size);
+ head = 0;
+ tail = size;
+
+ // Read in all elements in the proper order.
+ for (int i = 0; i < size; i++)
+ elements[i] = s.readObject();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/AsyncTask.java b/platform/android/src/com/artifex/mupdfdemo/AsyncTask.java
new file mode 100644
index 00000000..b370794c
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/AsyncTask.java
@@ -0,0 +1,670 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.artifex.mupdfdemo;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import android.os.Process;
+import android.os.Handler;
+import android.os.Message;
+
+/**
+ * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
+ * perform background operations and publish results on the UI thread without
+ * having to manipulate threads and/or handlers.</p>
+ *
+ * <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
+ * and does not constitute a generic threading framework. AsyncTasks should ideally be
+ * used for short operations (a few seconds at the most.) If you need to keep threads
+ * running for long periods of time, it is highly recommended you use the various APIs
+ * provided by the <code>java.util.concurrent</code> pacakge such as {@link Executor},
+ * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
+ *
+ * <p>An asynchronous task is defined by a computation that runs on a background thread and
+ * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
+ * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
+ * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
+ * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using tasks and threads, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
+ * Threads</a> developer guide.</p>
+ * </div>
+ *
+ * <h2>Usage</h2>
+ * <p>AsyncTask must be subclassed to be used. The subclass will override at least
+ * one method ({@link #doInBackground}), and most often will override a
+ * second one ({@link #onPostExecute}.)</p>
+ *
+ * <p>Here is an example of subclassing:</p>
+ * <pre class="prettyprint">
+ * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
+ * protected Long doInBackground(URL... urls) {
+ * int count = urls.length;
+ * long totalSize = 0;
+ * for (int i = 0; i < count; i++) {
+ * totalSize += Downloader.downloadFile(urls[i]);
+ * publishProgress((int) ((i / (float) count) * 100));
+ * // Escape early if cancel() is called
+ * if (isCancelled()) break;
+ * }
+ * return totalSize;
+ * }
+ *
+ * protected void onProgressUpdate(Integer... progress) {
+ * setProgressPercent(progress[0]);
+ * }
+ *
+ * protected void onPostExecute(Long result) {
+ * showDialog("Downloaded " + result + " bytes");
+ * }
+ * }
+ * </pre>
+ *
+ * <p>Once created, a task is executed very simply:</p>
+ * <pre class="prettyprint">
+ * new DownloadFilesTask().execute(url1, url2, url3);
+ * </pre>
+ *
+ * <h2>AsyncTask's generic types</h2>
+ * <p>The three types used by an asynchronous task are the following:</p>
+ * <ol>
+ * <li><code>Params</code>, the type of the parameters sent to the task upon
+ * execution.</li>
+ * <li><code>Progress</code>, the type of the progress units published during
+ * the background computation.</li>
+ * <li><code>Result</code>, the type of the result of the background
+ * computation.</li>
+ * </ol>
+ * <p>Not all types are always used by an asynchronous task. To mark a type as unused,
+ * simply use the type {@link Void}:</p>
+ * <pre>
+ * private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; { ... }
+ * </pre>
+ *
+ * <h2>The 4 steps</h2>
+ * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
+ * <ol>
+ * <li>{@link #onPreExecute()}, invoked on the UI thread before the task
+ * is executed. This step is normally used to setup the task, for instance by
+ * showing a progress bar in the user interface.</li>
+ * <li>{@link #doInBackground}, invoked on the background thread
+ * immediately after {@link #onPreExecute()} finishes executing. This step is used
+ * to perform background computation that can take a long time. The parameters
+ * of the asynchronous task are passed to this step. The result of the computation must
+ * be returned by this step and will be passed back to the last step. This step
+ * can also use {@link #publishProgress} to publish one or more units
+ * of progress. These values are published on the UI thread, in the
+ * {@link #onProgressUpdate} step.</li>
+ * <li>{@link #onProgressUpdate}, invoked on the UI thread after a
+ * call to {@link #publishProgress}. The timing of the execution is
+ * undefined. This method is used to display any form of progress in the user
+ * interface while the background computation is still executing. For instance,
+ * it can be used to animate a progress bar or show logs in a text field.</li>
+ * <li>{@link #onPostExecute}, invoked on the UI thread after the background
+ * computation finishes. The result of the background computation is passed to
+ * this step as a parameter.</li>
+ * </ol>
+ *
+ * <h2>Cancelling a task</h2>
+ * <p>A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking
+ * this method will cause subsequent calls to {@link #isCancelled()} to return true.
+ * After invoking this method, {@link #onCancelled(Object)}, instead of
+ * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])}
+ * returns. To ensure that a task is cancelled as quickly as possible, you should always
+ * check the return value of {@link #isCancelled()} periodically from
+ * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)</p>
+ *
+ * <h2>Threading rules</h2>
+ * <p>There are a few threading rules that must be followed for this class to
+ * work properly:</p>
+ * <ul>
+ * <li>The AsyncTask class must be loaded on the UI thread. This is done
+ * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
+ * <li>The task instance must be created on the UI thread.</li>
+ * <li>{@link #execute} must be invoked on the UI thread.</li>
+ * <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
+ * {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
+ * <li>The task can be executed only once (an exception will be thrown if
+ * a second execution is attempted.)</li>
+ * </ul>
+ *
+ * <h2>Memory observability</h2>
+ * <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
+ * operations are safe without explicit synchronizations.</p>
+ * <ul>
+ * <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
+ * in {@link #doInBackground}.
+ * <li>Set member fields in {@link #doInBackground}, and refer to them in
+ * {@link #onProgressUpdate} and {@link #onPostExecute}.
+ * </ul>
+ *
+ * <h2>Order of execution</h2>
+ * <p>When first introduced, AsyncTasks were executed serially on a single background
+ * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
+ * to a pool of threads allowing multiple tasks to operate in parallel. Starting with
+ * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single
+ * thread to avoid common application errors caused by parallel execution.</p>
+ * <p>If you truly want parallel execution, you can invoke
+ * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
+ * {@link #THREAD_POOL_EXECUTOR}.</p>
+ */
+public abstract class AsyncTask<Params, Progress, Result> {
+ private static final String LOG_TAG = "AsyncTask";
+
+ private static final int CORE_POOL_SIZE = 5;
+ private static final int MAXIMUM_POOL_SIZE = 128;
+ private static final int KEEP_ALIVE = 1;
+
+ private static final ThreadFactory sThreadFactory = new ThreadFactory() {
+ private final AtomicInteger mCount = new AtomicInteger(1);
+
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
+ }
+ };
+
+ private static final BlockingQueue<Runnable> sPoolWorkQueue =
+ new LinkedBlockingQueue<Runnable>(10);
+
+ /**
+ * An {@link Executor} that can be used to execute tasks in parallel.
+ */
+ public static final Executor THREAD_POOL_EXECUTOR
+ = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
+ TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
+
+ /**
+ * An {@link Executor} that executes tasks one at a time in serial
+ * order. This serialization is global to a particular process.
+ */
+ public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
+
+ private static final int MESSAGE_POST_RESULT = 0x1;
+ private static final int MESSAGE_POST_PROGRESS = 0x2;
+
+ private static final InternalHandler sHandler = new InternalHandler();
+
+ private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
+ private final WorkerRunnable<Params, Result> mWorker;
+ private final FutureTask<Result> mFuture;
+
+ private volatile Status mStatus = Status.PENDING;
+
+ private final AtomicBoolean mCancelled = new AtomicBoolean();
+ private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
+
+ private static class SerialExecutor implements Executor {
+ final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
+ Runnable mActive;
+
+ public synchronized void execute(final Runnable r) {
+ mTasks.offer(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+
+ protected synchronized void scheduleNext() {
+ if ((mActive = mTasks.poll()) != null) {
+ THREAD_POOL_EXECUTOR.execute(mActive);
+ }
+ }
+ }
+
+ /**
+ * Indicates the current status of the task. Each status will be set only once
+ * during the lifetime of a task.
+ */
+ public enum Status {
+ /**
+ * Indicates that the task has not been executed yet.
+ */
+ PENDING,
+ /**
+ * Indicates that the task is running.
+ */
+ RUNNING,
+ /**
+ * Indicates that {@link AsyncTask#onPostExecute} has finished.
+ */
+ FINISHED,
+ }
+
+ /** @hide Used to force static handler to be created. */
+ public static void init() {
+ sHandler.getLooper();
+ }
+
+ /** @hide */
+ public static void setDefaultExecutor(Executor exec) {
+ sDefaultExecutor = exec;
+ }
+
+ /**
+ * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
+ */
+ public AsyncTask() {
+ mWorker = new WorkerRunnable<Params, Result>() {
+ public Result call() throws Exception {
+ mTaskInvoked.set(true);
+
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ //noinspection unchecked
+ return postResult(doInBackground(mParams));
+ }
+ };
+
+ mFuture = new FutureTask<Result>(mWorker) {
+ @Override
+ protected void done() {
+ try {
+ postResultIfNotInvoked(get());
+ } catch (InterruptedException e) {
+ android.util.Log.w(LOG_TAG, e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("An error occured while executing doInBackground()",
+ e.getCause());
+ } catch (CancellationException e) {
+ postResultIfNotInvoked(null);
+ }
+ }
+ };
+ }
+
+ private void postResultIfNotInvoked(Result result) {
+ final boolean wasTaskInvoked = mTaskInvoked.get();
+ if (!wasTaskInvoked) {
+ postResult(result);
+ }
+ }
+
+ private Result postResult(Result result) {
+ @SuppressWarnings("unchecked")
+ Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
+ new AsyncTaskResult<Result>(this, result));
+ message.sendToTarget();
+ return result;
+ }
+
+ /**
+ * Returns the current status of this task.
+ *
+ * @return The current status.
+ */
+ public final Status getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Override this method to perform a computation on a background thread. The
+ * specified parameters are the parameters passed to {@link #execute}
+ * by the caller of this task.
+ *
+ * This method can call {@link #publishProgress} to publish updates
+ * on the UI thread.
+ *
+ * @param params The parameters of the task.
+ *
+ * @return A result, defined by the subclass of this task.
+ *
+ * @see #onPreExecute()
+ * @see #onPostExecute
+ * @see #publishProgress
+ */
+ protected abstract Result doInBackground(Params... params);
+
+ /**
+ * Runs on the UI thread before {@link #doInBackground}.
+ *
+ * @see #onPostExecute
+ * @see #doInBackground
+ */
+ protected void onPreExecute() {
+ }
+
+ /**
+ * <p>Runs on the UI thread after {@link #doInBackground}. The
+ * specified result is the value returned by {@link #doInBackground}.</p>
+ *
+ * <p>This method won't be invoked if the task was cancelled.</p>
+ *
+ * @param result The result of the operation computed by {@link #doInBackground}.
+ *
+ * @see #onPreExecute
+ * @see #doInBackground
+ * @see #onCancelled(Object)
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected void onPostExecute(Result result) {
+ }
+
+ /**
+ * Runs on the UI thread after {@link #publishProgress} is invoked.
+ * The specified values are the values passed to {@link #publishProgress}.
+ *
+ * @param values The values indicating progress.
+ *
+ * @see #publishProgress
+ * @see #doInBackground
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected void onProgressUpdate(Progress... values) {
+ }
+
+ /**
+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
+ * {@link #doInBackground(Object[])} has finished.</p>
+ *
+ * <p>The default implementation simply invokes {@link #onCancelled()} and
+ * ignores the result. If you write your own implementation, do not call
+ * <code>super.onCancelled(result)</code>.</p>
+ *
+ * @param result The result, if any, computed in
+ * {@link #doInBackground(Object[])}, can be null
+ *
+ * @see #cancel(boolean)
+ * @see #isCancelled()
+ */
+ @SuppressWarnings({"UnusedParameters"})
+ protected void onCancelled(Result result) {
+ onCancelled();
+ }
+
+ /**
+ * <p>Applications should preferably override {@link #onCancelled(Object)}.
+ * This method is invoked by the default implementation of
+ * {@link #onCancelled(Object)}.</p>
+ *
+ * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
+ * {@link #doInBackground(Object[])} has finished.</p>
+ *
+ * @see #onCancelled(Object)
+ * @see #cancel(boolean)
+ * @see #isCancelled()
+ */
+ protected void onCancelled() {
+ }
+
+ /**
+ * Returns <tt>true</tt> if this task was cancelled before it completed
+ * normally. If you are calling {@link #cancel(boolean)} on the task,
+ * the value returned by this method should be checked periodically from
+ * {@link #doInBackground(Object[])} to end the task as soon as possible.
+ *
+ * @return <tt>true</tt> if task was cancelled before it completed
+ *
+ * @see #cancel(boolean)
+ */
+ public final boolean isCancelled() {
+ return mCancelled.get();
+ }
+
+ /**
+ * <p>Attempts to cancel execution of this task. This attempt will
+ * fail if the task has already completed, already been cancelled,
+ * or could not be cancelled for some other reason. If successful,
+ * and this task has not started when <tt>cancel</tt> is called,
+ * this task should never run. If the task has already started,
+ * then the <tt>mayInterruptIfRunning</tt> parameter determines
+ * whether the thread executing this task should be interrupted in
+ * an attempt to stop the task.</p>
+ *
+ * <p>Calling this method will result in {@link #onCancelled(Object)} being
+ * invoked on the UI thread after {@link #doInBackground(Object[])}
+ * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
+ * is never invoked. After invoking this method, you should check the
+ * value returned by {@link #isCancelled()} periodically from
+ * {@link #doInBackground(Object[])} to finish the task as early as
+ * possible.</p>
+ *
+ * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+ * task should be interrupted; otherwise, in-progress tasks are allowed
+ * to complete.
+ *
+ * @return <tt>false</tt> if the task could not be cancelled,
+ * typically because it has already completed normally;
+ * <tt>true</tt> otherwise
+ *
+ * @see #isCancelled()
+ * @see #onCancelled(Object)
+ */
+ public final boolean cancel(boolean mayInterruptIfRunning) {
+ mCancelled.set(true);
+ return mFuture.cancel(mayInterruptIfRunning);
+ }
+
+ /**
+ * Waits if necessary for the computation to complete, and then
+ * retrieves its result.
+ *
+ * @return The computed result.
+ *
+ * @throws CancellationException If the computation was cancelled.
+ * @throws ExecutionException If the computation threw an exception.
+ * @throws InterruptedException If the current thread was interrupted
+ * while waiting.
+ */
+ public final Result get() throws InterruptedException, ExecutionException {
+ return mFuture.get();
+ }
+
+ /**
+ * Waits if necessary for at most the given time for the computation
+ * to complete, and then retrieves its result.
+ *
+ * @param timeout Time to wait before cancelling the operation.
+ * @param unit The time unit for the timeout.
+ *
+ * @return The computed result.
+ *
+ * @throws CancellationException If the computation was cancelled.
+ * @throws ExecutionException If the computation threw an exception.
+ * @throws InterruptedException If the current thread was interrupted
+ * while waiting.
+ * @throws TimeoutException If the wait timed out.
+ */
+ public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
+ ExecutionException, TimeoutException {
+ return mFuture.get(timeout, unit);
+ }
+
+ /**
+ * Executes the task with the specified parameters. The task returns
+ * itself (this) so that the caller can keep a reference to it.
+ *
+ * <p>Note: this function schedules the task on a queue for a single background
+ * thread or pool of threads depending on the platform version. When first
+ * introduced, AsyncTasks were executed serially on a single background thread.
+ * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed
+ * to a pool of threads allowing multiple tasks to operate in parallel. Starting
+ * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being
+ * executed on a single thread to avoid common application errors caused
+ * by parallel execution. If you truly want parallel execution, you can use
+ * the {@link #executeOnExecutor} version of this method
+ * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings
+ * on its use.
+ *
+ * <p>This method must be invoked on the UI thread.
+ *
+ * @param params The parameters of the task.
+ *
+ * @return This instance of AsyncTask.
+ *
+ * @throws IllegalStateException If {@link #getStatus()} returns either
+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+ *
+ * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
+ * @see #execute(Runnable)
+ */
+ public final AsyncTask<Params, Progress, Result> execute(Params... params) {
+ return executeOnExecutor(sDefaultExecutor, params);
+ }
+
+ /**
+ * Executes the task with the specified parameters. The task returns
+ * itself (this) so that the caller can keep a reference to it.
+ *
+ * <p>This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
+ * allow multiple tasks to run in parallel on a pool of threads managed by
+ * AsyncTask, however you can also use your own {@link Executor} for custom
+ * behavior.
+ *
+ * <p><em>Warning:</em> Allowing multiple tasks to run in parallel from
+ * a thread pool is generally <em>not</em> what one wants, because the order
+ * of their operation is not defined. For example, if these tasks are used
+ * to modify any state in common (such as writing a file due to a button click),
+ * there are no guarantees on the order of the modifications.
+ * Without careful work it is possible in rare cases for the newer version
+ * of the data to be over-written by an older one, leading to obscure data
+ * loss and stability issues. Such changes are best
+ * executed in serial; to guarantee such work is serialized regardless of
+ * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
+ *
+ * <p>This method must be invoked on the UI thread.
+ *
+ * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
+ * convenient process-wide thread pool for tasks that are loosely coupled.
+ * @param params The parameters of the task.
+ *
+ * @return This instance of AsyncTask.
+ *
+ * @throws IllegalStateException If {@link #getStatus()} returns either
+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+ *
+ * @see #execute(Object[])
+ */
+ public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
+ Params... params) {
+ if (mStatus != Status.PENDING) {
+ switch (mStatus) {
+ case RUNNING:
+ throw new IllegalStateException("Cannot execute task:"
+ + " the task is already running.");
+ case FINISHED:
+ throw new IllegalStateException("Cannot execute task:"
+ + " the task has already been executed "
+ + "(a task can be executed only once)");
+ }
+ }
+
+ mStatus = Status.RUNNING;
+
+ onPreExecute();
+
+ mWorker.mParams = params;
+ exec.execute(mFuture);
+
+ return this;
+ }
+
+ /**
+ * Convenience version of {@link #execute(Object...)} for use with
+ * a simple Runnable object. See {@link #execute(Object[])} for more
+ * information on the order of execution.
+ *
+ * @see #execute(Object[])
+ * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
+ */
+ public static void execute(Runnable runnable) {
+ sDefaultExecutor.execute(runnable);
+ }
+
+ /**
+ * This method can be invoked from {@link #doInBackground} to
+ * publish updates on the UI thread while the background computation is
+ * still running. Each call to this method will trigger the execution of
+ * {@link #onProgressUpdate} on the UI thread.
+ *
+ * {@link #onProgressUpdate} will note be called if the task has been
+ * canceled.
+ *
+ * @param values The progress values to update the UI with.
+ *
+ * @see #onProgressUpdate
+ * @see #doInBackground
+ */
+ protected final void publishProgress(Progress... values) {
+ if (!isCancelled()) {
+ sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
+ new AsyncTaskResult<Progress>(this, values)).sendToTarget();
+ }
+ }
+
+ private void finish(Result result) {
+ if (isCancelled()) {
+ onCancelled(result);
+ } else {
+ onPostExecute(result);
+ }
+ mStatus = Status.FINISHED;
+ }
+
+ private static class InternalHandler extends Handler {
+ @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncTaskResult result = (AsyncTaskResult) msg.obj;
+ switch (msg.what) {
+ case MESSAGE_POST_RESULT:
+ // There is only one result
+ result.mTask.finish(result.mData[0]);
+ break;
+ case MESSAGE_POST_PROGRESS:
+ result.mTask.onProgressUpdate(result.mData);
+ break;
+ }
+ }
+ }
+
+ private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
+ Params[] mParams;
+ }
+
+ @SuppressWarnings({"RawUseOfParameterizedType"})
+ private static class AsyncTaskResult<Data> {
+ final AsyncTask mTask;
+ final Data[] mData;
+
+ AsyncTaskResult(AsyncTask task, Data... data) {
+ mTask = task;
+ mData = data;
+ }
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java b/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java
new file mode 100644
index 00000000..5816e7bb
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java
@@ -0,0 +1,25 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.Bitmap;
+
+public class BitmapHolder {
+ private Bitmap bm;
+
+ public BitmapHolder() {
+ bm = null;
+ }
+
+ public synchronized void setBm(Bitmap abm) {
+ if (bm != null && bm != abm)
+ bm.recycle();
+ bm = abm;
+ }
+
+ public synchronized void drop() {
+ bm = null;
+ }
+
+ public synchronized Bitmap getBm() {
+ return bm;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/ChoosePDFActivity.java b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFActivity.java
new file mode 100644
index 00000000..c1c9142c
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFActivity.java
@@ -0,0 +1,195 @@
+package com.artifex.mupdfdemo;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.FileObserver;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ListView;
+
+public class ChoosePDFActivity extends ListActivity {
+ static private File mDirectory;
+ static private Map<String, Integer> mPositions = new HashMap<String, Integer>();
+ private File mParent;
+ private File [] mDirs;
+ private File [] mFiles;
+ private Handler mHandler;
+ private Runnable mUpdateFiles;
+ private ChoosePDFAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String storageState = Environment.getExternalStorageState();
+
+ if (!Environment.MEDIA_MOUNTED.equals(storageState)
+ && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(storageState))
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.no_media_warning);
+ builder.setMessage(R.string.no_media_hint);
+ AlertDialog alert = builder.create();
+ alert.setButton(AlertDialog.BUTTON_POSITIVE,getString(R.string.dismiss),
+ new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ alert.show();
+ return;
+ }
+
+ if (mDirectory == null)
+ mDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+
+ // Create a list adapter...
+ adapter = new ChoosePDFAdapter(getLayoutInflater());
+ setListAdapter(adapter);
+
+ // ...that is updated dynamically when files are scanned
+ mHandler = new Handler();
+ mUpdateFiles = new Runnable() {
+ public void run() {
+ Resources res = getResources();
+ String appName = res.getString(R.string.app_name);
+ String version = res.getString(R.string.version);
+ String title = res.getString(R.string.picker_title_App_Ver_Dir);
+ setTitle(String.format(title, appName, version, mDirectory));
+
+ mParent = mDirectory.getParentFile();
+
+ mDirs = mDirectory.listFiles(new FileFilter() {
+
+ public boolean accept(File file) {
+ return file.isDirectory();
+ }
+ });
+ if (mDirs == null)
+ mDirs = new File[0];
+
+ mFiles = mDirectory.listFiles(new FileFilter() {
+
+ public boolean accept(File file) {
+ if (file.isDirectory())
+ return false;
+ String fname = file.getName().toLowerCase();
+ if (fname.endsWith(".pdf"))
+ return true;
+ if (fname.endsWith(".xps"))
+ return true;
+ if (fname.endsWith(".cbz"))
+ return true;
+ if (fname.endsWith(".png"))
+ return true;
+ if (fname.endsWith(".jpe"))
+ return true;
+ if (fname.endsWith(".jpeg"))
+ return true;
+ if (fname.endsWith(".jpg"))
+ return true;
+ if (fname.endsWith(".jfif"))
+ return true;
+ if (fname.endsWith(".jfif-tbnl"))
+ return true;
+ if (fname.endsWith(".tif"))
+ return true;
+ if (fname.endsWith(".tiff"))
+ return true;
+ return false;
+ }
+ });
+ if (mFiles == null)
+ mFiles = new File[0];
+
+ Arrays.sort(mFiles, new Comparator<File>() {
+ public int compare(File arg0, File arg1) {
+ return arg0.getName().compareToIgnoreCase(arg1.getName());
+ }
+ });
+
+ Arrays.sort(mDirs, new Comparator<File>() {
+ public int compare(File arg0, File arg1) {
+ return arg0.getName().compareToIgnoreCase(arg1.getName());
+ }
+ });
+
+ adapter.clear();
+ if (mParent != null)
+ adapter.add(new ChoosePDFItem(ChoosePDFItem.Type.PARENT, getString(R.string.parent_directory)));
+ for (File f : mDirs)
+ adapter.add(new ChoosePDFItem(ChoosePDFItem.Type.DIR, f.getName()));
+ for (File f : mFiles)
+ adapter.add(new ChoosePDFItem(ChoosePDFItem.Type.DOC, f.getName()));
+
+ lastPosition();
+ }
+ };
+
+ // Start initial file scan...
+ mHandler.post(mUpdateFiles);
+
+ // ...and observe the directory and scan files upon changes.
+ FileObserver observer = new FileObserver(mDirectory.getPath(), FileObserver.CREATE | FileObserver.DELETE) {
+ public void onEvent(int event, String path) {
+ mHandler.post(mUpdateFiles);
+ }
+ };
+ observer.startWatching();
+ }
+
+ private void lastPosition() {
+ String p = mDirectory.getAbsolutePath();
+ if (mPositions.containsKey(p))
+ getListView().setSelection(mPositions.get(p));
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+
+ mPositions.put(mDirectory.getAbsolutePath(), getListView().getFirstVisiblePosition());
+
+ if (position < (mParent == null ? 0 : 1)) {
+ mDirectory = mParent;
+ mHandler.post(mUpdateFiles);
+ return;
+ }
+
+ position -= (mParent == null ? 0 : 1);
+
+ if (position < mDirs.length) {
+ mDirectory = mDirs[position];
+ mHandler.post(mUpdateFiles);
+ return;
+ }
+
+ position -= mDirs.length;
+
+ Uri uri = Uri.parse(mFiles[position].getAbsolutePath());
+ Intent intent = new Intent(this,MuPDFActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(uri);
+ startActivity(intent);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mPositions.put(mDirectory.getAbsolutePath(), getListView().getFirstVisiblePosition());
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/ChoosePDFAdapter.java b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFAdapter.java
new file mode 100644
index 00000000..0b3c6418
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFAdapter.java
@@ -0,0 +1,66 @@
+package com.artifex.mupdfdemo;
+
+import java.util.LinkedList;
+
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class ChoosePDFAdapter extends BaseAdapter {
+ private final LinkedList<ChoosePDFItem> mItems;
+ private final LayoutInflater mInflater;
+
+ public ChoosePDFAdapter(LayoutInflater inflater) {
+ mInflater = inflater;
+ mItems = new LinkedList<ChoosePDFItem>();
+ }
+
+ public void clear() {
+ mItems.clear();
+ }
+
+ public void add(ChoosePDFItem item) {
+ mItems.add(item);
+ notifyDataSetChanged();
+ }
+
+ public int getCount() {
+ return mItems.size();
+ }
+
+ public Object getItem(int i) {
+ return null;
+ }
+
+ public long getItemId(int arg0) {
+ return 0;
+ }
+
+ private int iconForType(ChoosePDFItem.Type type) {
+ switch (type) {
+ case PARENT: return R.drawable.ic_arrow_up;
+ case DIR: return R.drawable.ic_dir;
+ case DOC: return R.drawable.ic_doc;
+ default: return 0;
+ }
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v;
+ if (convertView == null) {
+ v = mInflater.inflate(R.layout.picker_entry, null);
+ } else {
+ v = convertView;
+ }
+ ChoosePDFItem item = mItems.get(position);
+ ((TextView)v.findViewById(R.id.name)).setText(item.name);
+ ((ImageView)v.findViewById(R.id.icon)).setImageResource(iconForType(item.type));
+ ((ImageView)v.findViewById(R.id.icon)).setColorFilter(Color.argb(255, 0, 0, 0));
+ return v;
+ }
+
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/ChoosePDFItem.java b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFItem.java
new file mode 100644
index 00000000..de6e1d52
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/ChoosePDFItem.java
@@ -0,0 +1,15 @@
+package com.artifex.mupdfdemo;
+
+public class ChoosePDFItem {
+ enum Type {
+ PARENT, DIR, DOC
+ }
+
+ final public Type type;
+ final public String name;
+
+ public ChoosePDFItem (Type t, String n) {
+ type = t;
+ name = n;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/Deque.java b/platform/android/src/com/artifex/mupdfdemo/Deque.java
new file mode 100644
index 00000000..4bb176b2
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/Deque.java
@@ -0,0 +1,554 @@
+/*
+ * Written by Doug Lea and Josh Bloch with assistance from members of
+ * JCP JSR-166 Expert Group and released to the public domain, as explained
+ * at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package com.artifex.mupdfdemo;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Stack;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * A linear collection that supports element insertion and removal at
+ * both ends. The name <i>deque</i> is short for "double ended queue"
+ * and is usually pronounced "deck". Most <tt>Deque</tt>
+ * implementations place no fixed limits on the number of elements
+ * they may contain, but this interface supports capacity-restricted
+ * deques as well as those with no fixed size limit.
+ *
+ * <p>This interface defines methods to access the elements at both
+ * ends of the deque. Methods are provided to insert, remove, and
+ * examine the element. Each of these methods exists in two forms:
+ * one throws an exception if the operation fails, the other returns a
+ * special value (either <tt>null</tt> or <tt>false</tt>, depending on
+ * the operation). The latter form of the insert operation is
+ * designed specifically for use with capacity-restricted
+ * <tt>Deque</tt> implementations; in most implementations, insert
+ * operations cannot fail.
+ *
+ * <p>The twelve methods described above are summarized in the
+ * following table:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <tr>
+ * <td></td>
+ * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
+ * <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
+ * </tr>
+ * <tr>
+ * <td></td>
+ * <td ALIGN=CENTER><em>Throws exception</em></td>
+ * <td ALIGN=CENTER><em>Special value</em></td>
+ * <td ALIGN=CENTER><em>Throws exception</em></td>
+ * <td ALIGN=CENTER><em>Special value</em></td>
+ * </tr>
+ * <tr>
+ * <td><b>Insert</b></td>
+ * <td>{@link #addFirst addFirst(e)}</td>
+ * <td>{@link #offerFirst offerFirst(e)}</td>
+ * <td>{@link #addLast addLast(e)}</td>
+ * <td>{@link #offerLast offerLast(e)}</td>
+ * </tr>
+ * <tr>
+ * <td><b>Remove</b></td>
+ * <td>{@link #removeFirst removeFirst()}</td>
+ * <td>{@link #pollFirst pollFirst()}</td>
+ * <td>{@link #removeLast removeLast()}</td>
+ * <td>{@link #pollLast pollLast()}</td>
+ * </tr>
+ * <tr>
+ * <td><b>Examine</b></td>
+ * <td>{@link #getFirst getFirst()}</td>
+ * <td>{@link #peekFirst peekFirst()}</td>
+ * <td>{@link #getLast getLast()}</td>
+ * <td>{@link #peekLast peekLast()}</td>
+ * </tr>
+ * </table>
+ *
+ * <p>This interface extends the {@link Queue} interface. When a deque is
+ * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are
+ * added at the end of the deque and removed from the beginning. The methods
+ * inherited from the <tt>Queue</tt> interface are precisely equivalent to
+ * <tt>Deque</tt> methods as indicated in the following table:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <tr>
+ * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
+ * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#add add(e)}</td>
+ * <td>{@link #addLast addLast(e)}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#offer offer(e)}</td>
+ * <td>{@link #offerLast offerLast(e)}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#remove remove()}</td>
+ * <td>{@link #removeFirst removeFirst()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#poll poll()}</td>
+ * <td>{@link #pollFirst pollFirst()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#element element()}</td>
+ * <td>{@link #getFirst getFirst()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.util.Queue#peek peek()}</td>
+ * <td>{@link #peek peekFirst()}</td>
+ * </tr>
+ * </table>
+ *
+ * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This
+ * interface should be used in preference to the legacy {@link Stack} class.
+ * When a deque is used as a stack, elements are pushed and popped from the
+ * beginning of the deque. Stack methods are precisely equivalent to
+ * <tt>Deque</tt> methods as indicated in the table below:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <tr>
+ * <td ALIGN=CENTER> <b>Stack Method</b></td>
+ * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #push push(e)}</td>
+ * <td>{@link #addFirst addFirst(e)}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #pop pop()}</td>
+ * <td>{@link #removeFirst removeFirst()}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #peek peek()}</td>
+ * <td>{@link #peekFirst peekFirst()}</td>
+ * </tr>
+ * </table>
+ *
+ * <p>Note that the {@link #peek peek} method works equally well when
+ * a deque is used as a queue or a stack; in either case, elements are
+ * drawn from the beginning of the deque.
+ *
+ * <p>This interface provides two methods to remove interior
+ * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and
+ * {@link #removeLastOccurrence removeLastOccurrence}.
+ *
+ * <p>Unlike the {@link List} interface, this interface does not
+ * provide support for indexed access to elements.
+ *
+ * <p>While <tt>Deque</tt> implementations are not strictly required
+ * to prohibit the insertion of null elements, they are strongly
+ * encouraged to do so. Users of any <tt>Deque</tt> implementations
+ * that do allow null elements are strongly encouraged <i>not</i> to
+ * take advantage of the ability to insert nulls. This is so because
+ * <tt>null</tt> is used as a special return value by various methods
+ * to indicated that the deque is empty.
+ *
+ * <p><tt>Deque</tt> implementations generally do not define
+ * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt>
+ * methods, but instead inherit the identity-based versions from class
+ * <tt>Object</tt>.
+ *
+ * @author Doug Lea
+ * @author Josh Bloch
+ * @since 1.6
+ * @param <E> the type of elements held in this collection
+ */
+
+public interface Deque<E> extends Queue<E> {
+ /**
+ * Inserts the specified element at the front of this deque if it is
+ * possible to do so immediately without violating capacity restrictions.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use method {@link #offerFirst}.
+ *
+ * @param e the element to add
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void addFirst(E e);
+
+ /**
+ * Inserts the specified element at the end of this deque if it is
+ * possible to do so immediately without violating capacity restrictions.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use method {@link #offerLast}.
+ *
+ * <p>This method is equivalent to {@link #add}.
+ *
+ * @param e the element to add
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void addLast(E e);
+
+ /**
+ * Inserts the specified element at the front of this deque unless it would
+ * violate capacity restrictions. When using a capacity-restricted deque,
+ * this method is generally preferable to the {@link #addFirst} method,
+ * which can fail to insert an element only by throwing an exception.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offerFirst(E e);
+
+ /**
+ * Inserts the specified element at the end of this deque unless it would
+ * violate capacity restrictions. When using a capacity-restricted deque,
+ * this method is generally preferable to the {@link #addLast} method,
+ * which can fail to insert an element only by throwing an exception.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offerLast(E e);
+
+ /**
+ * Retrieves and removes the first element of this deque. This method
+ * differs from {@link #pollFirst pollFirst} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * @return the head of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E removeFirst();
+
+ /**
+ * Retrieves and removes the last element of this deque. This method
+ * differs from {@link #pollLast pollLast} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * @return the tail of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E removeLast();
+
+ /**
+ * Retrieves and removes the first element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the head of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E pollFirst();
+
+ /**
+ * Retrieves and removes the last element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E pollLast();
+
+ /**
+ * Retrieves, but does not remove, the first element of this deque.
+ *
+ * This method differs from {@link #peekFirst peekFirst} only in that it
+ * throws an exception if this deque is empty.
+ *
+ * @return the head of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E getFirst();
+
+ /**
+ * Retrieves, but does not remove, the last element of this deque.
+ * This method differs from {@link #peekLast peekLast} only in that it
+ * throws an exception if this deque is empty.
+ *
+ * @return the tail of this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E getLast();
+
+ /**
+ * Retrieves, but does not remove, the first element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the head of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E peekFirst();
+
+ /**
+ * Retrieves, but does not remove, the last element of this deque,
+ * or returns <tt>null</tt> if this deque is empty.
+ *
+ * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+ */
+ E peekLast();
+
+ /**
+ * Removes the first occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean removeFirstOccurrence(Object o);
+
+ /**
+ * Removes the last occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the last element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean removeLastOccurrence(Object o);
+
+ // *** Queue methods ***
+
+ /**
+ * Inserts the specified element into the queue represented by this deque
+ * (in other words, at the tail of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and throwing an
+ * <tt>IllegalStateException</tt> if no space is currently available.
+ * When using a capacity-restricted deque, it is generally preferable to
+ * use {@link #offer(Object) offer}.
+ *
+ * <p>This method is equivalent to {@link #addLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> (as specified by {@link Collection#add})
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean add(E e);
+
+ /**
+ * Inserts the specified element into the queue represented by this deque
+ * (in other words, at the tail of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+ * available. When using a capacity-restricted deque, this method is
+ * generally preferable to the {@link #add} method, which can fail to
+ * insert an element only by throwing an exception.
+ *
+ * <p>This method is equivalent to {@link #offerLast}.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this deque, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ boolean offer(E e);
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque).
+ * This method differs from {@link #poll poll} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E remove();
+
+ /**
+ * Retrieves and removes the head of the queue represented by this deque
+ * (in other words, the first element of this deque), or returns
+ * <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst()}.
+ *
+ * @return the first element of this deque, or <tt>null</tt> if
+ * this deque is empty
+ */
+ E poll();
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque (in other words, the first element of this deque).
+ * This method differs from {@link #peek peek} only in that it throws an
+ * exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #getFirst()}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E element();
+
+ /**
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque (in other words, the first element of this deque), or
+ * returns <tt>null</tt> if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #peekFirst()}.
+ *
+ * @return the head of the queue represented by this deque, or
+ * <tt>null</tt> if this deque is empty
+ */
+ E peek();
+
+
+ // *** Stack methods ***
+
+ /**
+ * Pushes an element onto the stack represented by this deque (in other
+ * words, at the head of this deque) if it is possible to do so
+ * immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and throwing an
+ * <tt>IllegalStateException</tt> if no space is currently available.
+ *
+ * <p>This method is equivalent to {@link #addFirst}.
+ *
+ * @param e the element to push
+ * @throws IllegalStateException if the element cannot be added at this
+ * time due to capacity restrictions
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this deque
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this deque
+ */
+ void push(E e);
+
+ /**
+ * Pops an element from the stack represented by this deque. In other
+ * words, removes and returns the first element of this deque.
+ *
+ * <p>This method is equivalent to {@link #removeFirst()}.
+ *
+ * @return the element at the front of this deque (which is the top
+ * of the stack represented by this deque)
+ * @throws NoSuchElementException if this deque is empty
+ */
+ E pop();
+
+
+ // *** Collection methods ***
+
+ /**
+ * Removes the first occurrence of the specified element from this deque.
+ * If the deque does not contain the element, it is unchanged.
+ * More formally, removes the first element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
+ * (if such an element exists).
+ * Returns <tt>true</tt> if this deque contained the specified element
+ * (or equivalently, if this deque changed as a result of the call).
+ *
+ * <p>This method is equivalent to {@link #removeFirstOccurrence}.
+ *
+ * @param o element to be removed from this deque, if present
+ * @return <tt>true</tt> if an element was removed as a result of this call
+ * @throws ClassCastException if the class of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean remove(Object o);
+
+ /**
+ * Returns <tt>true</tt> if this deque contains the specified element.
+ * More formally, returns <tt>true</tt> if and only if this deque contains
+ * at least one element <tt>e</tt> such that
+ * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
+ *
+ * @param o element whose presence in this deque is to be tested
+ * @return <tt>true</tt> if this deque contains the specified element
+ * @throws ClassCastException if the type of the specified element
+ * is incompatible with this deque (optional)
+ * @throws NullPointerException if the specified element is null and this
+ * deque does not permit null elements (optional)
+ */
+ boolean contains(Object o);
+
+ /**
+ * Returns the number of elements in this deque.
+ *
+ * @return the number of elements in this deque
+ */
+ public int size();
+
+ /**
+ * Returns an iterator over the elements in this deque in proper sequence.
+ * The elements will be returned in order from first (head) to last (tail).
+ *
+ * @return an iterator over the elements in this deque in proper sequence
+ */
+ Iterator<E> iterator();
+
+ /**
+ * Returns an iterator over the elements in this deque in reverse
+ * sequential order. The elements will be returned in order from
+ * last (tail) to first (head).
+ *
+ * @return an iterator over the elements in this deque in reverse
+ * sequence
+ */
+ Iterator<E> descendingIterator();
+
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/LinkInfo.java b/platform/android/src/com/artifex/mupdfdemo/LinkInfo.java
new file mode 100644
index 00000000..5aeaccbe
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/LinkInfo.java
@@ -0,0 +1,14 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.RectF;
+
+public class LinkInfo {
+ final public RectF rect;
+
+ public LinkInfo(float l, float t, float r, float b) {
+ rect = new RectF(l, t, r, b);
+ }
+
+ public void acceptVisitor(LinkInfoVisitor visitor) {
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/LinkInfoExternal.java b/platform/android/src/com/artifex/mupdfdemo/LinkInfoExternal.java
new file mode 100644
index 00000000..574b6264
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/LinkInfoExternal.java
@@ -0,0 +1,14 @@
+package com.artifex.mupdfdemo;
+
+public class LinkInfoExternal extends LinkInfo {
+ final public String url;
+
+ public LinkInfoExternal(float l, float t, float r, float b, String u) {
+ super(l, t, r, b);
+ url = u;
+ }
+
+ public void acceptVisitor(LinkInfoVisitor visitor) {
+ visitor.visitExternal(this);
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/LinkInfoInternal.java b/platform/android/src/com/artifex/mupdfdemo/LinkInfoInternal.java
new file mode 100644
index 00000000..761bf87a
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/LinkInfoInternal.java
@@ -0,0 +1,14 @@
+package com.artifex.mupdfdemo;
+
+public class LinkInfoInternal extends LinkInfo {
+ final public int pageNumber;
+
+ public LinkInfoInternal(float l, float t, float r, float b, int p) {
+ super(l, t, r, b);
+ pageNumber = p;
+ }
+
+ public void acceptVisitor(LinkInfoVisitor visitor) {
+ visitor.visitInternal(this);
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/LinkInfoRemote.java b/platform/android/src/com/artifex/mupdfdemo/LinkInfoRemote.java
new file mode 100644
index 00000000..731e6408
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/LinkInfoRemote.java
@@ -0,0 +1,18 @@
+package com.artifex.mupdfdemo;
+
+public class LinkInfoRemote extends LinkInfo {
+ final public String fileSpec;
+ final public int pageNumber;
+ final public boolean newWindow;
+
+ public LinkInfoRemote(float l, float t, float r, float b, String f, int p, boolean n) {
+ super(l, t, r, b);
+ fileSpec = f;
+ pageNumber = p;
+ newWindow = n;
+ }
+
+ public void acceptVisitor(LinkInfoVisitor visitor) {
+ visitor.visitRemote(this);
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/LinkInfoVisitor.java b/platform/android/src/com/artifex/mupdfdemo/LinkInfoVisitor.java
new file mode 100644
index 00000000..ecd093e4
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/LinkInfoVisitor.java
@@ -0,0 +1,7 @@
+package com.artifex.mupdfdemo;
+
+abstract public class LinkInfoVisitor {
+ public abstract void visitInternal(LinkInfoInternal li);
+ public abstract void visitExternal(LinkInfoExternal li);
+ public abstract void visitRemote(LinkInfoRemote li);
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
new file mode 100644
index 00000000..ff38b22a
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java
@@ -0,0 +1,1090 @@
+package com.artifex.mupdfdemo;
+
+import java.io.InputStream;
+import java.util.concurrent.Executor;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.method.PasswordTransformationMethod;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.ViewAnimator;
+
+class ThreadPerTaskExecutor implements Executor {
+ public void execute(Runnable r) {
+ new Thread(r).start();
+ }
+}
+
+public class MuPDFActivity extends Activity
+{
+ /* The core rendering instance */
+ enum TopBarMode {Main, Search, Annot, Delete, More, Accept};
+ enum AcceptMode {Highlight, Underline, StrikeOut, Ink, CopyText};
+
+ private final int OUTLINE_REQUEST=0;
+ private final int PRINT_REQUEST=1;
+ private MuPDFCore core;
+ private String mFileName;
+ private MuPDFReaderView mDocView;
+ private View mButtonsView;
+ private boolean mButtonsVisible;
+ private EditText mPasswordView;
+ private TextView mFilenameView;
+ private SeekBar mPageSlider;
+ private int mPageSliderRes;
+ private TextView mPageNumberView;
+ private TextView mInfoView;
+ private ImageButton mSearchButton;
+ private ImageButton mReflowButton;
+ private ImageButton mOutlineButton;
+ private ImageButton mMoreButton;
+ private TextView mAnnotTypeText;
+ private ImageButton mAnnotButton;
+ private ViewAnimator mTopBarSwitcher;
+ private ImageButton mLinkButton;
+ private TopBarMode mTopBarMode = TopBarMode.Main;
+ private AcceptMode mAcceptMode;
+ private ImageButton mSearchBack;
+ private ImageButton mSearchFwd;
+ private EditText mSearchText;
+ private SearchTask mSearchTask;
+ private AlertDialog.Builder mAlertBuilder;
+ private boolean mLinkHighlight = false;
+ private final Handler mHandler = new Handler();
+ private boolean mAlertsActive= false;
+ private boolean mReflow = false;
+ private AsyncTask<Void,Void,MuPDFAlert> mAlertTask;
+ private AlertDialog mAlertDialog;
+
+ public void createAlertWaiter() {
+ mAlertsActive = true;
+ // All mupdf library calls are performed on asynchronous tasks to avoid stalling
+ // the UI. Some calls can lead to javascript-invoked requests to display an
+ // alert dialog and collect a reply from the user. The task has to be blocked
+ // until the user's reply is received. This method creates an asynchronous task,
+ // the purpose of which is to wait of these requests and produce the dialog
+ // in response, while leaving the core blocked. When the dialog receives the
+ // user's response, it is sent to the core via replyToAlert, unblocking it.
+ // Another alert-waiting task is then created to pick up the next alert.
+ if (mAlertTask != null) {
+ mAlertTask.cancel(true);
+ mAlertTask = null;
+ }
+ if (mAlertDialog != null) {
+ mAlertDialog.cancel();
+ mAlertDialog = null;
+ }
+ mAlertTask = new AsyncTask<Void,Void,MuPDFAlert>() {
+
+ @Override
+ protected MuPDFAlert doInBackground(Void... arg0) {
+ if (!mAlertsActive)
+ return null;
+
+ return core.waitForAlert();
+ }
+
+ @Override
+ protected void onPostExecute(final MuPDFAlert result) {
+ // core.waitForAlert may return null when shutting down
+ if (result == null)
+ return;
+ final MuPDFAlert.ButtonPressed pressed[] = new MuPDFAlert.ButtonPressed[3];
+ for(int i = 0; i < 3; i++)
+ pressed[i] = MuPDFAlert.ButtonPressed.None;
+ DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mAlertDialog = null;
+ if (mAlertsActive) {
+ int index = 0;
+ switch (which) {
+ case AlertDialog.BUTTON1: index=0; break;
+ case AlertDialog.BUTTON2: index=1; break;
+ case AlertDialog.BUTTON3: index=2; break;
+ }
+ result.buttonPressed = pressed[index];
+ // Send the user's response to the core, so that it can
+ // continue processing.
+ core.replyToAlert(result);
+ // Create another alert-waiter to pick up the next alert.
+ createAlertWaiter();
+ }
+ }
+ };
+ mAlertDialog = mAlertBuilder.create();
+ mAlertDialog.setTitle(result.title);
+ mAlertDialog.setMessage(result.message);
+ switch (result.iconType)
+ {
+ case Error:
+ break;
+ case Warning:
+ break;
+ case Question:
+ break;
+ case Status:
+ break;
+ }
+ switch (result.buttonGroupType)
+ {
+ case OkCancel:
+ mAlertDialog.setButton(AlertDialog.BUTTON2, getString(R.string.cancel), listener);
+ pressed[1] = MuPDFAlert.ButtonPressed.Cancel;
+ case Ok:
+ mAlertDialog.setButton(AlertDialog.BUTTON1, getString(R.string.okay), listener);
+ pressed[0] = MuPDFAlert.ButtonPressed.Ok;
+ break;
+ case YesNoCancel:
+ mAlertDialog.setButton(AlertDialog.BUTTON3, getString(R.string.cancel), listener);
+ pressed[2] = MuPDFAlert.ButtonPressed.Cancel;
+ case YesNo:
+ mAlertDialog.setButton(AlertDialog.BUTTON1, getString(R.string.yes), listener);
+ pressed[0] = MuPDFAlert.ButtonPressed.Yes;
+ mAlertDialog.setButton(AlertDialog.BUTTON2, getString(R.string.no), listener);
+ pressed[1] = MuPDFAlert.ButtonPressed.No;
+ break;
+ }
+ mAlertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ mAlertDialog = null;
+ if (mAlertsActive) {
+ result.buttonPressed = MuPDFAlert.ButtonPressed.None;
+ core.replyToAlert(result);
+ createAlertWaiter();
+ }
+ }
+ });
+
+ mAlertDialog.show();
+ }
+ };
+
+ mAlertTask.executeOnExecutor(new ThreadPerTaskExecutor());
+ }
+
+ public void destroyAlertWaiter() {
+ mAlertsActive = false;
+ if (mAlertDialog != null) {
+ mAlertDialog.cancel();
+ mAlertDialog = null;
+ }
+ if (mAlertTask != null) {
+ mAlertTask.cancel(true);
+ mAlertTask = null;
+ }
+ }
+
+ private MuPDFCore openFile(String path)
+ {
+ int lastSlashPos = path.lastIndexOf('/');
+ mFileName = new String(lastSlashPos == -1
+ ? path
+ : path.substring(lastSlashPos+1));
+ System.out.println("Trying to open "+path);
+ try
+ {
+ core = new MuPDFCore(this, path);
+ // New file: drop the old outline data
+ OutlineActivityData.set(null);
+ }
+ catch (Exception e)
+ {
+ System.out.println(e);
+ return null;
+ }
+ return core;
+ }
+
+ private MuPDFCore openBuffer(byte buffer[])
+ {
+ System.out.println("Trying to open byte buffer");
+ try
+ {
+ core = new MuPDFCore(this, buffer);
+ // New file: drop the old outline data
+ OutlineActivityData.set(null);
+ }
+ catch (Exception e)
+ {
+ System.out.println(e);
+ return null;
+ }
+ return core;
+ }
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ mAlertBuilder = new AlertDialog.Builder(this);
+
+ if (core == null) {
+ core = (MuPDFCore)getLastNonConfigurationInstance();
+
+ if (savedInstanceState != null && savedInstanceState.containsKey("FileName")) {
+ mFileName = savedInstanceState.getString("FileName");
+ }
+ }
+ if (core == null) {
+ Intent intent = getIntent();
+ byte buffer[] = null;
+ if (Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ if (uri.toString().startsWith("content://")) {
+ // Handle view requests from the Transformer Prime's file manager
+ // Hopefully other file managers will use this same scheme, if not
+ // using explicit paths.
+ Cursor cursor = getContentResolver().query(uri, new String[]{"_data"}, null, null, null);
+ if (cursor.moveToFirst()) {
+ String str = cursor.getString(0);
+ String reason = null;
+ if (str == null) {
+ try {
+ InputStream is = getContentResolver().openInputStream(uri);
+ int len = is.available();
+ buffer = new byte[len];
+ is.read(buffer, 0, len);
+ is.close();
+ }
+ catch (java.lang.OutOfMemoryError e)
+ {
+ System.out.println("Out of memory during buffer reading");
+ reason = e.toString();
+ }
+ catch (Exception e) {
+ reason = e.toString();
+ }
+ if (reason != null)
+ {
+ buffer = null;
+ Resources res = getResources();
+ AlertDialog alert = mAlertBuilder.create();
+ setTitle(String.format(res.getString(R.string.cannot_open_document_Reason), reason));
+ alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.dismiss),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ alert.show();
+ return;
+ }
+ } else {
+ uri = Uri.parse(str);
+ }
+ }
+ }
+ if (buffer != null) {
+ core = openBuffer(buffer);
+ } else {
+ core = openFile(Uri.decode(uri.getEncodedPath()));
+ }
+ SearchTaskResult.set(null);
+ if (core.countPages() == 0)
+ core = null;
+ }
+ if (core != null && core.needsPassword()) {
+ requestPassword(savedInstanceState);
+ return;
+ }
+ }
+ if (core == null)
+ {
+ AlertDialog alert = mAlertBuilder.create();
+ alert.setTitle(R.string.cannot_open_document);
+ alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.dismiss),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ alert.show();
+ return;
+ }
+
+ createUI(savedInstanceState);
+ }
+
+ public void requestPassword(final Bundle savedInstanceState) {
+ mPasswordView = new EditText(this);
+ mPasswordView.setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
+ mPasswordView.setTransformationMethod(new PasswordTransformationMethod());
+
+ AlertDialog alert = mAlertBuilder.create();
+ alert.setTitle(R.string.enter_password);
+ alert.setView(mPasswordView);
+ alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.okay),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (core.authenticatePassword(mPasswordView.getText().toString())) {
+ createUI(savedInstanceState);
+ } else {
+ requestPassword(savedInstanceState);
+ }
+ }
+ });
+ alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.cancel),
+ new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ alert.show();
+ }
+
+ public void createUI(Bundle savedInstanceState) {
+ if (core == null)
+ return;
+
+ // Now create the UI.
+ // First create the document view
+ mDocView = new MuPDFReaderView(this) {
+ @Override
+ protected void onMoveToChild(int i) {
+ if (core == null)
+ return;
+ mPageNumberView.setText(String.format("%d / %d", i + 1,
+ core.countPages()));
+ mPageSlider.setMax((core.countPages() - 1) * mPageSliderRes);
+ mPageSlider.setProgress(i * mPageSliderRes);
+ super.onMoveToChild(i);
+ }
+
+ @Override
+ protected void onTapMainDocArea() {
+ if (!mButtonsVisible) {
+ showButtons();
+ } else {
+ if (mTopBarMode == TopBarMode.Main)
+ hideButtons();
+ }
+ }
+
+ @Override
+ protected void onDocMotion() {
+ hideButtons();
+ }
+
+ @Override
+ protected void onHit(Hit item) {
+ switch (mTopBarMode) {
+ case Annot:
+ if (item == Hit.Annotation) {
+ showButtons();
+ mTopBarMode = TopBarMode.Delete;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ break;
+ case Delete:
+ mTopBarMode = TopBarMode.Annot;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ // fall through
+ default:
+ // Not in annotation editing mode, but the pageview will
+ // still select and highlight hit annotations, so
+ // deselect just in case.
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.deselectAnnotation();
+ break;
+ }
+ }
+ };
+ mDocView.setAdapter(new MuPDFPageAdapter(this, core));
+
+ mSearchTask = new SearchTask(this, core) {
+ @Override
+ protected void onTextFound(SearchTaskResult result) {
+ SearchTaskResult.set(result);
+ // Ask the ReaderView to move to the resulting page
+ mDocView.setDisplayedViewIndex(result.pageNumber);
+ // Make the ReaderView act on the change to SearchTaskResult
+ // via overridden onChildSetup method.
+ mDocView.resetupChildren();
+ }
+ };
+
+ // Make the buttons overlay, and store all its
+ // controls in variables
+ makeButtonsView();
+
+ // Set up the page slider
+ int smax = Math.max(core.countPages()-1,1);
+ mPageSliderRes = ((10 + smax - 1)/smax) * 2;
+
+ // Set the file-name text
+ mFilenameView.setText(mFileName);
+
+ // Activate the seekbar
+ mPageSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ mDocView.setDisplayedViewIndex((seekBar.getProgress()+mPageSliderRes/2)/mPageSliderRes);
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {}
+
+ public void onProgressChanged(SeekBar seekBar, int progress,
+ boolean fromUser) {
+ updatePageNumView((progress+mPageSliderRes/2)/mPageSliderRes);
+ }
+ });
+
+ // Activate the search-preparing button
+ mSearchButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ searchModeOn();
+ }
+ });
+
+ // Activate the reflow button
+ mReflowButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ toggleReflow();
+ }
+ });
+
+ if (core.fileFormat().startsWith("PDF"))
+ {
+ mAnnotButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mTopBarMode = TopBarMode.Annot;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ });
+ }
+ else
+ {
+ mAnnotButton.setVisibility(View.GONE);
+ }
+
+ // Search invoking buttons are disabled while there is no text specified
+ mSearchBack.setEnabled(false);
+ mSearchFwd.setEnabled(false);
+ mSearchBack.setColorFilter(Color.argb(255, 128, 128, 128));
+ mSearchFwd.setColorFilter(Color.argb(255, 128, 128, 128));
+
+ // React to interaction with the text widget
+ mSearchText.addTextChangedListener(new TextWatcher() {
+
+ public void afterTextChanged(Editable s) {
+ boolean haveText = s.toString().length() > 0;
+ setButtonEnabled(mSearchBack, haveText);
+ setButtonEnabled(mSearchFwd, haveText);
+
+ // Remove any previous search results
+ if (SearchTaskResult.get() != null && !mSearchText.getText().toString().equals(SearchTaskResult.get().txt)) {
+ SearchTaskResult.set(null);
+ mDocView.resetupChildren();
+ }
+ }
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {}
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {}
+ });
+
+ //React to Done button on keyboard
+ mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE)
+ search(1);
+ return false;
+ }
+ });
+
+ mSearchText.setOnKeyListener(new View.OnKeyListener() {
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER)
+ search(1);
+ return false;
+ }
+ });
+
+ // Activate search invoking buttons
+ mSearchBack.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ search(-1);
+ }
+ });
+ mSearchFwd.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ search(1);
+ }
+ });
+
+ mLinkButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ setLinkHighlight(!mLinkHighlight);
+ }
+ });
+
+ if (core.hasOutline()) {
+ mOutlineButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ OutlineItem outline[] = core.getOutline();
+ if (outline != null) {
+ OutlineActivityData.get().items = outline;
+ Intent intent = new Intent(MuPDFActivity.this, OutlineActivity.class);
+ startActivityForResult(intent, OUTLINE_REQUEST);
+ }
+ }
+ });
+ } else {
+ mOutlineButton.setVisibility(View.GONE);
+ }
+
+ // Reenstate last state if it was recorded
+ SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
+ mDocView.setDisplayedViewIndex(prefs.getInt("page"+mFileName, 0));
+
+ if (savedInstanceState == null || !savedInstanceState.getBoolean("ButtonsHidden", false))
+ showButtons();
+
+ if(savedInstanceState != null && savedInstanceState.getBoolean("SearchMode", false))
+ searchModeOn();
+
+ if(savedInstanceState != null && savedInstanceState.getBoolean("ReflowMode", false))
+ reflowModeSet(true);
+
+ // Stick the document view and the buttons overlay into a parent view
+ RelativeLayout layout = new RelativeLayout(this);
+ layout.addView(mDocView);
+ layout.addView(mButtonsView);
+ setContentView(layout);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case OUTLINE_REQUEST:
+ if (resultCode >= 0)
+ mDocView.setDisplayedViewIndex(resultCode);
+ break;
+ case PRINT_REQUEST:
+ if (resultCode == RESULT_CANCELED)
+ showInfo(getString(R.string.print_failed));
+ break;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ public Object onRetainNonConfigurationInstance()
+ {
+ MuPDFCore mycore = core;
+ core = null;
+ return mycore;
+ }
+
+ private void reflowModeSet(boolean reflow)
+ {
+ mReflow = reflow;
+ mDocView.setAdapter(mReflow ? new MuPDFReflowAdapter(this, core) : new MuPDFPageAdapter(this, core));
+ mReflowButton.setColorFilter(mReflow ? Color.argb(0xFF, 172, 114, 37) : Color.argb(0xFF, 255, 255, 255));
+ setButtonEnabled(mAnnotButton, !reflow);
+ setButtonEnabled(mSearchButton, !reflow);
+ if (reflow) setLinkHighlight(false);
+ setButtonEnabled(mLinkButton, !reflow);
+ setButtonEnabled(mMoreButton, !reflow);
+ mDocView.refresh(mReflow);
+ }
+
+ private void toggleReflow() {
+ reflowModeSet(!mReflow);
+ showInfo(mReflow ? getString(R.string.entering_reflow_mode) : getString(R.string.leaving_reflow_mode));
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ if (mFileName != null && mDocView != null) {
+ outState.putString("FileName", mFileName);
+
+ // Store current page in the prefs against the file name,
+ // so that we can pick it up each time the file is loaded
+ // Other info is needed only for screen-orientation change,
+ // so it can go in the bundle
+ SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putInt("page"+mFileName, mDocView.getDisplayedViewIndex());
+ edit.commit();
+ }
+
+ if (!mButtonsVisible)
+ outState.putBoolean("ButtonsHidden", true);
+
+ if (mTopBarMode == TopBarMode.Search)
+ outState.putBoolean("SearchMode", true);
+
+ if (mReflow)
+ outState.putBoolean("ReflowMode", true);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ if (mSearchTask != null)
+ mSearchTask.stop();
+
+ if (mFileName != null && mDocView != null) {
+ SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = prefs.edit();
+ edit.putInt("page"+mFileName, mDocView.getDisplayedViewIndex());
+ edit.commit();
+ }
+ }
+
+ public void onDestroy()
+ {
+ if (core != null)
+ core.onDestroy();
+ if (mAlertTask != null) {
+ mAlertTask.cancel(true);
+ mAlertTask = null;
+ }
+ core = null;
+ super.onDestroy();
+ }
+
+ private void setButtonEnabled(ImageButton button, boolean enabled) {
+ button.setEnabled(enabled);
+ button.setColorFilter(enabled ? Color.argb(255, 255, 255, 255):Color.argb(255, 128, 128, 128));
+ }
+
+ private void setLinkHighlight(boolean highlight) {
+ mLinkHighlight = highlight;
+ // LINK_COLOR tint
+ mLinkButton.setColorFilter(highlight ? Color.argb(0xFF, 172, 114, 37) : Color.argb(0xFF, 255, 255, 255));
+ // Inform pages of the change.
+ mDocView.setLinksEnabled(highlight);
+ }
+
+ private void showButtons() {
+ if (core == null)
+ return;
+ if (!mButtonsVisible) {
+ mButtonsVisible = true;
+ // Update page number text and slider
+ int index = mDocView.getDisplayedViewIndex();
+ updatePageNumView(index);
+ mPageSlider.setMax((core.countPages()-1)*mPageSliderRes);
+ mPageSlider.setProgress(index*mPageSliderRes);
+ if (mTopBarMode == TopBarMode.Search) {
+ mSearchText.requestFocus();
+ showKeyboard();
+ }
+
+ Animation anim = new TranslateAnimation(0, 0, -mTopBarSwitcher.getHeight(), 0);
+ anim.setDuration(200);
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ public void onAnimationStart(Animation animation) {
+ mTopBarSwitcher.setVisibility(View.VISIBLE);
+ }
+ public void onAnimationRepeat(Animation animation) {}
+ public void onAnimationEnd(Animation animation) {}
+ });
+ mTopBarSwitcher.startAnimation(anim);
+
+ anim = new TranslateAnimation(0, 0, mPageSlider.getHeight(), 0);
+ anim.setDuration(200);
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ public void onAnimationStart(Animation animation) {
+ mPageSlider.setVisibility(View.VISIBLE);
+ }
+ public void onAnimationRepeat(Animation animation) {}
+ public void onAnimationEnd(Animation animation) {
+ mPageNumberView.setVisibility(View.VISIBLE);
+ }
+ });
+ mPageSlider.startAnimation(anim);
+ }
+ }
+
+ private void hideButtons() {
+ if (mButtonsVisible) {
+ mButtonsVisible = false;
+ hideKeyboard();
+
+ Animation anim = new TranslateAnimation(0, 0, 0, -mTopBarSwitcher.getHeight());
+ anim.setDuration(200);
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ public void onAnimationStart(Animation animation) {}
+ public void onAnimationRepeat(Animation animation) {}
+ public void onAnimationEnd(Animation animation) {
+ mTopBarSwitcher.setVisibility(View.INVISIBLE);
+ }
+ });
+ mTopBarSwitcher.startAnimation(anim);
+
+ anim = new TranslateAnimation(0, 0, 0, mPageSlider.getHeight());
+ anim.setDuration(200);
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ public void onAnimationStart(Animation animation) {
+ mPageNumberView.setVisibility(View.INVISIBLE);
+ }
+ public void onAnimationRepeat(Animation animation) {}
+ public void onAnimationEnd(Animation animation) {
+ mPageSlider.setVisibility(View.INVISIBLE);
+ }
+ });
+ mPageSlider.startAnimation(anim);
+ }
+ }
+
+ private void searchModeOn() {
+ if (mTopBarMode != TopBarMode.Search) {
+ mTopBarMode = TopBarMode.Search;
+ //Focus on EditTextWidget
+ mSearchText.requestFocus();
+ showKeyboard();
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+ }
+
+ private void searchModeOff() {
+ if (mTopBarMode == TopBarMode.Search) {
+ mTopBarMode = TopBarMode.Main;
+ hideKeyboard();
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ SearchTaskResult.set(null);
+ // Make the ReaderView act on the change to mSearchTaskResult
+ // via overridden onChildSetup method.
+ mDocView.resetupChildren();
+ }
+ }
+
+ private void updatePageNumView(int index) {
+ if (core == null)
+ return;
+ mPageNumberView.setText(String.format("%d / %d", index+1, core.countPages()));
+ }
+
+ private void printDoc() {
+ if (!core.fileFormat().startsWith("PDF")) {
+ showInfo(getString(R.string.format_currently_not_supported));
+ return;
+ }
+
+ Intent myIntent = getIntent();
+ Uri docUri = myIntent != null ? myIntent.getData() : null;
+
+ if (docUri == null) {
+ showInfo(getString(R.string.print_failed));
+ }
+
+ if (docUri.getScheme() == null)
+ docUri = Uri.parse("file://"+docUri.toString());
+
+ Intent printIntent = new Intent(this, PrintDialogActivity.class);
+ printIntent.setDataAndType(docUri, "aplication/pdf");
+ printIntent.putExtra("title", mFileName);
+ startActivityForResult(printIntent, PRINT_REQUEST);
+ }
+
+ private void showInfo(String message) {
+ mInfoView.setText(message);
+
+ int currentApiVersion = android.os.Build.VERSION.SDK_INT;
+ if (currentApiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ SafeAnimatorInflater safe = new SafeAnimatorInflater((Activity)this, R.animator.info, (View)mInfoView);
+ } else {
+ mInfoView.setVisibility(View.VISIBLE);
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ mInfoView.setVisibility(View.INVISIBLE);
+ }
+ }, 500);
+ }
+ }
+
+ private void makeButtonsView() {
+ mButtonsView = getLayoutInflater().inflate(R.layout.buttons,null);
+ mFilenameView = (TextView)mButtonsView.findViewById(R.id.docNameText);
+ mPageSlider = (SeekBar)mButtonsView.findViewById(R.id.pageSlider);
+ mPageNumberView = (TextView)mButtonsView.findViewById(R.id.pageNumber);
+ mInfoView = (TextView)mButtonsView.findViewById(R.id.info);
+ mSearchButton = (ImageButton)mButtonsView.findViewById(R.id.searchButton);
+ mReflowButton = (ImageButton)mButtonsView.findViewById(R.id.reflowButton);
+ mOutlineButton = (ImageButton)mButtonsView.findViewById(R.id.outlineButton);
+ mAnnotButton = (ImageButton)mButtonsView.findViewById(R.id.editAnnotButton);
+ mAnnotTypeText = (TextView)mButtonsView.findViewById(R.id.annotType);
+ mTopBarSwitcher = (ViewAnimator)mButtonsView.findViewById(R.id.switcher);
+ mSearchBack = (ImageButton)mButtonsView.findViewById(R.id.searchBack);
+ mSearchFwd = (ImageButton)mButtonsView.findViewById(R.id.searchForward);
+ mSearchText = (EditText)mButtonsView.findViewById(R.id.searchText);
+ mLinkButton = (ImageButton)mButtonsView.findViewById(R.id.linkButton);
+ mMoreButton = (ImageButton)mButtonsView.findViewById(R.id.moreButton);
+ mTopBarSwitcher.setVisibility(View.INVISIBLE);
+ mPageNumberView.setVisibility(View.INVISIBLE);
+ mInfoView.setVisibility(View.INVISIBLE);
+ mPageSlider.setVisibility(View.INVISIBLE);
+ }
+
+ public void OnMoreButtonClick(View v) {
+ mTopBarMode = TopBarMode.More;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnCancelMoreButtonClick(View v) {
+ mTopBarMode = TopBarMode.Main;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnPrintButtonClick(View v) {
+ printDoc();
+ }
+
+ public void OnCopyTextButtonClick(View v) {
+ mTopBarMode = TopBarMode.Accept;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mAcceptMode = AcceptMode.CopyText;
+ mDocView.setMode(MuPDFReaderView.Mode.Selecting);
+ mAnnotTypeText.setText(getString(R.string.copy_text));
+ showInfo(getString(R.string.select_text));
+ }
+
+ public void OnEditAnnotButtonClick(View v) {
+ mTopBarMode = TopBarMode.Annot;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnCancelAnnotButtonClick(View v) {
+ mTopBarMode = TopBarMode.More;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnHighlightButtonClick(View v) {
+ mTopBarMode = TopBarMode.Accept;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mAcceptMode = AcceptMode.Highlight;
+ mDocView.setMode(MuPDFReaderView.Mode.Selecting);
+ mAnnotTypeText.setText(R.string.highlight);
+ showInfo(getString(R.string.select_text));
+ }
+
+ public void OnUnderlineButtonClick(View v) {
+ mTopBarMode = TopBarMode.Accept;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mAcceptMode = AcceptMode.Underline;
+ mDocView.setMode(MuPDFReaderView.Mode.Selecting);
+ mAnnotTypeText.setText(R.string.underline);
+ showInfo(getString(R.string.select_text));
+ }
+
+ public void OnStrikeOutButtonClick(View v) {
+ mTopBarMode = TopBarMode.Accept;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mAcceptMode = AcceptMode.StrikeOut;
+ mDocView.setMode(MuPDFReaderView.Mode.Selecting);
+ mAnnotTypeText.setText(R.string.strike_out);
+ showInfo(getString(R.string.select_text));
+ }
+
+ public void OnInkButtonClick(View v) {
+ mTopBarMode = TopBarMode.Accept;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mAcceptMode = AcceptMode.Ink;
+ mDocView.setMode(MuPDFReaderView.Mode.Drawing);
+ mAnnotTypeText.setText(R.string.ink);
+ showInfo(getString(R.string.draw_annotation));
+ }
+
+ public void OnCancelAcceptButtonClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null) {
+ pageView.deselectText();
+ pageView.cancelDraw();
+ }
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ switch (mAcceptMode) {
+ case CopyText:
+ mTopBarMode = TopBarMode.More;
+ break;
+ default:
+ mTopBarMode = TopBarMode.Annot;
+ break;
+ }
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnAcceptButtonClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ boolean success = false;
+ switch (mAcceptMode) {
+ case CopyText:
+ if (pageView != null)
+ success = pageView.copySelection();
+ mTopBarMode = TopBarMode.More;
+ showInfo(success?getString(R.string.copied_to_clipboard):getString(R.string.no_text_selected));
+ break;
+
+ case Highlight:
+ if (pageView != null)
+ success = pageView.markupSelection(Annotation.Type.HIGHLIGHT);
+ mTopBarMode = TopBarMode.Annot;
+ if (!success)
+ showInfo(getString(R.string.no_text_selected));
+ break;
+
+ case Underline:
+ if (pageView != null)
+ success = pageView.markupSelection(Annotation.Type.UNDERLINE);
+ mTopBarMode = TopBarMode.Annot;
+ if (!success)
+ showInfo(getString(R.string.no_text_selected));
+ break;
+
+ case StrikeOut:
+ if (pageView != null)
+ success = pageView.markupSelection(Annotation.Type.STRIKEOUT);
+ mTopBarMode = TopBarMode.Annot;
+ if (!success)
+ showInfo(getString(R.string.no_text_selected));
+ break;
+
+ case Ink:
+ if (pageView != null)
+ success = pageView.saveDraw();
+ mTopBarMode = TopBarMode.Annot;
+ if (!success)
+ showInfo(getString(R.string.nothing_to_save));
+ break;
+ }
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ mDocView.setMode(MuPDFReaderView.Mode.Viewing);
+ }
+
+ public void OnCancelSearchButtonClick(View v) {
+ searchModeOff();
+ }
+
+ public void OnDeleteButtonClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.deleteSelectedAnnotation();
+ mTopBarMode = TopBarMode.Annot;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ public void OnCancelDeleteButtonClick(View v) {
+ MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
+ if (pageView != null)
+ pageView.deselectAnnotation();
+ mTopBarMode = TopBarMode.Annot;
+ mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
+ }
+
+ private void showKeyboard() {
+ InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null)
+ imm.showSoftInput(mSearchText, 0);
+ }
+
+ private void hideKeyboard() {
+ InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null)
+ imm.hideSoftInputFromWindow(mSearchText.getWindowToken(), 0);
+ }
+
+ private void search(int direction) {
+ hideKeyboard();
+ int displayPage = mDocView.getDisplayedViewIndex();
+ SearchTaskResult r = SearchTaskResult.get();
+ int searchPage = r != null ? r.pageNumber : -1;
+ mSearchTask.go(mSearchText.getText().toString(), direction, displayPage, searchPage);
+ }
+
+ @Override
+ public boolean onSearchRequested() {
+ if (mButtonsVisible && mTopBarMode == TopBarMode.Search) {
+ hideButtons();
+ } else {
+ showButtons();
+ searchModeOn();
+ }
+ return super.onSearchRequested();
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ if (mButtonsVisible && mTopBarMode != TopBarMode.Search) {
+ hideButtons();
+ } else {
+ showButtons();
+ searchModeOff();
+ }
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ protected void onStart() {
+ if (core != null)
+ {
+ core.startAlerts();
+ createAlertWaiter();
+ }
+
+ super.onStart();
+ }
+
+ @Override
+ protected void onStop() {
+ if (core != null)
+ {
+ destroyAlertWaiter();
+ core.stopAlerts();
+ }
+
+ super.onStop();
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (core.hasChanges()) {
+ DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == AlertDialog.BUTTON_POSITIVE)
+ core.save();
+
+ finish();
+ }
+ };
+ AlertDialog alert = mAlertBuilder.create();
+ alert.setTitle("MuPDF");
+ alert.setMessage(getString(R.string.document_has_changes_save_them_));
+ alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.yes), listener);
+ alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.no), listener);
+ alert.show();
+ } else {
+ super.onBackPressed();
+ }
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFAlert.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFAlert.java
new file mode 100644
index 00000000..76ed3a65
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFAlert.java
@@ -0,0 +1,21 @@
+package com.artifex.mupdfdemo;
+
+public class MuPDFAlert {
+ public enum IconType {Error,Warning,Question,Status};
+ public enum ButtonPressed {None,Ok,Cancel,No,Yes};
+ public enum ButtonGroupType {Ok,OkCancel,YesNo,YesNoCancel};
+
+ public final String message;
+ public final IconType iconType;
+ public final ButtonGroupType buttonGroupType;
+ public final String title;
+ public ButtonPressed buttonPressed;
+
+ MuPDFAlert(String aMessage, IconType aIconType, ButtonGroupType aButtonGroupType, String aTitle, ButtonPressed aButtonPressed) {
+ message = aMessage;
+ iconType = aIconType;
+ buttonGroupType = aButtonGroupType;
+ title = aTitle;
+ buttonPressed = aButtonPressed;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFAlertInternal.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFAlertInternal.java
new file mode 100644
index 00000000..5d65768f
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFAlertInternal.java
@@ -0,0 +1,30 @@
+package com.artifex.mupdfdemo;
+
+// Version of MuPDFAlert without enums to simplify JNI
+public class MuPDFAlertInternal {
+ public final String message;
+ public final int iconType;
+ public final int buttonGroupType;
+ public final String title;
+ public int buttonPressed;
+
+ MuPDFAlertInternal(String aMessage, int aIconType, int aButtonGroupType, String aTitle, int aButtonPressed) {
+ message = aMessage;
+ iconType = aIconType;
+ buttonGroupType = aButtonGroupType;
+ title = aTitle;
+ buttonPressed = aButtonPressed;
+ }
+
+ MuPDFAlertInternal(MuPDFAlert alert) {
+ message = alert.message;
+ iconType = alert.iconType.ordinal();
+ buttonGroupType = alert.buttonGroupType.ordinal();
+ title = alert.message;
+ buttonPressed = alert.buttonPressed.ordinal();
+ }
+
+ MuPDFAlert toAlert() {
+ return new MuPDFAlert(message, MuPDFAlert.IconType.values()[iconType], MuPDFAlert.ButtonGroupType.values()[buttonGroupType], title, MuPDFAlert.ButtonPressed.values()[buttonPressed]);
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java
new file mode 100644
index 00000000..bc1fea71
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java
@@ -0,0 +1,300 @@
+package com.artifex.mupdfdemo;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+public class MuPDFCore
+{
+ /* load our native library */
+ static {
+ System.loadLibrary("mupdf");
+ }
+
+ /* Readable members */
+ private int numPages = -1;
+ private float pageWidth;
+ private float pageHeight;
+ private long globals;
+ private byte fileBuffer[];
+ private String file_format;
+
+ /* The native functions */
+ private native long openFile(String filename);
+ private native long openBuffer();
+ private native String fileFormatInternal();
+ private native int countPagesInternal();
+ private native void gotoPageInternal(int localActionPageNum);
+ private native float getPageWidth();
+ private native float getPageHeight();
+ private native void drawPage(Bitmap bitmap,
+ int pageW, int pageH,
+ int patchX, int patchY,
+ int patchW, int patchH);
+ private native void updatePageInternal(Bitmap bitmap,
+ int page,
+ int pageW, int pageH,
+ int patchX, int patchY,
+ int patchW, int patchH);
+ private native RectF[] searchPage(String text);
+ private native TextChar[][][][] text();
+ private native byte[] textAsHtml();
+ private native void addMarkupAnnotationInternal(PointF[] quadPoints, int type);
+ private native void addInkAnnotationInternal(PointF[][] arcs);
+ private native void deleteAnnotationInternal(int annot_index);
+ private native int passClickEventInternal(int page, float x, float y);
+ private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
+ private native String [] getFocusedWidgetChoiceSelected();
+ private native String [] getFocusedWidgetChoiceOptions();
+ private native int setFocusedWidgetTextInternal(String text);
+ private native String getFocusedWidgetTextInternal();
+ private native int getFocusedWidgetTypeInternal();
+ private native LinkInfo [] getPageLinksInternal(int page);
+ private native RectF[] getWidgetAreasInternal(int page);
+ private native Annotation[] getAnnotationsInternal(int page);
+ private native OutlineItem [] getOutlineInternal();
+ private native boolean hasOutlineInternal();
+ private native boolean needsPasswordInternal();
+ private native boolean authenticatePasswordInternal(String password);
+ private native MuPDFAlertInternal waitForAlertInternal();
+ private native void replyToAlertInternal(MuPDFAlertInternal alert);
+ private native void startAlertsInternal();
+ private native void stopAlertsInternal();
+ private native void destroying();
+ private native boolean hasChangesInternal();
+ private native void saveInternal();
+
+ public static native boolean javascriptSupported();
+
+ public MuPDFCore(Context context, String filename) throws Exception
+ {
+ globals = openFile(filename);
+ if (globals == 0)
+ {
+ throw new Exception(String.format(context.getString(R.string.cannot_open_file_Path), filename));
+ }
+ file_format = fileFormatInternal();
+ }
+
+ public MuPDFCore(Context context, byte buffer[]) throws Exception
+ {
+ fileBuffer = buffer;
+ globals = openBuffer();
+ if (globals == 0)
+ {
+ throw new Exception(context.getString(R.string.cannot_open_buffer));
+ }
+ file_format = fileFormatInternal();
+ }
+
+ public int countPages()
+ {
+ if (numPages < 0)
+ numPages = countPagesSynchronized();
+
+ return numPages;
+ }
+
+ public String fileFormat()
+ {
+ return file_format;
+ }
+
+ private synchronized int countPagesSynchronized() {
+ return countPagesInternal();
+ }
+
+ /* Shim function */
+ private void gotoPage(int page)
+ {
+ if (page > numPages-1)
+ page = numPages-1;
+ else if (page < 0)
+ page = 0;
+ gotoPageInternal(page);
+ this.pageWidth = getPageWidth();
+ this.pageHeight = getPageHeight();
+ }
+
+ public synchronized PointF getPageSize(int page) {
+ gotoPage(page);
+ return new PointF(pageWidth, pageHeight);
+ }
+
+ public MuPDFAlert waitForAlert() {
+ MuPDFAlertInternal alert = waitForAlertInternal();
+ return alert != null ? alert.toAlert() : null;
+ }
+
+ public void replyToAlert(MuPDFAlert alert) {
+ replyToAlertInternal(new MuPDFAlertInternal(alert));
+ }
+
+ public void stopAlerts() {
+ stopAlertsInternal();
+ }
+
+ public void startAlerts() {
+ startAlertsInternal();
+ }
+
+ public synchronized void onDestroy() {
+ destroying();
+ globals = 0;
+ }
+
+ public synchronized Bitmap drawPage(int page,
+ int pageW, int pageH,
+ int patchX, int patchY,
+ int patchW, int patchH) {
+ gotoPage(page);
+ Bitmap bm = Bitmap.createBitmap(patchW, patchH, Config.ARGB_8888);
+ drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH);
+ return bm;
+ }
+
+ public synchronized Bitmap updatePage(BitmapHolder h, int page,
+ int pageW, int pageH,
+ int patchX, int patchY,
+ int patchW, int patchH) {
+ Bitmap bm = null;
+ Bitmap old_bm = h.getBm();
+
+ if (old_bm == null)
+ return null;
+
+ bm = old_bm.copy(Bitmap.Config.ARGB_8888, false);
+ old_bm = null;
+
+ updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH);
+ return bm;
+ }
+
+ public synchronized PassClickResult passClickEvent(int page, float x, float y) {
+ boolean changed = passClickEventInternal(page, x, y) != 0;
+
+ switch (WidgetType.values()[getFocusedWidgetTypeInternal()])
+ {
+ case TEXT:
+ return new PassClickResultText(changed, getFocusedWidgetTextInternal());
+ case LISTBOX:
+ case COMBOBOX:
+ return new PassClickResultChoice(changed, getFocusedWidgetChoiceOptions(), getFocusedWidgetChoiceSelected());
+ default:
+ return new PassClickResult(changed);
+ }
+
+ }
+
+ public synchronized boolean setFocusedWidgetText(int page, String text) {
+ boolean success;
+ gotoPage(page);
+ success = setFocusedWidgetTextInternal(text) != 0 ? true : false;
+
+ return success;
+ }
+
+ public synchronized void setFocusedWidgetChoiceSelected(String [] selected) {
+ setFocusedWidgetChoiceSelectedInternal(selected);
+ }
+
+ public synchronized LinkInfo [] getPageLinks(int page) {
+ return getPageLinksInternal(page);
+ }
+
+ public synchronized RectF [] getWidgetAreas(int page) {
+ return getWidgetAreasInternal(page);
+ }
+
+ public synchronized Annotation [] getAnnoations(int page) {
+ return getAnnotationsInternal(page);
+ }
+
+ public synchronized RectF [] searchPage(int page, String text) {
+ gotoPage(page);
+ return searchPage(text);
+ }
+
+ public synchronized byte[] html(int page) {
+ gotoPage(page);
+ return textAsHtml();
+ }
+
+ public synchronized TextWord [][] textLines(int page) {
+ gotoPage(page);
+ TextChar[][][][] chars = text();
+
+ // The text of the page held in a hierarchy (blocks, lines, spans).
+ // Currently we don't need to distinguish the blocks level or
+ // the spans, and we need to collect the text into words.
+ ArrayList<TextWord[]> lns = new ArrayList<TextWord[]>();
+
+ for (TextChar[][][] bl: chars) {
+ for (TextChar[][] ln: bl) {
+ ArrayList<TextWord> wds = new ArrayList<TextWord>();
+ TextWord wd = new TextWord();
+
+ for (TextChar[] sp: ln) {
+ for (TextChar tc: sp) {
+ if (tc.c != ' ') {
+ wd.Add(tc);
+ } else if (wd.w.length() > 0) {
+ wds.add(wd);
+ wd = new TextWord();
+ }
+ }
+ }
+
+ if (wd.w.length() > 0)
+ wds.add(wd);
+
+ if (wds.size() > 0)
+ lns.add(wds.toArray(new TextWord[wds.size()]));
+ }
+ }
+
+ return lns.toArray(new TextWord[lns.size()][]);
+ }
+
+ public synchronized void addMarkupAnnotation(int page, PointF[] quadPoints, Annotation.Type type) {
+ gotoPage(page);
+ addMarkupAnnotationInternal(quadPoints, type.ordinal());
+ }
+
+ public synchronized void addInkAnnotation(int page, PointF[][] arcs) {
+ gotoPage(page);
+ addInkAnnotationInternal(arcs);
+ }
+
+ public synchronized void deleteAnnotation(int page, int annot_index) {
+ gotoPage(page);
+ deleteAnnotationInternal(annot_index);
+ }
+
+ public synchronized boolean hasOutline() {
+ return hasOutlineInternal();
+ }
+
+ public synchronized OutlineItem [] getOutline() {
+ return getOutlineInternal();
+ }
+
+ public synchronized boolean needsPassword() {
+ return needsPasswordInternal();
+ }
+
+ public synchronized boolean authenticatePassword(String password) {
+ return authenticatePasswordInternal(password);
+ }
+
+ public synchronized boolean hasChanges() {
+ return hasChangesInternal();
+ }
+
+ public synchronized void save() {
+ saveInternal();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java
new file mode 100644
index 00000000..806d0830
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java
@@ -0,0 +1,72 @@
+package com.artifex.mupdfdemo;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+public class MuPDFPageAdapter extends BaseAdapter {
+ private final Context mContext;
+ private final MuPDFCore mCore;
+ private final SparseArray<PointF> mPageSizes = new SparseArray<PointF>();
+
+ public MuPDFPageAdapter(Context c, MuPDFCore core) {
+ mContext = c;
+ mCore = core;
+ }
+
+ public int getCount() {
+ return mCore.countPages();
+ }
+
+ public Object getItem(int position) {
+ return null;
+ }
+
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ final MuPDFPageView pageView;
+ if (convertView == null) {
+ pageView = new MuPDFPageView(mContext, mCore, new Point(parent.getWidth(), parent.getHeight()));
+ } else {
+ pageView = (MuPDFPageView) convertView;
+ }
+
+ PointF pageSize = mPageSizes.get(position);
+ if (pageSize != null) {
+ // We already know the page size. Set it up
+ // immediately
+ pageView.setPage(position, pageSize);
+ } else {
+ // Page size as yet unknown. Blank it for now, and
+ // start a background task to find the size
+ pageView.blank(position);
+ AsyncTask<Void,Void,PointF> sizingTask = new AsyncTask<Void,Void,PointF>() {
+ @Override
+ protected PointF doInBackground(Void... arg0) {
+ return mCore.getPageSize(position);
+ }
+
+ @Override
+ protected void onPostExecute(PointF result) {
+ super.onPostExecute(result);
+ // We now know the page size
+ mPageSizes.put(position, result);
+ // Check that this view hasn't been reused for
+ // another page since we started
+ if (pageView.getPage() == position)
+ pageView.setPage(position, result);
+ }
+ };
+
+ sizingTask.execute((Void)null);
+ }
+ return pageView;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
new file mode 100644
index 00000000..043b90ab
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
@@ -0,0 +1,502 @@
+package com.artifex.mupdfdemo;
+
+import java.util.ArrayList;
+
+import android.app.AlertDialog;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.view.LayoutInflater;
+import android.view.WindowManager;
+import android.widget.EditText;
+
+abstract class PassClickResultVisitor {
+ public abstract void visitText(PassClickResultText result);
+ public abstract void visitChoice(PassClickResultChoice result);
+}
+
+class PassClickResult {
+ public final boolean changed;
+
+ public PassClickResult(boolean _changed) {
+ changed = _changed;
+ }
+
+ public void acceptVisitor(PassClickResultVisitor visitor) {
+ }
+}
+
+class PassClickResultText extends PassClickResult {
+ public final String text;
+
+ public PassClickResultText(boolean _changed, String _text) {
+ super(_changed);
+ text = _text;
+ }
+
+ public void acceptVisitor(PassClickResultVisitor visitor) {
+ visitor.visitText(this);
+ }
+}
+
+class PassClickResultChoice extends PassClickResult {
+ public final String [] options;
+ public final String [] selected;
+
+ public PassClickResultChoice(boolean _changed, String [] _options, String [] _selected) {
+ super(_changed);
+ options = _options;
+ selected = _selected;
+ }
+
+ public void acceptVisitor(PassClickResultVisitor visitor) {
+ visitor.visitChoice(this);
+ }
+}
+
+public class MuPDFPageView extends PageView implements MuPDFView {
+ private final MuPDFCore mCore;
+ private AsyncTask<Void,Void,PassClickResult> mPassClick;
+ private RectF mWidgetAreas[];
+ private Annotation mAnnotations[];
+ private int mSelectedAnnotationIndex = -1;
+ private AsyncTask<Void,Void,RectF[]> mLoadWidgetAreas;
+ private AsyncTask<Void,Void,Annotation[]> mLoadAnnotations;
+ private AlertDialog.Builder mTextEntryBuilder;
+ private AlertDialog.Builder mChoiceEntryBuilder;
+ private AlertDialog mTextEntry;
+ private EditText mEditText;
+ private AsyncTask<String,Void,Boolean> mSetWidgetText;
+ private AsyncTask<String,Void,Void> mSetWidgetChoice;
+ private AsyncTask<PointF[],Void,Void> mAddStrikeOut;
+ private AsyncTask<PointF[][],Void,Void> mAddInk;
+ private AsyncTask<Integer,Void,Void> mDeleteAnnotation;
+ private Runnable changeReporter;
+
+ public MuPDFPageView(Context c, MuPDFCore core, Point parentSize) {
+ super(c, parentSize);
+ mCore = core;
+ mTextEntryBuilder = new AlertDialog.Builder(c);
+ mTextEntryBuilder.setTitle(getContext().getString(R.string.fill_out_text_field));
+ LayoutInflater inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mEditText = (EditText)inflater.inflate(R.layout.textentry, null);
+ mTextEntryBuilder.setView(mEditText);
+ mTextEntryBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+ mTextEntryBuilder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mSetWidgetText = new AsyncTask<String,Void,Boolean> () {
+ @Override
+ protected Boolean doInBackground(String... arg0) {
+ return mCore.setFocusedWidgetText(mPageNumber, arg0[0]);
+ }
+ @Override
+ protected void onPostExecute(Boolean result) {
+ changeReporter.run();
+ if (!result)
+ invokeTextDialog(mEditText.getText().toString());
+ }
+ };
+
+ mSetWidgetText.execute(mEditText.getText().toString());
+ }
+ });
+ mTextEntry = mTextEntryBuilder.create();
+
+ mChoiceEntryBuilder = new AlertDialog.Builder(c);
+ mChoiceEntryBuilder.setTitle(getContext().getString(R.string.choose_value));
+ }
+
+ public LinkInfo hitLink(float x, float y) {
+ // Since link highlighting was implemented, the super class
+ // PageView has had sufficient information to be able to
+ // perform this method directly. Making that change would
+ // make MuPDFCore.hitLinkPage superfluous.
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX = (x - getLeft())/scale;
+ float docRelY = (y - getTop())/scale;
+
+ for (LinkInfo l: mLinks)
+ if (l.rect.contains(docRelX, docRelY))
+ return l;
+
+ return null;
+ }
+
+ private void invokeTextDialog(String text) {
+ mEditText.setText(text);
+ mTextEntry.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ mTextEntry.show();
+ }
+
+ private void invokeChoiceDialog(final String [] options) {
+ mChoiceEntryBuilder.setItems(options, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mSetWidgetChoice = new AsyncTask<String,Void,Void>() {
+ @Override
+ protected Void doInBackground(String... params) {
+ String [] sel = {params[0]};
+ mCore.setFocusedWidgetChoiceSelected(sel);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ changeReporter.run();
+ }
+ };
+
+ mSetWidgetChoice.execute(options[which]);
+ }
+ });
+ AlertDialog dialog = mChoiceEntryBuilder.create();
+ dialog.show();
+ }
+
+ public void setChangeReporter(Runnable reporter) {
+ changeReporter = reporter;
+ }
+
+ public Hit passClickEvent(float x, float y) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ final float docRelX = (x - getLeft())/scale;
+ final float docRelY = (y - getTop())/scale;
+ boolean hit = false;
+ int i;
+
+ if (mAnnotations != null) {
+ for (i = 0; i < mAnnotations.length; i++)
+ if (mAnnotations[i].contains(docRelX, docRelY)) {
+ hit = true;
+ break;
+ }
+
+ if (hit) {
+ switch (mAnnotations[i].type) {
+ case HIGHLIGHT:
+ case UNDERLINE:
+ case SQUIGGLY:
+ case STRIKEOUT:
+ case INK:
+ mSelectedAnnotationIndex = i;
+ setItemSelectBox(mAnnotations[i]);
+ return Hit.Annotation;
+ }
+ }
+ }
+
+ mSelectedAnnotationIndex = -1;
+ setItemSelectBox(null);
+
+ if (!MuPDFCore.javascriptSupported())
+ return Hit.Nothing;
+
+ if (mWidgetAreas != null) {
+ for (i = 0; i < mWidgetAreas.length && !hit; i++)
+ if (mWidgetAreas[i].contains(docRelX, docRelY))
+ hit = true;
+ }
+
+ if (hit) {
+ mPassClick = new AsyncTask<Void,Void,PassClickResult>() {
+ @Override
+ protected PassClickResult doInBackground(Void... arg0) {
+ return mCore.passClickEvent(mPageNumber, docRelX, docRelY);
+ }
+
+ @Override
+ protected void onPostExecute(PassClickResult result) {
+ if (result.changed) {
+ changeReporter.run();
+ }
+
+ result.acceptVisitor(new PassClickResultVisitor() {
+ @Override
+ public void visitText(PassClickResultText result) {
+ invokeTextDialog(result.text);
+ }
+
+ @Override
+ public void visitChoice(PassClickResultChoice result) {
+ invokeChoiceDialog(result.options);
+ }
+ });
+ }
+ };
+
+ mPassClick.execute();
+ return Hit.Widget;
+ }
+
+ return Hit.Nothing;
+ }
+
+ public boolean copySelection() {
+ final StringBuilder text = new StringBuilder();
+
+ processSelectedText(new TextProcessor() {
+ StringBuilder line;
+
+ public void onStartLine() {
+ line = new StringBuilder();
+ }
+
+ public void onWord(TextWord word) {
+ if (line.length() > 0)
+ line.append(' ');
+ line.append(word.w);
+ }
+
+ public void onEndLine() {
+ if (text.length() > 0)
+ text.append('\n');
+ text.append(line);
+ }
+ });
+
+ if (text.length() == 0)
+ return false;
+
+ int currentApiVersion = android.os.Build.VERSION.SDK_INT;
+ if (currentApiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ android.content.ClipboardManager cm = (android.content.ClipboardManager)mContext.getSystemService(Context.CLIPBOARD_SERVICE);
+
+ cm.setPrimaryClip(ClipData.newPlainText("MuPDF", text));
+ } else {
+ android.text.ClipboardManager cm = (android.text.ClipboardManager)mContext.getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setText(text);
+ }
+
+ deselectText();
+
+ return true;
+ }
+
+ public boolean markupSelection(final Annotation.Type type) {
+ final ArrayList<PointF> quadPoints = new ArrayList<PointF>();
+ processSelectedText(new TextProcessor() {
+ RectF rect;
+
+ public void onStartLine() {
+ rect = new RectF();
+ }
+
+ public void onWord(TextWord word) {
+ rect.union(word);
+ }
+
+ public void onEndLine() {
+ if (!rect.isEmpty()) {
+ quadPoints.add(new PointF(rect.left, rect.bottom));
+ quadPoints.add(new PointF(rect.right, rect.bottom));
+ quadPoints.add(new PointF(rect.right, rect.top));
+ quadPoints.add(new PointF(rect.left, rect.top));
+ }
+ }
+ });
+
+ if (quadPoints.size() == 0)
+ return false;
+
+ mAddStrikeOut = new AsyncTask<PointF[],Void,Void>() {
+ @Override
+ protected Void doInBackground(PointF[]... params) {
+ addMarkup(params[0], type);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ loadAnnotations();
+ update();
+ }
+ };
+
+ mAddStrikeOut.execute(quadPoints.toArray(new PointF[quadPoints.size()]));
+
+ deselectText();
+
+ return true;
+ }
+
+ public void deleteSelectedAnnotation() {
+ if (mSelectedAnnotationIndex != -1) {
+ if (mDeleteAnnotation != null)
+ mDeleteAnnotation.cancel(true);
+
+ mDeleteAnnotation = new AsyncTask<Integer,Void,Void>() {
+ @Override
+ protected Void doInBackground(Integer... params) {
+ mCore.deleteAnnotation(mPageNumber, params[0]);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ loadAnnotations();
+ update();
+ }
+ };
+
+ mDeleteAnnotation.execute(mSelectedAnnotationIndex);
+
+ mSelectedAnnotationIndex = -1;
+ setItemSelectBox(null);
+ }
+ }
+
+ public void deselectAnnotation() {
+ mSelectedAnnotationIndex = -1;
+ setItemSelectBox(null);
+ }
+
+ public boolean saveDraw() {
+ PointF[][] path = getDraw();
+
+ if (path == null)
+ return false;
+
+ if (mAddInk != null) {
+ mAddInk.cancel(true);
+ mAddInk = null;
+ }
+ mAddInk = new AsyncTask<PointF[][],Void,Void>() {
+ @Override
+ protected Void doInBackground(PointF[][]... params) {
+ mCore.addInkAnnotation(mPageNumber, params[0]);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ loadAnnotations();
+ update();
+ }
+
+ };
+
+ mAddInk.execute(getDraw());
+ cancelDraw();
+
+ return true;
+ }
+
+ @Override
+ protected Bitmap drawPage(int sizeX, int sizeY,
+ int patchX, int patchY, int patchWidth, int patchHeight) {
+ return mCore.drawPage(mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight);
+ }
+
+ @Override
+ protected Bitmap updatePage(BitmapHolder h, int sizeX, int sizeY,
+ int patchX, int patchY, int patchWidth, int patchHeight) {
+ return mCore.updatePage(h, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight);
+ }
+
+ @Override
+ protected LinkInfo[] getLinkInfo() {
+ return mCore.getPageLinks(mPageNumber);
+ }
+
+ @Override
+ protected TextWord[][] getText() {
+ return mCore.textLines(mPageNumber);
+ }
+
+ @Override
+ protected void addMarkup(PointF[] quadPoints, Annotation.Type type) {
+ mCore.addMarkupAnnotation(mPageNumber, quadPoints, type);
+ }
+
+ private void loadAnnotations() {
+ mAnnotations = null;
+ if (mLoadAnnotations != null)
+ mLoadAnnotations.cancel(true);
+ mLoadAnnotations = new AsyncTask<Void,Void,Annotation[]> () {
+ @Override
+ protected Annotation[] doInBackground(Void... params) {
+ return mCore.getAnnoations(mPageNumber);
+ }
+
+ @Override
+ protected void onPostExecute(Annotation[] result) {
+ mAnnotations = result;
+ }
+ };
+
+ mLoadAnnotations.execute();
+ }
+
+ @Override
+ public void setPage(final int page, PointF size) {
+ loadAnnotations();
+
+ mLoadWidgetAreas = new AsyncTask<Void,Void,RectF[]> () {
+ @Override
+ protected RectF[] doInBackground(Void... arg0) {
+ return mCore.getWidgetAreas(page);
+ }
+
+ @Override
+ protected void onPostExecute(RectF[] result) {
+ mWidgetAreas = result;
+ }
+ };
+
+ mLoadWidgetAreas.execute();
+
+ super.setPage(page, size);
+ }
+
+ public void setScale(float scale) {
+ // This type of view scales automatically to fit the size
+ // determined by the parent view groups during layout
+ }
+
+ @Override
+ public void releaseResources() {
+ if (mPassClick != null) {
+ mPassClick.cancel(true);
+ mPassClick = null;
+ }
+
+ if (mLoadWidgetAreas != null) {
+ mLoadWidgetAreas.cancel(true);
+ mLoadWidgetAreas = null;
+ }
+
+ if (mLoadAnnotations != null) {
+ mLoadAnnotations.cancel(true);
+ mLoadAnnotations = null;
+ }
+
+ if (mSetWidgetText != null) {
+ mSetWidgetText.cancel(true);
+ mSetWidgetText = null;
+ }
+
+ if (mSetWidgetChoice != null) {
+ mSetWidgetChoice.cancel(true);
+ mSetWidgetChoice = null;
+ }
+
+ if (mAddStrikeOut != null) {
+ mAddStrikeOut.cancel(true);
+ mAddStrikeOut = null;
+ }
+
+ if (mDeleteAnnotation != null) {
+ mDeleteAnnotation.cancel(true);
+ mDeleteAnnotation = null;
+ }
+
+ super.releaseResources();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java
new file mode 100644
index 00000000..9cab70b7
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFReaderView.java
@@ -0,0 +1,261 @@
+package com.artifex.mupdfdemo;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.View;
+
+public class MuPDFReaderView extends ReaderView {
+ enum Mode {Viewing, Selecting, Drawing}
+ private final Context mContext;
+ private boolean mLinksEnabled = false;
+ private Mode mMode = Mode.Viewing;
+ private boolean tapDisabled = false;
+ private int tapPageMargin;
+
+ protected void onTapMainDocArea() {}
+ protected void onDocMotion() {}
+ protected void onHit(Hit item) {};
+
+ public void setLinksEnabled(boolean b) {
+ mLinksEnabled = b;
+ resetupChildren();
+ }
+
+ public void setMode(Mode m) {
+ mMode = m;
+ }
+
+ public MuPDFReaderView(Activity act) {
+ super(act);
+ mContext = act;
+ // Get the screen size etc to customise tap margins.
+ // We calculate the size of 1 inch of the screen for tapping.
+ // On some devices the dpi values returned are wrong, so we
+ // sanity check it: we first restrict it so that we are never
+ // less than 100 pixels (the smallest Android device screen
+ // dimension I've seen is 480 pixels or so). Then we check
+ // to ensure we are never more than 1/5 of the screen width.
+ DisplayMetrics dm = new DisplayMetrics();
+ act.getWindowManager().getDefaultDisplay().getMetrics(dm);
+ tapPageMargin = (int)dm.xdpi;
+ if (tapPageMargin < 100)
+ tapPageMargin = 100;
+ if (tapPageMargin > dm.widthPixels/5)
+ tapPageMargin = dm.widthPixels/5;
+ }
+
+ public boolean onSingleTapUp(MotionEvent e) {
+ LinkInfo link = null;
+
+ if (mMode == Mode.Viewing && !tapDisabled) {
+ MuPDFView pageView = (MuPDFView) getDisplayedView();
+ Hit item = pageView.passClickEvent(e.getX(), e.getY());
+ onHit(item);
+ if (item == Hit.Nothing) {
+ if (mLinksEnabled && pageView != null
+ && (link = pageView.hitLink(e.getX(), e.getY())) != null) {
+ link.acceptVisitor(new LinkInfoVisitor() {
+ @Override
+ public void visitInternal(LinkInfoInternal li) {
+ // Clicked on an internal (GoTo) link
+ setDisplayedViewIndex(li.pageNumber);
+ }
+
+ @Override
+ public void visitExternal(LinkInfoExternal li) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri
+ .parse(li.url));
+ mContext.startActivity(intent);
+ }
+
+ @Override
+ public void visitRemote(LinkInfoRemote li) {
+ // Clicked on a remote (GoToR) link
+ }
+ });
+ } else if (e.getX() < tapPageMargin) {
+ super.smartMoveBackwards();
+ } else if (e.getX() > super.getWidth() - tapPageMargin) {
+ super.smartMoveForwards();
+ } else if (e.getY() < tapPageMargin) {
+ super.smartMoveBackwards();
+ } else if (e.getY() > super.getHeight() - tapPageMargin) {
+ super.smartMoveForwards();
+ } else {
+ onTapMainDocArea();
+ }
+ }
+ }
+ return super.onSingleTapUp(e);
+ }
+
+ @Override
+ public boolean onDown(MotionEvent e) {
+
+ return super.onDown(e);
+ }
+
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
+ float distanceY) {
+ MuPDFView pageView = (MuPDFView)getDisplayedView();
+ switch (mMode) {
+ case Viewing:
+ if (!tapDisabled)
+ onDocMotion();
+
+ return super.onScroll(e1, e2, distanceX, distanceY);
+ case Selecting:
+ if (pageView != null)
+ pageView.selectText(e1.getX(), e1.getY(), e2.getX(), e2.getY());
+ return true;
+ default:
+ return true;
+ }
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
+ switch (mMode) {
+ case Viewing:
+ return super.onFling(e1, e2, velocityX, velocityY);
+ default:
+ return true;
+ }
+ }
+
+ public boolean onScaleBegin(ScaleGestureDetector d) {
+ // Disabled showing the buttons until next touch.
+ // Not sure why this is needed, but without it
+ // pinch zoom can make the buttons appear
+ tapDisabled = true;
+ return super.onScaleBegin(d);
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+
+ if ( mMode == Mode.Drawing )
+ {
+ float x = event.getX();
+ float y = event.getY();
+ switch (event.getAction())
+ {
+ case MotionEvent.ACTION_DOWN:
+ touch_start(x, y);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ touch_move(x, y);
+ break;
+ case MotionEvent.ACTION_UP:
+ touch_up();
+ break;
+ }
+ }
+
+ if ((event.getAction() & event.getActionMasked()) == MotionEvent.ACTION_DOWN)
+ {
+ tapDisabled = false;
+ }
+
+ return super.onTouchEvent(event);
+ }
+
+ private float mX, mY;
+
+ private static final float TOUCH_TOLERANCE = 2;
+
+ private void touch_start(float x, float y) {
+
+ MuPDFView pageView = (MuPDFView)getDisplayedView();
+ if (pageView != null)
+ {
+ pageView.startDraw(x, y);
+ }
+ mX = x;
+ mY = y;
+ }
+
+ private void touch_move(float x, float y) {
+
+ float dx = Math.abs(x - mX);
+ float dy = Math.abs(y - mY);
+ if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
+ {
+ MuPDFView pageView = (MuPDFView)getDisplayedView();
+ if (pageView != null)
+ {
+ pageView.continueDraw(x, y);
+ }
+ mX = x;
+ mY = y;
+ }
+ }
+
+ private void touch_up() {
+
+ // NOOP
+ }
+
+ protected void onChildSetup(int i, View v) {
+ if (SearchTaskResult.get() != null
+ && SearchTaskResult.get().pageNumber == i)
+ ((MuPDFView) v).setSearchBoxes(SearchTaskResult.get().searchBoxes);
+ else
+ ((MuPDFView) v).setSearchBoxes(null);
+
+ ((MuPDFView) v).setLinkHighlighting(mLinksEnabled);
+
+ ((MuPDFView) v).setChangeReporter(new Runnable() {
+ public void run() {
+ applyToChildren(new ReaderView.ViewMapper() {
+ @Override
+ void applyToView(View view) {
+ ((MuPDFView) view).update();
+ }
+ });
+ }
+ });
+ }
+
+ protected void onMoveToChild(int i) {
+ if (SearchTaskResult.get() != null
+ && SearchTaskResult.get().pageNumber != i) {
+ SearchTaskResult.set(null);
+ resetupChildren();
+ }
+ }
+
+ @Override
+ protected void onMoveOffChild(int i) {
+ View v = getView(i);
+ if (v != null)
+ ((MuPDFView)v).deselectAnnotation();
+ }
+
+ protected void onSettle(View v) {
+ // When the layout has settled ask the page to render
+ // in HQ
+ ((MuPDFView) v).addHq(false);
+ }
+
+ protected void onUnsettle(View v) {
+ // When something changes making the previous settled view
+ // no longer appropriate, tell the page to remove HQ
+ ((MuPDFView) v).removeHq();
+ }
+
+ @Override
+ protected void onNotInUse(View v) {
+ ((MuPDFView) v).releaseResources();
+ }
+
+ @Override
+ protected void onScaleChild(View v, Float scale) {
+ ((MuPDFView) v).setScale(scale);
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java
new file mode 100644
index 00000000..48625a7e
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowAdapter.java
@@ -0,0 +1,43 @@
+package com.artifex.mupdfdemo;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+public class MuPDFReflowAdapter extends BaseAdapter {
+ private final Context mContext;
+ private final MuPDFCore mCore;
+
+ public MuPDFReflowAdapter(Context c, MuPDFCore core) {
+ mContext = c;
+ mCore = core;
+ }
+
+ public int getCount() {
+ return mCore.countPages();
+ }
+
+ public Object getItem(int arg0) {
+ return null;
+ }
+
+ public long getItemId(int arg0) {
+ return 0;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final MuPDFReflowView reflowView;
+ if (convertView == null) {
+ reflowView = new MuPDFReflowView(mContext, mCore, new Point(parent.getWidth(), parent.getHeight()));
+ } else {
+ reflowView = (MuPDFReflowView) convertView;
+ }
+
+ reflowView.setPage(position, new PointF());
+
+ return reflowView;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
new file mode 100644
index 00000000..0c7074bc
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java
@@ -0,0 +1,176 @@
+package com.artifex.mupdfdemo;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.Base64;
+import android.view.MotionEvent;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+public class MuPDFReflowView extends WebView implements MuPDFView {
+ private final MuPDFCore mCore;
+ private final Handler mHandler;
+ private final Point mParentSize;
+ private int mPage;
+ private int mContentHeight;
+ AsyncTask<Void,Void,byte[]> mLoadHTML;
+
+ public MuPDFReflowView(Context c, MuPDFCore core, Point parentSize) {
+ super(c);
+ mHandler = new Handler();
+ mCore = core;
+ mParentSize = parentSize;
+ mContentHeight = parentSize.y;
+ getSettings().setJavaScriptEnabled(true);
+ addJavascriptInterface(new Object(){
+ public void reportContentHeight(String value) {
+ mContentHeight = (int)Float.parseFloat(value);
+ mHandler.post(new Runnable() {
+ public void run() {
+ requestLayout();
+ }
+ });
+ }
+ }, "HTMLOUT");
+ setWebViewClient(new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ requestHeight();
+ }
+ });
+ }
+
+ private void requestHeight() {
+ // Get the webview to report the content height via the interface setup
+ // above. Workaround for getContentHeight not working
+ loadUrl("javascript:elem=document.getElementById('content');window.HTMLOUT.reportContentHeight("+mParentSize.x+"*elem.offsetHeight/elem.offsetWidth)");
+ }
+
+ public void setPage(int page, PointF size) {
+ mPage = page;
+ if (mLoadHTML != null) {
+ mLoadHTML.cancel(true);
+ }
+ mLoadHTML = new AsyncTask<Void,Void,byte[]>() {
+ @Override
+ protected byte[] doInBackground(Void... params) {
+ return mCore.html(mPage);
+ }
+ @Override
+ protected void onPostExecute(byte[] result) {
+ String b64 = Base64.encodeToString(result, Base64.DEFAULT);
+ loadData(b64, "text/html; charset=utf-8", "base64");
+ }
+ };
+ mLoadHTML.execute();
+ }
+
+ public int getPage() {
+ return mPage;
+ }
+
+ public void setScale(float scale) {
+ loadUrl("javascript:document.getElementById('content').style.zoom=\""+(int)(scale*100)+"%\"");
+ requestHeight();
+ }
+
+ public void blank(int page) {
+ }
+
+ public Hit passClickEvent(float x, float y) {
+ return Hit.Nothing;
+ }
+
+ public LinkInfo hitLink(float x, float y) {
+ return null;
+ }
+
+ public void selectText(float x0, float y0, float x1, float y1) {
+ }
+
+ public void deselectText() {
+ }
+
+ public boolean copySelection() {
+ return false;
+ }
+
+ public boolean markupSelection(Annotation.Type type) {
+ return false;
+ }
+
+ public void startDraw(float x, float y) {
+ }
+
+ public void continueDraw(float x, float y) {
+ }
+
+ public void cancelDraw() {
+ }
+
+ public boolean saveDraw() {
+ return false;
+ }
+
+ public void setSearchBoxes(RectF[] searchBoxes) {
+ }
+
+ public void setLinkHighlighting(boolean f) {
+ }
+
+ public void deleteSelectedAnnotation() {
+ }
+
+ public void deselectAnnotation() {
+ }
+
+ public void setChangeReporter(Runnable reporter) {
+ }
+
+ public void update() {
+ }
+
+ public void addHq(boolean update) {
+ }
+
+ public void removeHq() {
+ }
+
+ public void releaseResources() {
+ if (mLoadHTML != null) {
+ mLoadHTML.cancel(true);
+ mLoadHTML = null;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int x, y;
+ switch(View.MeasureSpec.getMode(widthMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ x = mParentSize.x;
+ break;
+ default:
+ x = View.MeasureSpec.getSize(widthMeasureSpec);
+ }
+ switch(View.MeasureSpec.getMode(heightMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ y = mContentHeight;
+ break;
+ default:
+ y = View.MeasureSpec.getSize(heightMeasureSpec);
+ }
+
+ setMeasuredDimension(x, y);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java
new file mode 100644
index 00000000..cc0405d1
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java
@@ -0,0 +1,32 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+enum Hit {Nothing, Widget, Annotation};
+
+public interface MuPDFView {
+ public void setPage(int page, PointF size);
+ public void setScale(float scale);
+ public int getPage();
+ public void blank(int page);
+ public Hit passClickEvent(float x, float y);
+ public LinkInfo hitLink(float x, float y);
+ public void selectText(float x0, float y0, float x1, float y1);
+ public void deselectText();
+ public boolean copySelection();
+ public boolean markupSelection(Annotation.Type type);
+ public void deleteSelectedAnnotation();
+ public void setSearchBoxes(RectF searchBoxes[]);
+ public void setLinkHighlighting(boolean f);
+ public void deselectAnnotation();
+ public void startDraw(float x, float y);
+ public void continueDraw(float x, float y);
+ public void cancelDraw();
+ public boolean saveDraw();
+ public void setChangeReporter(Runnable reporter);
+ public void update();
+ public void addHq(boolean update);
+ public void removeHq();
+ public void releaseResources();
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/OutlineActivity.java b/platform/android/src/com/artifex/mupdfdemo/OutlineActivity.java
new file mode 100644
index 00000000..52b0d410
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/OutlineActivity.java
@@ -0,0 +1,31 @@
+package com.artifex.mupdfdemo;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+
+public class OutlineActivity extends ListActivity {
+ OutlineItem mItems[];
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mItems = OutlineActivityData.get().items;
+ setListAdapter(new OutlineAdapter(getLayoutInflater(),mItems));
+ // Restore the position within the list from last viewing
+ getListView().setSelection(OutlineActivityData.get().position);
+ getListView().setDividerHeight(0);
+ setResult(-1);
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+ OutlineActivityData.get().position = getListView().getFirstVisiblePosition();
+ setResult(mItems[position].page);
+ finish();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/OutlineActivityData.java b/platform/android/src/com/artifex/mupdfdemo/OutlineActivityData.java
new file mode 100644
index 00000000..a703e61e
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/OutlineActivityData.java
@@ -0,0 +1,17 @@
+package com.artifex.mupdfdemo;
+
+public class OutlineActivityData {
+ public OutlineItem items[];
+ public int position;
+ static private OutlineActivityData singleton;
+
+ static public void set(OutlineActivityData d) {
+ singleton = d;
+ }
+
+ static public OutlineActivityData get() {
+ if (singleton == null)
+ singleton = new OutlineActivityData();
+ return singleton;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/OutlineAdapter.java b/platform/android/src/com/artifex/mupdfdemo/OutlineAdapter.java
new file mode 100644
index 00000000..4251ed8e
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/OutlineAdapter.java
@@ -0,0 +1,46 @@
+package com.artifex.mupdfdemo;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+public class OutlineAdapter extends BaseAdapter {
+ private final OutlineItem mItems[];
+ private final LayoutInflater mInflater;
+ public OutlineAdapter(LayoutInflater inflater, OutlineItem items[]) {
+ mInflater = inflater;
+ mItems = items;
+ }
+
+ public int getCount() {
+ return mItems.length;
+ }
+
+ public Object getItem(int arg0) {
+ return null;
+ }
+
+ public long getItemId(int arg0) {
+ return 0;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v;
+ if (convertView == null) {
+ v = mInflater.inflate(R.layout.outline_entry, null);
+ } else {
+ v = convertView;
+ }
+ int level = mItems[position].level;
+ if (level > 8) level = 8;
+ String space = "";
+ for (int i=0; i<level;i++)
+ space += " ";
+ ((TextView)v.findViewById(R.id.title)).setText(space+mItems[position].title);
+ ((TextView)v.findViewById(R.id.page)).setText(String.valueOf(mItems[position].page+1));
+ return v;
+ }
+
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/OutlineItem.java b/platform/android/src/com/artifex/mupdfdemo/OutlineItem.java
new file mode 100644
index 00000000..7730991e
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/OutlineItem.java
@@ -0,0 +1,14 @@
+package com.artifex.mupdfdemo;
+
+public class OutlineItem {
+ public final int level;
+ public final String title;
+ public final int page;
+
+ OutlineItem(int _level, String _title, int _page) {
+ level = _level;
+ title = _title;
+ page = _page;
+ }
+
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/PageView.java b/platform/android/src/com/artifex/mupdfdemo/PageView.java
new file mode 100644
index 00000000..200821dd
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/PageView.java
@@ -0,0 +1,704 @@
+package com.artifex.mupdfdemo;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+
+class PatchInfo {
+ public BitmapHolder bmh;
+ public Bitmap bm;
+ public Point patchViewSize;
+ public Rect patchArea;
+ public boolean completeRedraw;
+
+ public PatchInfo(Point aPatchViewSize, Rect aPatchArea, BitmapHolder aBmh, boolean aCompleteRedraw) {
+ bmh = aBmh;
+ bm = null;
+ patchViewSize = aPatchViewSize;
+ patchArea = aPatchArea;
+ completeRedraw = aCompleteRedraw;
+ }
+}
+
+// Make our ImageViews opaque to optimize redraw
+class OpaqueImageView extends ImageView {
+
+ public OpaqueImageView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+}
+
+interface TextProcessor {
+ void onStartLine();
+ void onWord(TextWord word);
+ void onEndLine();
+}
+
+class TextSelector {
+ final private TextWord[][] mText;
+ final private RectF mSelectBox;
+
+ public TextSelector(TextWord[][] text, RectF selectBox) {
+ mText = text;
+ mSelectBox = selectBox;
+ }
+
+ public void select(TextProcessor tp) {
+ if (mText == null || mSelectBox == null)
+ return;
+
+ ArrayList<TextWord[]> lines = new ArrayList<TextWord[]>();
+ for (TextWord[] line : mText)
+ if (line[0].bottom > mSelectBox.top && line[0].top < mSelectBox.bottom)
+ lines.add(line);
+
+ Iterator<TextWord[]> it = lines.iterator();
+ while (it.hasNext()) {
+ TextWord[] line = it.next();
+ boolean firstLine = line[0].top < mSelectBox.top;
+ boolean lastLine = line[0].bottom > mSelectBox.bottom;
+ float start = Float.NEGATIVE_INFINITY;
+ float end = Float.POSITIVE_INFINITY;
+
+ if (firstLine && lastLine) {
+ start = Math.min(mSelectBox.left, mSelectBox.right);
+ end = Math.max(mSelectBox.left, mSelectBox.right);
+ } else if (firstLine) {
+ start = mSelectBox.left;
+ } else if (lastLine) {
+ end = mSelectBox.right;
+ }
+
+ tp.onStartLine();
+
+ for (TextWord word : line)
+ if (word.right > start && word.left < end)
+ tp.onWord(word);
+
+ tp.onEndLine();
+ }
+ }
+}
+
+public abstract class PageView extends ViewGroup {
+ private static final int HIGHLIGHT_COLOR = 0x802572AC;
+ private static final int LINK_COLOR = 0x80AC7225;
+ private static final int BOX_COLOR = 0xFF4444FF;
+ private static final int INK_COLOR = 0xFFFF0000;
+ private static final float INK_THICKNESS = 10.0f;
+ private static final int BACKGROUND_COLOR = 0xFFFFFFFF;
+ private static final int PROGRESS_DIALOG_DELAY = 200;
+ protected final Context mContext;
+ protected int mPageNumber;
+ private Point mParentSize;
+ protected Point mSize; // Size of page at minimum zoom
+ protected float mSourceScale;
+
+ private ImageView mEntire; // Image rendered at minimum zoom
+ private BitmapHolder mEntireBmh;
+ private AsyncTask<Void,Void,TextWord[][]> mGetText;
+ private AsyncTask<Void,Void,LinkInfo[]> mGetLinkInfo;
+ private AsyncTask<Void,Void,Bitmap> mDrawEntire;
+
+ private Point mPatchViewSize; // View size on the basis of which the patch was created
+ private Rect mPatchArea;
+ private ImageView mPatch;
+ private BitmapHolder mPatchBmh;
+ private AsyncTask<PatchInfo,Void,PatchInfo> mDrawPatch;
+ private RectF mSearchBoxes[];
+ protected LinkInfo mLinks[];
+ private RectF mSelectBox;
+ private TextWord mText[][];
+ private RectF mItemSelectBox;
+ protected ArrayList<ArrayList<PointF>> mDrawing;
+ private View mSearchView;
+ private boolean mIsBlank;
+ private boolean mHighlightLinks;
+
+ private ProgressBar mBusyIndicator;
+ private final Handler mHandler = new Handler();
+
+ public PageView(Context c, Point parentSize) {
+ super(c);
+ mContext = c;
+ mParentSize = parentSize;
+ setBackgroundColor(BACKGROUND_COLOR);
+ mEntireBmh = new BitmapHolder();
+ mPatchBmh = new BitmapHolder();
+ }
+
+ protected abstract Bitmap drawPage(int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight);
+ protected abstract Bitmap updatePage(BitmapHolder h, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight);
+ protected abstract LinkInfo[] getLinkInfo();
+ protected abstract TextWord[][] getText();
+ protected abstract void addMarkup(PointF[] quadPoints, Annotation.Type type);
+
+ private void reinit() {
+ // Cancel pending render task
+ if (mDrawEntire != null) {
+ mDrawEntire.cancel(true);
+ mDrawEntire = null;
+ }
+
+ if (mDrawPatch != null) {
+ mDrawPatch.cancel(true);
+ mDrawPatch = null;
+ }
+
+ if (mGetLinkInfo != null) {
+ mGetLinkInfo.cancel(true);
+ mGetLinkInfo = null;
+ }
+
+ if (mGetText != null) {
+ mGetText.cancel(true);
+ mGetText = null;
+ }
+
+ mIsBlank = true;
+ mPageNumber = 0;
+
+ if (mSize == null)
+ mSize = mParentSize;
+
+ if (mEntire != null) {
+ mEntire.setImageBitmap(null);
+ mEntireBmh.setBm(null);
+ }
+
+ if (mPatch != null) {
+ mPatch.setImageBitmap(null);
+ mPatchBmh.setBm(null);
+ }
+
+ mPatchViewSize = null;
+ mPatchArea = null;
+
+ mSearchBoxes = null;
+ mLinks = null;
+ mSelectBox = null;
+ mText = null;
+ mItemSelectBox = null;
+ }
+
+ public void releaseResources() {
+ reinit();
+
+ if (mBusyIndicator != null) {
+ removeView(mBusyIndicator);
+ mBusyIndicator = null;
+ }
+ }
+
+ public void blank(int page) {
+ reinit();
+ mPageNumber = page;
+
+ if (mBusyIndicator == null) {
+ mBusyIndicator = new ProgressBar(mContext);
+ mBusyIndicator.setIndeterminate(true);
+ mBusyIndicator.setBackgroundResource(R.drawable.busy);
+ addView(mBusyIndicator);
+ }
+
+ setBackgroundColor(BACKGROUND_COLOR);
+ }
+
+ public void setPage(int page, PointF size) {
+ // Cancel pending render task
+ if (mDrawEntire != null) {
+ mDrawEntire.cancel(true);
+ mDrawEntire = null;
+ }
+
+ mIsBlank = false;
+ // Highlights may be missing because mIsBlank was true on last draw
+ if (mSearchView != null)
+ mSearchView.invalidate();
+
+ mPageNumber = page;
+ if (mEntire == null) {
+ mEntire = new OpaqueImageView(mContext);
+ mEntire.setScaleType(ImageView.ScaleType.FIT_CENTER);
+ addView(mEntire);
+ }
+
+ // Calculate scaled size that fits within the screen limits
+ // This is the size at minimum zoom
+ mSourceScale = Math.min(mParentSize.x/size.x, mParentSize.y/size.y);
+ Point newSize = new Point((int)(size.x*mSourceScale), (int)(size.y*mSourceScale));
+ mSize = newSize;
+
+ mEntire.setImageBitmap(null);
+ mEntireBmh.setBm(null);
+
+ // Get the link info in the background
+ mGetLinkInfo = new AsyncTask<Void,Void,LinkInfo[]>() {
+ protected LinkInfo[] doInBackground(Void... v) {
+ return getLinkInfo();
+ }
+
+ protected void onPostExecute(LinkInfo[] v) {
+ mLinks = v;
+ invalidate();
+ }
+ };
+
+ mGetLinkInfo.execute();
+
+ // Render the page in the background
+ mDrawEntire = new AsyncTask<Void,Void,Bitmap>() {
+ protected Bitmap doInBackground(Void... v) {
+ return drawPage(mSize.x, mSize.y, 0, 0, mSize.x, mSize.y);
+ }
+
+ protected void onPreExecute() {
+ setBackgroundColor(BACKGROUND_COLOR);
+ mEntire.setImageBitmap(null);
+ mEntireBmh.setBm(null);
+
+ if (mBusyIndicator == null) {
+ mBusyIndicator = new ProgressBar(mContext);
+ mBusyIndicator.setIndeterminate(true);
+ mBusyIndicator.setBackgroundResource(R.drawable.busy);
+ addView(mBusyIndicator);
+ mBusyIndicator.setVisibility(INVISIBLE);
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ if (mBusyIndicator != null)
+ mBusyIndicator.setVisibility(VISIBLE);
+ }
+ }, PROGRESS_DIALOG_DELAY);
+ }
+ }
+
+ protected void onPostExecute(Bitmap bm) {
+ removeView(mBusyIndicator);
+ mBusyIndicator = null;
+ mEntire.setImageBitmap(bm);
+ mEntireBmh.setBm(bm);
+ setBackgroundColor(Color.TRANSPARENT);
+ }
+ };
+
+ mDrawEntire.execute();
+
+ if (mSearchView == null) {
+ mSearchView = new View(mContext) {
+ @Override
+ protected void onDraw(final Canvas canvas) {
+ super.onDraw(canvas);
+ // Work out current total scale factor
+ // from source to view
+ final float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ final Paint paint = new Paint();
+
+ if (!mIsBlank && mSearchBoxes != null) {
+ paint.setColor(HIGHLIGHT_COLOR);
+ for (RectF rect : mSearchBoxes)
+ canvas.drawRect(rect.left*scale, rect.top*scale,
+ rect.right*scale, rect.bottom*scale,
+ paint);
+ }
+
+ if (!mIsBlank && mLinks != null && mHighlightLinks) {
+ paint.setColor(LINK_COLOR);
+ for (LinkInfo link : mLinks)
+ canvas.drawRect(link.rect.left*scale, link.rect.top*scale,
+ link.rect.right*scale, link.rect.bottom*scale,
+ paint);
+ }
+
+ if (mSelectBox != null && mText != null) {
+ paint.setColor(HIGHLIGHT_COLOR);
+ processSelectedText(new TextProcessor() {
+ RectF rect;
+
+ public void onStartLine() {
+ rect = new RectF();
+ }
+
+ public void onWord(TextWord word) {
+ rect.union(word);
+ }
+
+ public void onEndLine() {
+ if (!rect.isEmpty())
+ canvas.drawRect(rect.left*scale, rect.top*scale, rect.right*scale, rect.bottom*scale, paint);
+ }
+ });
+ }
+
+ if (mItemSelectBox != null) {
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setColor(BOX_COLOR);
+ canvas.drawRect(mItemSelectBox.left*scale, mItemSelectBox.top*scale, mItemSelectBox.right*scale, mItemSelectBox.bottom*scale, paint);
+ }
+
+ if (mDrawing != null) {
+ Path path = new Path();
+ PointF p;
+ Iterator<ArrayList<PointF>> it = mDrawing.iterator();
+ while (it.hasNext()) {
+ ArrayList<PointF> arc = it.next();
+ if (arc.size() >= 2) {
+ Iterator<PointF> iit = arc.iterator();
+ p = iit.next();
+ float mX = p.x * scale;
+ float mY = p.y * scale;
+ path.moveTo(mX, mY);
+ while (iit.hasNext()) {
+ p = iit.next();
+ float x = p.x * scale;
+ float y = p.y * scale;
+ path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
+ mX = x;
+ mY = y;
+ }
+ path.lineTo(mX, mY);
+ }
+ }
+
+ paint.setAntiAlias(true);
+ paint.setDither(true);
+ paint.setStrokeJoin(Paint.Join.ROUND);
+ paint.setStrokeCap(Paint.Cap.ROUND);
+
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(INK_THICKNESS * scale);
+ paint.setColor(INK_COLOR);
+
+ canvas.drawPath(path, paint);
+ }
+ }
+ };
+
+ addView(mSearchView);
+ }
+ requestLayout();
+ }
+
+ public void setSearchBoxes(RectF searchBoxes[]) {
+ mSearchBoxes = searchBoxes;
+ if (mSearchView != null)
+ mSearchView.invalidate();
+ }
+
+ public void setLinkHighlighting(boolean f) {
+ mHighlightLinks = f;
+ if (mSearchView != null)
+ mSearchView.invalidate();
+ }
+
+ public void deselectText() {
+ mSelectBox = null;
+ mSearchView.invalidate();
+ }
+
+ public void selectText(float x0, float y0, float x1, float y1) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX0 = (x0 - getLeft())/scale;
+ float docRelY0 = (y0 - getTop())/scale;
+ float docRelX1 = (x1 - getLeft())/scale;
+ float docRelY1 = (y1 - getTop())/scale;
+ // Order on Y but maintain the point grouping
+ if (docRelY0 <= docRelY1)
+ mSelectBox = new RectF(docRelX0, docRelY0, docRelX1, docRelY1);
+ else
+ mSelectBox = new RectF(docRelX1, docRelY1, docRelX0, docRelY0);
+
+ mSearchView.invalidate();
+
+ if (mGetText == null) {
+ mGetText = new AsyncTask<Void,Void,TextWord[][]>() {
+ @Override
+ protected TextWord[][] doInBackground(Void... params) {
+ return getText();
+ }
+ @Override
+ protected void onPostExecute(TextWord[][] result) {
+ mText = result;
+ mSearchView.invalidate();
+ }
+ };
+
+ mGetText.execute();
+ }
+ }
+
+ public void startDraw(float x, float y) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX = (x - getLeft())/scale;
+ float docRelY = (y - getTop())/scale;
+ if (mDrawing == null)
+ mDrawing = new ArrayList<ArrayList<PointF>>();
+
+ ArrayList<PointF> arc = new ArrayList<PointF>();
+ arc.add(new PointF(docRelX, docRelY));
+ mDrawing.add(arc);
+ }
+
+ public void continueDraw(float x, float y) {
+ float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
+ float docRelX = (x - getLeft())/scale;
+ float docRelY = (y - getTop())/scale;
+
+ if (mDrawing != null && mDrawing.size() > 0) {
+ ArrayList<PointF> arc = mDrawing.get(mDrawing.size() - 1);
+ arc.add(new PointF(docRelX, docRelY));
+ mSearchView.invalidate();
+ }
+ }
+
+ public void cancelDraw() {
+ mDrawing = null;
+ mSearchView.invalidate();
+ }
+
+ protected PointF[][] getDraw() {
+ if (mDrawing == null)
+ return null;
+
+ PointF[][] path = new PointF[mDrawing.size()][];
+
+ for (int i = 0; i < mDrawing.size(); i++) {
+ ArrayList<PointF> arc = mDrawing.get(i);
+ path[i] = arc.toArray(new PointF[arc.size()]);
+ }
+
+ return path;
+ }
+
+ protected void processSelectedText(TextProcessor tp) {
+ (new TextSelector(mText, mSelectBox)).select(tp);
+ }
+
+ public void setItemSelectBox(RectF rect) {
+ mItemSelectBox = rect;
+ if (mSearchView != null)
+ mSearchView.invalidate();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int x, y;
+ switch(View.MeasureSpec.getMode(widthMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ x = mSize.x;
+ break;
+ default:
+ x = View.MeasureSpec.getSize(widthMeasureSpec);
+ }
+ switch(View.MeasureSpec.getMode(heightMeasureSpec)) {
+ case View.MeasureSpec.UNSPECIFIED:
+ y = mSize.y;
+ break;
+ default:
+ y = View.MeasureSpec.getSize(heightMeasureSpec);
+ }
+
+ setMeasuredDimension(x, y);
+
+ if (mBusyIndicator != null) {
+ int limit = Math.min(mParentSize.x, mParentSize.y)/2;
+ mBusyIndicator.measure(View.MeasureSpec.AT_MOST | limit, View.MeasureSpec.AT_MOST | limit);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ int w = right-left;
+ int h = bottom-top;
+
+ if (mEntire != null) {
+ mEntire.layout(0, 0, w, h);
+ }
+
+ if (mSearchView != null) {
+ mSearchView.layout(0, 0, w, h);
+ }
+
+ if (mPatchViewSize != null) {
+ if (mPatchViewSize.x != w || mPatchViewSize.y != h) {
+ // Zoomed since patch was created
+ mPatchViewSize = null;
+ mPatchArea = null;
+ if (mPatch != null) {
+ mPatch.setImageBitmap(null);
+ mPatchBmh.setBm(null);
+ }
+ } else {
+ mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
+ }
+ }
+
+ if (mBusyIndicator != null) {
+ int bw = mBusyIndicator.getMeasuredWidth();
+ int bh = mBusyIndicator.getMeasuredHeight();
+
+ mBusyIndicator.layout((w-bw)/2, (h-bh)/2, (w+bw)/2, (h+bh)/2);
+ }
+ }
+
+ public void addHq(boolean update) {
+ Rect viewArea = new Rect(getLeft(),getTop(),getRight(),getBottom());
+ // If the viewArea's size matches the unzoomed size, there is no need for an hq patch
+ if (viewArea.width() != mSize.x || viewArea.height() != mSize.y) {
+ Point patchViewSize = new Point(viewArea.width(), viewArea.height());
+ Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y);
+
+ // Intersect and test that there is an intersection
+ if (!patchArea.intersect(viewArea))
+ return;
+
+ // Offset patch area to be relative to the view top left
+ patchArea.offset(-viewArea.left, -viewArea.top);
+
+ boolean area_unchanged = patchArea.equals(mPatchArea) && patchViewSize.equals(mPatchViewSize);
+
+ // If being asked for the same area as last time and not because of an update then nothing to do
+ if (area_unchanged && !update)
+ return;
+
+ boolean completeRedraw = !(area_unchanged && update);
+
+ // Stop the drawing of previous patch if still going
+ if (mDrawPatch != null) {
+ mDrawPatch.cancel(true);
+ mDrawPatch = null;
+ }
+
+ if (completeRedraw) {
+ // The bitmap holder mPatchBm may still be rendered to by a
+ // previously invoked task, and possibly for a different
+ // area, so we cannot risk the bitmap generated by this task
+ // being passed to it
+ mPatchBmh.drop();
+ mPatchBmh = new BitmapHolder();
+ }
+
+ // Create and add the image view if not already done
+ if (mPatch == null) {
+ mPatch = new OpaqueImageView(mContext);
+ mPatch.setScaleType(ImageView.ScaleType.FIT_CENTER);
+ addView(mPatch);
+ mSearchView.bringToFront();
+ }
+
+ mDrawPatch = new AsyncTask<PatchInfo,Void,PatchInfo>() {
+ protected PatchInfo doInBackground(PatchInfo... v) {
+ if (v[0].completeRedraw) {
+ v[0].bm = drawPage(v[0].patchViewSize.x, v[0].patchViewSize.y,
+ v[0].patchArea.left, v[0].patchArea.top,
+ v[0].patchArea.width(), v[0].patchArea.height());
+ } else {
+ v[0].bm = updatePage(v[0].bmh, v[0].patchViewSize.x, v[0].patchViewSize.y,
+ v[0].patchArea.left, v[0].patchArea.top,
+ v[0].patchArea.width(), v[0].patchArea.height());
+ }
+
+ return v[0];
+ }
+
+ protected void onPostExecute(PatchInfo v) {
+ if (mPatchBmh == v.bmh) {
+ mPatchViewSize = v.patchViewSize;
+ mPatchArea = v.patchArea;
+ if (v.bm != null) {
+ mPatch.setImageBitmap(v.bm);
+ v.bmh.setBm(v.bm);
+ v.bm = null;
+ }
+ //requestLayout();
+ // Calling requestLayout here doesn't lead to a later call to layout. No idea
+ // why, but apparently others have run into the problem.
+ mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom);
+ invalidate();
+ }
+ }
+ };
+
+ mDrawPatch.execute(new PatchInfo(patchViewSize, patchArea, mPatchBmh, completeRedraw));
+ }
+ }
+
+ public void update() {
+ // Cancel pending render task
+ if (mDrawEntire != null) {
+ mDrawEntire.cancel(true);
+ mDrawEntire = null;
+ }
+
+ if (mDrawPatch != null) {
+ mDrawPatch.cancel(true);
+ mDrawPatch = null;
+ }
+
+ // Render the page in the background
+ mDrawEntire = new AsyncTask<Void,Void,Bitmap>() {
+ protected Bitmap doInBackground(Void... v) {
+ // Pass the current bitmap as a basis for the update, but use a bitmap
+ // holder so that the held bitmap will be nulled and not hold on to
+ // memory, should this view become redundant.
+ return updatePage(mEntireBmh, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y);
+ }
+
+ protected void onPostExecute(Bitmap bm) {
+ if (bm != null) {
+ mEntire.setImageBitmap(bm);
+ mEntireBmh.setBm(bm);
+ }
+ invalidate();
+ }
+ };
+
+ mDrawEntire.execute();
+
+ addHq(true);
+ }
+
+ public void removeHq() {
+ // Stop the drawing of the patch if still going
+ if (mDrawPatch != null) {
+ mDrawPatch.cancel(true);
+ mDrawPatch = null;
+ }
+
+ // And get rid of it
+ mPatchViewSize = null;
+ mPatchArea = null;
+ if (mPatch != null) {
+ mPatch.setImageBitmap(null);
+ mPatchBmh.setBm(null);
+ }
+ }
+
+ public int getPage() {
+ return mPageNumber;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/PrintDialogActivity.java b/platform/android/src/com/artifex/mupdfdemo/PrintDialogActivity.java
new file mode 100644
index 00000000..d96322d5
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/PrintDialogActivity.java
@@ -0,0 +1,145 @@
+package com.artifex.mupdfdemo;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Base64;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+public class PrintDialogActivity extends Activity {
+ private static final String PRINT_DIALOG_URL = "https://www.google.com/cloudprint/dialog.html";
+ private static final String JS_INTERFACE = "AndroidPrintDialog";
+ private static final String CONTENT_TRANSFER_ENCODING = "base64";
+
+ private static final String ZXING_URL = "http://zxing.appspot.com";
+ private static final int ZXING_SCAN_REQUEST = 65743;
+
+ /**
+ * Post message that is sent by Print Dialog web page when the printing dialog
+ * needs to be closed.
+ */
+ private static final String CLOSE_POST_MESSAGE_NAME = "cp-dialog-on-close";
+
+ /**
+ * Web view element to show the printing dialog in.
+ */
+ private WebView dialogWebView;
+
+ /**
+ * Intent that started the action.
+ */
+ Intent cloudPrintIntent;
+
+ private int resultCode;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ resultCode = RESULT_OK;
+ setContentView(R.layout.print_dialog);
+ dialogWebView = (WebView) findViewById(R.id.webview);
+ cloudPrintIntent = this.getIntent();
+
+ WebSettings settings = dialogWebView.getSettings();
+ settings.setJavaScriptEnabled(true);
+
+ dialogWebView.setWebViewClient(new PrintDialogWebClient());
+ dialogWebView.addJavascriptInterface(
+ new PrintDialogJavaScriptInterface(), JS_INTERFACE);
+
+ dialogWebView.loadUrl(PRINT_DIALOG_URL);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (requestCode == ZXING_SCAN_REQUEST && resultCode == RESULT_OK) {
+ dialogWebView.loadUrl(intent.getStringExtra("SCAN_RESULT"));
+ }
+ }
+
+ final class PrintDialogJavaScriptInterface {
+ public String getType() {
+ return cloudPrintIntent.getType();
+ }
+
+ public String getTitle() {
+ return cloudPrintIntent.getExtras().getString("title");
+ }
+
+ public String getContent() {
+ try {
+ ContentResolver contentResolver = getContentResolver();
+ InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[4096];
+ int n = is.read(buffer);
+ while (n >= 0) {
+ baos.write(buffer, 0, n);
+ n = is.read(buffer);
+ }
+ is.close();
+ baos.flush();
+
+ return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
+ } catch (Throwable e) {
+ resultCode = RESULT_CANCELED;
+ setResult(resultCode);
+ finish();
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public String getEncoding() {
+ return CONTENT_TRANSFER_ENCODING;
+ }
+
+ public void onPostMessage(String message) {
+ if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
+ setResult(resultCode);
+ finish();
+ }
+ }
+ }
+
+ private final class PrintDialogWebClient extends WebViewClient {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ if (url.startsWith(ZXING_URL)) {
+ Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
+ intentScan.putExtra("SCAN_MODE", "QR_CODE_MODE");
+ try {
+ startActivityForResult(intentScan, ZXING_SCAN_REQUEST);
+ } catch (ActivityNotFoundException error) {
+ view.loadUrl(url);
+ }
+ } else {
+ view.loadUrl(url);
+ }
+ return false;
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ if (PRINT_DIALOG_URL.equals(url)) {
+ // Submit print document.
+ view.loadUrl("javascript:printDialog.setPrintDocument(printDialog.createPrintDocument("
+ + "window." + JS_INTERFACE + ".getType(),window." + JS_INTERFACE + ".getTitle(),"
+ + "window." + JS_INTERFACE + ".getContent(),window." + JS_INTERFACE + ".getEncoding()))");
+
+ // Add post messages listener.
+ view.loadUrl("javascript:window.addEventListener('message',"
+ + "function(evt){window." + JS_INTERFACE + ".onPostMessage(evt.data)}, false)");
+ }
+ }
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/ReaderView.java b/platform/android/src/com/artifex/mupdfdemo/ReaderView.java
new file mode 100644
index 00000000..f4f54722
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/ReaderView.java
@@ -0,0 +1,803 @@
+package com.artifex.mupdfdemo;
+
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.View;
+import android.widget.Adapter;
+import android.widget.AdapterView;
+import android.widget.Scroller;
+
+public class ReaderView
+ extends AdapterView<Adapter>
+ implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, Runnable {
+ private static final int MOVING_DIAGONALLY = 0;
+ private static final int MOVING_LEFT = 1;
+ private static final int MOVING_RIGHT = 2;
+ private static final int MOVING_UP = 3;
+ private static final int MOVING_DOWN = 4;
+
+ private static final int FLING_MARGIN = 100;
+ private static final int GAP = 20;
+
+ private static final float MIN_SCALE = 1.0f;
+ private static final float MAX_SCALE = 5.0f;
+ private static final float REFLOW_SCALE_FACTOR = 0.5f;
+
+ private Adapter mAdapter;
+ private int mCurrent; // Adapter's index for the current view
+ private boolean mResetLayout;
+ private final SparseArray<View>
+ mChildViews = new SparseArray<View>(3);
+ // Shadows the children of the adapter view
+ // but with more sensible indexing
+ private final LinkedList<View>
+ mViewCache = new LinkedList<View>();
+ private boolean mUserInteracting; // Whether the user is interacting
+ private boolean mScaling; // Whether the user is currently pinch zooming
+ private float mScale = 1.0f;
+ private int mXScroll; // Scroll amounts recorded from events.
+ private int mYScroll; // and then accounted for in onLayout
+ private boolean mReflow = false;
+ private final GestureDetector
+ mGestureDetector;
+ private final ScaleGestureDetector
+ mScaleGestureDetector;
+ private final Scroller mScroller;
+ private int mScrollerLastX;
+ private int mScrollerLastY;
+ private boolean mScrollDisabled;
+
+ static abstract class ViewMapper {
+ abstract void applyToView(View view);
+ }
+
+ public ReaderView(Context context) {
+ super(context);
+ mGestureDetector = new GestureDetector(this);
+ mScaleGestureDetector = new ScaleGestureDetector(context, this);
+ mScroller = new Scroller(context);
+ }
+
+ public ReaderView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mGestureDetector = new GestureDetector(this);
+ mScaleGestureDetector = new ScaleGestureDetector(context, this);
+ mScroller = new Scroller(context);
+ }
+
+ public ReaderView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mGestureDetector = new GestureDetector(this);
+ mScaleGestureDetector = new ScaleGestureDetector(context, this);
+ mScroller = new Scroller(context);
+ }
+
+ public int getDisplayedViewIndex() {
+ return mCurrent;
+ }
+
+ public void setDisplayedViewIndex(int i) {
+ if (0 <= i && i < mAdapter.getCount()) {
+ onMoveOffChild(mCurrent);
+ mCurrent = i;
+ onMoveToChild(i);
+ mResetLayout = true;
+ requestLayout();
+ }
+ }
+
+ public void moveToNext() {
+ View v = mChildViews.get(mCurrent+1);
+ if (v != null)
+ slideViewOntoScreen(v);
+ }
+
+ public void moveToPrevious() {
+ View v = mChildViews.get(mCurrent-1);
+ if (v != null)
+ slideViewOntoScreen(v);
+ }
+
+ // When advancing down the page, we want to advance by about
+ // 90% of a screenful. But we'd be happy to advance by between
+ // 80% and 95% if it means we hit the bottom in a whole number
+ // of steps.
+ private int smartAdvanceAmount(int screenHeight, int max) {
+ int advance = (int)(screenHeight * 0.9 + 0.5);
+ int leftOver = max % advance;
+ int steps = max / advance;
+ if (leftOver == 0) {
+ // We'll make it exactly. No adjustment
+ } else if ((float)leftOver / steps <= screenHeight * 0.05) {
+ // We can adjust up by less than 5% to make it exact.
+ advance += (int)((float)leftOver/steps + 0.5);
+ } else {
+ int overshoot = advance - leftOver;
+ if ((float)overshoot / steps <= screenHeight * 0.1) {
+ // We can adjust down by less than 10% to make it exact.
+ advance -= (int)((float)overshoot/steps + 0.5);
+ }
+ }
+ if (advance > max)
+ advance = max;
+ return advance;
+ }
+
+ public void smartMoveForwards() {
+ View v = mChildViews.get(mCurrent);
+ if (v == null)
+ return;
+
+ // The following code works in terms of where the screen is on the views;
+ // so for example, if the currentView is at (-100,-100), the visible
+ // region would be at (100,100). If the previous page was (2000, 3000) in
+ // size, the visible region of the previous page might be (2100 + GAP, 100)
+ // (i.e. off the previous page). This is different to the way the rest of
+ // the code in this file is written, but it's easier for me to think about.
+ // At some point we may refactor this to fit better with the rest of the
+ // code.
+
+ // screenWidth/Height are the actual width/height of the screen. e.g. 480/800
+ int screenWidth = getWidth();
+ int screenHeight = getHeight();
+ // We might be mid scroll; we want to calculate where we scroll to based on
+ // where this scroll would end, not where we are now (to allow for people
+ // bashing 'forwards' very fast.
+ int remainingX = mScroller.getFinalX() - mScroller.getCurrX();
+ int remainingY = mScroller.getFinalY() - mScroller.getCurrY();
+ // right/bottom is in terms of pixels within the scaled document; e.g. 1000
+ int top = -(v.getTop() + mYScroll + remainingY);
+ int right = screenWidth -(v.getLeft() + mXScroll + remainingX);
+ int bottom = screenHeight+top;
+ // docWidth/Height are the width/height of the scaled document e.g. 2000x3000
+ int docWidth = v.getMeasuredWidth();
+ int docHeight = v.getMeasuredHeight();
+
+ int xOffset, yOffset;
+ if (bottom >= docHeight) {
+ // We are flush with the bottom. Advance to next column.
+ if (right + screenWidth > docWidth) {
+ // No room for another column - go to next page
+ View nv = mChildViews.get(mCurrent+1);
+ if (nv == null) // No page to advance to
+ return;
+ int nextTop = -(nv.getTop() + mYScroll + remainingY);
+ int nextLeft = -(nv.getLeft() + mXScroll + remainingX);
+ int nextDocWidth = nv.getMeasuredWidth();
+ int nextDocHeight = nv.getMeasuredHeight();
+
+ // Allow for the next page maybe being shorter than the screen is high
+ yOffset = (nextDocHeight < screenHeight ? ((nextDocHeight - screenHeight)>>1) : 0);
+
+ if (nextDocWidth < screenWidth) {
+ // Next page is too narrow to fill the screen. Scroll to the top, centred.
+ xOffset = (nextDocWidth - screenWidth)>>1;
+ } else {
+ // Reset X back to the left hand column
+ xOffset = right % screenWidth;
+ // Adjust in case the previous page is less wide
+ if (xOffset + screenWidth > nextDocWidth)
+ xOffset = nextDocWidth - screenWidth;
+ }
+ xOffset -= nextLeft;
+ yOffset -= nextTop;
+ } else {
+ // Move to top of next column
+ xOffset = screenWidth;
+ yOffset = screenHeight - bottom;
+ }
+ } else {
+ // Advance by 90% of the screen height downwards (in case lines are partially cut off)
+ xOffset = 0;
+ yOffset = smartAdvanceAmount(screenHeight, docHeight - bottom);
+ }
+ mScrollerLastX = mScrollerLastY = 0;
+ mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400);
+ post(this);
+ }
+
+ public void smartMoveBackwards() {
+ View v = mChildViews.get(mCurrent);
+ if (v == null)
+ return;
+
+ // The following code works in terms of where the screen is on the views;
+ // so for example, if the currentView is at (-100,-100), the visible
+ // region would be at (100,100). If the previous page was (2000, 3000) in
+ // size, the visible region of the previous page might be (2100 + GAP, 100)
+ // (i.e. off the previous page). This is different to the way the rest of
+ // the code in this file is written, but it's easier for me to think about.
+ // At some point we may refactor this to fit better with the rest of the
+ // code.
+
+ // screenWidth/Height are the actual width/height of the screen. e.g. 480/800
+ int screenWidth = getWidth();
+ int screenHeight = getHeight();
+ // We might be mid scroll; we want to calculate where we scroll to based on
+ // where this scroll would end, not where we are now (to allow for people
+ // bashing 'forwards' very fast.
+ int remainingX = mScroller.getFinalX() - mScroller.getCurrX();
+ int remainingY = mScroller.getFinalY() - mScroller.getCurrY();
+ // left/top is in terms of pixels within the scaled document; e.g. 1000
+ int left = -(v.getLeft() + mXScroll + remainingX);
+ int top = -(v.getTop() + mYScroll + remainingY);
+ // docWidth/Height are the width/height of the scaled document e.g. 2000x3000
+ int docHeight = v.getMeasuredHeight();
+
+ int xOffset, yOffset;
+ if (top <= 0) {
+ // We are flush with the top. Step back to previous column.
+ if (left < screenWidth) {
+ /* No room for previous column - go to previous page */
+ View pv = mChildViews.get(mCurrent-1);
+ if (pv == null) /* No page to advance to */
+ return;
+ int prevDocWidth = pv.getMeasuredWidth();
+ int prevDocHeight = pv.getMeasuredHeight();
+
+ // Allow for the next page maybe being shorter than the screen is high
+ yOffset = (prevDocHeight < screenHeight ? ((prevDocHeight - screenHeight)>>1) : 0);
+
+ int prevLeft = -(pv.getLeft() + mXScroll);
+ int prevTop = -(pv.getTop() + mYScroll);
+ if (prevDocWidth < screenWidth) {
+ // Previous page is too narrow to fill the screen. Scroll to the bottom, centred.
+ xOffset = (prevDocWidth - screenWidth)>>1;
+ } else {
+ // Reset X back to the right hand column
+ xOffset = (left > 0 ? left % screenWidth : 0);
+ if (xOffset + screenWidth > prevDocWidth)
+ xOffset = prevDocWidth - screenWidth;
+ while (xOffset + screenWidth*2 < prevDocWidth)
+ xOffset += screenWidth;
+ }
+ xOffset -= prevLeft;
+ yOffset -= prevTop-prevDocHeight+screenHeight;
+ } else {
+ // Move to bottom of previous column
+ xOffset = -screenWidth;
+ yOffset = docHeight - screenHeight + top;
+ }
+ } else {
+ // Retreat by 90% of the screen height downwards (in case lines are partially cut off)
+ xOffset = 0;
+ yOffset = -smartAdvanceAmount(screenHeight, top);
+ }
+ mScrollerLastX = mScrollerLastY = 0;
+ mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400);
+ post(this);
+ }
+
+ public void resetupChildren() {
+ for (int i = 0; i < mChildViews.size(); i++)
+ onChildSetup(mChildViews.keyAt(i), mChildViews.valueAt(i));
+ }
+
+ public void applyToChildren(ViewMapper mapper) {
+ for (int i = 0; i < mChildViews.size(); i++)
+ mapper.applyToView(mChildViews.valueAt(i));
+ }
+
+ public void refresh(boolean reflow) {
+ mReflow = reflow;
+
+ mScale = 1.0f;
+ mXScroll = mYScroll = 0;
+
+ int numChildren = mChildViews.size();
+ for (int i = 0; i < numChildren; i++) {
+ View v = mChildViews.valueAt(i);
+ onNotInUse(v);
+ removeViewInLayout(v);
+ }
+ mChildViews.clear();
+ mViewCache.clear();
+
+ requestLayout();
+ }
+
+ protected void onChildSetup(int i, View v) {}
+
+ protected void onMoveToChild(int i) {}
+
+ protected void onMoveOffChild(int i) {}
+
+ protected void onSettle(View v) {};
+
+ protected void onUnsettle(View v) {};
+
+ protected void onNotInUse(View v) {};
+
+ protected void onScaleChild(View v, Float scale) {};
+
+ public View getView(int i) {
+ return mChildViews.get(i);
+ }
+
+ public View getDisplayedView() {
+ return mChildViews.get(mCurrent);
+ }
+
+ public void run() {
+ if (!mScroller.isFinished()) {
+ mScroller.computeScrollOffset();
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+ mXScroll += x - mScrollerLastX;
+ mYScroll += y - mScrollerLastY;
+ mScrollerLastX = x;
+ mScrollerLastY = y;
+ requestLayout();
+ post(this);
+ }
+ else if (!mUserInteracting) {
+ // End of an inertial scroll and the user is not interacting.
+ // The layout is stable
+ View v = mChildViews.get(mCurrent);
+ if (v != null)
+ postSettle(v);
+ }
+ }
+
+ public boolean onDown(MotionEvent arg0) {
+ mScroller.forceFinished(true);
+ return true;
+ }
+
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
+ if (mScrollDisabled)
+ return true;
+
+ View v = mChildViews.get(mCurrent);
+ if (v != null) {
+ Rect bounds = getScrollBounds(v);
+ switch(directionOfTravel(velocityX, velocityY)) {
+ case MOVING_LEFT:
+ if (bounds.left >= 0) {
+ // Fling off to the left bring next view onto screen
+ View vl = mChildViews.get(mCurrent+1);
+
+ if (vl != null) {
+ slideViewOntoScreen(vl);
+ return true;
+ }
+ }
+ break;
+ case MOVING_RIGHT:
+ if (bounds.right <= 0) {
+ // Fling off to the right bring previous view onto screen
+ View vr = mChildViews.get(mCurrent-1);
+
+ if (vr != null) {
+ slideViewOntoScreen(vr);
+ return true;
+ }
+ }
+ break;
+ }
+ mScrollerLastX = mScrollerLastY = 0;
+ // If the page has been dragged out of bounds then we want to spring back
+ // nicely. fling jumps back into bounds instantly, so we don't want to use
+ // fling in that case. On the other hand, we don't want to forgo a fling
+ // just because of a slightly off-angle drag taking us out of bounds other
+ // than in the direction of the drag, so we test for out of bounds only
+ // in the direction of travel.
+ //
+ // Also don't fling if out of bounds in any direction by more than fling
+ // margin
+ Rect expandedBounds = new Rect(bounds);
+ expandedBounds.inset(-FLING_MARGIN, -FLING_MARGIN);
+
+ if(withinBoundsInDirectionOfTravel(bounds, velocityX, velocityY)
+ && expandedBounds.contains(0, 0)) {
+ mScroller.fling(0, 0, (int)velocityX, (int)velocityY, bounds.left, bounds.right, bounds.top, bounds.bottom);
+ post(this);
+ }
+ }
+
+ return true;
+ }
+
+ public void onLongPress(MotionEvent e) {
+ }
+
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
+ float distanceY) {
+ if (!mScrollDisabled) {
+ mXScroll -= distanceX;
+ mYScroll -= distanceY;
+ requestLayout();
+ }
+ return true;
+ }
+
+ public void onShowPress(MotionEvent e) {
+ }
+
+ public boolean onSingleTapUp(MotionEvent e) {
+ return false;
+ }
+
+ public boolean onScale(ScaleGestureDetector detector) {
+ float previousScale = mScale;
+ float scale_factor = mReflow ? REFLOW_SCALE_FACTOR : 1.0f;
+ float min_scale = MIN_SCALE * scale_factor;
+ float max_scale = MAX_SCALE * scale_factor;
+ mScale = Math.min(Math.max(mScale * detector.getScaleFactor(), min_scale), max_scale);
+
+ if (mReflow) {
+ applyToChildren(new ViewMapper() {
+ @Override
+ void applyToView(View view) {
+ onScaleChild(view, mScale);
+ }
+ });
+ } else {
+ float factor = mScale/previousScale;
+
+ View v = mChildViews.get(mCurrent);
+ if (v != null) {
+ // Work out the focus point relative to the view top left
+ int viewFocusX = (int)detector.getFocusX() - (v.getLeft() + mXScroll);
+ int viewFocusY = (int)detector.getFocusY() - (v.getTop() + mYScroll);
+ // Scroll to maintain the focus point
+ mXScroll += viewFocusX - viewFocusX * factor;
+ mYScroll += viewFocusY - viewFocusY * factor;
+ requestLayout();
+ }
+ }
+ return true;
+ }
+
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ mScaling = true;
+ // Ignore any scroll amounts yet to be accounted for: the
+ // screen is not showing the effect of them, so they can
+ // only confuse the user
+ mXScroll = mYScroll = 0;
+ // Avoid jump at end of scaling by disabling scrolling
+ // until the next start of gesture
+ mScrollDisabled = true;
+ return true;
+ }
+
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ mScaling = false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ mScaleGestureDetector.onTouchEvent(event);
+
+ if (!mScaling)
+ mGestureDetector.onTouchEvent(event);
+
+ if ((event.getAction() & event.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
+ mUserInteracting = true;
+ }
+ if ((event.getAction() & event.ACTION_MASK) == MotionEvent.ACTION_UP) {
+ mScrollDisabled = false;
+ mUserInteracting = false;
+
+ View v = mChildViews.get(mCurrent);
+ if (v != null) {
+ if (mScroller.isFinished()) {
+ // If, at the end of user interaction, there is no
+ // current inertial scroll in operation then animate
+ // the view onto screen if necessary
+ slideViewOntoScreen(v);
+ }
+
+ if (mScroller.isFinished()) {
+ // If still there is no inertial scroll in operation
+ // then the layout is stable
+ postSettle(v);
+ }
+ }
+ }
+
+ requestLayout();
+ return true;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ int n = getChildCount();
+ for (int i = 0; i < n; i++)
+ measureView(getChildAt(i));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right,
+ int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ View cv = mChildViews.get(mCurrent);
+ Point cvOffset;
+
+ if (!mResetLayout) {
+ // Move to next or previous if current is sufficiently off center
+ if (cv != null) {
+ cvOffset = subScreenSizeOffset(cv);
+ // cv.getRight() may be out of date with the current scale
+ // so add left to the measured width for the correct position
+ if (cv.getLeft() + cv.getMeasuredWidth() + cvOffset.x + GAP/2 + mXScroll < getWidth()/2 && mCurrent + 1 < mAdapter.getCount()) {
+ postUnsettle(cv);
+ // post to invoke test for end of animation
+ // where we must set hq area for the new current view
+ post(this);
+
+ onMoveOffChild(mCurrent);
+ mCurrent++;
+ onMoveToChild(mCurrent);
+ }
+
+ if (cv.getLeft() - cvOffset.x - GAP/2 + mXScroll >= getWidth()/2 && mCurrent > 0) {
+ postUnsettle(cv);
+ // post to invoke test for end of animation
+ // where we must set hq area for the new current view
+ post(this);
+
+ onMoveOffChild(mCurrent);
+ mCurrent--;
+ onMoveToChild(mCurrent);
+ }
+ }
+
+ // Remove not needed children and hold them for reuse
+ int numChildren = mChildViews.size();
+ int childIndices[] = new int[numChildren];
+ for (int i = 0; i < numChildren; i++)
+ childIndices[i] = mChildViews.keyAt(i);
+
+ for (int i = 0; i < numChildren; i++) {
+ int ai = childIndices[i];
+ if (ai < mCurrent - 1 || ai > mCurrent + 1) {
+ View v = mChildViews.get(ai);
+ onNotInUse(v);
+ mViewCache.add(v);
+ removeViewInLayout(v);
+ mChildViews.remove(ai);
+ }
+ }
+ } else {
+ mResetLayout = false;
+ mXScroll = mYScroll = 0;
+
+ // Remove all children and hold them for reuse
+ int numChildren = mChildViews.size();
+ for (int i = 0; i < numChildren; i++) {
+ View v = mChildViews.valueAt(i);
+ onNotInUse(v);
+ mViewCache.add(v);
+ removeViewInLayout(v);
+ }
+ mChildViews.clear();
+ // post to ensure generation of hq area
+ post(this);
+ }
+
+ // Ensure current view is present
+ int cvLeft, cvRight, cvTop, cvBottom;
+ boolean notPresent = (mChildViews.get(mCurrent) == null);
+ cv = getOrCreateChild(mCurrent);
+ // When the view is sub-screen-size in either dimension we
+ // offset it to center within the screen area, and to keep
+ // the views spaced out
+ cvOffset = subScreenSizeOffset(cv);
+ if (notPresent) {
+ //Main item not already present. Just place it top left
+ cvLeft = cvOffset.x;
+ cvTop = cvOffset.y;
+ } else {
+ // Main item already present. Adjust by scroll offsets
+ cvLeft = cv.getLeft() + mXScroll;
+ cvTop = cv.getTop() + mYScroll;
+ }
+ // Scroll values have been accounted for
+ mXScroll = mYScroll = 0;
+ cvRight = cvLeft + cv.getMeasuredWidth();
+ cvBottom = cvTop + cv.getMeasuredHeight();
+
+ if (!mUserInteracting && mScroller.isFinished()) {
+ Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
+ cvRight += corr.x;
+ cvLeft += corr.x;
+ cvTop += corr.y;
+ cvBottom += corr.y;
+ } else if (cv.getMeasuredHeight() <= getHeight()) {
+ // When the current view is as small as the screen in height, clamp
+ // it vertically
+ Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
+ cvTop += corr.y;
+ cvBottom += corr.y;
+ }
+
+ cv.layout(cvLeft, cvTop, cvRight, cvBottom);
+
+ if (mCurrent > 0) {
+ View lv = getOrCreateChild(mCurrent - 1);
+ Point leftOffset = subScreenSizeOffset(lv);
+ int gap = leftOffset.x + GAP + cvOffset.x;
+ lv.layout(cvLeft - lv.getMeasuredWidth() - gap,
+ (cvBottom + cvTop - lv.getMeasuredHeight())/2,
+ cvLeft - gap,
+ (cvBottom + cvTop + lv.getMeasuredHeight())/2);
+ }
+
+ if (mCurrent + 1 < mAdapter.getCount()) {
+ View rv = getOrCreateChild(mCurrent + 1);
+ Point rightOffset = subScreenSizeOffset(rv);
+ int gap = cvOffset.x + GAP + rightOffset.x;
+ rv.layout(cvRight + gap,
+ (cvBottom + cvTop - rv.getMeasuredHeight())/2,
+ cvRight + rv.getMeasuredWidth() + gap,
+ (cvBottom + cvTop + rv.getMeasuredHeight())/2);
+ }
+
+ invalidate();
+ }
+
+ @Override
+ public Adapter getAdapter() {
+ return mAdapter;
+ }
+
+ @Override
+ public View getSelectedView() {
+ throw new UnsupportedOperationException(getContext().getString(R.string.not_supported));
+ }
+
+ @Override
+ public void setAdapter(Adapter adapter) {
+ mAdapter = adapter;
+ mChildViews.clear();
+ removeAllViewsInLayout();
+ requestLayout();
+ }
+
+ @Override
+ public void setSelection(int arg0) {
+ throw new UnsupportedOperationException(getContext().getString(R.string.not_supported));
+ }
+
+ private View getCached() {
+ if (mViewCache.size() == 0)
+ return null;
+ else
+ return mViewCache.removeFirst();
+ }
+
+ private View getOrCreateChild(int i) {
+ View v = mChildViews.get(i);
+ if (v == null) {
+ v = mAdapter.getView(i, getCached(), this);
+ addAndMeasureChild(i, v);
+ onChildSetup(i, v);
+ onScaleChild(v, mScale);
+ }
+
+ return v;
+ }
+
+ private void addAndMeasureChild(int i, View v) {
+ LayoutParams params = v.getLayoutParams();
+ if (params == null) {
+ params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+ addViewInLayout(v, 0, params, true);
+ mChildViews.append(i, v); // Record the view against it's adapter index
+ measureView(v);
+ }
+
+ private void measureView(View v) {
+ // See what size the view wants to be
+ v.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+
+ if (!mReflow) {
+ // Work out a scale that will fit it to this view
+ float scale = Math.min((float)getWidth()/(float)v.getMeasuredWidth(),
+ (float)getHeight()/(float)v.getMeasuredHeight());
+ // Use the fitting values scaled by our current scale factor
+ v.measure(View.MeasureSpec.EXACTLY | (int)(v.getMeasuredWidth()*scale*mScale),
+ View.MeasureSpec.EXACTLY | (int)(v.getMeasuredHeight()*scale*mScale));
+ } else {
+ v.measure(View.MeasureSpec.EXACTLY | (int)(v.getMeasuredWidth()),
+ View.MeasureSpec.EXACTLY | (int)(v.getMeasuredHeight()));
+ }
+ }
+
+ private Rect getScrollBounds(int left, int top, int right, int bottom) {
+ int xmin = getWidth() - right;
+ int xmax = -left;
+ int ymin = getHeight() - bottom;
+ int ymax = -top;
+
+ // In either dimension, if view smaller than screen then
+ // constrain it to be central
+ if (xmin > xmax) xmin = xmax = (xmin + xmax)/2;
+ if (ymin > ymax) ymin = ymax = (ymin + ymax)/2;
+
+ return new Rect(xmin, ymin, xmax, ymax);
+ }
+
+ private Rect getScrollBounds(View v) {
+ // There can be scroll amounts not yet accounted for in
+ // onLayout, so add mXScroll and mYScroll to the current
+ // positions when calculating the bounds.
+ return getScrollBounds(v.getLeft() + mXScroll,
+ v.getTop() + mYScroll,
+ v.getLeft() + v.getMeasuredWidth() + mXScroll,
+ v.getTop() + v.getMeasuredHeight() + mYScroll);
+ }
+
+ private Point getCorrection(Rect bounds) {
+ return new Point(Math.min(Math.max(0,bounds.left),bounds.right),
+ Math.min(Math.max(0,bounds.top),bounds.bottom));
+ }
+
+ private void postSettle(final View v) {
+ // onSettle and onUnsettle are posted so that the calls
+ // wont be executed until after the system has performed
+ // layout.
+ post (new Runnable() {
+ public void run () {
+ onSettle(v);
+ }
+ });
+ }
+
+ private void postUnsettle(final View v) {
+ post (new Runnable() {
+ public void run () {
+ onUnsettle(v);
+ }
+ });
+ }
+
+ private void slideViewOntoScreen(View v) {
+ Point corr = getCorrection(getScrollBounds(v));
+ if (corr.x != 0 || corr.y != 0) {
+ mScrollerLastX = mScrollerLastY = 0;
+ mScroller.startScroll(0, 0, corr.x, corr.y, 400);
+ post(this);
+ }
+ }
+
+ private Point subScreenSizeOffset(View v) {
+ return new Point(Math.max((getWidth() - v.getMeasuredWidth())/2, 0),
+ Math.max((getHeight() - v.getMeasuredHeight())/2, 0));
+ }
+
+ private static int directionOfTravel(float vx, float vy) {
+ if (Math.abs(vx) > 2 * Math.abs(vy))
+ return (vx > 0) ? MOVING_RIGHT : MOVING_LEFT;
+ else if (Math.abs(vy) > 2 * Math.abs(vx))
+ return (vy > 0) ? MOVING_DOWN : MOVING_UP;
+ else
+ return MOVING_DIAGONALLY;
+ }
+
+ private static boolean withinBoundsInDirectionOfTravel(Rect bounds, float vx, float vy) {
+ switch (directionOfTravel(vx, vy)) {
+ case MOVING_DIAGONALLY: return bounds.contains(0, 0);
+ case MOVING_LEFT: return bounds.left <= 0;
+ case MOVING_RIGHT: return bounds.right >= 0;
+ case MOVING_UP: return bounds.top <= 0;
+ case MOVING_DOWN: return bounds.bottom >= 0;
+ default: throw new NoSuchElementException();
+ }
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/SafeAnimatorInflater.java b/platform/android/src/com/artifex/mupdfdemo/SafeAnimatorInflater.java
new file mode 100644
index 00000000..7c6a7ebc
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/SafeAnimatorInflater.java
@@ -0,0 +1,37 @@
+package com.artifex.mupdfdemo;
+
+import android.animation.Animator;
+import android.view.View;
+import android.view.animation.Animation;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.view.View;
+import android.app.Activity;
+
+public class SafeAnimatorInflater
+{
+ private View mView;
+
+ public SafeAnimatorInflater(Activity activity, int animation, View view)
+ {
+ AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(activity, R.animator.info);
+ mView = view;
+ set.setTarget(view);
+ set.addListener(new Animator.AnimatorListener() {
+ public void onAnimationStart(Animator animation) {
+ mView.setVisibility(View.VISIBLE);
+ }
+
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ public void onAnimationEnd(Animator animation) {
+ mView.setVisibility(View.INVISIBLE);
+ }
+
+ public void onAnimationCancel(Animator animation) {
+ }
+ });
+ set.start();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/SearchTask.java b/platform/android/src/com/artifex/mupdfdemo/SearchTask.java
new file mode 100644
index 00000000..d3969f10
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/SearchTask.java
@@ -0,0 +1,128 @@
+package com.artifex.mupdfdemo;
+
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.RectF;
+import android.os.Handler;
+
+class ProgressDialogX extends ProgressDialog {
+ public ProgressDialogX(Context context) {
+ super(context);
+ }
+
+ private boolean mCancelled = false;
+
+ public boolean isCancelled() {
+ return mCancelled;
+ }
+
+ @Override
+ public void cancel() {
+ mCancelled = true;
+ super.cancel();
+ }
+}
+
+public abstract class SearchTask {
+ private static final int SEARCH_PROGRESS_DELAY = 200;
+ private final Context mContext;
+ private final MuPDFCore mCore;
+ private final Handler mHandler;
+ private final AlertDialog.Builder mAlertBuilder;
+ private AsyncTask<Void,Integer,SearchTaskResult> mSearchTask;
+
+ public SearchTask(Context context, MuPDFCore core) {
+ mContext = context;
+ mCore = core;
+ mHandler = new Handler();
+ mAlertBuilder = new AlertDialog.Builder(context);
+ }
+
+ protected abstract void onTextFound(SearchTaskResult result);
+
+ public void stop() {
+ if (mSearchTask != null) {
+ mSearchTask.cancel(true);
+ mSearchTask = null;
+ }
+ }
+
+ public void go(final String text, int direction, int displayPage, int searchPage) {
+ if (mCore == null)
+ return;
+ stop();
+
+ final int increment = direction;
+ final int startIndex = searchPage == -1 ? displayPage : searchPage + increment;
+
+ final ProgressDialogX progressDialog = new ProgressDialogX(mContext);
+ progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ progressDialog.setTitle(mContext.getString(R.string.searching_));
+ progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ stop();
+ }
+ });
+ progressDialog.setMax(mCore.countPages());
+
+ mSearchTask = new AsyncTask<Void,Integer,SearchTaskResult>() {
+ @Override
+ protected SearchTaskResult doInBackground(Void... params) {
+ int index = startIndex;
+
+ while (0 <= index && index < mCore.countPages() && !isCancelled()) {
+ publishProgress(index);
+ RectF searchHits[] = mCore.searchPage(index, text);
+
+ if (searchHits != null && searchHits.length > 0)
+ return new SearchTaskResult(text, index, searchHits);
+
+ index += increment;
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(SearchTaskResult result) {
+ progressDialog.cancel();
+ if (result != null) {
+ onTextFound(result);
+ } else {
+ mAlertBuilder.setTitle(SearchTaskResult.get() == null ? R.string.text_not_found : R.string.no_further_occurrences_found);
+ AlertDialog alert = mAlertBuilder.create();
+ alert.setButton(AlertDialog.BUTTON_POSITIVE, mContext.getString(R.string.dismiss),
+ (DialogInterface.OnClickListener)null);
+ alert.show();
+ }
+ }
+
+ @Override
+ protected void onCancelled() {
+ progressDialog.cancel();
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... values) {
+ progressDialog.setProgress(values[0].intValue());
+ }
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ if (!progressDialog.isCancelled())
+ {
+ progressDialog.show();
+ progressDialog.setProgress(startIndex);
+ }
+ }
+ }, SEARCH_PROGRESS_DELAY);
+ }
+ };
+
+ mSearchTask.execute();
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/SearchTaskResult.java b/platform/android/src/com/artifex/mupdfdemo/SearchTaskResult.java
new file mode 100644
index 00000000..8fa3c3a2
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/SearchTaskResult.java
@@ -0,0 +1,24 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.RectF;
+
+public class SearchTaskResult {
+ public final String txt;
+ public final int pageNumber;
+ public final RectF searchBoxes[];
+ static private SearchTaskResult singleton;
+
+ SearchTaskResult(String _txt, int _pageNumber, RectF _searchBoxes[]) {
+ txt = _txt;
+ pageNumber = _pageNumber;
+ searchBoxes = _searchBoxes;
+ }
+
+ static public SearchTaskResult get() {
+ return singleton;
+ }
+
+ static public void set(SearchTaskResult r) {
+ singleton = r;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/TextChar.java b/platform/android/src/com/artifex/mupdfdemo/TextChar.java
new file mode 100644
index 00000000..aebf519f
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/TextChar.java
@@ -0,0 +1,12 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.RectF;
+
+public class TextChar extends RectF {
+ public char c;
+
+ public TextChar(float x0, float y0, float x1, float y1, char _c) {
+ super(x0, y0, x1, y1);
+ c = _c;
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/TextWord.java b/platform/android/src/com/artifex/mupdfdemo/TextWord.java
new file mode 100644
index 00000000..d9672573
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/TextWord.java
@@ -0,0 +1,17 @@
+package com.artifex.mupdfdemo;
+
+import android.graphics.RectF;
+
+public class TextWord extends RectF {
+ public String w;
+
+ public TextWord() {
+ super();
+ w = new String();
+ }
+
+ public void Add(TextChar tc) {
+ super.union(tc);
+ w = w.concat(new String(new char[]{tc.c}));
+ }
+}
diff --git a/platform/android/src/com/artifex/mupdfdemo/WidgetType.java b/platform/android/src/com/artifex/mupdfdemo/WidgetType.java
new file mode 100644
index 00000000..5a22975d
--- /dev/null
+++ b/platform/android/src/com/artifex/mupdfdemo/WidgetType.java
@@ -0,0 +1,8 @@
+package com.artifex.mupdfdemo;
+
+public enum WidgetType {
+ NONE,
+ TEXT,
+ LISTBOX,
+ COMBOBOX
+}
diff --git a/platform/debian/changelog b/platform/debian/changelog
new file mode 100644
index 00000000..717d02ee
--- /dev/null
+++ b/platform/debian/changelog
@@ -0,0 +1,41 @@
+mupdf (1.2-1) unstable; urgency=low
+
+ * MuPDF version 1.2
+
+ -- Tor Andersson <tor@ghostscript.com> Sun, 28 Apr 2013 12:35:35 +0200
+
+mupdf (1.1-1) unstable; urgency=low
+
+ * MuPDF version 1.1
+
+ -- Tor Andersson <tor@ghostscript.com> Thu, 16 Aug 2012 15:10:55 +0200
+
+mupdf (1.0-1) unstable; urgency=low
+
+ * MuPDF version 1.0
+
+ -- Tor Andersson <tor@ghostscript.com> Tue, 24 Apr 2012 17:07:27 +0200
+
+mupdf (0.9-1) unstable; urgency=low
+
+ * MuPDF version 0.9
+
+ -- Tor Andersson <tor@ghostscript.com> Sat, 03 Sep 2011 13:45:37 +0200
+
+mupdf (0.8-1) unstable; urgency=low
+
+ * MuPDF version 0.8
+
+ -- Tor Andersson <tor@ghostscript.com> Mon, 11 Oct 2010 11:04:00 +0100
+
+mupdf (0.7-1) unstable; urgency=low
+
+ * MuPDF version 0.7
+
+ -- Tor Andersson <tor@ghostscript.com> Thu, 27 May 2010 17:11:13 +0100
+
+mupdf (0.6-1) unstable; urgency=low
+
+ * First release of MuPDF with debian package.
+
+ -- Tor Andersson <tor@ghostscript.com> Thu, 27 May 2010 17:11:13 +0100
diff --git a/platform/debian/compat b/platform/debian/compat
new file mode 100644
index 00000000..7ed6ff82
--- /dev/null
+++ b/platform/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/platform/debian/control b/platform/debian/control
new file mode 100644
index 00000000..f9943b35
--- /dev/null
+++ b/platform/debian/control
@@ -0,0 +1,38 @@
+Source: mupdf
+Section: text
+Priority: optional
+Maintainer: Tor Andersson <tor@ghostscript.com>
+Build-Depends: debhelper (>= 5), make, pkg-config, gcc, coreutils, binutils, tar, libfreetype6-dev, libx11-dev, libxext-dev, libjbig2dec-dev, libopenjpeg-dev, libjpeg8-dev, zlib1g-dev
+Standards-Version: 3.7.2
+
+Package: libmupdf-dev
+Architecture: any
+Description: Development files for the MuPDF viewer
+ MuPDF is a lightweight PDF viewer and toolkit written in portable C.
+ .
+ This package contains the static library and headers.
+
+Package: mupdf
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: A lightweight PDF viewer
+ MuPDF is a lightweight PDF viewer and toolkit written in portable C.
+ .
+ The renderer in MuPDF is tailored for high quality anti-aliased graphics.
+ It renders text with metrics and spacing accurate to within fractions of a
+ pixel for the highest fidelity in reproducing the look of a printed page
+ on screen.
+
+Package: mupdf-tools
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Commmand line tools for the MuPDF viewer
+ MuPDF is a lightweight PDF viewer and toolkit written in portable C.
+ .
+ This package contains command line tools using the MuPDF library:
+ .
+ pdfdraw to render pages to image files.
+ .
+ pdfshow to examine objects in a PDF file.
+ .
+ pdfclean to decompress and pretty print streams and objects in PDF files.
diff --git a/platform/debian/copyright b/platform/debian/copyright
new file mode 100644
index 00000000..7510d63c
--- /dev/null
+++ b/platform/debian/copyright
@@ -0,0 +1,63 @@
+This package was debianized by Sebastian Rasmussen <sebras@hotmail.com> on
+Sun, 28 Apr 2013 12:50:16 +0200.
+
+It was downloaded from http://mupdf.com/repos/mupdf
+
+Upstream Author: Tor Andersson <tor@ghostscript.com>
+
+Copyright: MuPDF is Copyright 2006-2013 Artifex Software, Inc.
+
+License:
+
+MuPDF is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+MuPDF is Copyright 2006-2013 Artifex Software, Inc.
+
+For commercial licensing please contact sales@artifex.com.
+
+The character map and mapping for pdf resources are from Adobe and are
+covered by their own copyright and license:
+
+-----------------------------------------------------------
+Copyright 1990-20xx Adobe Systems Incorporated.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+Redistributions of source code must retain the above
+copyright notice, this list of conditions and the following
+disclaimer.
+
+Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following
+disclaimer in the documentation and/or other materials
+provided with the distribution.
+
+Neither the name of Adobe Systems Incorporated nor the names
+of its contributors may be used to endorse or promote
+products derived from this software without specific prior
+written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------
+
+The Debian packaging is Coyright 2010-2013 Artifex Software, Inc.
+and is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
+
diff --git a/platform/debian/dirs b/platform/debian/dirs
new file mode 100644
index 00000000..84e4627d
--- /dev/null
+++ b/platform/debian/dirs
@@ -0,0 +1,3 @@
+usr/bin
+usr/include
+usr/lib
diff --git a/platform/debian/libmupdf-dev.install b/platform/debian/libmupdf-dev.install
new file mode 100644
index 00000000..119cf8cd
--- /dev/null
+++ b/platform/debian/libmupdf-dev.install
@@ -0,0 +1,3 @@
+debian/tmp/usr/include
+debian/tmp/usr/lib
+debian/mupdf.pc usr/lib/pkgconfig
diff --git a/platform/debian/mupdf-tools.docs b/platform/debian/mupdf-tools.docs
new file mode 100644
index 00000000..e845566c
--- /dev/null
+++ b/platform/debian/mupdf-tools.docs
@@ -0,0 +1 @@
+README
diff --git a/platform/debian/mupdf-tools.install b/platform/debian/mupdf-tools.install
new file mode 100644
index 00000000..957aef82
--- /dev/null
+++ b/platform/debian/mupdf-tools.install
@@ -0,0 +1,2 @@
+debian/tmp/usr/bin/mutool
+debian/tmp/usr/bin/mudraw
diff --git a/platform/debian/mupdf-tools.manpages b/platform/debian/mupdf-tools.manpages
new file mode 100644
index 00000000..50eb4643
--- /dev/null
+++ b/platform/debian/mupdf-tools.manpages
@@ -0,0 +1,2 @@
+apps/man/mutool.1
+apps/man/mudraw.1
diff --git a/platform/debian/mupdf.applications b/platform/debian/mupdf.applications
new file mode 100644
index 00000000..ca536c8b
--- /dev/null
+++ b/platform/debian/mupdf.applications
@@ -0,0 +1,7 @@
+mupdf
+ command=mupdf
+ name=MuPDF
+ expect_uris=false
+ requires_terminal=false
+ mime_types=application/x-pdf
+ can_open_multiple_files=false
diff --git a/platform/debian/mupdf.desktop b/platform/debian/mupdf.desktop
new file mode 100644
index 00000000..16e78659
--- /dev/null
+++ b/platform/debian/mupdf.desktop
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Name=MuPDF
+GenericName=PDF file viewer
+Exec=mupdf %f
+TryExec=mupdf
+Icon=mupdf
+Terminal=false
+Type=Application
+MimeType=application/pdf;application/x-pdf;
+Categories=Viewer;Graphics;
+Actions=View
+
+[Desktop Action View]
+Name=View with mupdf
+Exec=mupdf %f
diff --git a/platform/debian/mupdf.docs b/platform/debian/mupdf.docs
new file mode 100644
index 00000000..e845566c
--- /dev/null
+++ b/platform/debian/mupdf.docs
@@ -0,0 +1 @@
+README
diff --git a/platform/debian/mupdf.install b/platform/debian/mupdf.install
new file mode 100644
index 00000000..024f9f6a
--- /dev/null
+++ b/platform/debian/mupdf.install
@@ -0,0 +1,5 @@
+debian/mupdf.xpm usr/share/pixmaps
+debian/mupdf.png usr/share/pixmaps
+debian/mupdf.desktop usr/share/applications
+debian/mupdf.applications usr/share/application-registry
+debian/tmp/usr/bin/mupdf
diff --git a/platform/debian/mupdf.manpages b/platform/debian/mupdf.manpages
new file mode 100644
index 00000000..05ce11a3
--- /dev/null
+++ b/platform/debian/mupdf.manpages
@@ -0,0 +1 @@
+apps/man/mupdf.1
diff --git a/platform/debian/mupdf.menu b/platform/debian/mupdf.menu
new file mode 100644
index 00000000..138938cc
--- /dev/null
+++ b/platform/debian/mupdf.menu
@@ -0,0 +1,8 @@
+?package(mupdf):\
+ needs="x11" \
+ section="Applications/Viewers" \
+ command="/usr/bin/mupdf" \
+ title="MuPDF" \
+ hints="Documents" \
+ icon="/usr/share/pixmaps/mupdf.xpm" \
+ longtitle="MuPDF: A lightweight PDF viewer written in portable C"
diff --git a/platform/debian/mupdf.mime b/platform/debian/mupdf.mime
new file mode 100644
index 00000000..65bc0fbc
--- /dev/null
+++ b/platform/debian/mupdf.mime
@@ -0,0 +1,2 @@
+application/pdf; mupdf %s; test=test -n "$DISPLAY" ; nametemplate=%s.pdf; priority=5
+application/x-pdf; mupdf %s; test=test -n "$DISPLAY" ; nametemplate=%s.pdf; priority=5
diff --git a/platform/debian/mupdf.pc b/platform/debian/mupdf.pc
new file mode 100644
index 00000000..7196cd5c
--- /dev/null
+++ b/platform/debian/mupdf.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: mupdf
+Description: Library for rendering PDF documents
+Requires.private: freetype2
+Version: 0.5.0
+Libs: -L${libdir} -lmupdf
+Libs.private: -lopenjpeg -ljbig2dec -ljpeg -lz -lm
+Cflags: -I${includedir}
diff --git a/platform/debian/mupdf.png b/platform/debian/mupdf.png
new file mode 100644
index 00000000..e05de27c
--- /dev/null
+++ b/platform/debian/mupdf.png
Binary files differ
diff --git a/platform/debian/mupdf.xpm b/platform/debian/mupdf.xpm
new file mode 100644
index 00000000..2c042f4e
--- /dev/null
+++ b/platform/debian/mupdf.xpm
@@ -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 "
+};
diff --git a/platform/debian/rules b/platform/debian/rules
new file mode 100755
index 00000000..77e5858f
--- /dev/null
+++ b/platform/debian/rules
@@ -0,0 +1,49 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build: build-stamp
+build-stamp:
+ dh_testdir
+ dh_testroot
+ $(MAKE) build=release prefix=$(CURDIR)/debian/tmp/usr install
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+ -$(MAKE) nuke
+ dh_clean
+
+# Build architecture-independent files here.
+binary-indep: build
+ dh_testdir
+ dh_testroot
+ dh_installdirs
+ dh_installdocs
+ dh_installchangelogs
+ dh_installmenu
+ dh_installmime
+ dh_installman
+ dh_compress
+
+# Build architecture-dependent files here.
+binary-arch: build
+ dh_testdir
+ dh_testroot
+ dh_installdirs -a
+ dh_install -a
+ dh_strip -a
+ dh_fixperms -a
+ dh_makeshlibs -a
+ dh_installdeb -a
+ dh_shlibdeps -a
+ dh_gencontrol -a
+ dh_md5sums -a
+ dh_builddeb -a
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary
diff --git a/platform/ios/About.xps b/platform/ios/About.xps
new file mode 100644
index 00000000..3fcec260
--- /dev/null
+++ b/platform/ios/About.xps
Binary files differ
diff --git a/platform/ios/Default-568h@2x.png b/platform/ios/Default-568h@2x.png
new file mode 100644
index 00000000..0891b7aa
--- /dev/null
+++ b/platform/ios/Default-568h@2x.png
Binary files differ
diff --git a/platform/ios/Icon-72.png b/platform/ios/Icon-72.png
new file mode 100644
index 00000000..f24f4999
--- /dev/null
+++ b/platform/ios/Icon-72.png
Binary files differ
diff --git a/platform/ios/Icon-72@2x.png b/platform/ios/Icon-72@2x.png
new file mode 100644
index 00000000..4a428833
--- /dev/null
+++ b/platform/ios/Icon-72@2x.png
Binary files differ
diff --git a/platform/ios/Icon.png b/platform/ios/Icon.png
new file mode 100644
index 00000000..ae65dbea
--- /dev/null
+++ b/platform/ios/Icon.png
Binary files differ
diff --git a/platform/ios/Icon@2x.png b/platform/ios/Icon@2x.png
new file mode 100644
index 00000000..70518f4d
--- /dev/null
+++ b/platform/ios/Icon@2x.png
Binary files differ
diff --git a/platform/ios/Info.plist b/platform/ios/Info.plist
new file mode 100644
index 00000000..0595910d
--- /dev/null
+++ b/platform/ios/Info.plist
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFiles</key>
+ <array/>
+ <key>CFBundleIdentifier</key>
+ <string>com.artifex.mupdf</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.2</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.2</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIFileSharingEnabled</key>
+ <true/>
+ <key>UIPrerenderedIcon</key>
+ <true/>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeName</key>
+ <string>PDF</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.adobe.pdf</string>
+ </array>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.microsoft.xps</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>XPS</string>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeName</key>
+ <string>CBZ</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>public.zip-archive</string>
+ </array>
+ <key>LSHandlerRank</key>
+ <string>Alternate</string>
+ </dict>
+ </array>
+ <key>UTImportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeIdentifier</key>
+ <string>com.microsoft.xps</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>xps</string>
+ <string>oxps</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeIdentifier</key>
+ <string>public.zip-archive</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>zip</string>
+ <string>cbz</string>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeIdentifier</key>
+ <string>com.adobe.pdf</string>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>pdf</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/platform/ios/MuPDF.xcodeproj/project.pbxproj b/platform/ios/MuPDF.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..2e33f3c3
--- /dev/null
+++ b/platform/ios/MuPDF.xcodeproj/project.pbxproj
@@ -0,0 +1,357 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 9668C8D91476A30200D7BA52 /* About.xps in Resources */ = {isa = PBXBuildFile; fileRef = 9668C8D81476A30200D7BA52 /* About.xps */; };
+ 968F2E9C14539C880085264E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 968F2E9B14539C880085264E /* UIKit.framework */; };
+ 968F2E9E14539C880085264E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 968F2E9D14539C880085264E /* Foundation.framework */; };
+ 968F2EA014539C880085264E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 968F2E9F14539C880085264E /* CoreGraphics.framework */; };
+ 968F2EB014539CDA0085264E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 968F2E9014539BEB0085264E /* main.m */; };
+ 96A4739B147C1C3A003D757D /* libLibraries.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 968461E214642DB00012AE09 /* libLibraries.a */; };
+ 96B6AF8315D16A7E00EAAF7B /* x_alt_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 96B6AF8115D16A7E00EAAF7B /* x_alt_blue.png */; };
+ 96B6AF8415D16A7E00EAAF7B /* x_alt_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96B6AF8215D16A7E00EAAF7B /* x_alt_blue@2x.png */; };
+ 96BD2B38145AC485001CEBC3 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 96BD2B35145AC485001CEBC3 /* Icon-72.png */; };
+ 96BD2B39145AC485001CEBC3 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96BD2B36145AC485001CEBC3 /* Icon.png */; };
+ 96EC0F931672AAC60007F804 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96EC0F921672AAC60007F804 /* Default-568h@2x.png */; };
+ 96F2341514603FBA004A8A22 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 96F2341414603FBA004A8A22 /* Icon@2x.png */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 968461EE14642E3A0012AE09 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 96A3B27614539BAD00D0A895 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 968461E114642DB00012AE09;
+ remoteInfo = Libraries;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 9668C8D81476A30200D7BA52 /* About.xps */ = {isa = PBXFileReference; lastKnownFileType = file; path = About.xps; sourceTree = "<group>"; };
+ 968461E214642DB00012AE09 /* libLibraries.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLibraries.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 968F2E8E14539BEB0085264E /* build_libs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_libs.sh; sourceTree = "<group>"; };
+ 968F2E8F14539BEB0085264E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 968F2E9014539BEB0085264E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 968F2E9714539C880085264E /* MuPDF.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MuPDF.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 968F2E9B14539C880085264E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+ 968F2E9D14539C880085264E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+ 968F2E9F14539C880085264E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
+ 96B6AF8115D16A7E00EAAF7B /* x_alt_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = x_alt_blue.png; sourceTree = "<group>"; };
+ 96B6AF8215D16A7E00EAAF7B /* x_alt_blue@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "x_alt_blue@2x.png"; sourceTree = "<group>"; };
+ 96BD2B35145AC485001CEBC3 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = "<group>"; };
+ 96BD2B36145AC485001CEBC3 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
+ 96EC0F921672AAC60007F804 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
+ 96F2341414603FBA004A8A22 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 968F2E9414539C880085264E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 968F2E9C14539C880085264E /* UIKit.framework in Frameworks */,
+ 968F2E9E14539C880085264E /* Foundation.framework in Frameworks */,
+ 968F2EA014539C880085264E /* CoreGraphics.framework in Frameworks */,
+ 96A4739B147C1C3A003D757D /* libLibraries.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 968F2E9214539BF10085264E /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 9668C8D81476A30200D7BA52 /* About.xps */,
+ 96BD2B36145AC485001CEBC3 /* Icon.png */,
+ 96F2341414603FBA004A8A22 /* Icon@2x.png */,
+ 96BD2B35145AC485001CEBC3 /* Icon-72.png */,
+ 96B6AF8115D16A7E00EAAF7B /* x_alt_blue.png */,
+ 96B6AF8215D16A7E00EAAF7B /* x_alt_blue@2x.png */,
+ 968F2E8F14539BEB0085264E /* Info.plist */,
+ 968F2E8E14539BEB0085264E /* build_libs.sh */,
+ 968F2E9014539BEB0085264E /* main.m */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 968F2E9814539C880085264E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 968F2E9714539C880085264E /* MuPDF.app */,
+ 968461E214642DB00012AE09 /* libLibraries.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 968F2E9A14539C880085264E /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 968F2E9B14539C880085264E /* UIKit.framework */,
+ 968F2E9D14539C880085264E /* Foundation.framework */,
+ 968F2E9F14539C880085264E /* CoreGraphics.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 96A3B27414539BAD00D0A895 = {
+ isa = PBXGroup;
+ children = (
+ 96EC0F921672AAC60007F804 /* Default-568h@2x.png */,
+ 968F2E9214539BF10085264E /* Sources */,
+ 968F2E9A14539C880085264E /* Frameworks */,
+ 968F2E9814539C880085264E /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 968461E114642DB00012AE09 /* Libraries */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 968461EA14642DB00012AE09 /* Build configuration list for PBXNativeTarget "Libraries" */;
+ buildPhases = (
+ 968461ED14642DE50012AE09 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Libraries;
+ productName = Libraries;
+ productReference = 968461E214642DB00012AE09 /* libLibraries.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 968F2E9614539C880085264E /* MuPDF */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 968F2EAD14539C880085264E /* Build configuration list for PBXNativeTarget "MuPDF" */;
+ buildPhases = (
+ 968F2E9314539C880085264E /* Sources */,
+ 968F2E9414539C880085264E /* Frameworks */,
+ 968F2E9514539C880085264E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 968461EF14642E3A0012AE09 /* PBXTargetDependency */,
+ );
+ name = MuPDF;
+ productName = MuPDF;
+ productReference = 968F2E9714539C880085264E /* MuPDF.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 96A3B27614539BAD00D0A895 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0420;
+ };
+ buildConfigurationList = 96A3B27914539BAD00D0A895 /* Build configuration list for PBXProject "MuPDF" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 96A3B27414539BAD00D0A895;
+ productRefGroup = 968F2E9814539C880085264E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 968F2E9614539C880085264E /* MuPDF */,
+ 968461E114642DB00012AE09 /* Libraries */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 968F2E9514539C880085264E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 96BD2B38145AC485001CEBC3 /* Icon-72.png in Resources */,
+ 96BD2B39145AC485001CEBC3 /* Icon.png in Resources */,
+ 96F2341514603FBA004A8A22 /* Icon@2x.png in Resources */,
+ 9668C8D91476A30200D7BA52 /* About.xps in Resources */,
+ 96B6AF8315D16A7E00EAAF7B /* x_alt_blue.png in Resources */,
+ 96B6AF8415D16A7E00EAAF7B /* x_alt_blue@2x.png in Resources */,
+ 96EC0F931672AAC60007F804 /* Default-568h@2x.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 968461ED14642DE50012AE09 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/libLibraries.a",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "bash build_libs.sh";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 968F2E9314539C880085264E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 968F2EB014539CDA0085264E /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 968461EF14642E3A0012AE09 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 968461E114642DB00012AE09 /* Libraries */;
+ targetProxy = 968461EE14642E3A0012AE09 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 968461EB14642DB00012AE09 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = armv7;
+ PRODUCT_NAME = Libraries;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ 968461EC14642DB00012AE09 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = armv7;
+ PRODUCT_NAME = Libraries;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+ 968F2EAE14539C880085264E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = armv7;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "../**";
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ 968F2EAF14539C880085264E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = armv7;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
+ );
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "../**";
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ 96A3B27B14539BAD00D0A895 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ 96A3B27C14539BAD00D0A895 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 968461EA14642DB00012AE09 /* Build configuration list for PBXNativeTarget "Libraries" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 968461EB14642DB00012AE09 /* Debug */,
+ 968461EC14642DB00012AE09 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 968F2EAD14539C880085264E /* Build configuration list for PBXNativeTarget "MuPDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 968F2EAE14539C880085264E /* Debug */,
+ 968F2EAF14539C880085264E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 96A3B27914539BAD00D0A895 /* Build configuration list for PBXProject "MuPDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 96A3B27B14539BAD00D0A895 /* Debug */,
+ 96A3B27C14539BAD00D0A895 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 96A3B27614539BAD00D0A895 /* Project object */;
+}
diff --git a/platform/ios/build_libs.sh b/platform/ios/build_libs.sh
new file mode 100644
index 00000000..9f06ab0b
--- /dev/null
+++ b/platform/ios/build_libs.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Call this script from a "Run Script" target in the Xcode project to
+# cross compile MuPDF and third party libraries using the regular Makefile.
+# Also see "iOS" section in Makerules.
+
+echo Generating cmap and font files
+echo "Apple broke Xcode external targets yet again, and I can't be bothered to fix it."
+echo "Run the 'make generate' command manually from now on!"
+echo "If you see an error while running GEN, you've forgotten."
+
+# make -C .. verbose=yes generate || exit 1
+
+export OS=ios
+export build=$(echo $CONFIGURATION | tr A-Z a-z)
+
+case $ARCHS in
+ armv6) ARCHFLAGS="-arch armv6 -mno-thumb" ;;
+ armv7) ARCHFLAGS="-arch armv7 -mthumb" ;;
+ i386) ARCHFLAGS="-arch i386" ;;
+ *) echo "Unknown architecture:" $ARCHS; exit 1 ;;
+esac
+
+export CFLAGS="$ARCHFLAGS -isysroot $SDKROOT"
+export LDFLAGS="$ARCHFLAGS -isysroot $SDKROOT"
+export OUT=build/$build-$OS-$ARCHS
+
+echo Building libraries for $ARCHS.
+make -C .. libs || exit 1
+
+echo Assembling final library in $TARGET_BUILD_DIR/.
+mkdir -p "$TARGET_BUILD_DIR"
+rm -f $TARGET_BUILD_DIR/libLibraries.a
+ar cr $TARGET_BUILD_DIR/libLibraries.a ../$OUT/*.o
+ranlib $TARGET_BUILD_DIR/libLibraries.a
+
+echo Done.
diff --git a/platform/ios/iTunesArtwork.png b/platform/ios/iTunesArtwork.png
new file mode 100644
index 00000000..45aec0b7
--- /dev/null
+++ b/platform/ios/iTunesArtwork.png
Binary files differ
diff --git a/platform/ios/main.m b/platform/ios/main.m
new file mode 100644
index 00000000..5668d415
--- /dev/null
+++ b/platform/ios/main.m
@@ -0,0 +1,1661 @@
+#import <UIKit/UIKit.h>
+
+#undef ABS
+#undef MIN
+#undef MAX
+
+#include "fitz/fitz.h"
+
+#define GAP 20
+#define INDICATOR_Y -44-24
+#define SLIDER_W (width - GAP - 24)
+#define SEARCH_W (width - GAP - 170)
+
+static dispatch_queue_t queue;
+static float screenScale = 1;
+static fz_context *ctx = NULL;
+
+@interface MuLibraryController : UITableViewController <UIActionSheetDelegate>
+{
+ NSArray *files;
+ NSTimer *timer;
+ fz_document *_doc; // temporaries for juggling password dialog
+ NSString *_filename;
+}
+- (void) openDocument: (NSString*)filename;
+- (void) askForPassword: (NSString*)prompt;
+- (void) onPasswordOkay;
+- (void) onPasswordCancel;
+- (void) reload;
+@end
+
+@interface MuOutlineController : UITableViewController
+{
+ id target;
+ NSMutableArray *titles;
+ NSMutableArray *pages;
+}
+- (id) initWithTarget: (id)aTarget titles: (NSMutableArray*)aTitles pages: (NSMutableArray*)aPages;
+@end
+
+@interface MuHitView : UIView
+{
+ CGSize pageSize;
+ int hitCount;
+ CGRect hitRects[500];
+ int linkPage[500];
+ char *linkUrl[500];
+ UIColor *color;
+}
+- (id) initWithSearchResults: (int)n forDocument: (fz_document *)doc;
+- (id) initWithLinks: (fz_link*)links forDocument: (fz_document *)doc;
+- (void) setPageSize: (CGSize)s;
+@end
+
+@interface MuPageView : UIScrollView <UIScrollViewDelegate>
+{
+ fz_document *doc;
+ fz_page *page;
+ int number;
+ UIActivityIndicatorView *loadingView;
+ UIImageView *imageView;
+ UIImageView *tileView;
+ MuHitView *hitView;
+ MuHitView *linkView;
+ CGSize pageSize;
+ CGRect tileFrame;
+ float tileScale;
+ BOOL cancel;
+}
+- (id) initWithFrame: (CGRect)frame document: (fz_document*)aDoc page: (int)aNumber;
+- (void) displayImage: (UIImage*)image;
+- (void) resizeImage;
+- (void) loadPage;
+- (void) loadTile;
+- (void) willRotate;
+- (void) resetZoomAnimated: (BOOL)animated;
+- (void) showSearchResults: (int)count;
+- (void) clearSearchResults;
+- (void) showLinks;
+- (void) hideLinks;
+- (int) number;
+@end
+
+@interface MuDocumentController : UIViewController <UIScrollViewDelegate, UISearchBarDelegate>
+{
+ fz_document *doc;
+ NSString *key;
+ MuOutlineController *outline;
+ UIScrollView *canvas;
+ UILabel *indicator;
+ UISlider *slider;
+ UISearchBar *searchBar;
+ UIBarButtonItem *nextButton, *prevButton, *cancelButton, *searchButton, *outlineButton, *linkButton;
+ UIBarButtonItem *sliderWrapper;
+ int searchPage;
+ int cancelSearch;
+ int showLinks;
+ int width; // current screen size
+ int height;
+ int current; // currently visible page
+ int scroll_animating; // stop view updates during scrolling animations
+}
+- (id) initWithFilename: (NSString*)nsfilename document: (fz_document *)aDoc;
+- (void) createPageView: (int)number;
+- (void) gotoPage: (int)number animated: (BOOL)animated;
+- (void) onShowOutline: (id)sender;
+- (void) onShowSearch: (id)sender;
+- (void) onCancelSearch: (id)sender;
+- (void) resetSearch;
+- (void) showSearchResults: (int)count forPage: (int)number;
+- (void) onSlide: (id)sender;
+- (void) onTap: (UITapGestureRecognizer*)sender;
+- (void) showNavigationBar;
+- (void) hideNavigationBar;
+@end
+
+@interface MuAppDelegate : NSObject <UIApplicationDelegate, UINavigationControllerDelegate>
+{
+ UIWindow *window;
+ UINavigationController *navigator;
+ MuLibraryController *library;
+}
+@end
+
+#pragma mark -
+
+static int hit_count = 0;
+static fz_rect hit_bbox[500];
+
+static int
+search_page(fz_document *doc, int number, char *needle, fz_cookie *cookie)
+{
+ fz_page *page = fz_load_page(doc, number);
+
+ fz_text_sheet *sheet = fz_new_text_sheet(ctx);
+ fz_text_page *text = fz_new_text_page(ctx);
+ fz_device *dev = fz_new_text_device(ctx, sheet, text);
+ fz_run_page(doc, page, dev, &fz_identity, cookie);
+ fz_free_device(dev);
+
+ hit_count = fz_search_text_page(ctx, text, needle, hit_bbox, nelem(hit_bbox));
+
+ fz_free_text_page(ctx, text);
+ fz_free_text_sheet(ctx, sheet);
+ fz_free_page(doc, page);
+
+ return hit_count;
+}
+
+static fz_rect
+search_result_bbox(fz_document *doc, int i)
+{
+ return hit_bbox[i];
+}
+
+static void showAlert(NSString *msg, NSString *filename)
+{
+ UIAlertView *alert = [[UIAlertView alloc]
+ initWithTitle: msg
+ message: filename
+ delegate: nil
+ cancelButtonTitle: @"Okay"
+ otherButtonTitles: nil];
+ [alert show];
+ [alert release];
+}
+
+static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_outline *outline, int level)
+{
+ char indent[8*4+1];
+ if (level > 8)
+ level = 8;
+ memset(indent, ' ', level * 4);
+ indent[level * 4] = 0;
+ while (outline)
+ {
+ if (outline->dest.kind == FZ_LINK_GOTO)
+ {
+ int page = outline->dest.ld.gotor.page;
+ if (page >= 0 && outline->title)
+ {
+ NSString *title = [NSString stringWithUTF8String: outline->title];
+ [titles addObject: [NSString stringWithFormat: @"%s%@", indent, title]];
+ [pages addObject: [NSNumber numberWithInt: page]];
+ }
+ }
+ flattenOutline(titles, pages, outline->down, level + 1);
+ outline = outline->next;
+ }
+}
+
+static void releasePixmap(void *info, const void *data, size_t size)
+{
+ fz_drop_pixmap(ctx, info);
+}
+
+static UIImage *newImageWithPixmap(fz_pixmap *pix)
+{
+ unsigned char *samples = fz_pixmap_samples(ctx, pix);
+ int w = fz_pixmap_width(ctx, pix);
+ int h = fz_pixmap_height(ctx, pix);
+ CGDataProviderRef cgdata = CGDataProviderCreateWithData(pix, samples, w * 4 * h, releasePixmap);
+ CGColorSpaceRef cgcolor = CGColorSpaceCreateDeviceRGB();
+ CGImageRef cgimage = CGImageCreate(w, h, 8, 32, 4 * w,
+ cgcolor, kCGBitmapByteOrderDefault,
+ cgdata, NULL, NO, kCGRenderingIntentDefault);
+ UIImage *image = [[UIImage alloc]
+ initWithCGImage: cgimage
+ scale: screenScale
+ orientation: UIImageOrientationUp];
+ CGDataProviderRelease(cgdata);
+ CGColorSpaceRelease(cgcolor);
+ CGImageRelease(cgimage);
+ return image;
+}
+
+static CGSize fitPageToScreen(CGSize page, CGSize screen)
+{
+ float hscale = screen.width / page.width;
+ float vscale = screen.height / page.height;
+ float scale = fz_min(hscale, vscale);
+ hscale = floorf(page.width * scale) / page.width;
+ vscale = floorf(page.height * scale) / page.height;
+ return CGSizeMake(hscale, vscale);
+}
+
+static CGSize measurePage(fz_document *doc, fz_page *page)
+{
+ CGSize pageSize;
+ fz_rect bounds;
+ fz_bound_page(doc, page, &bounds);
+ pageSize.width = bounds.x1 - bounds.x0;
+ pageSize.height = bounds.y1 - bounds.y0;
+ return pageSize;
+}
+
+static UIImage *renderPage(fz_document *doc, fz_page *page, CGSize screenSize)
+{
+ CGSize pageSize;
+ fz_irect bbox;
+ fz_matrix ctm;
+ fz_device *dev;
+ fz_pixmap *pix;
+ CGSize scale;
+
+ screenSize.width *= screenScale;
+ screenSize.height *= screenScale;
+
+ pageSize = measurePage(doc, page);
+ scale = fitPageToScreen(pageSize, screenSize);
+ fz_scale(&ctm, scale.width, scale.height);
+ bbox = (fz_irect){0, 0, pageSize.width * scale.width, pageSize.height * scale.height};
+
+ pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, &bbox);
+ fz_clear_pixmap_with_value(ctx, pix, 255);
+
+ dev = fz_new_draw_device(ctx, pix);
+ fz_run_page(doc, page, dev, &ctm, NULL);
+ fz_free_device(dev);
+
+ return newImageWithPixmap(pix);
+}
+
+static UIImage *renderTile(fz_document *doc, fz_page *page, CGSize screenSize, CGRect tileRect, float zoom)
+{
+ CGSize pageSize;
+ fz_irect bbox;
+ fz_matrix ctm;
+ fz_device *dev;
+ fz_pixmap *pix;
+ CGSize scale;
+
+ screenSize.width *= screenScale;
+ screenSize.height *= screenScale;
+ tileRect.origin.x *= screenScale;
+ tileRect.origin.y *= screenScale;
+ tileRect.size.width *= screenScale;
+ tileRect.size.height *= screenScale;
+
+ pageSize = measurePage(doc, page);
+ scale = fitPageToScreen(pageSize, screenSize);
+ fz_scale(&ctm, scale.width * zoom, scale.height * zoom);
+
+ bbox.x0 = tileRect.origin.x;
+ bbox.y0 = tileRect.origin.y;
+ bbox.x1 = tileRect.origin.x + tileRect.size.width;
+ bbox.y1 = tileRect.origin.y + tileRect.size.height;
+
+ pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, &bbox);
+ fz_clear_pixmap_with_value(ctx, pix, 255);
+
+ dev = fz_new_draw_device(ctx, pix);
+ fz_run_page(doc, page, dev, &ctm, NULL);
+ fz_free_device(dev);
+
+ return newImageWithPixmap(pix);
+}
+
+#pragma mark -
+
+@implementation MuLibraryController
+
+- (void) viewWillAppear: (BOOL)animated
+{
+ [self setTitle: @"PDF, XPS and CBZ Documents"];
+ [self reload];
+ printf("library viewWillAppear (starting reload timer)\n");
+ timer = [NSTimer timerWithTimeInterval: 3
+ target: self selector: @selector(reload) userInfo: nil
+ repeats: YES];
+ [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode];
+}
+
+- (void) viewWillDisappear: (BOOL)animated
+{
+ printf("library viewWillDisappear (stopping reload timer)\n");
+ [timer invalidate];
+ timer = nil;
+}
+
+- (void) reload
+{
+ if (files) {
+ [files release];
+ files = nil;
+ }
+
+ NSFileManager *fileman = [NSFileManager defaultManager];
+ NSString *docdir = [NSString stringWithFormat: @"%@/Documents", NSHomeDirectory()];
+ NSMutableArray *outfiles = [[NSMutableArray alloc] init];
+ NSDirectoryEnumerator *direnum = [fileman enumeratorAtPath:docdir];
+ NSString *file;
+ BOOL isdir;
+ while (file = [direnum nextObject]) {
+ NSString *filepath = [docdir stringByAppendingPathComponent:file];
+ NSLog(@"file %@\n", file);
+ if ([fileman fileExistsAtPath:filepath isDirectory:&isdir] && !isdir) {
+ [outfiles addObject:file];
+ }
+ }
+
+ files = outfiles;
+
+ [[self tableView] reloadData];
+}
+
+- (void) dealloc
+{
+ [files release];
+ [super dealloc];
+}
+
+- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o
+{
+ return YES;
+}
+
+- (NSInteger) numberOfSectionsInTableView: (UITableView*)tableView
+{
+ return 1;
+}
+
+- (NSInteger) tableView: (UITableView*)tableView numberOfRowsInSection: (NSInteger)section
+{
+ return [files count] + 1;
+}
+
+- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ if (buttonIndex == [actionSheet destructiveButtonIndex])
+ {
+ char filename[PATH_MAX];
+ int row = [actionSheet tag];
+
+ dispatch_sync(queue, ^{});
+
+ strcpy(filename, [NSHomeDirectory() UTF8String]);
+ strcat(filename, "/Documents/");
+ strcat(filename, [[files objectAtIndex: row - 1] UTF8String]);
+
+ printf("delete document '%s'\n", filename);
+
+ unlink(filename);
+
+ [self reload];
+ }
+}
+
+- (void) onTapDelete: (UIControl*)sender
+{
+ int row = [sender tag];
+ NSString *title = [NSString stringWithFormat: @"Delete %@?", [files objectAtIndex: row - 1]];
+ UIActionSheet *sheet = [[UIActionSheet alloc]
+ initWithTitle: title
+ delegate: self
+ cancelButtonTitle: @"Cancel"
+ destructiveButtonTitle: @"Delete"
+ otherButtonTitles: nil];
+ [sheet setTag: row];
+ [sheet showInView: [self tableView]];
+ [sheet release];
+}
+
+- (UITableViewCell*) tableView: (UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
+{
+ static NSString *cellid = @"MuCellIdent";
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellid];
+ if (!cell)
+ cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellid] autorelease];
+ int row = [indexPath row];
+ if (row == 0) {
+ [[cell textLabel] setText: @"About MuPDF"];
+ [[cell textLabel] setFont: [UIFont systemFontOfSize: 20]];
+ } else {
+ [[cell textLabel] setText: [files objectAtIndex: row - 1]];
+ [[cell textLabel] setFont: [UIFont systemFontOfSize: 20]];
+ }
+
+ if (row > 0)
+ {
+ UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [deleteButton setImage: [UIImage imageNamed: @"x_alt_blue.png"] forState: UIControlStateNormal];
+ [deleteButton setFrame: CGRectMake(0, 0, 35, 35)];
+ [deleteButton addTarget: self action: @selector(onTapDelete:) forControlEvents: UIControlEventTouchUpInside];
+ [deleteButton setTag: row];
+ [cell setAccessoryView: deleteButton];
+ }
+ else
+ {
+ [cell setAccessoryView: nil];
+ }
+
+ return cell;
+}
+
+- (void) tableView: (UITableView*)tableView didSelectRowAtIndexPath: (NSIndexPath*)indexPath
+{
+ int row = [indexPath row];
+ if (row == 0)
+ [self openDocument: @"../MuPDF.app/About.xps"];
+ else
+ [self openDocument: [files objectAtIndex: row - 1]];
+}
+
+- (void) openDocument: (NSString*)nsfilename
+{
+ char filename[PATH_MAX];
+
+ dispatch_sync(queue, ^{});
+
+ strcpy(filename, [NSHomeDirectory() UTF8String]);
+ strcat(filename, "/Documents/");
+ strcat(filename, [nsfilename UTF8String]);
+
+ printf("open document '%s'\n", filename);
+
+ _filename = [nsfilename retain];
+ _doc = fz_open_document(ctx, filename);
+ if (!_doc) {
+ showAlert(@"Cannot open document", nsfilename);
+ return;
+ }
+
+ if (fz_needs_password(_doc))
+ [self askForPassword: @"'%@' needs a password:"];
+ else
+ [self onPasswordOkay];
+}
+
+- (void) askForPassword: (NSString*)prompt
+{
+ UIAlertView *passwordAlertView = [[UIAlertView alloc]
+ initWithTitle: @"Password Protected"
+ message: [NSString stringWithFormat: prompt, [_filename lastPathComponent]]
+ delegate: self
+ cancelButtonTitle: @"Cancel"
+ otherButtonTitles: @"Done", nil];
+ [passwordAlertView setAlertViewStyle: UIAlertViewStyleSecureTextInput];
+ [passwordAlertView show];
+ [passwordAlertView release];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ char *password = (char*) [[[alertView textFieldAtIndex: 0] text] UTF8String];
+ [alertView dismissWithClickedButtonIndex: buttonIndex animated: TRUE];
+ if (buttonIndex == 1) {
+ if (fz_authenticate_password(_doc, password))
+ [self onPasswordOkay];
+ else
+ [self askForPassword: @"Wrong password for '%@'. Try again:"];
+ } else {
+ [self onPasswordCancel];
+ }
+}
+
+- (void) onPasswordOkay
+{
+ MuDocumentController *document = [[MuDocumentController alloc] initWithFilename: _filename document: _doc];
+ if (document) {
+ [self setTitle: @"Library"];
+ [[self navigationController] pushViewController: document animated: YES];
+ [document release];
+ }
+ [_filename release];
+ _doc = NULL;
+}
+
+- (void) onPasswordCancel
+{
+ [_filename release];
+ printf("close document (password cancel)\n");
+ fz_close_document(_doc);
+ _doc = NULL;
+}
+
+@end
+
+#pragma mark -
+
+@implementation MuOutlineController
+
+- (id) initWithTarget: (id)aTarget titles: (NSMutableArray*)aTitles pages: (NSMutableArray*)aPages
+{
+ self = [super initWithStyle: UITableViewStylePlain];
+ if (self) {
+ [self setTitle: @"Table of Contents"];
+ target = aTarget; // only keep a weak reference, to avoid retain cycles
+ titles = [aTitles retain];
+ pages = [aPages retain];
+ [[self tableView] setSeparatorStyle: UITableViewCellSeparatorStyleNone];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [titles release];
+ [pages release];
+ [super dealloc];
+}
+
+- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o
+{
+ return YES;
+}
+
+- (NSInteger) numberOfSectionsInTableView: (UITableView*)tableView
+{
+ return 1;
+}
+
+- (NSInteger) tableView: (UITableView*)tableView numberOfRowsInSection: (NSInteger)section
+{
+ return [titles count];
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ return 28;
+}
+
+- (UITableViewCell*) tableView: (UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
+{
+ static NSString *cellid = @"MuCellIdent";
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellid];
+ if (!cell)
+ {
+ cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleValue1 reuseIdentifier: cellid] autorelease];
+ [[cell textLabel] setFont: [UIFont systemFontOfSize: 16]];
+ [[cell detailTextLabel] setFont: [UIFont systemFontOfSize: 16]];
+ }
+ NSString *title = [titles objectAtIndex: [indexPath row]];
+ NSString *page = [pages objectAtIndex: [indexPath row]];
+ [[cell textLabel] setText: title];
+ [[cell detailTextLabel] setText: [NSString stringWithFormat: @"%d", [page intValue]+1]];
+ return cell;
+}
+
+- (void) tableView: (UITableView*)tableView didSelectRowAtIndexPath: (NSIndexPath*)indexPath
+{
+ NSNumber *page = [pages objectAtIndex: [indexPath row]];
+ [target gotoPage: [page intValue] animated: NO];
+ [[self navigationController] popViewControllerAnimated: YES];
+}
+
+@end
+
+#pragma mark -
+
+@implementation MuHitView
+
+- (id) initWithSearchResults: (int)n forDocument: (fz_document *)doc
+{
+ self = [super initWithFrame: CGRectMake(0,0,100,100)];
+ if (self) {
+ [self setOpaque: NO];
+
+ color = [[UIColor colorWithRed: 0x25/255.0 green: 0x72/255.0 blue: 0xAC/255.0 alpha: 0.5] retain];
+
+ pageSize = CGSizeMake(100,100);
+
+ for (int i = 0; i < n && i < nelem(hitRects); i++) {
+ fz_rect bbox = search_result_bbox(doc, i); // this is thread-safe enough
+ hitRects[i].origin.x = bbox.x0;
+ hitRects[i].origin.y = bbox.y0;
+ hitRects[i].size.width = bbox.x1 - bbox.x0;
+ hitRects[i].size.height = bbox.y1 - bbox.y0;
+ }
+ hitCount = n;
+ }
+ return self;
+}
+
+- (id) initWithLinks: (fz_link*)link forDocument: (fz_document *)doc
+{
+ self = [super initWithFrame: CGRectMake(0,0,100,100)];
+ if (self) {
+ [self setOpaque: NO];
+
+ color = [[UIColor colorWithRed: 0xAC/255.0 green: 0x72/255.0 blue: 0x25/255.0 alpha: 0.5] retain];
+
+ pageSize = CGSizeMake(100,100);
+
+ while (link && hitCount < nelem(hitRects)) {
+ if (link->dest.kind == FZ_LINK_GOTO || link->dest.kind == FZ_LINK_URI) {
+ fz_rect bbox = link->rect;
+ hitRects[hitCount].origin.x = bbox.x0;
+ hitRects[hitCount].origin.y = bbox.y0;
+ hitRects[hitCount].size.width = bbox.x1 - bbox.x0;
+ hitRects[hitCount].size.height = bbox.y1 - bbox.y0;
+ linkPage[hitCount] = link->dest.kind == FZ_LINK_GOTO ? link->dest.ld.gotor.page : -1;
+ linkUrl[hitCount] = link->dest.kind == FZ_LINK_URI ? strdup(link->dest.ld.uri.uri) : nil;
+ hitCount++;
+ }
+ link = link->next;
+ }
+ }
+ return self;
+}
+
+- (void) setPageSize: (CGSize)s
+{
+ pageSize = s;
+ // if page takes a long time to load we may have drawn at the initial (wrong) size
+ [self setNeedsDisplay];
+}
+
+- (void) drawRect: (CGRect)r
+{
+ CGSize scale = fitPageToScreen(pageSize, self.bounds.size);
+
+ [color set];
+
+ for (int i = 0; i < hitCount; i++) {
+ CGRect rect = hitRects[i];
+ rect.origin.x *= scale.width;
+ rect.origin.y *= scale.height;
+ rect.size.width *= scale.width;
+ rect.size.height *= scale.height;
+ UIRectFill(rect);
+ }
+}
+
+- (void) dealloc
+{
+ int i;
+ [color release];
+ for (i = 0; i < hitCount; i++)
+ free(linkUrl[i]);
+ [super dealloc];
+}
+
+@end
+
+@implementation MuPageView
+
+- (id) initWithFrame: (CGRect)frame document: (fz_document*)aDoc page: (int)aNumber
+{
+ self = [super initWithFrame: frame];
+ if (self) {
+ doc = aDoc;
+ number = aNumber;
+ cancel = NO;
+
+ [self setShowsVerticalScrollIndicator: NO];
+ [self setShowsHorizontalScrollIndicator: NO];
+ [self setDecelerationRate: UIScrollViewDecelerationRateFast];
+ [self setDelegate: self];
+
+ // zoomDidFinish/Begin events fire before bounce animation completes,
+ // making a mess when we rearrange views during the animation.
+ [self setBouncesZoom: NO];
+
+ [self resetZoomAnimated: NO];
+
+ // TODO: use a one shot timer to delay the display of this?
+ loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+ [loadingView startAnimating];
+ [self addSubview: loadingView];
+
+ [self loadPage];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ // dealloc can trigger in background thread when the queued block is
+ // our last owner, and releases us on completion.
+ // Send the dealloc back to the main thread so we don't mess up UIKit.
+ if (dispatch_get_current_queue() != dispatch_get_main_queue()) {
+ __block id block_self = self; // don't auto-retain self!
+ dispatch_async(dispatch_get_main_queue(), ^{ [block_self dealloc]; });
+ } else {
+ __block fz_page *block_page = page;
+ __block fz_document *block_doc = doc;
+ dispatch_async(queue, ^{
+ if (block_page)
+ fz_free_page(block_doc, block_page);
+ block_page = nil;
+ });
+ [linkView release];
+ [hitView release];
+ [tileView release];
+ [loadingView release];
+ [imageView release];
+ [super dealloc];
+ }
+}
+
+- (int) number
+{
+ return number;
+}
+
+- (void) showLinks
+{
+ if (!linkView) {
+ dispatch_async(queue, ^{
+ if (!page)
+ page = fz_load_page(doc, number);
+ fz_link *links = fz_load_links(doc, page);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ linkView = [[MuHitView alloc] initWithLinks: links forDocument: doc];
+ dispatch_async(queue, ^{
+ fz_drop_link(ctx, links);
+ });
+ if (imageView) {
+ [linkView setFrame: [imageView frame]];
+ [linkView setPageSize: pageSize];
+ }
+ [self addSubview: linkView];
+ });
+ });
+ }
+}
+
+- (void) hideLinks
+{
+ [linkView removeFromSuperview];
+ [linkView release];
+ linkView = nil;
+}
+
+- (void) showSearchResults: (int)count
+{
+ if (hitView) {
+ [hitView removeFromSuperview];
+ [hitView release];
+ hitView = nil;
+ }
+ hitView = [[MuHitView alloc] initWithSearchResults: count forDocument: doc];
+ if (imageView) {
+ [hitView setFrame: [imageView frame]];
+ [hitView setPageSize: pageSize];
+ }
+ [self addSubview: hitView];
+}
+
+- (void) clearSearchResults
+{
+ if (hitView) {
+ [hitView removeFromSuperview];
+ [hitView release];
+ hitView = nil;
+ }
+}
+
+- (void) resetZoomAnimated: (BOOL)animated
+{
+ // discard tile and any pending tile jobs
+ tileFrame = CGRectZero;
+ tileScale = 1;
+ if (tileView) {
+ [tileView removeFromSuperview];
+ [tileView release];
+ tileView = nil;
+ }
+
+ [self setMinimumZoomScale: 1];
+ [self setMaximumZoomScale: 5];
+ [self setZoomScale: 1 animated: animated];
+}
+
+- (void) removeFromSuperview
+{
+ cancel = YES;
+ [super removeFromSuperview];
+}
+
+- (void) loadPage
+{
+ if (number < 0 || number >= fz_count_pages(doc))
+ return;
+ dispatch_async(queue, ^{
+ if (!cancel) {
+ printf("render page %d\n", number);
+ if (!page)
+ page = fz_load_page(doc, number);
+ CGSize size = measurePage(doc, page);
+ UIImage *image = renderPage(doc, page, self.bounds.size);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ pageSize = size;
+ [self displayImage: image];
+ [image release];
+ });
+ } else {
+ printf("cancel page %d\n", number);
+ }
+ });
+}
+
+- (void) displayImage: (UIImage*)image
+{
+ if (loadingView) {
+ [loadingView removeFromSuperview];
+ [loadingView release];
+ loadingView = nil;
+ }
+
+ if (hitView)
+ [hitView setPageSize: pageSize];
+
+ if (!imageView) {
+ imageView = [[UIImageView alloc] initWithImage: image];
+ imageView.opaque = YES;
+ [self addSubview: imageView];
+ if (hitView)
+ [self bringSubviewToFront: hitView];
+ } else {
+ [imageView setImage: image];
+ }
+
+ [self resizeImage];
+}
+
+- (void) resizeImage
+{
+ if (imageView) {
+ CGSize imageSize = imageView.image.size;
+ CGSize scale = fitPageToScreen(imageSize, self.bounds.size);
+ if (fabs(scale.width - 1) > 0.1) {
+ CGRect frame = [imageView frame];
+ frame.size.width = imageSize.width * scale.width;
+ frame.size.height = imageSize.height * scale.height;
+ [imageView setFrame: frame];
+
+ printf("resized view; queuing up a reload (%d)\n", number);
+ dispatch_async(queue, ^{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ CGSize scale = fitPageToScreen(imageView.image.size, self.bounds.size);
+ if (fabs(scale.width - 1) > 0.01)
+ [self loadPage];
+ });
+ });
+ } else {
+ [imageView sizeToFit];
+ }
+
+ [self setContentSize: imageView.frame.size];
+
+ [self layoutIfNeeded];
+ }
+
+}
+
+- (void) willRotate
+{
+ if (imageView) {
+ [self resetZoomAnimated: NO];
+ [self resizeImage];
+ }
+}
+
+- (void) layoutSubviews
+{
+ [super layoutSubviews];
+
+ // center the image as it becomes smaller than the size of the screen
+
+ CGSize boundsSize = self.bounds.size;
+ CGRect frameToCenter = loadingView ? loadingView.frame : imageView.frame;
+
+ // center horizontally
+ if (frameToCenter.size.width < boundsSize.width)
+ frameToCenter.origin.x = floor((boundsSize.width - frameToCenter.size.width) / 2);
+ else
+ frameToCenter.origin.x = 0;
+
+ // center vertically
+ if (frameToCenter.size.height < boundsSize.height)
+ frameToCenter.origin.y = floor((boundsSize.height - frameToCenter.size.height) / 2);
+ else
+ frameToCenter.origin.y = 0;
+
+ if (loadingView)
+ loadingView.frame = frameToCenter;
+ else
+ imageView.frame = frameToCenter;
+
+ if (hitView && imageView)
+ [hitView setFrame: [imageView frame]];
+}
+
+- (UIView*) viewForZoomingInScrollView: (UIScrollView*)scrollView
+{
+ return imageView;
+}
+
+- (void) loadTile
+{
+ CGSize screenSize = self.bounds.size;
+
+ tileFrame.origin = self.contentOffset;
+ tileFrame.size = self.bounds.size;
+ tileFrame = CGRectIntersection(tileFrame, imageView.frame);
+ tileScale = self.zoomScale;
+
+ CGRect frame = tileFrame;
+ float scale = tileScale;
+
+ CGRect viewFrame = frame;
+ if (self.contentOffset.x < imageView.frame.origin.x)
+ viewFrame.origin.x = 0;
+ if (self.contentOffset.y < imageView.frame.origin.y)
+ viewFrame.origin.y = 0;
+
+ if (scale < 1.01)
+ return;
+
+ dispatch_async(queue, ^{
+ __block BOOL isValid;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ isValid = CGRectEqualToRect(frame, tileFrame) && scale == tileScale;
+ });
+ if (!isValid) {
+ printf("cancel tile\n");
+ return;
+ }
+
+ if (!page)
+ page = fz_load_page(doc, number);
+
+ printf("render tile\n");
+ UIImage *image = renderTile(doc, page, screenSize, viewFrame, scale);
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ isValid = CGRectEqualToRect(frame, tileFrame) && scale == tileScale;
+ if (isValid) {
+ tileFrame = CGRectZero;
+ tileScale = 1;
+ if (tileView) {
+ [tileView removeFromSuperview];
+ [tileView release];
+ tileView = nil;
+ }
+
+ tileView = [[UIImageView alloc] initWithFrame: frame];
+ [tileView setImage: image];
+ [self addSubview: tileView];
+ if (hitView)
+ [self bringSubviewToFront: hitView];
+ } else {
+ printf("discard tile\n");
+ }
+ [image release];
+ });
+ });
+}
+
+- (void) scrollViewDidScrollToTop:(UIScrollView *)scrollView { [self loadTile]; }
+- (void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { [self loadTile]; }
+- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self loadTile]; }
+- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
+{
+ if (!decelerate)
+ [self loadTile];
+}
+
+- (void) scrollViewWillBeginZooming: (UIScrollView*)scrollView withView: (UIView*)view
+{
+ // discard tile and any pending tile jobs
+ tileFrame = CGRectZero;
+ tileScale = 1;
+ if (tileView) {
+ [tileView removeFromSuperview];
+ [tileView release];
+ tileView = nil;
+ }
+}
+
+- (void) scrollViewDidEndZooming: (UIScrollView*)scrollView withView: (UIView*)view atScale: (float)scale
+{
+ [self loadTile];
+}
+
+- (void) scrollViewDidZoom: (UIScrollView*)scrollView
+{
+ if (hitView && imageView)
+ [hitView setFrame: [imageView frame]];
+}
+
+@end
+
+#pragma mark -
+
+@implementation MuDocumentController
+
+- (id) initWithFilename: (NSString*)filename document: (fz_document *)aDoc
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ key = [filename retain];
+ doc = aDoc;
+
+ dispatch_sync(queue, ^{});
+
+ fz_outline *root = fz_load_outline(doc);
+ if (root) {
+ NSMutableArray *titles = [[NSMutableArray alloc] init];
+ NSMutableArray *pages = [[NSMutableArray alloc] init];
+ flattenOutline(titles, pages, root, 0);
+ if ([titles count])
+ outline = [[MuOutlineController alloc] initWithTarget: self titles: titles pages: pages];
+ [titles release];
+ [pages release];
+ fz_free_outline(ctx, root);
+ }
+
+ return self;
+}
+
+- (void) loadView
+{
+ [[NSUserDefaults standardUserDefaults] setObject: key forKey: @"OpenDocumentKey"];
+
+ current = [[NSUserDefaults standardUserDefaults] integerForKey: key];
+ if (current < 0 || current >= fz_count_pages(doc))
+ current = 0;
+
+ UIView *view = [[UIView alloc] initWithFrame: CGRectZero];
+ [view setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
+ [view setAutoresizesSubviews: YES];
+
+ canvas = [[UIScrollView alloc] initWithFrame: CGRectMake(0,0,GAP,0)];
+ [canvas setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
+ [canvas setPagingEnabled: YES];
+ [canvas setShowsHorizontalScrollIndicator: NO];
+ [canvas setShowsVerticalScrollIndicator: NO];
+ [canvas setDelegate: self];
+
+ [canvas addGestureRecognizer: [[[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(onTap:)] autorelease]];
+
+ scroll_animating = NO;
+
+ indicator = [[UILabel alloc] initWithFrame: CGRectZero];
+ [indicator setAutoresizingMask: UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin];
+ [indicator setText: @"0000 of 9999"];
+ [indicator sizeToFit];
+ [indicator setCenter: CGPointMake(0, INDICATOR_Y)];
+ [indicator setTextAlignment: UITextAlignmentCenter];
+ [indicator setBackgroundColor: [[UIColor blackColor] colorWithAlphaComponent: 0.5]];
+ [indicator setTextColor: [UIColor whiteColor]];
+
+ [view addSubview: canvas];
+ [view addSubview: indicator];
+
+ slider = [[UISlider alloc] initWithFrame: CGRectZero];
+ [slider setMinimumValue: 0];
+ [slider setMaximumValue: fz_count_pages(doc) - 1];
+ [slider addTarget: self action: @selector(onSlide:) forControlEvents: UIControlEventValueChanged];
+
+ sliderWrapper = [[UIBarButtonItem alloc] initWithCustomView: slider];
+
+ [self setToolbarItems: [NSArray arrayWithObjects: sliderWrapper, nil]];
+
+ // Set up the buttons on the navigation and search bar
+
+ if (outline) {
+ outlineButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem: UIBarButtonSystemItemBookmarks
+ target:self action:@selector(onShowOutline:)];
+ }
+ linkButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem: UIBarButtonSystemItemAction
+ target:self action:@selector(onToggleLinks:)];
+ cancelButton = [[UIBarButtonItem alloc]
+ initWithTitle: @"Cancel" style: UIBarButtonItemStyleBordered
+ target:self action:@selector(onCancelSearch:)];
+ searchButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem: UIBarButtonSystemItemSearch
+ target:self action:@selector(onShowSearch:)];
+ prevButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem: UIBarButtonSystemItemRewind
+ target:self action:@selector(onSearchPrev:)];
+ nextButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem: UIBarButtonSystemItemFastForward
+ target:self action:@selector(onSearchNext:)];
+
+ searchBar = [[UISearchBar alloc] initWithFrame: CGRectMake(0,0,50,32)];
+ [searchBar setPlaceholder: @"Search"];
+ [searchBar setDelegate: self];
+ // HACK to make transparent background
+ [[searchBar.subviews objectAtIndex:0] removeFromSuperview];
+
+ [prevButton setEnabled: NO];
+ [nextButton setEnabled: NO];
+
+ [[self navigationItem] setRightBarButtonItems:
+ [NSArray arrayWithObjects: searchButton, linkButton, outlineButton, nil]];
+
+ // TODO: add activityindicator to search bar
+
+ [self setView: view];
+ [view release];
+}
+
+- (void) dealloc
+{
+ if (doc) {
+ fz_document *self_doc = doc; // don't auto-retain self here!
+ dispatch_async(queue, ^{
+ printf("close document\n");
+ fz_close_document(self_doc);
+ });
+ }
+
+ [indicator release]; indicator = nil;
+ [slider release]; slider = nil;
+ [sliderWrapper release]; sliderWrapper = nil;
+ [searchBar release]; searchBar = nil;
+ [outlineButton release]; outlineButton = nil;
+ [searchButton release]; searchButton = nil;
+ [cancelButton release]; cancelButton = nil;
+ [prevButton release]; prevButton = nil;
+ [nextButton release]; nextButton = nil;
+ [canvas release]; canvas = nil;
+
+ [outline release];
+ [key release];
+ [super dealloc];
+}
+
+- (void) viewWillAppear: (BOOL)animated
+{
+ [self setTitle: [key lastPathComponent]];
+
+ [slider setValue: current];
+
+ [indicator setText: [NSString stringWithFormat: @" %d of %d ", current+1, fz_count_pages(doc)]];
+
+ [[self navigationController] setToolbarHidden: NO animated: animated];
+}
+
+- (void) viewWillLayoutSubviews
+{
+ CGSize size = [canvas frame].size;
+ int max_width = fz_max(width, size.width);
+
+ width = size.width;
+ height = size.height;
+
+ [canvas setContentInset: UIEdgeInsetsZero];
+ [canvas setContentSize: CGSizeMake(fz_count_pages(doc) * width, height)];
+ [canvas setContentOffset: CGPointMake(current * width, 0)];
+
+ [sliderWrapper setWidth: SLIDER_W];
+ [searchBar setFrame: CGRectMake(0,0,SEARCH_W,32)];
+
+ [[[self navigationController] toolbar] setNeedsLayout]; // force layout!
+
+ // use max_width so we don't clamp the content offset too early during animation
+ [canvas setContentSize: CGSizeMake(fz_count_pages(doc) * max_width, height)];
+ [canvas setContentOffset: CGPointMake(current * width, 0)];
+
+ for (MuPageView *view in [canvas subviews]) {
+ if ([view number] == current) {
+ [view setFrame: CGRectMake([view number] * width, 0, width-GAP, height)];
+ [view willRotate];
+ }
+ }
+ for (MuPageView *view in [canvas subviews]) {
+ if ([view number] != current) {
+ [view setFrame: CGRectMake([view number] * width, 0, width-GAP, height)];
+ [view willRotate];
+ }
+ }
+}
+
+- (void) viewDidAppear: (BOOL)animated
+{
+ [self scrollViewDidScroll: canvas];
+}
+
+- (void) viewWillDisappear: (BOOL)animated
+{
+ [self setTitle: @"Resume"];
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey: @"OpenDocumentKey"];
+ [[self navigationController] setToolbarHidden: YES animated: animated];
+}
+
+- (void) showNavigationBar
+{
+ if ([[self navigationController] isNavigationBarHidden]) {
+ [[self navigationController] setNavigationBarHidden: NO];
+ [[self navigationController] setToolbarHidden: NO];
+ [indicator setHidden: NO];
+
+ [UIView beginAnimations: @"MuNavBar" context: NULL];
+
+ [[[self navigationController] navigationBar] setAlpha: 1];
+ [[[self navigationController] toolbar] setAlpha: 1];
+ [indicator setAlpha: 1];
+
+ [UIView commitAnimations];
+ }
+}
+
+- (void) hideNavigationBar
+{
+ if (![[self navigationController] isNavigationBarHidden]) {
+ [searchBar resignFirstResponder];
+
+ [UIView beginAnimations: @"MuNavBar" context: NULL];
+ [UIView setAnimationDelegate: self];
+ [UIView setAnimationDidStopSelector: @selector(onHideNavigationBarFinished)];
+
+ [[[self navigationController] navigationBar] setAlpha: 0];
+ [[[self navigationController] toolbar] setAlpha: 0];
+ [indicator setAlpha: 0];
+
+ [UIView commitAnimations];
+ }
+}
+
+- (void) onHideNavigationBarFinished
+{
+ [[self navigationController] setNavigationBarHidden: YES];
+ [[self navigationController] setToolbarHidden: YES];
+ [indicator setHidden: YES];
+}
+
+- (void) onShowOutline: (id)sender
+{
+ [[self navigationController] pushViewController: outline animated: YES];
+}
+
+- (void) onToggleLinks: (id)sender
+{
+ showLinks = !showLinks;
+ for (MuPageView *view in [canvas subviews])
+ {
+ if (showLinks)
+ [view showLinks];
+ else
+ [view hideLinks];
+ }
+}
+
+- (void) onShowSearch: (id)sender
+{
+ [[self navigationItem] setTitleView: searchBar];
+ [[self navigationItem] setRightBarButtonItems:
+ [NSArray arrayWithObjects: nextButton, prevButton, nil]];
+ [[self navigationItem] setLeftBarButtonItem: cancelButton];
+ [searchBar becomeFirstResponder];
+}
+
+- (void) onCancelSearch: (id)sender
+{
+ cancelSearch = YES;
+ [searchBar resignFirstResponder];
+ [[self navigationItem] setTitleView: nil];
+ [[self navigationItem] setRightBarButtonItems:
+ [NSArray arrayWithObjects: searchButton, linkButton, outlineButton, nil]];
+ [[self navigationItem] setLeftBarButtonItem: nil];
+ [self resetSearch];
+}
+
+- (void) resetSearch
+{
+ searchPage = -1;
+ for (MuPageView *view in [canvas subviews])
+ [view clearSearchResults];
+}
+
+- (void) showSearchResults: (int)count forPage: (int)number
+{
+ printf("search found match on page %d\n", number);
+ searchPage = number;
+ [self gotoPage: number animated: NO];
+ for (MuPageView *view in [canvas subviews])
+ if ([view number] == number)
+ [view showSearchResults: count];
+ else
+ [view clearSearchResults];
+}
+
+- (void) searchInDirection: (int)dir
+{
+ UITextField *searchField;
+ char *needle;
+ int start;
+
+ [searchBar resignFirstResponder];
+
+ if (searchPage == current)
+ start = current + dir;
+ else
+ start = current;
+
+ needle = strdup([[searchBar text] UTF8String]);
+
+ searchField = nil;
+ for (id view in [searchBar subviews])
+ if ([view isKindOfClass: [UITextField class]])
+ searchField = view;
+
+ [prevButton setEnabled: NO];
+ [nextButton setEnabled: NO];
+ [searchField setEnabled: NO];
+
+ cancelSearch = NO;
+
+ dispatch_async(queue, ^{
+ for (int i = start; i >= 0 && i < fz_count_pages(doc); i += dir) {
+ int n = search_page(doc, i, needle, NULL);
+ if (n) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [prevButton setEnabled: YES];
+ [nextButton setEnabled: YES];
+ [searchField setEnabled: YES];
+ [self showSearchResults: n forPage: i];
+ free(needle);
+ });
+ return;
+ }
+ if (cancelSearch) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [prevButton setEnabled: YES];
+ [nextButton setEnabled: YES];
+ [searchField setEnabled: YES];
+ free(needle);
+ });
+ return;
+ }
+ }
+ dispatch_async(dispatch_get_main_queue(), ^{
+ printf("no search results found\n");
+ [prevButton setEnabled: YES];
+ [nextButton setEnabled: YES];
+ [searchField setEnabled: YES];
+ UIAlertView *alert = [[UIAlertView alloc]
+ initWithTitle: @"No matches found for:"
+ message: [NSString stringWithUTF8String: needle]
+ delegate: nil
+ cancelButtonTitle: @"Close"
+ otherButtonTitles: nil];
+ [alert show];
+ [alert release];
+ free(needle);
+ });
+ });
+}
+
+- (void) onSearchPrev: (id)sender
+{
+ [self searchInDirection: -1];
+}
+
+- (void) onSearchNext: (id)sender
+{
+ [self searchInDirection: 1];
+}
+
+- (void) searchBarSearchButtonClicked: (UISearchBar*)sender
+{
+ [self onSearchNext: sender];
+}
+
+- (void) searchBar: (UISearchBar*)sender textDidChange: (NSString*)searchText
+{
+ [self resetSearch];
+ if ([[searchBar text] length] > 0) {
+ [prevButton setEnabled: YES];
+ [nextButton setEnabled: YES];
+ } else {
+ [prevButton setEnabled: NO];
+ [nextButton setEnabled: NO];
+ }
+}
+
+- (void) onSlide: (id)sender
+{
+ int number = [slider value];
+ if ([slider isTracking])
+ [indicator setText: [NSString stringWithFormat: @" %d of %d ", number+1, fz_count_pages(doc)]];
+ else
+ [self gotoPage: number animated: NO];
+}
+
+- (void) onTap: (UITapGestureRecognizer*)sender
+{
+ CGPoint p = [sender locationInView: canvas];
+ CGPoint ofs = [canvas contentOffset];
+ float x0 = (width - GAP) / 5;
+ float x1 = (width - GAP) - x0;
+ p.x -= ofs.x;
+ p.y -= ofs.y;
+ if (p.x < x0) {
+ [self gotoPage: current-1 animated: YES];
+ } else if (p.x > x1) {
+ [self gotoPage: current+1 animated: YES];
+ } else {
+ if ([[self navigationController] isNavigationBarHidden])
+ [self showNavigationBar];
+ else
+ [self hideNavigationBar];
+ }
+}
+
+- (void) scrollViewWillBeginDragging: (UIScrollView *)scrollView
+{
+ [self hideNavigationBar];
+}
+
+- (void) scrollViewDidScroll: (UIScrollView*)scrollview
+{
+ if (width == 0)
+ return; // not visible yet
+
+ if (scroll_animating)
+ return; // don't mess with layout during animations
+
+ float x = [canvas contentOffset].x + width * 0.5f;
+ current = x / width;
+
+ [[NSUserDefaults standardUserDefaults] setInteger: current forKey: key];
+
+ [indicator setText: [NSString stringWithFormat: @" %d of %d ", current+1, fz_count_pages(doc)]];
+ [slider setValue: current];
+
+ // swap the distant page views out
+
+ NSMutableSet *invisiblePages = [[NSMutableSet alloc] init];
+ for (MuPageView *view in [canvas subviews]) {
+ if ([view number] != current)
+ [view resetZoomAnimated: YES];
+ if ([view number] < current - 2 || [view number] > current + 2)
+ [invisiblePages addObject: view];
+ }
+ for (MuPageView *view in invisiblePages)
+ [view removeFromSuperview];
+ [invisiblePages release]; // don't bother recycling them...
+
+ [self createPageView: current];
+ [self createPageView: current - 1];
+ [self createPageView: current + 1];
+
+ // reset search results when page has flipped
+ if (current != searchPage)
+ [self resetSearch];
+}
+
+- (void) createPageView: (int)number
+{
+ if (number < 0 || number >= fz_count_pages(doc))
+ return;
+ int found = 0;
+ for (MuPageView *view in [canvas subviews])
+ if ([view number] == number)
+ found = 1;
+ if (!found) {
+ MuPageView *view = [[MuPageView alloc] initWithFrame: CGRectMake(number * width, 0, width-GAP, height) document: doc page: number];
+ [canvas addSubview: view];
+ if (showLinks)
+ [view showLinks];
+ [view release];
+ }
+}
+
+- (void) gotoPage: (int)number animated: (BOOL)animated
+{
+ if (number < 0)
+ number = 0;
+ if (number >= fz_count_pages(doc))
+ number = fz_count_pages(doc) - 1;
+ if (current == number)
+ return;
+ if (animated) {
+ // setContentOffset:animated: does not use the normal animation
+ // framework. It also doesn't play nice with the tap gesture
+ // recognizer. So we do our own page flipping animation here.
+ // We must set the scroll_animating flag so that we don't create
+ // or remove subviews until after the animation, or they'll
+ // swoop in from origo during the animation.
+
+ scroll_animating = YES;
+ [UIView beginAnimations: @"MuScroll" context: NULL];
+ [UIView setAnimationDuration: 0.4];
+ [UIView setAnimationBeginsFromCurrentState: YES];
+ [UIView setAnimationDelegate: self];
+ [UIView setAnimationDidStopSelector: @selector(onGotoPageFinished)];
+
+ for (MuPageView *view in [canvas subviews])
+ [view resetZoomAnimated: NO];
+
+ [canvas setContentOffset: CGPointMake(number * width, 0)];
+ [slider setValue: number];
+ [indicator setText: [NSString stringWithFormat: @" %d of %d ", number+1, fz_count_pages(doc)]];
+
+ [UIView commitAnimations];
+ } else {
+ for (MuPageView *view in [canvas subviews])
+ [view resetZoomAnimated: NO];
+ [canvas setContentOffset: CGPointMake(number * width, 0)];
+ }
+ current = number;
+}
+
+- (void) onGotoPageFinished
+{
+ scroll_animating = NO;
+ [self scrollViewDidScroll: canvas];
+}
+
+- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o
+{
+ return YES;
+}
+
+- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation)o
+{
+ [canvas setContentSize: CGSizeMake(fz_count_pages(doc) * width, height)];
+ [canvas setContentOffset: CGPointMake(current * width, 0)];
+}
+
+@end
+
+#pragma mark -
+
+@implementation MuAppDelegate
+
+- (BOOL) application: (UIApplication*)application didFinishLaunchingWithOptions: (NSDictionary*)launchOptions
+{
+ NSString *filename;
+
+ queue = dispatch_queue_create("com.artifex.mupdf.queue", NULL);
+
+ // use at most 128M for resource cache
+ ctx = fz_new_context(NULL, NULL, 128<<20);
+
+ screenScale = [[UIScreen mainScreen] scale];
+
+ library = [[MuLibraryController alloc] initWithStyle: UITableViewStylePlain];
+
+ navigator = [[UINavigationController alloc] initWithRootViewController: library];
+ [[navigator navigationBar] setTranslucent: YES];
+ [[navigator toolbar] setTranslucent: YES];
+ [navigator setDelegate: self];
+
+ window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
+ [window setBackgroundColor: [UIColor scrollViewTexturedBackgroundColor]];
+ [window setRootViewController: navigator];
+ [window makeKeyAndVisible];
+
+ filename = [[NSUserDefaults standardUserDefaults] objectForKey: @"OpenDocumentKey"];
+ if (filename)
+ [library openDocument: filename];
+
+ filename = [launchOptions objectForKey: UIApplicationLaunchOptionsURLKey];
+ NSLog(@"urlkey = %@\n", filename);
+
+ return YES;
+}
+
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+ NSLog(@"openURL: %@\n", url);
+ if ([url isFileURL]) {
+ NSString *path = [url path];
+ NSString *dir = [NSString stringWithFormat: @"%@/Documents/", NSHomeDirectory()];
+ path = [path stringByReplacingOccurrencesOfString:@"/private" withString:@""];
+ path = [path stringByReplacingOccurrencesOfString:dir withString:@""];
+ NSLog(@"file relative path: %@\n", path);
+ [library openDocument:path];
+ return YES;
+ }
+ return NO;
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+ printf("applicationDidEnterBackground!\n");
+ [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+ printf("applicationWillEnterForeground!\n");
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+ printf("applicationDidBecomeActive!\n");
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ printf("applicationWillTerminate!\n");
+ [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
+{
+ printf("applicationDidReceiveMemoryWarning\n");
+}
+
+- (void) dealloc
+{
+ dispatch_release(queue);
+ [library release];
+ [navigator release];
+ [window release];
+ [super dealloc];
+}
+
+@end
+
+#pragma mark -
+
+int main(int argc, char *argv[])
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ int retVal = UIApplicationMain(argc, argv, nil, @"MuAppDelegate");
+ [pool release];
+ return retVal;
+}
diff --git a/platform/ios/x_alt_blue.png b/platform/ios/x_alt_blue.png
new file mode 100644
index 00000000..0ca9a6cc
--- /dev/null
+++ b/platform/ios/x_alt_blue.png
Binary files differ
diff --git a/platform/ios/x_alt_blue@2x.png b/platform/ios/x_alt_blue@2x.png
new file mode 100644
index 00000000..1cb67549
--- /dev/null
+++ b/platform/ios/x_alt_blue@2x.png
Binary files differ
diff --git a/platform/win32/README.txt b/platform/win32/README.txt
new file mode 100644
index 00000000..01915f8e
--- /dev/null
+++ b/platform/win32/README.txt
@@ -0,0 +1 @@
+This MSVC project needs the thirdparty sources to be in place.
diff --git a/platform/win32/generate.bat b/platform/win32/generate.bat
new file mode 100644
index 00000000..c10a9d8f
--- /dev/null
+++ b/platform/win32/generate.bat
@@ -0,0 +1,45 @@
+@echo off
+
+if not exist scripts/fontdump.c cd ..
+if not exist generated mkdir generated
+
+cl /nologo -Iinclude scripts/fontdump.c
+cl /nologo -Iinclude scripts/cmapdump.c
+cl /nologo -Iinclude scripts/cquote.c
+cl /nologo -Iinclude scripts/bin2hex.c
+
+if not exist fontdump.exe goto usage
+if not exist cmapdump.exe goto usage
+if not exist cquote.exe goto usage
+if not exist bin2hex.exe goto usage
+
+if not exist generated/gen_font_base14.h fontdump.exe generated/gen_font_base14.h fonts/Dingbats.cff fonts/NimbusMonL-Bold.cff fonts/NimbusMonL-BoldObli.cff fonts/NimbusMonL-Regu.cff fonts/NimbusMonL-ReguObli.cff fonts/NimbusRomNo9L-Medi.cff fonts/NimbusRomNo9L-MediItal.cff fonts/NimbusRomNo9L-Regu.cff fonts/NimbusRomNo9L-ReguItal.cff fonts/NimbusSanL-Bold.cff fonts/NimbusSanL-BoldItal.cff fonts/NimbusSanL-Regu.cff fonts/NimbusSanL-ReguItal.cff fonts/StandardSymL.cff
+
+if not exist generated/gen_font_droid.h fontdump.exe generated/gen_font_droid.h fonts/droid/DroidSans.ttf fonts/droid/DroidSansMono.ttf
+
+if not exist generated/gen_font_cjk.h fontdump.exe generated/gen_font_cjk.h fonts/droid/DroidSansFallback.ttf
+
+if not exist generated/gen_font_cjk_full.h fontdump.exe generated/gen_font_cjk_full.h fonts/droid/DroidSansFallbackFull.ttf
+
+if not exist generated/gen_cmap_cns.h cmapdump.exe generated/gen_cmap_cns.h cmaps/cns/Adobe-CNS1-UCS2 cmaps/cns/Adobe-CNS1-0 cmaps/cns/Adobe-CNS1-1 cmaps/cns/Adobe-CNS1-2 cmaps/cns/Adobe-CNS1-3 cmaps/cns/Adobe-CNS1-4 cmaps/cns/Adobe-CNS1-5 cmaps/cns/Adobe-CNS1-6 cmaps/cns/B5-H cmaps/cns/B5-V cmaps/cns/B5pc-H cmaps/cns/B5pc-V cmaps/cns/CNS-EUC-H cmaps/cns/CNS-EUC-V cmaps/cns/CNS1-H cmaps/cns/CNS1-V cmaps/cns/CNS2-H cmaps/cns/CNS2-V cmaps/cns/ETen-B5-H cmaps/cns/ETen-B5-V cmaps/cns/ETenms-B5-H cmaps/cns/ETenms-B5-V cmaps/cns/ETHK-B5-H cmaps/cns/ETHK-B5-V cmaps/cns/HKdla-B5-H cmaps/cns/HKdla-B5-V cmaps/cns/HKdlb-B5-H cmaps/cns/HKdlb-B5-V cmaps/cns/HKgccs-B5-H cmaps/cns/HKgccs-B5-V cmaps/cns/HKm314-B5-H cmaps/cns/HKm314-B5-V cmaps/cns/HKm471-B5-H cmaps/cns/HKm471-B5-V cmaps/cns/HKscs-B5-H cmaps/cns/HKscs-B5-V cmaps/cns/UniCNS-UCS2-H cmaps/cns/UniCNS-UCS2-V cmaps/cns/UniCNS-UTF16-H cmaps/cns/UniCNS-UTF16-V
+
+if not exist generated/gen_cmap_gb.h cmapdump.exe generated/gen_cmap_gb.h cmaps/gb/Adobe-GB1-UCS2 cmaps/gb/Adobe-GB1-0 cmaps/gb/Adobe-GB1-1 cmaps/gb/Adobe-GB1-2 cmaps/gb/Adobe-GB1-3 cmaps/gb/Adobe-GB1-4 cmaps/gb/Adobe-GB1-5 cmaps/gb/GB-EUC-H cmaps/gb/GB-EUC-V cmaps/gb/GB-H cmaps/gb/GB-V cmaps/gb/GBK-EUC-H cmaps/gb/GBK-EUC-V cmaps/gb/GBK2K-H cmaps/gb/GBK2K-V cmaps/gb/GBKp-EUC-H cmaps/gb/GBKp-EUC-V cmaps/gb/GBpc-EUC-H cmaps/gb/GBpc-EUC-V cmaps/gb/GBT-EUC-H cmaps/gb/GBT-EUC-V cmaps/gb/GBT-H cmaps/gb/GBT-V cmaps/gb/GBTpc-EUC-H cmaps/gb/GBTpc-EUC-V cmaps/gb/UniGB-UCS2-H cmaps/gb/UniGB-UCS2-V cmaps/gb/UniGB-UTF16-H cmaps/gb/UniGB-UTF16-V
+
+if not exist generated/gen_cmap_japan.h cmapdump.exe generated/gen_cmap_japan.h cmaps/japan/Adobe-Japan1-UCS2 cmaps/japan/78-EUC-H cmaps/japan/78-EUC-V cmaps/japan/78-H cmaps/japan/78-RKSJ-H cmaps/japan/78-RKSJ-V cmaps/japan/78-V cmaps/japan/78ms-RKSJ-H cmaps/japan/78ms-RKSJ-V cmaps/japan/83pv-RKSJ-H cmaps/japan/90ms-RKSJ-H cmaps/japan/90ms-RKSJ-V cmaps/japan/90msp-RKSJ-H cmaps/japan/90msp-RKSJ-V cmaps/japan/90pv-RKSJ-H cmaps/japan/90pv-RKSJ-V cmaps/japan/Add-H cmaps/japan/Add-RKSJ-H cmaps/japan/Add-RKSJ-V cmaps/japan/Add-V cmaps/japan/Adobe-Japan1-0 cmaps/japan/Adobe-Japan1-1 cmaps/japan/Adobe-Japan1-2 cmaps/japan/Adobe-Japan1-3 cmaps/japan/Adobe-Japan1-4 cmaps/japan/Adobe-Japan1-5 cmaps/japan/Adobe-Japan1-6 cmaps/japan/EUC-H cmaps/japan/EUC-V cmaps/japan/Ext-H cmaps/japan/Ext-RKSJ-H cmaps/japan/Ext-RKSJ-V cmaps/japan/Ext-V cmaps/japan/H cmaps/japan/Hankaku cmaps/japan/Hiragana cmaps/japan/Katakana cmaps/japan/NWP-H cmaps/japan/NWP-V cmaps/japan/RKSJ-H cmaps/japan/RKSJ-V cmaps/japan/Roman cmaps/japan/UniJIS-UCS2-H cmaps/japan/UniJIS-UCS2-HW-H cmaps/japan/UniJIS-UCS2-HW-V cmaps/japan/UniJIS-UCS2-V cmaps/japan/UniJISPro-UCS2-HW-V cmaps/japan/UniJISPro-UCS2-V cmaps/japan/V cmaps/japan/WP-Symbol cmaps/japan/Adobe-Japan2-0 cmaps/japan/Hojo-EUC-H cmaps/japan/Hojo-EUC-V cmaps/japan/Hojo-H cmaps/japan/Hojo-V cmaps/japan/UniHojo-UCS2-H cmaps/japan/UniHojo-UCS2-V cmaps/japan/UniHojo-UTF16-H cmaps/japan/UniHojo-UTF16-V cmaps/japan/UniJIS-UTF16-H cmaps/japan/UniJIS-UTF16-V
+
+if not exist generated/gen_cmap_korea.h cmapdump.exe generated/gen_cmap_korea.h cmaps/korea/Adobe-Korea1-UCS2 cmaps/korea/Adobe-Korea1-0 cmaps/korea/Adobe-Korea1-1 cmaps/korea/Adobe-Korea1-2 cmaps/korea/KSC-EUC-H cmaps/korea/KSC-EUC-V cmaps/korea/KSC-H cmaps/korea/KSC-Johab-H cmaps/korea/KSC-Johab-V cmaps/korea/KSC-V cmaps/korea/KSCms-UHC-H cmaps/korea/KSCms-UHC-HW-H cmaps/korea/KSCms-UHC-HW-V cmaps/korea/KSCms-UHC-V cmaps/korea/KSCpc-EUC-H cmaps/korea/KSCpc-EUC-V cmaps/korea/UniKS-UCS2-H cmaps/korea/UniKS-UCS2-V cmaps/korea/UniKS-UTF16-H cmaps/korea/UniKS-UTF16-V
+
+if not exist generated/gen_js_util.h cquote.exe generated/gen_js_util.h pdf/pdf_util.js
+
+if not exist generated/gen_adobe_ca.h bin2hex.exe generated/gen_adobe_ca.h certs/AdobeCA.p7c
+
+del cmapdump.obj fontdump.obj cquote.obj bin2hex.obj cmapdump.exe fontdump.exe cquote.exe bin2hex.exe
+
+goto fin
+
+:usage
+echo ERROR: Run this script in the mupdf directory.
+echo ERROR: Run this script in a Visual Studio command prompt.
+pause
+
+:fin
diff --git a/platform/win32/generated.vcproj b/platform/win32/generated.vcproj
new file mode 100644
index 00000000..4fef3694
--- /dev/null
+++ b/platform/win32/generated.vcproj
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="generated"
+ ProjectGUID="{A5053AA7-02E5-4903-B596-04F17AEB1526}"
+ Keyword="MakeFileProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="generate.bat"
+ ReBuildCommandLine="del /q ..\generated &amp;&amp; generate.bat"
+ CleanCommandLine="del /q ..\generated"
+ Output=""
+ PreprocessorDefinitions="WIN32;_DEBUG"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="generate.bat"
+ ReBuildCommandLine="del /q ..\generated &amp;&amp; generate.bat"
+ CleanCommandLine="del /q ..\generated"
+ Output="generated\cmap_cns.h"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="generate.bat"
+ ReBuildCommandLine="del /q ..\generated &amp;&amp; generate.bat"
+ CleanCommandLine="del /q ..\generated"
+ Output="generated\cmap_cns.h"
+ PreprocessorDefinitions="WIN32;_DEBUG"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\scripts\bin2hex.c"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\cmapdump.c"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\cquote.c"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\fontdump.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\scripts\jconfig.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\opj_config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\slimftmodules.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\slimftoptions.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="CMAPs"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <Filter
+ Name="cns"
+ >
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-0"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-1"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-3"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-4"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-5"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-6"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\Adobe-CNS1-UCS2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\B5pc-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\B5pc-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS1-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS1-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\CNS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETen-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETen-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETenms-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETenms-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETHK-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\ETHK-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKdla-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKdla-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKdlb-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKdlb-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKgccs-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKgccs-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKm314-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKm314-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKm471-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKm471-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKscs-B5-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\HKscs-B5-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\UniCNS-UCS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\UniCNS-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\UniCNS-UTF16-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\cns\UniCNS-UTF16-V"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="gb"
+ >
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-0"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-1"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-3"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-4"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-5"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\Adobe-GB1-UCS2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GB-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GB-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GB-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GB-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBK-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBK-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBK2K-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBK2K-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBKp-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBKp-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBpc-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBpc-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBT-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBT-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBT-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBT-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBTpc-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\GBTpc-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\UniGB-UCS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\UniGB-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\UniGB-UTF16-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\gb\UniGB-UTF16-V"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="japan"
+ >
+ <File
+ RelativePath="..\cmaps\japan\78-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78ms-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\78ms-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\83pv-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90ms-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90ms-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90msp-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90msp-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90pv-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\90pv-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Add-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Add-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Add-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Add-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-0"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-1"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-3"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-4"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-5"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-6"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan1-UCS2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Adobe-Japan2-0"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Ext-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Ext-RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Ext-RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Ext-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hankaku"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hiragana"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hojo-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hojo-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hojo-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Hojo-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Katakana"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\NWP-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\NWP-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\RKSJ-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\RKSJ-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\Roman"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniHojo-UCS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniHojo-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniHojo-UTF16-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniHojo-UTF16-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UCS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UCS2-HW-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UCS2-HW-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UTF16-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJIS-UTF16-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJISPro-UCS2-HW-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\UniJISPro-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\japan\WP-Symbol"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="korea"
+ >
+ <File
+ RelativePath="..\cmaps\korea\Adobe-Korea1-0"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\Adobe-Korea1-1"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\Adobe-Korea1-2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\Adobe-Korea1-UCS2"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-Johab-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-Johab-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCms-UHC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCms-UHC-HW-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCms-UHC-HW-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCms-UHC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCpc-EUC-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\KSCpc-EUC-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\UniKS-UCS2-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\UniKS-UCS2-V"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\UniKS-UTF16-H"
+ >
+ </File>
+ <File
+ RelativePath="..\cmaps\korea\UniKS-UTF16-V"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Fonts"
+ >
+ <File
+ RelativePath="..\fonts\Dingbats.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusMonL-Bold.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusMonL-BoldObli.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusMonL-Regu.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusMonL-ReguObli.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusRomNo9L-Medi.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusRomNo9L-MediItal.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusRomNo9L-Regu.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusRomNo9L-ReguItal.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusSanL-Bold.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusSanL-BoldItal.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusSanL-Regu.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\NimbusSanL-ReguItal.cff"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\StandardSymL.cff"
+ >
+ </File>
+ <Filter
+ Name="droid"
+ >
+ <File
+ RelativePath="..\fonts\droid\DroidSans.ttf"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\droid\DroidSansFallback.ttf"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\droid\DroidSansMono.ttf"
+ >
+ </File>
+ <File
+ RelativePath="..\fonts\droid\NOTICE"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/libmupdf-nov8.vcproj b/platform/win32/libmupdf-nov8.vcproj
new file mode 100644
index 00000000..108b82a5
--- /dev/null
+++ b/platform/win32/libmupdf-nov8.vcproj
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libmupdf-nov8"
+ ProjectGUID="{EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;&quot;..\thirdparty\jpeg&quot;;&quot;..\thirdparty\openjpeg\libopenjpeg&quot;;&quot;..\thirdparty\zlib&quot;;&quot;..\thirdparty\freetype\include&quot;;&quot;..\thirdparty\v8-3.9\include&quot;"
+ PreprocessorDefinitions="DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalLibraryDirectories=""
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ Description=""
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;&quot;..\thirdparty\v8-3.9\include&quot;"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;&quot;..\thirdparty\v8-3.9\include&quot;"
+ PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="pdf"
+ >
+ <File
+ RelativePath="..\pdf\pdf_js_none.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/libmupdf-v8.vcproj b/platform/win32/libmupdf-v8.vcproj
new file mode 100644
index 00000000..36b6ccd8
--- /dev/null
+++ b/platform/win32/libmupdf-v8.vcproj
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libmupdf-v8"
+ ProjectGUID="{2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;&quot;..\thirdparty\jpeg&quot;;&quot;..\thirdparty\openjpeg\libopenjpeg&quot;;&quot;..\thirdparty\zlib&quot;;&quot;..\thirdparty\freetype\include&quot;;&quot;..\thirdparty\v8-3.9\include&quot;"
+ PreprocessorDefinitions="DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalLibraryDirectories=""
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ Description=""
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;&quot;..\thirdparty\v8-3.9\include&quot;"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;&quot;..\thirdparty\v8-3.9\include&quot;"
+ PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="pdf"
+ >
+ <File
+ RelativePath="..\pdf\pdf_js.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_jsimp_cpp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_jsimp_cpp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_jsimp_v8.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
new file mode 100644
index 00000000..9bf997ec
--- /dev/null
+++ b/platform/win32/libmupdf.vcproj
@@ -0,0 +1,1003 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libmupdf"
+ ProjectGUID="{5F615F91-DFF8-4F05-BF48-6222B7D86519}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\ucdn;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ PreprocessorDefinitions="DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ Description="Generate CMap and Font source files"
+ CommandLine="generate.bat"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\ucdn;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\include;..\ucdn;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="pdf"
+ >
+ <File
+ RelativePath="..\pdf\data_encodings.h"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\data_glyphlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\mupdf-internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\mupdf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_annot.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_cmap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_cmap_load.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_cmap_parse.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_cmap_table.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_colorspace.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_crypt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_device.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_encoding.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_event.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_field.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_font.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_fontfile.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_form.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_function.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_image.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_interpret.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_lex.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_metrics.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_nametree.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_object.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_outline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_page.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_parse.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_pattern.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_repair.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_shade.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_store.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_stream.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_type3.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_unicode.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_write.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_xobject.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_xref.c"
+ >
+ </File>
+ <File
+ RelativePath="..\pdf\pdf_xref_aux.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="fitz"
+ >
+ <File
+ RelativePath="..\fitz\base_context.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_error.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_geometry.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_getopt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_hash.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_memory.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_string.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_time.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_trans.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\base_xml.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\crypt_aes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\crypt_arc4.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\crypt_md5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\crypt_sha2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\dev_bbox.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\dev_list.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\dev_null.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\dev_svg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\dev_trace.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\doc_document.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\doc_link.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\doc_outline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_basic.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_dctd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_faxd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_flate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_jbig2d.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_lzwd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\filt_predict.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\fitz-internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\fitz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\image_jpeg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\image_jpx.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\image_md5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\image_png.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\image_tiff.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\memento.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\memento.h"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_bitmap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_colorspace.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_font.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_func.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_halftone.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_image.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_path.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_pcl.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_pixmap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_pwg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_shade.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_store.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\res_text.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\stm_buffer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\stm_comp_buf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\stm_open.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\stm_output.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\stm_read.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\text_extract.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\text_output.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\text_paragraph.c"
+ >
+ </File>
+ <File
+ RelativePath="..\fitz\text_search.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="draw"
+ >
+ <File
+ RelativePath="..\draw\draw_affine.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_blend.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_device.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_edge.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_glyph.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_mesh.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_paint.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_path.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_simple_scale.c"
+ >
+ </File>
+ <File
+ RelativePath="..\draw\draw_unpack.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="ucdn"
+ >
+ <File
+ RelativePath="..\ucdn\ucdn.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="xps"
+ >
+ <File
+ RelativePath="..\xps\muxps-internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\muxps.h"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_common.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_doc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_glyphs.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_gradient.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_image.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_outline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_path.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_resource.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_tile.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_util.c"
+ >
+ </File>
+ <File
+ RelativePath="..\xps\xps_zip.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="cbz"
+ >
+ <File
+ RelativePath="..\cbz\mucbz.c"
+ >
+ </File>
+ <File
+ RelativePath="..\cbz\mucbz.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="image"
+ >
+ <File
+ RelativePath="..\image\muimage.c"
+ >
+ </File>
+ <File
+ RelativePath="..\image\muimage.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="api"
+ >
+ <Filter
+ Name="mupdf"
+ >
+ <File
+ RelativePath="..\include\mupdf\cbz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\image.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\memento.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\xps.h"
+ >
+ </File>
+ <Filter
+ Name="pdf"
+ >
+ <File
+ RelativePath="..\include\mupdf\pdf\annot.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\cmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\crypt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\document.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\event.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\field.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\font.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\javascript.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\object.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\output-pdf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\page.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\parse.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\widget.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\pdf\xref.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="fitz"
+ >
+ <File
+ RelativePath="..\include\mupdf\fitz\annotation.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\bitmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\buffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\colorspace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\compressed-buffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\context.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\crypt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\device.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\display-list.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\document.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\filter.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\font.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\function.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\getopt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\glyph-cache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\hash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\image.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\link.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\math.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\meta.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\outline.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output-pcl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output-png.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output-pnm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output-pwg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output-svg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\output.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\path.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\pixmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\shade.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\store.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\stream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\string.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\structured-text.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\system.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\text.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\transition.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\write-document.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\mupdf\fitz\xml.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/libthirdparty.vcproj b/platform/win32/libthirdparty.vcproj
new file mode 100644
index 00000000..32576cfe
--- /dev/null
+++ b/platform/win32/libthirdparty.vcproj
@@ -0,0 +1,1108 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libthirdparty"
+ ProjectGUID="{5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;;DEBUG=1;verbose=-1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;;verbose=-1"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include"
+ PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;;MEMENTO=1;DEBUG=1;verbose=-1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="libjpeg"
+ >
+ <File
+ RelativePath="..\thirdparty\jpeg\jaricom.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jcomapi.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdapimin.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdapistd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdarith.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdatadst.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdatasrc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdcoefct.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdcolor.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jddctmgr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdhuff.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdinput.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdmainct.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdmarker.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdmaster.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdmerge.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdpostct.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdsample.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jdtrans.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jerror.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jfdctflt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jfdctfst.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jfdctint.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jidctflt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jidctfst.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jidctint.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jmemmgr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jmemnobs.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jquant1.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jquant2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jpeg\jutils.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libjbig2dec"
+ >
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_arith.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_arith_iaid.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_arith_int.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_generic.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_halftone.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_huffman.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_image.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_metadata.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_mmr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_page.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_refinement.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_segment.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_symbol_dict.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\jbig2dec\jbig2_text.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libz"
+ >
+ <File
+ RelativePath="..\thirdparty\zlib\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\compress.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\trees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\uncompr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\zlib\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libopenjpeg"
+ >
+ <Filter
+ Name="openjp2"
+ >
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\bio.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\bio.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\cio.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\cio.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\dwt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\dwt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\event.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\event.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\function_list.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\function_list.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\image.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\image.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\indexbox_manager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\invert.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\invert.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\j2k.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\j2k.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\jp2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\jp2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\mct.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\mct.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\mqc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\mqc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_includes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_intmath.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_inttypes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_malloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\opj_stdint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\phix_manager.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\pi.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\pi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\ppix_manager.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\raw.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\raw.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t1.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t1.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t1_generate_luts.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t1_luts.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\t2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\tcd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\tcd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\tgt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\tgt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\thix_manager.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg\src\lib\openjp2\tpix_manager.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="libfreetype"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\src\cff\cff.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\psaux\psaux.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\pshinter\pshinter.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\psnames\psnames.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\raster\raster.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\sfnt\sfnt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\smooth\smooth.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\truetype\truetype.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\type1\type1.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\cid\type1cid.c"
+ >
+ </File>
+ <Filter
+ Name="base"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftbase.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftbbox.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftbitmap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftgasp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftglyph.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftinit.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftstroke.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftsynth.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftsystem.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\fttype1.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\src\base\ftxf86.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="include"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\include\ft2build.h"
+ >
+ </File>
+ <Filter
+ Name="freetype"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\freetype.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftadvanc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftbbox.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftbdf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftbitmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftbzip2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftcache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftchapters.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftcid.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\fterrdef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\fterrors.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftgasp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftglyph.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftgxval.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftgzip.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftimage.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftincrem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftlcdfil.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftlist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftlzw.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftmac.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftmm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftmodapi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftmoderr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftotval.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftoutln.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftpfr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftrender.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftsizes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftsnames.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftstroke.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftsynth.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftsystem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\fttrigon.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\fttypes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftwinfnt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ftxf86.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\t1tables.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ttnameid.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\tttables.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\tttags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\ttunpat.h"
+ >
+ </File>
+ <Filter
+ Name="config"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\config\ftconfig.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\config\ftheader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\config\ftmodule.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\config\ftoption.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\config\ftstdlib.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="internal"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\autohint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftcalc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftdebug.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftdriver.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftgloadr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftmemory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftobjs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftpic.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftrfork.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftserv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftstream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\fttrace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\ftvalid.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\psaux.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\pshints.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\sfnt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\t1types.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\tttypes.h"
+ >
+ </File>
+ <Filter
+ Name="services"
+ >
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svbdf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svcid.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svgldict.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svgxval.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svkern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svmm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svotval.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svpfr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svpostnm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svpscmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svpsinfo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svsfnt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svttcmap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svtteng.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svttglyf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svwinfnt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\freetype\include\freetype\internal\services\svxf86nm.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mudraw.vcproj b/platform/win32/mudraw.vcproj
new file mode 100644
index 00000000..6310fb06
--- /dev/null
+++ b/platform/win32/mudraw.vcproj
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mudraw"
+ ProjectGUID="{0B51171B-B10E-4EAC-8FFA-19226A1828A3}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\apps\mudraw.c"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mujstest-v8.vcproj b/platform/win32/mujstest-v8.vcproj
new file mode 100644
index 00000000..1b37bb12
--- /dev/null
+++ b/platform/win32/mujstest-v8.vcproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mujstest-v8"
+ ProjectGUID="{21E28758-E4D2-4B84-8EC5-B631CEE66B30}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/FORCE"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\Debug\lib\&quot;"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\Release\lib&quot;"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\Build\Debug\lib&quot;"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1;HAVE_OPENSSL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/FORCE"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib libeay32.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\Debug\lib\&quot;;..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="HAVE_OPENSSL"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib libeay32.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\release\lib\&quot;;..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\fitz\crypt_pkcs7.c"
+ >
+ <FileConfiguration
+ Name="DebugOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include;..\generated"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\apps\jstest_main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mupdf-v8.vcproj b/platform/win32/mupdf-v8.vcproj
new file mode 100644
index 00000000..c66c2d99
--- /dev/null
+++ b/platform/win32/mupdf-v8.vcproj
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mupdf-v8"
+ ProjectGUID="{9035A4F3-4219-45A5-985D-FBF4D9609713}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/FORCE"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\Debug\lib&quot;"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\Build\release\lib&quot;"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\Build\Debug\lib&quot;"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1;HAVE_OPENSSL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/FORCE"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib libeay32.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\build\Debug\lib&quot;;..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="HAVE_OPENSSL"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="v8_base.lib v8_snapshot.lib libeay32.lib ws2_32.lib winmm.lib"
+ AdditionalLibraryDirectories="&quot;..\thirdparty\v8-3.9\Build\release\lib&quot;;..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\fitz\crypt_pkcs7.c"
+ >
+ <FileConfiguration
+ Name="DebugOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include;..\generated"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\win_main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\win_res.rc"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mupdf.sln b/platform/win32/mupdf.sln
new file mode 100644
index 00000000..7b3de7fa
--- /dev/null
+++ b/platform/win32/mupdf.sln
@@ -0,0 +1,166 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf", "mupdf.vcproj", "{E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6} = {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthirdparty", "libthirdparty.vcproj", "{5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf", "libmupdf.vcproj", "{5F615F91-DFF8-4F05-BF48-6222B7D86519}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mudraw", "mudraw.vcproj", "{0B51171B-B10E-4EAC-8FFA-19226A1828A3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6} = {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutool", "mutool.vcproj", "{00811970-815B-4F64-BC9D-219078B1F3AA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6} = {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generated", "generated.vcproj", "{A5053AA7-02E5-4903-B596-04F17AEB1526}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf-v8", "libmupdf-v8.vcproj", "{2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf-v8", "mupdf-v8.vcproj", "{9035A4F3-4219-45A5-985D-FBF4D9609713}"
+ ProjectSection(ProjectDependencies) = postProject
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D} = {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mujstest-v8", "mujstest-v8.vcproj", "{21E28758-E4D2-4B84-8EC5-B631CEE66B30}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D} = {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf-nov8", "libmupdf-nov8.vcproj", "{EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ DebugOpenssl|Win32 = DebugOpenssl|Win32
+ Memento|Win32 = Memento|Win32
+ Release|Win32 = Release|Win32
+ ReleaseOpenssl|Win32 = ReleaseOpenssl|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Debug|Win32.Build.0 = Debug|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.DebugOpenssl|Win32.ActiveCfg = DebugOpenssl|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.DebugOpenssl|Win32.Build.0 = DebugOpenssl|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Memento|Win32.ActiveCfg = Memento|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Memento|Win32.Build.0 = Memento|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Release|Win32.ActiveCfg = Release|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.Release|Win32.Build.0 = Release|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.ReleaseOpenssl|Win32.ActiveCfg = ReleaseOpenssl|Win32
+ {E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}.ReleaseOpenssl|Win32.Build.0 = ReleaseOpenssl|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Debug|Win32.Build.0 = Debug|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Memento|Win32.ActiveCfg = Memento|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Memento|Win32.Build.0 = Memento|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Release|Win32.ActiveCfg = Release|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.Release|Win32.Build.0 = Release|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Debug|Win32.Build.0 = Debug|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Memento|Win32.ActiveCfg = Memento|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Memento|Win32.Build.0 = Memento|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Release|Win32.ActiveCfg = Release|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.Release|Win32.Build.0 = Release|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Debug|Win32.Build.0 = Debug|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Memento|Win32.ActiveCfg = Memento|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Memento|Win32.Build.0 = Memento|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Release|Win32.ActiveCfg = Release|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.Release|Win32.Build.0 = Release|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {0B51171B-B10E-4EAC-8FFA-19226A1828A3}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Debug|Win32.Build.0 = Debug|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Memento|Win32.ActiveCfg = Memento|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Memento|Win32.Build.0 = Memento|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Release|Win32.ActiveCfg = Release|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.Release|Win32.Build.0 = Release|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {00811970-815B-4F64-BC9D-219078B1F3AA}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Win32.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Win32.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Win32.Build.0 = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Win32.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Win32.Build.0 = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Debug|Win32.Build.0 = Debug|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Memento|Win32.ActiveCfg = Memento|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Memento|Win32.Build.0 = Memento|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Release|Win32.ActiveCfg = Release|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.Release|Win32.Build.0 = Release|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {2E5DAFDB-A060-4011-B760-32F6A3A4BC9D}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Debug|Win32.Build.0 = Debug|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.DebugOpenssl|Win32.ActiveCfg = DebugOpenssl|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.DebugOpenssl|Win32.Build.0 = DebugOpenssl|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Memento|Win32.ActiveCfg = Memento|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Memento|Win32.Build.0 = Memento|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Release|Win32.ActiveCfg = Release|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.Release|Win32.Build.0 = Release|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.ReleaseOpenssl|Win32.ActiveCfg = ReleaseOpenssl|Win32
+ {9035A4F3-4219-45A5-985D-FBF4D9609713}.ReleaseOpenssl|Win32.Build.0 = ReleaseOpenssl|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Debug|Win32.ActiveCfg = Debug|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Debug|Win32.Build.0 = Debug|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.DebugOpenssl|Win32.ActiveCfg = DebugOpenssl|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.DebugOpenssl|Win32.Build.0 = DebugOpenssl|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Memento|Win32.ActiveCfg = Memento|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Memento|Win32.Build.0 = Memento|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Release|Win32.ActiveCfg = Release|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.Release|Win32.Build.0 = Release|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.ReleaseOpenssl|Win32.ActiveCfg = ReleaseOpenssl|Win32
+ {21E28758-E4D2-4B84-8EC5-B631CEE66B30}.ReleaseOpenssl|Win32.Build.0 = ReleaseOpenssl|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Debug|Win32.Build.0 = Debug|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.DebugOpenssl|Win32.ActiveCfg = Debug|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.DebugOpenssl|Win32.Build.0 = Debug|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Memento|Win32.ActiveCfg = Memento|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Memento|Win32.Build.0 = Memento|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Release|Win32.ActiveCfg = Release|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.Release|Win32.Build.0 = Release|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
+ {EC81A9F3-88A6-4170-B7B4-C41CB789A7F6}.ReleaseOpenssl|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/platform/win32/mupdf.vcproj b/platform/win32/mupdf.vcproj
new file mode 100644
index 00000000..eca2df73
--- /dev/null
+++ b/platform/win32/mupdf.vcproj
@@ -0,0 +1,429 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mupdf"
+ ProjectGUID="{E74F29F0-FA43-4ADC-B92C-6AFA08E4A417}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="FT2_BUILD_LIBRARY;OPJ_STATIC;DEBUG=1;HAVE_OPENSSL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="libeay32.lib"
+ AdditionalLibraryDirectories="..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseOpenssl|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="HAVE_OPENSSL"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="libeay32.lib"
+ AdditionalLibraryDirectories="..\thirdparty\openssl\lib"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\fitz\crypt_pkcs7.c"
+ >
+ <FileConfiguration
+ Name="DebugOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include;..\generated"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseOpenssl|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\thirdparty\openssl\include"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfapp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\win_main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\win_res.rc"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mutool.vcproj b/platform/win32/mutool.vcproj
new file mode 100644
index 00000000..a208dbc6
--- /dev/null
+++ b/platform/win32/mutool.vcproj
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mutool"
+ ProjectGUID="{00811970-815B-4F64-BC9D-219078B1F3AA}"
+ RootNamespace="mupdf"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\apps\mutool.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfclean.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfextract.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfinfo.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfposter.c"
+ >
+ </File>
+ <File
+ RelativePath="..\apps\pdfshow.c"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/winrt/README.txt b/platform/winrt/README.txt
new file mode 100644
index 00000000..4beaefbf
--- /dev/null
+++ b/platform/winrt/README.txt
@@ -0,0 +1,39 @@
+This MSVC project needs the thirdparty sources to be in place.
+
+mupdf_cpp:
+
+This is the c++ viewer code, which creates and handles the UI.
+
+mupdfwinrt:
+
+This defines the WinRT interface to mupdf.
+There are two primary classes, mudocument and muctx.
+The viewer code should create a
+mudocument type and make use of the methods in
+this winRT class. The mupdocument class is a winRT
+class and the methods should be callable from
+C++, C#, Javascript etc.
+
+The muctx class interfaces to the mupdf API calls
+and pretty much uses standard c++ methods with
+the exception of the Windows types String and Point.
+
+mupdfwinrt lib is linked statically to the viewer
+code, but this could be set up as a DLL if desired.
+
+The libraries generated, libmupdf_winRT, libmupdf-nov8_winRT
+and libthridparty_winRT are essentially the same as those
+in the win32 project, however they are needed here for
+building with VS 2012 ARM target.
+
+Current Issues:
+
+Space/Tab needs to be reworked in files
+
+State needs to be saved during suspension
+
+Still needs additional error checking
+
+Needs progress bar during text search
+
+Help info needs to be populated
diff --git a/platform/winrt/generate.bat b/platform/winrt/generate.bat
new file mode 100644
index 00000000..c10a9d8f
--- /dev/null
+++ b/platform/winrt/generate.bat
@@ -0,0 +1,45 @@
+@echo off
+
+if not exist scripts/fontdump.c cd ..
+if not exist generated mkdir generated
+
+cl /nologo -Iinclude scripts/fontdump.c
+cl /nologo -Iinclude scripts/cmapdump.c
+cl /nologo -Iinclude scripts/cquote.c
+cl /nologo -Iinclude scripts/bin2hex.c
+
+if not exist fontdump.exe goto usage
+if not exist cmapdump.exe goto usage
+if not exist cquote.exe goto usage
+if not exist bin2hex.exe goto usage
+
+if not exist generated/gen_font_base14.h fontdump.exe generated/gen_font_base14.h fonts/Dingbats.cff fonts/NimbusMonL-Bold.cff fonts/NimbusMonL-BoldObli.cff fonts/NimbusMonL-Regu.cff fonts/NimbusMonL-ReguObli.cff fonts/NimbusRomNo9L-Medi.cff fonts/NimbusRomNo9L-MediItal.cff fonts/NimbusRomNo9L-Regu.cff fonts/NimbusRomNo9L-ReguItal.cff fonts/NimbusSanL-Bold.cff fonts/NimbusSanL-BoldItal.cff fonts/NimbusSanL-Regu.cff fonts/NimbusSanL-ReguItal.cff fonts/StandardSymL.cff
+
+if not exist generated/gen_font_droid.h fontdump.exe generated/gen_font_droid.h fonts/droid/DroidSans.ttf fonts/droid/DroidSansMono.ttf
+
+if not exist generated/gen_font_cjk.h fontdump.exe generated/gen_font_cjk.h fonts/droid/DroidSansFallback.ttf
+
+if not exist generated/gen_font_cjk_full.h fontdump.exe generated/gen_font_cjk_full.h fonts/droid/DroidSansFallbackFull.ttf
+
+if not exist generated/gen_cmap_cns.h cmapdump.exe generated/gen_cmap_cns.h cmaps/cns/Adobe-CNS1-UCS2 cmaps/cns/Adobe-CNS1-0 cmaps/cns/Adobe-CNS1-1 cmaps/cns/Adobe-CNS1-2 cmaps/cns/Adobe-CNS1-3 cmaps/cns/Adobe-CNS1-4 cmaps/cns/Adobe-CNS1-5 cmaps/cns/Adobe-CNS1-6 cmaps/cns/B5-H cmaps/cns/B5-V cmaps/cns/B5pc-H cmaps/cns/B5pc-V cmaps/cns/CNS-EUC-H cmaps/cns/CNS-EUC-V cmaps/cns/CNS1-H cmaps/cns/CNS1-V cmaps/cns/CNS2-H cmaps/cns/CNS2-V cmaps/cns/ETen-B5-H cmaps/cns/ETen-B5-V cmaps/cns/ETenms-B5-H cmaps/cns/ETenms-B5-V cmaps/cns/ETHK-B5-H cmaps/cns/ETHK-B5-V cmaps/cns/HKdla-B5-H cmaps/cns/HKdla-B5-V cmaps/cns/HKdlb-B5-H cmaps/cns/HKdlb-B5-V cmaps/cns/HKgccs-B5-H cmaps/cns/HKgccs-B5-V cmaps/cns/HKm314-B5-H cmaps/cns/HKm314-B5-V cmaps/cns/HKm471-B5-H cmaps/cns/HKm471-B5-V cmaps/cns/HKscs-B5-H cmaps/cns/HKscs-B5-V cmaps/cns/UniCNS-UCS2-H cmaps/cns/UniCNS-UCS2-V cmaps/cns/UniCNS-UTF16-H cmaps/cns/UniCNS-UTF16-V
+
+if not exist generated/gen_cmap_gb.h cmapdump.exe generated/gen_cmap_gb.h cmaps/gb/Adobe-GB1-UCS2 cmaps/gb/Adobe-GB1-0 cmaps/gb/Adobe-GB1-1 cmaps/gb/Adobe-GB1-2 cmaps/gb/Adobe-GB1-3 cmaps/gb/Adobe-GB1-4 cmaps/gb/Adobe-GB1-5 cmaps/gb/GB-EUC-H cmaps/gb/GB-EUC-V cmaps/gb/GB-H cmaps/gb/GB-V cmaps/gb/GBK-EUC-H cmaps/gb/GBK-EUC-V cmaps/gb/GBK2K-H cmaps/gb/GBK2K-V cmaps/gb/GBKp-EUC-H cmaps/gb/GBKp-EUC-V cmaps/gb/GBpc-EUC-H cmaps/gb/GBpc-EUC-V cmaps/gb/GBT-EUC-H cmaps/gb/GBT-EUC-V cmaps/gb/GBT-H cmaps/gb/GBT-V cmaps/gb/GBTpc-EUC-H cmaps/gb/GBTpc-EUC-V cmaps/gb/UniGB-UCS2-H cmaps/gb/UniGB-UCS2-V cmaps/gb/UniGB-UTF16-H cmaps/gb/UniGB-UTF16-V
+
+if not exist generated/gen_cmap_japan.h cmapdump.exe generated/gen_cmap_japan.h cmaps/japan/Adobe-Japan1-UCS2 cmaps/japan/78-EUC-H cmaps/japan/78-EUC-V cmaps/japan/78-H cmaps/japan/78-RKSJ-H cmaps/japan/78-RKSJ-V cmaps/japan/78-V cmaps/japan/78ms-RKSJ-H cmaps/japan/78ms-RKSJ-V cmaps/japan/83pv-RKSJ-H cmaps/japan/90ms-RKSJ-H cmaps/japan/90ms-RKSJ-V cmaps/japan/90msp-RKSJ-H cmaps/japan/90msp-RKSJ-V cmaps/japan/90pv-RKSJ-H cmaps/japan/90pv-RKSJ-V cmaps/japan/Add-H cmaps/japan/Add-RKSJ-H cmaps/japan/Add-RKSJ-V cmaps/japan/Add-V cmaps/japan/Adobe-Japan1-0 cmaps/japan/Adobe-Japan1-1 cmaps/japan/Adobe-Japan1-2 cmaps/japan/Adobe-Japan1-3 cmaps/japan/Adobe-Japan1-4 cmaps/japan/Adobe-Japan1-5 cmaps/japan/Adobe-Japan1-6 cmaps/japan/EUC-H cmaps/japan/EUC-V cmaps/japan/Ext-H cmaps/japan/Ext-RKSJ-H cmaps/japan/Ext-RKSJ-V cmaps/japan/Ext-V cmaps/japan/H cmaps/japan/Hankaku cmaps/japan/Hiragana cmaps/japan/Katakana cmaps/japan/NWP-H cmaps/japan/NWP-V cmaps/japan/RKSJ-H cmaps/japan/RKSJ-V cmaps/japan/Roman cmaps/japan/UniJIS-UCS2-H cmaps/japan/UniJIS-UCS2-HW-H cmaps/japan/UniJIS-UCS2-HW-V cmaps/japan/UniJIS-UCS2-V cmaps/japan/UniJISPro-UCS2-HW-V cmaps/japan/UniJISPro-UCS2-V cmaps/japan/V cmaps/japan/WP-Symbol cmaps/japan/Adobe-Japan2-0 cmaps/japan/Hojo-EUC-H cmaps/japan/Hojo-EUC-V cmaps/japan/Hojo-H cmaps/japan/Hojo-V cmaps/japan/UniHojo-UCS2-H cmaps/japan/UniHojo-UCS2-V cmaps/japan/UniHojo-UTF16-H cmaps/japan/UniHojo-UTF16-V cmaps/japan/UniJIS-UTF16-H cmaps/japan/UniJIS-UTF16-V
+
+if not exist generated/gen_cmap_korea.h cmapdump.exe generated/gen_cmap_korea.h cmaps/korea/Adobe-Korea1-UCS2 cmaps/korea/Adobe-Korea1-0 cmaps/korea/Adobe-Korea1-1 cmaps/korea/Adobe-Korea1-2 cmaps/korea/KSC-EUC-H cmaps/korea/KSC-EUC-V cmaps/korea/KSC-H cmaps/korea/KSC-Johab-H cmaps/korea/KSC-Johab-V cmaps/korea/KSC-V cmaps/korea/KSCms-UHC-H cmaps/korea/KSCms-UHC-HW-H cmaps/korea/KSCms-UHC-HW-V cmaps/korea/KSCms-UHC-V cmaps/korea/KSCpc-EUC-H cmaps/korea/KSCpc-EUC-V cmaps/korea/UniKS-UCS2-H cmaps/korea/UniKS-UCS2-V cmaps/korea/UniKS-UTF16-H cmaps/korea/UniKS-UTF16-V
+
+if not exist generated/gen_js_util.h cquote.exe generated/gen_js_util.h pdf/pdf_util.js
+
+if not exist generated/gen_adobe_ca.h bin2hex.exe generated/gen_adobe_ca.h certs/AdobeCA.p7c
+
+del cmapdump.obj fontdump.obj cquote.obj bin2hex.obj cmapdump.exe fontdump.exe cquote.exe bin2hex.exe
+
+goto fin
+
+:usage
+echo ERROR: Run this script in the mupdf directory.
+echo ERROR: Run this script in a Visual Studio command prompt.
+pause
+
+:fin
diff --git a/platform/winrt/generated.vcxproj b/platform/winrt/generated.vcxproj
new file mode 100644
index 00000000..11d2b479
--- /dev/null
+++ b/platform/winrt/generated.vcxproj
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|ARM">
+ <Configuration>Memento</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|Win32">
+ <Configuration>Memento</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A5053AA7-02E5-4903-B596-04F17AEB1526}</ProjectGuid>
+ <Keyword>MakeFileProj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>11.0.51106.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput>generated\cmap_cns.h</NMakeOutput>
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput>generated\cmap_cns.h</NMakeOutput>
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput>generated\cmap_cns.h</NMakeOutput>
+ <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'">
+ <NMakeBuildCommandLine>generate.bat</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine>del /q ..\generated &amp;&amp; generate.bat</NMakeReBuildCommandLine>
+ <NMakeCleanCommandLine>del /q ..\generated</NMakeCleanCommandLine>
+ <NMakeOutput>generated\cmap_cns.h</NMakeOutput>
+ <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\scripts\cmapdump.c" />
+ <ClCompile Include="..\scripts\cquote.c" />
+ <ClCompile Include="..\scripts\fontdump.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\scripts\jconfig.h" />
+ <ClInclude Include="..\scripts\opj_config.h" />
+ <ClInclude Include="..\scripts\slimftmodules.h" />
+ <ClInclude Include="..\scripts\slimftoptions.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cmaps\cns\Adobe-CNS1-0" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-1" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-2" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-3" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-4" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-5" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-6" />
+ <None Include="..\cmaps\cns\Adobe-CNS1-UCS2" />
+ <None Include="..\cmaps\cns\B5-H" />
+ <None Include="..\cmaps\cns\B5-V" />
+ <None Include="..\cmaps\cns\B5pc-H" />
+ <None Include="..\cmaps\cns\B5pc-V" />
+ <None Include="..\cmaps\cns\CNS-EUC-H" />
+ <None Include="..\cmaps\cns\CNS-EUC-V" />
+ <None Include="..\cmaps\cns\CNS1-H" />
+ <None Include="..\cmaps\cns\CNS1-V" />
+ <None Include="..\cmaps\cns\CNS2-H" />
+ <None Include="..\cmaps\cns\CNS2-V" />
+ <None Include="..\cmaps\cns\ETen-B5-H" />
+ <None Include="..\cmaps\cns\ETen-B5-V" />
+ <None Include="..\cmaps\cns\ETenms-B5-H" />
+ <None Include="..\cmaps\cns\ETenms-B5-V" />
+ <None Include="..\cmaps\cns\ETHK-B5-H" />
+ <None Include="..\cmaps\cns\ETHK-B5-V" />
+ <None Include="..\cmaps\cns\HKdla-B5-H" />
+ <None Include="..\cmaps\cns\HKdla-B5-V" />
+ <None Include="..\cmaps\cns\HKdlb-B5-H" />
+ <None Include="..\cmaps\cns\HKdlb-B5-V" />
+ <None Include="..\cmaps\cns\HKgccs-B5-H" />
+ <None Include="..\cmaps\cns\HKgccs-B5-V" />
+ <None Include="..\cmaps\cns\HKm314-B5-H" />
+ <None Include="..\cmaps\cns\HKm314-B5-V" />
+ <None Include="..\cmaps\cns\HKm471-B5-H" />
+ <None Include="..\cmaps\cns\HKm471-B5-V" />
+ <None Include="..\cmaps\cns\HKscs-B5-H" />
+ <None Include="..\cmaps\cns\HKscs-B5-V" />
+ <None Include="..\cmaps\cns\UniCNS-UCS2-H" />
+ <None Include="..\cmaps\cns\UniCNS-UCS2-V" />
+ <None Include="..\cmaps\cns\UniCNS-UTF16-H" />
+ <None Include="..\cmaps\cns\UniCNS-UTF16-V" />
+ <None Include="..\cmaps\gb\Adobe-GB1-0" />
+ <None Include="..\cmaps\gb\Adobe-GB1-1" />
+ <None Include="..\cmaps\gb\Adobe-GB1-2" />
+ <None Include="..\cmaps\gb\Adobe-GB1-3" />
+ <None Include="..\cmaps\gb\Adobe-GB1-4" />
+ <None Include="..\cmaps\gb\Adobe-GB1-5" />
+ <None Include="..\cmaps\gb\Adobe-GB1-UCS2" />
+ <None Include="..\cmaps\gb\GB-EUC-H" />
+ <None Include="..\cmaps\gb\GB-EUC-V" />
+ <None Include="..\cmaps\gb\GB-H" />
+ <None Include="..\cmaps\gb\GB-V" />
+ <None Include="..\cmaps\gb\GBK-EUC-H" />
+ <None Include="..\cmaps\gb\GBK-EUC-V" />
+ <None Include="..\cmaps\gb\GBK2K-H" />
+ <None Include="..\cmaps\gb\GBK2K-V" />
+ <None Include="..\cmaps\gb\GBKp-EUC-H" />
+ <None Include="..\cmaps\gb\GBKp-EUC-V" />
+ <None Include="..\cmaps\gb\GBpc-EUC-H" />
+ <None Include="..\cmaps\gb\GBpc-EUC-V" />
+ <None Include="..\cmaps\gb\GBT-EUC-H" />
+ <None Include="..\cmaps\gb\GBT-EUC-V" />
+ <None Include="..\cmaps\gb\GBT-H" />
+ <None Include="..\cmaps\gb\GBT-V" />
+ <None Include="..\cmaps\gb\GBTpc-EUC-H" />
+ <None Include="..\cmaps\gb\GBTpc-EUC-V" />
+ <None Include="..\cmaps\gb\UniGB-UCS2-H" />
+ <None Include="..\cmaps\gb\UniGB-UCS2-V" />
+ <None Include="..\cmaps\gb\UniGB-UTF16-H" />
+ <None Include="..\cmaps\gb\UniGB-UTF16-V" />
+ <None Include="..\cmaps\japan\78-EUC-H" />
+ <None Include="..\cmaps\japan\78-EUC-V" />
+ <None Include="..\cmaps\japan\78-H" />
+ <None Include="..\cmaps\japan\78-RKSJ-H" />
+ <None Include="..\cmaps\japan\78-RKSJ-V" />
+ <None Include="..\cmaps\japan\78-V" />
+ <None Include="..\cmaps\japan\78ms-RKSJ-H" />
+ <None Include="..\cmaps\japan\78ms-RKSJ-V" />
+ <None Include="..\cmaps\japan\83pv-RKSJ-H" />
+ <None Include="..\cmaps\japan\90ms-RKSJ-H" />
+ <None Include="..\cmaps\japan\90ms-RKSJ-V" />
+ <None Include="..\cmaps\japan\90msp-RKSJ-H" />
+ <None Include="..\cmaps\japan\90msp-RKSJ-V" />
+ <None Include="..\cmaps\japan\90pv-RKSJ-H" />
+ <None Include="..\cmaps\japan\90pv-RKSJ-V" />
+ <None Include="..\cmaps\japan\Add-H" />
+ <None Include="..\cmaps\japan\Add-RKSJ-H" />
+ <None Include="..\cmaps\japan\Add-RKSJ-V" />
+ <None Include="..\cmaps\japan\Add-V" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-0" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-1" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-2" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-3" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-4" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-5" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-6" />
+ <None Include="..\cmaps\japan\Adobe-Japan1-UCS2" />
+ <None Include="..\cmaps\japan\Adobe-Japan2-0" />
+ <None Include="..\cmaps\japan\EUC-H" />
+ <None Include="..\cmaps\japan\EUC-V" />
+ <None Include="..\cmaps\japan\Ext-H" />
+ <None Include="..\cmaps\japan\Ext-RKSJ-H" />
+ <None Include="..\cmaps\japan\Ext-RKSJ-V" />
+ <None Include="..\cmaps\japan\Ext-V" />
+ <None Include="..\cmaps\japan\H" />
+ <None Include="..\cmaps\japan\Hankaku" />
+ <None Include="..\cmaps\japan\Hiragana" />
+ <None Include="..\cmaps\japan\Hojo-EUC-H" />
+ <None Include="..\cmaps\japan\Hojo-EUC-V" />
+ <None Include="..\cmaps\japan\Hojo-H" />
+ <None Include="..\cmaps\japan\Hojo-V" />
+ <None Include="..\cmaps\japan\Katakana" />
+ <None Include="..\cmaps\japan\NWP-H" />
+ <None Include="..\cmaps\japan\NWP-V" />
+ <None Include="..\cmaps\japan\RKSJ-H" />
+ <None Include="..\cmaps\japan\RKSJ-V" />
+ <None Include="..\cmaps\japan\Roman" />
+ <None Include="..\cmaps\japan\UniHojo-UCS2-H" />
+ <None Include="..\cmaps\japan\UniHojo-UCS2-V" />
+ <None Include="..\cmaps\japan\UniHojo-UTF16-H" />
+ <None Include="..\cmaps\japan\UniHojo-UTF16-V" />
+ <None Include="..\cmaps\japan\UniJIS-UCS2-H" />
+ <None Include="..\cmaps\japan\UniJIS-UCS2-HW-H" />
+ <None Include="..\cmaps\japan\UniJIS-UCS2-HW-V" />
+ <None Include="..\cmaps\japan\UniJIS-UCS2-V" />
+ <None Include="..\cmaps\japan\UniJIS-UTF16-H" />
+ <None Include="..\cmaps\japan\UniJIS-UTF16-V" />
+ <None Include="..\cmaps\japan\UniJISPro-UCS2-HW-V" />
+ <None Include="..\cmaps\japan\UniJISPro-UCS2-V" />
+ <None Include="..\cmaps\japan\V" />
+ <None Include="..\cmaps\japan\WP-Symbol" />
+ <None Include="..\cmaps\korea\Adobe-Korea1-0" />
+ <None Include="..\cmaps\korea\Adobe-Korea1-1" />
+ <None Include="..\cmaps\korea\Adobe-Korea1-2" />
+ <None Include="..\cmaps\korea\Adobe-Korea1-UCS2" />
+ <None Include="..\cmaps\korea\KSC-EUC-H" />
+ <None Include="..\cmaps\korea\KSC-EUC-V" />
+ <None Include="..\cmaps\korea\KSC-H" />
+ <None Include="..\cmaps\korea\KSC-Johab-H" />
+ <None Include="..\cmaps\korea\KSC-Johab-V" />
+ <None Include="..\cmaps\korea\KSC-V" />
+ <None Include="..\cmaps\korea\KSCms-UHC-H" />
+ <None Include="..\cmaps\korea\KSCms-UHC-HW-H" />
+ <None Include="..\cmaps\korea\KSCms-UHC-HW-V" />
+ <None Include="..\cmaps\korea\KSCms-UHC-V" />
+ <None Include="..\cmaps\korea\KSCpc-EUC-H" />
+ <None Include="..\cmaps\korea\KSCpc-EUC-V" />
+ <None Include="..\cmaps\korea\UniKS-UCS2-H" />
+ <None Include="..\cmaps\korea\UniKS-UCS2-V" />
+ <None Include="..\cmaps\korea\UniKS-UTF16-H" />
+ <None Include="..\cmaps\korea\UniKS-UTF16-V" />
+ <None Include="..\fonts\Dingbats.cff" />
+ <None Include="..\fonts\NimbusMonL-Bold.cff" />
+ <None Include="..\fonts\NimbusMonL-BoldObli.cff" />
+ <None Include="..\fonts\NimbusMonL-Regu.cff" />
+ <None Include="..\fonts\NimbusMonL-ReguObli.cff" />
+ <None Include="..\fonts\NimbusRomNo9L-Medi.cff" />
+ <None Include="..\fonts\NimbusRomNo9L-MediItal.cff" />
+ <None Include="..\fonts\NimbusRomNo9L-Regu.cff" />
+ <None Include="..\fonts\NimbusRomNo9L-ReguItal.cff" />
+ <None Include="..\fonts\NimbusSanL-Bold.cff" />
+ <None Include="..\fonts\NimbusSanL-BoldItal.cff" />
+ <None Include="..\fonts\NimbusSanL-Regu.cff" />
+ <None Include="..\fonts\NimbusSanL-ReguItal.cff" />
+ <None Include="..\fonts\StandardSymL.cff" />
+ <None Include="..\fonts\droid\NOTICE" />
+ </ItemGroup>
+ <ItemGroup>
+ <Font Include="..\fonts\droid\DroidSans.ttf" />
+ <Font Include="..\fonts\droid\DroidSansFallback.ttf" />
+ <Font Include="..\fonts\droid\DroidSansMono.ttf" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/generated.vcxproj.filters b/platform/winrt/generated.vcxproj.filters
new file mode 100644
index 00000000..1a078e59
--- /dev/null
+++ b/platform/winrt/generated.vcxproj.filters
@@ -0,0 +1,568 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="CMAPs">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ <Filter Include="CMAPs\cns">
+ <UniqueIdentifier>{5129a522-0f9b-4dd3-aaf8-5b20b66060d8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CMAPs\gb">
+ <UniqueIdentifier>{75b3deb7-11ce-4813-b282-6dc1c099e669}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CMAPs\japan">
+ <UniqueIdentifier>{1706f021-1fce-4074-9299-6fd9c516c7ca}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CMAPs\korea">
+ <UniqueIdentifier>{f2a3739d-4175-47e4-9711-4a066e0f7094}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Fonts">
+ <UniqueIdentifier>{5168e64f-094a-43e0-b53f-83df3632d7ae}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Fonts\droid">
+ <UniqueIdentifier>{8462cde5-1461-408e-8708-d2b844cbb69d}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\scripts\cmapdump.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\scripts\cquote.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\scripts\fontdump.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\scripts\jconfig.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\scripts\opj_config.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\scripts\slimftmodules.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\scripts\slimftoptions.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\cmaps\cns\Adobe-CNS1-0">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-1">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-2">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-3">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-4">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-5">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-6">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\Adobe-CNS1-UCS2">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\B5pc-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\B5pc-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS-EUC-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS-EUC-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS1-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS1-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS2-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\CNS2-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETen-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETen-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETenms-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETenms-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETHK-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\ETHK-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKdla-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKdla-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKdlb-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKdlb-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKgccs-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKgccs-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKm314-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKm314-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKm471-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKm471-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKscs-B5-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\HKscs-B5-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\UniCNS-UCS2-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\UniCNS-UCS2-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\UniCNS-UTF16-H">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\cns\UniCNS-UTF16-V">
+ <Filter>CMAPs\cns</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-0">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-1">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-2">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-3">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-4">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-5">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\Adobe-GB1-UCS2">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GB-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GB-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GB-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GB-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBK-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBK-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBK2K-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBK2K-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBKp-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBKp-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBpc-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBpc-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBT-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBT-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBT-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBT-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBTpc-EUC-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\GBTpc-EUC-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\UniGB-UCS2-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\UniGB-UCS2-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\UniGB-UTF16-H">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\gb\UniGB-UTF16-V">
+ <Filter>CMAPs\gb</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-EUC-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-EUC-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78ms-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\78ms-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\83pv-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90ms-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90ms-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90msp-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90msp-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90pv-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\90pv-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Add-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Add-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Add-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Add-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-0">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-1">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-2">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-3">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-4">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-5">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-6">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan1-UCS2">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Adobe-Japan2-0">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\EUC-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\EUC-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Ext-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Ext-RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Ext-RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Ext-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hankaku">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hiragana">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hojo-EUC-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hojo-EUC-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hojo-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Hojo-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Katakana">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\NWP-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\NWP-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\RKSJ-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\RKSJ-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\Roman">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniHojo-UCS2-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniHojo-UCS2-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniHojo-UTF16-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniHojo-UTF16-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UCS2-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UCS2-HW-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UCS2-HW-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UCS2-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UTF16-H">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJIS-UTF16-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJISPro-UCS2-HW-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\UniJISPro-UCS2-V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\V">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\japan\WP-Symbol">
+ <Filter>CMAPs\japan</Filter>
+ </None>
+ <None Include="..\cmaps\korea\Adobe-Korea1-0">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\Adobe-Korea1-1">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\Adobe-Korea1-2">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\Adobe-Korea1-UCS2">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-EUC-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-EUC-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-Johab-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-Johab-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSC-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCms-UHC-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCms-UHC-HW-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCms-UHC-HW-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCms-UHC-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCpc-EUC-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\KSCpc-EUC-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\UniKS-UCS2-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\UniKS-UCS2-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\UniKS-UTF16-H">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\cmaps\korea\UniKS-UTF16-V">
+ <Filter>CMAPs\korea</Filter>
+ </None>
+ <None Include="..\fonts\Dingbats.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusMonL-Bold.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusMonL-BoldObli.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusMonL-Regu.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusMonL-ReguObli.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusRomNo9L-Medi.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusRomNo9L-MediItal.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusRomNo9L-Regu.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusRomNo9L-ReguItal.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusSanL-Bold.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusSanL-BoldItal.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusSanL-Regu.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\NimbusSanL-ReguItal.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\StandardSymL.cff">
+ <Filter>Fonts</Filter>
+ </None>
+ <None Include="..\fonts\droid\NOTICE">
+ <Filter>Fonts\droid</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Font Include="..\fonts\droid\DroidSans.ttf">
+ <Filter>Fonts\droid</Filter>
+ </Font>
+ <Font Include="..\fonts\droid\DroidSansFallback.ttf">
+ <Filter>Fonts\droid</Filter>
+ </Font>
+ <Font Include="..\fonts\droid\DroidSansMono.ttf">
+ <Filter>Fonts\droid</Filter>
+ </Font>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libmupdf-nov8_winRT.vcxproj b/platform/winrt/libmupdf-nov8_winRT.vcxproj
new file mode 100644
index 00000000..4c643aae
--- /dev/null
+++ b/platform/winrt/libmupdf-nov8_winRT.vcxproj
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|ARM">
+ <Configuration>Memento</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|Win32">
+ <Configuration>Memento</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|x64">
+ <Configuration>Memento</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\pdf\pdf_js_none.c" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{5affe821-c5c8-45fb-b834-10fed76e49a7}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>libmupdf-nov8_winRT</ProjectName>
+ <RootNamespace>libmupdf_nov8_winRT</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\include;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libmupdf-nov8_winRT.vcxproj.filters b/platform/winrt/libmupdf-nov8_winRT.vcxproj.filters
new file mode 100644
index 00000000..c0612d85
--- /dev/null
+++ b/platform/winrt/libmupdf-nov8_winRT.vcxproj.filters
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="pdf">
+ <UniqueIdentifier>{9cbc5d32-1ade-452f-9a40-cd43b9e313aa}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\pdf\pdf_js_none.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libmupdf_winRT.vcxproj b/platform/winrt/libmupdf_winRT.vcxproj
new file mode 100644
index 00000000..9db1732a
--- /dev/null
+++ b/platform/winrt/libmupdf_winRT.vcxproj
@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|ARM">
+ <Configuration>Memento</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|Win32">
+ <Configuration>Memento</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|x64">
+ <Configuration>Memento</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\cbz\mucbz.c" />
+ <ClCompile Include="..\draw\draw_affine.c" />
+ <ClCompile Include="..\draw\draw_blend.c" />
+ <ClCompile Include="..\draw\draw_device.c" />
+ <ClCompile Include="..\draw\draw_edge.c" />
+ <ClCompile Include="..\draw\draw_glyph.c" />
+ <ClCompile Include="..\draw\draw_mesh.c" />
+ <ClCompile Include="..\draw\draw_paint.c" />
+ <ClCompile Include="..\draw\draw_path.c" />
+ <ClCompile Include="..\draw\draw_simple_scale.c" />
+ <ClCompile Include="..\draw\draw_unpack.c" />
+ <ClCompile Include="..\fitz\base_context.c" />
+ <ClCompile Include="..\fitz\base_error.c" />
+ <ClCompile Include="..\fitz\base_geometry.c" />
+ <ClCompile Include="..\fitz\base_getopt.c" />
+ <ClCompile Include="..\fitz\base_hash.c" />
+ <ClCompile Include="..\fitz\base_memory.c" />
+ <ClCompile Include="..\fitz\base_string.c" />
+ <ClCompile Include="..\fitz\base_time.c" />
+ <ClCompile Include="..\fitz\base_trans.c" />
+ <ClCompile Include="..\fitz\base_xml.c" />
+ <ClCompile Include="..\fitz\crypt_aes.c" />
+ <ClCompile Include="..\fitz\crypt_arc4.c" />
+ <ClCompile Include="..\fitz\crypt_md5.c" />
+ <ClCompile Include="..\fitz\crypt_sha2.c" />
+ <ClCompile Include="..\fitz\dev_bbox.c" />
+ <ClCompile Include="..\fitz\dev_list.c" />
+ <ClCompile Include="..\fitz\dev_null.c" />
+ <ClCompile Include="..\fitz\dev_trace.c" />
+ <ClCompile Include="..\fitz\doc_document.c" />
+ <ClCompile Include="..\fitz\doc_link.c" />
+ <ClCompile Include="..\fitz\doc_outline.c" />
+ <ClCompile Include="..\fitz\filt_basic.c" />
+ <ClCompile Include="..\fitz\filt_dctd.c" />
+ <ClCompile Include="..\fitz\filt_faxd.c" />
+ <ClCompile Include="..\fitz\filt_flate.c" />
+ <ClCompile Include="..\fitz\filt_jbig2d.c" />
+ <ClCompile Include="..\fitz\filt_lzwd.c" />
+ <ClCompile Include="..\fitz\filt_predict.c" />
+ <ClCompile Include="..\fitz\image_jpeg.c" />
+ <ClCompile Include="..\fitz\image_jpx.c" />
+ <ClCompile Include="..\fitz\image_png.c" />
+ <ClCompile Include="..\fitz\image_tiff.c" />
+ <ClCompile Include="..\fitz\memento.c" />
+ <ClCompile Include="..\fitz\res_bitmap.c" />
+ <ClCompile Include="..\fitz\res_colorspace.c" />
+ <ClCompile Include="..\fitz\res_font.c" />
+ <ClCompile Include="..\fitz\res_func.c" />
+ <ClCompile Include="..\fitz\res_halftone.c" />
+ <ClCompile Include="..\fitz\res_image.c" />
+ <ClCompile Include="..\fitz\res_path.c" />
+ <ClCompile Include="..\fitz\res_pixmap.c" />
+ <ClCompile Include="..\fitz\res_shade.c" />
+ <ClCompile Include="..\fitz\res_store.c" />
+ <ClCompile Include="..\fitz\res_text.c" />
+ <ClCompile Include="..\fitz\stm_buffer.c" />
+ <ClCompile Include="..\fitz\stm_comp_buf.c" />
+ <ClCompile Include="..\fitz\stm_open.c" />
+ <ClCompile Include="..\fitz\stm_output.c" />
+ <ClCompile Include="..\fitz\stm_read.c" />
+ <ClCompile Include="..\fitz\text_extract.c" />
+ <ClCompile Include="..\fitz\text_output.c" />
+ <ClCompile Include="..\fitz\text_paragraph.c" />
+ <ClCompile Include="..\fitz\text_search.c" />
+ <ClCompile Include="..\image\muimage.c" />
+ <ClCompile Include="..\pdf\pdf_annot.c" />
+ <ClCompile Include="..\pdf\pdf_cmap.c" />
+ <ClCompile Include="..\pdf\pdf_cmap_load.c" />
+ <ClCompile Include="..\pdf\pdf_cmap_parse.c" />
+ <ClCompile Include="..\pdf\pdf_cmap_table.c" />
+ <ClCompile Include="..\pdf\pdf_colorspace.c" />
+ <ClCompile Include="..\pdf\pdf_crypt.c" />
+ <ClCompile Include="..\pdf\pdf_device.c" />
+ <ClCompile Include="..\pdf\pdf_encoding.c" />
+ <ClCompile Include="..\pdf\pdf_event.c" />
+ <ClCompile Include="..\pdf\pdf_field.c" />
+ <ClCompile Include="..\pdf\pdf_font.c" />
+ <ClCompile Include="..\pdf\pdf_fontfile.c" />
+ <ClCompile Include="..\pdf\pdf_form.c" />
+ <ClCompile Include="..\pdf\pdf_function.c" />
+ <ClCompile Include="..\pdf\pdf_image.c" />
+ <ClCompile Include="..\pdf\pdf_interpret.c" />
+ <ClCompile Include="..\pdf\pdf_lex.c" />
+ <ClCompile Include="..\pdf\pdf_metrics.c" />
+ <ClCompile Include="..\pdf\pdf_nametree.c" />
+ <ClCompile Include="..\pdf\pdf_object.c" />
+ <ClCompile Include="..\pdf\pdf_outline.c" />
+ <ClCompile Include="..\pdf\pdf_page.c" />
+ <ClCompile Include="..\pdf\pdf_parse.c" />
+ <ClCompile Include="..\pdf\pdf_pattern.c" />
+ <ClCompile Include="..\pdf\pdf_repair.c" />
+ <ClCompile Include="..\pdf\pdf_shade.c" />
+ <ClCompile Include="..\pdf\pdf_store.c" />
+ <ClCompile Include="..\pdf\pdf_stream.c" />
+ <ClCompile Include="..\pdf\pdf_type3.c" />
+ <ClCompile Include="..\pdf\pdf_unicode.c" />
+ <ClCompile Include="..\pdf\pdf_write.c" />
+ <ClCompile Include="..\pdf\pdf_xobject.c" />
+ <ClCompile Include="..\pdf\pdf_xref.c" />
+ <ClCompile Include="..\pdf\pdf_xref_aux.c" />
+ <ClCompile Include="..\ucdn\ucdn.c" />
+ <ClCompile Include="..\xps\xps_common.c" />
+ <ClCompile Include="..\xps\xps_doc.c" />
+ <ClCompile Include="..\xps\xps_glyphs.c" />
+ <ClCompile Include="..\xps\xps_gradient.c" />
+ <ClCompile Include="..\xps\xps_image.c" />
+ <ClCompile Include="..\xps\xps_outline.c" />
+ <ClCompile Include="..\xps\xps_path.c" />
+ <ClCompile Include="..\xps\xps_resource.c" />
+ <ClCompile Include="..\xps\xps_tile.c" />
+ <ClCompile Include="..\xps\xps_util.c" />
+ <ClCompile Include="..\xps\xps_zip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\cbz\mucbz.h" />
+ <ClInclude Include="..\fitz\fitz-internal.h" />
+ <ClInclude Include="..\fitz\fitz.h" />
+ <ClInclude Include="..\fitz\memento.h" />
+ <ClInclude Include="..\image\muimage.h" />
+ <ClInclude Include="..\pdf\data_encodings.h" />
+ <ClInclude Include="..\pdf\data_glyphlist.h" />
+ <ClInclude Include="..\pdf\mupdf-internal.h" />
+ <ClInclude Include="..\pdf\mupdf.h" />
+ <ClInclude Include="..\xps\muxps-internal.h" />
+ <ClInclude Include="..\xps\muxps.h" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0715f3cf-5d1b-4617-a331-6527371365b7}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>libmupdf_winRT</ProjectName>
+ <RootNamespace>libmupdf_winRT</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>MEMENTO=1;DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>MEMENTO=1;DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>MEMENTO=1;DEBUG=1;_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\ucdn;..\include;..\generated;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\src\lib\openjp2;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libmupdf_winRT.vcxproj.filters b/platform/winrt/libmupdf_winRT.vcxproj.filters
new file mode 100644
index 00000000..f2dfaec7
--- /dev/null
+++ b/platform/winrt/libmupdf_winRT.vcxproj.filters
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="cbz">
+ <UniqueIdentifier>{d78079b0-99b0-4ce6-b1ec-cc101aecfc0d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="draw">
+ <UniqueIdentifier>{18aad001-4979-4a53-885b-57b50c49d073}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="fitz">
+ <UniqueIdentifier>{31bd53e0-4b00-4f84-8c40-cb2c16a716e1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="pdf">
+ <UniqueIdentifier>{b16a1218-c130-43b1-b956-091542c365d6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="xps">
+ <UniqueIdentifier>{be1af520-39c9-4c25-938e-4c90e486c89c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="ucdn">
+ <UniqueIdentifier>{3e7ffbf1-2975-4b19-96d3-ed2e168c870e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="image">
+ <UniqueIdentifier>{726654cd-aa58-4ed2-90df-7e02c3615031}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\cbz\mucbz.c">
+ <Filter>cbz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_affine.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_blend.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_device.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_edge.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_glyph.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_mesh.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_paint.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_path.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_simple_scale.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\draw\draw_unpack.c">
+ <Filter>draw</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_context.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_error.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_geometry.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_getopt.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_hash.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_memory.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_string.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_time.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_trans.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\base_xml.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\crypt_aes.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\crypt_arc4.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\crypt_md5.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\crypt_sha2.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\dev_bbox.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\dev_list.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\dev_null.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\dev_trace.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\doc_document.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\doc_link.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\doc_outline.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_basic.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_dctd.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_faxd.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_flate.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_jbig2d.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_lzwd.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\filt_predict.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\image_jpeg.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\image_jpx.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\image_png.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\image_tiff.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\memento.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_bitmap.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_colorspace.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_font.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_halftone.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_path.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_pixmap.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_shade.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_store.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_text.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\stm_buffer.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\stm_comp_buf.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\stm_open.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\stm_output.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\stm_read.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_annot.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_cmap.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_cmap_load.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_cmap_parse.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_cmap_table.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_colorspace.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_crypt.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_device.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_encoding.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_event.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_font.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_fontfile.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_form.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_function.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_image.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_interpret.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_lex.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_metrics.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_nametree.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_object.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_outline.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_page.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_parse.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_pattern.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_repair.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_shade.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_store.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_stream.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_type3.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_unicode.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_write.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_xobject.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_xref.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_xref_aux.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_common.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_doc.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_glyphs.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_gradient.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_image.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_outline.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_path.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_resource.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_tile.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_util.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\xps\xps_zip.c">
+ <Filter>xps</Filter>
+ </ClCompile>
+ <ClCompile Include="..\pdf\pdf_field.c">
+ <Filter>pdf</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_func.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\text_extract.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\text_output.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\text_paragraph.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\text_search.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ucdn\ucdn.c">
+ <Filter>ucdn</Filter>
+ </ClCompile>
+ <ClCompile Include="..\fitz\res_image.c">
+ <Filter>fitz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\image\muimage.c">
+ <Filter>image</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\cbz\mucbz.h">
+ <Filter>cbz</Filter>
+ </ClInclude>
+ <ClInclude Include="..\fitz\fitz-internal.h">
+ <Filter>fitz</Filter>
+ </ClInclude>
+ <ClInclude Include="..\fitz\fitz.h">
+ <Filter>fitz</Filter>
+ </ClInclude>
+ <ClInclude Include="..\fitz\memento.h">
+ <Filter>fitz</Filter>
+ </ClInclude>
+ <ClInclude Include="..\pdf\data_encodings.h">
+ <Filter>pdf</Filter>
+ </ClInclude>
+ <ClInclude Include="..\pdf\data_glyphlist.h">
+ <Filter>pdf</Filter>
+ </ClInclude>
+ <ClInclude Include="..\pdf\mupdf-internal.h">
+ <Filter>pdf</Filter>
+ </ClInclude>
+ <ClInclude Include="..\pdf\mupdf.h">
+ <Filter>pdf</Filter>
+ </ClInclude>
+ <ClInclude Include="..\xps\muxps-internal.h">
+ <Filter>xps</Filter>
+ </ClInclude>
+ <ClInclude Include="..\xps\muxps.h">
+ <Filter>xps</Filter>
+ </ClInclude>
+ <ClInclude Include="..\image\muimage.h">
+ <Filter>image</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libthirdparty_winRT.vcxproj b/platform/winrt/libthirdparty_winRT.vcxproj
new file mode 100644
index 00000000..386f6d95
--- /dev/null
+++ b/platform/winrt/libthirdparty_winRT.vcxproj
@@ -0,0 +1,524 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|ARM">
+ <Configuration>Memento</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|Win32">
+ <Configuration>Memento</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Memento|x64">
+ <Configuration>Memento</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbase.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbbox.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbitmap.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftgasp.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftglyph.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftinit.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftstroke.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftsynth.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftsystem.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\fttype1.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftxf86.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\cff\cff.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\cid\type1cid.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\psaux\psaux.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\pshinter\pshinter.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\psnames\psnames.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\raster\raster.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\sfnt\sfnt.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\smooth\smooth.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\truetype\truetype.c" />
+ <ClCompile Include="..\thirdparty\freetype\src\type1\type1.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith_iaid.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith_int.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_generic.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_halftone.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_huffman.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_image.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_metadata.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_mmr.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_page.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_refinement.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_segment.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_symbol_dict.c" />
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_text.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jaricom.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jcomapi.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdapimin.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdapistd.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdarith.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdatadst.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdatasrc.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdcoefct.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdcolor.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jddctmgr.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdhuff.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdinput.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdmainct.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdmarker.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdmaster.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdmerge.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdpostct.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdsample.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jdtrans.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jerror.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jfdctflt.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jfdctfst.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jfdctint.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jidctflt.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jidctfst.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jidctint.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jmemmgr.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jmemnobs.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jquant1.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jquant2.c" />
+ <ClCompile Include="..\thirdparty\jpeg\jutils.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\bio.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\cio.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\dwt.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\event.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\function_list.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\image.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\invert.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\j2k.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\jp2.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\mct.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\mqc.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\phix_manager.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\pi.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\ppix_manager.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\raw.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t1.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t1_generate_luts.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t2.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tcd.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tgt.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\thix_manager.c" />
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tpix_manager.c" />
+ <ClCompile Include="..\thirdparty\zlib\adler32.c" />
+ <ClCompile Include="..\thirdparty\zlib\compress.c" />
+ <ClCompile Include="..\thirdparty\zlib\crc32.c" />
+ <ClCompile Include="..\thirdparty\zlib\deflate.c" />
+ <ClCompile Include="..\thirdparty\zlib\inffast.c" />
+ <ClCompile Include="..\thirdparty\zlib\inflate.c" />
+ <ClCompile Include="..\thirdparty\zlib\inftrees.c" />
+ <ClCompile Include="..\thirdparty\zlib\trees.c" />
+ <ClCompile Include="..\thirdparty\zlib\uncompr.c" />
+ <ClCompile Include="..\thirdparty\zlib\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftconfig.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftheader.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftmodule.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftoption.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftstdlib.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\freetype.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftadvanc.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbbox.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbdf.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbitmap.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbzip2.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftcache.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftchapters.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftcid.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fterrdef.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fterrors.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgasp.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftglyph.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgxval.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgzip.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftimage.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftincrem.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlcdfil.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlist.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlzw.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmac.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmm.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmodapi.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmoderr.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftotval.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftoutln.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftpfr.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftrender.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsizes.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsnames.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftstroke.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsynth.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsystem.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fttrigon.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fttypes.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftwinfnt.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftxf86.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\autohint.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftcalc.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftdebug.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftdriver.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftgloadr.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftmemory.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftobjs.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftpic.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftrfork.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftserv.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftstream.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\fttrace.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftvalid.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\internal.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\psaux.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\pshints.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svbdf.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svcid.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svgldict.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svgxval.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svkern.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svmm.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svotval.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpfr.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpostnm.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpscmap.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpsinfo.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svsfnt.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svttcmap.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svtteng.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svttglyf.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svwinfnt.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svxf86nm.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\sfnt.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\t1types.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\tttypes.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\t1tables.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ttnameid.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\tttables.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\tttags.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ttunpat.h" />
+ <ClInclude Include="..\thirdparty\freetype\include\ft2build.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\bio.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\cio.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\dwt.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\event.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\function_list.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\image.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\indexbox_manager.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\invert.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\j2k.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\jp2.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\mct.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\mqc.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_includes.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_intmath.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_inttypes.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_malloc.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_stdint.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\pi.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\raw.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t1.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t1_luts.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t2.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\tcd.h" />
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\tgt.h" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{c0d1c355-1bee-40e1-9ef4-fd9fffdbf396}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>libthirdparty_winRT</ProjectName>
+ <RootNamespace>libthirdparty_winRT</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Memento|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>false</SDLCheck>
+ <AdditionalIncludeDirectories>..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg;..\thirdparty\openjpeg\libopenjpeg;..\thirdparty\zlib;..\thirdparty\freetype\include;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WINRT;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H="slimftmodules.h";FT_CONFIG_OPTIONS_H="slimftoptions.h";DEBUG=1;verbose=-1;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/libthirdparty_winRT.vcxproj.filters b/platform/winrt/libthirdparty_winRT.vcxproj.filters
new file mode 100644
index 00000000..55f068b0
--- /dev/null
+++ b/platform/winrt/libthirdparty_winRT.vcxproj.filters
@@ -0,0 +1,684 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="libfreetype">
+ <UniqueIdentifier>{01b3001f-e457-469b-935e-a61e6bb80bea}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\base">
+ <UniqueIdentifier>{e719ccda-496e-44f1-a848-3f7e1ee5ec8d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\include">
+ <UniqueIdentifier>{be2b973e-2b42-45d9-9225-d017d1abd744}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\include\freetype">
+ <UniqueIdentifier>{b6fa3d37-cb6e-45ea-88de-530cb5b26c41}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\include\freetype\config">
+ <UniqueIdentifier>{7cc0c26e-d546-4a6b-a193-a7b0b88393d3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\include\freetype\internal">
+ <UniqueIdentifier>{2093ee27-7231-4db1-8764-40f4fe3dc8e8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libfreetype\include\freetype\internal\services">
+ <UniqueIdentifier>{993c585b-3680-4d68-9afd-dc921a0acd2d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libjbig2dec">
+ <UniqueIdentifier>{34f17a77-9d71-40b1-a18b-75b0704bddf0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libjpeg">
+ <UniqueIdentifier>{f0d06dd8-ab23-445f-82bd-b524f7206761}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libopenjpeg">
+ <UniqueIdentifier>{e6b91098-43cf-4337-8677-22b2c582785b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libz">
+ <UniqueIdentifier>{5e55ef18-6449-49c1-99aa-1cd88b6f4453}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="libopenjpeg\openjp2">
+ <UniqueIdentifier>{3a31ee2f-bdac-4091-a83f-7a6236269aaf}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\thirdparty\freetype\src\cff\cff.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\psaux\psaux.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\pshinter\pshinter.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\psnames\psnames.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\raster\raster.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\sfnt\sfnt.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\smooth\smooth.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\truetype\truetype.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\type1\type1.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\cid\type1cid.c">
+ <Filter>libfreetype</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbase.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbbox.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftbitmap.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftgasp.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftglyph.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftinit.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftstroke.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftsynth.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftsystem.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\fttype1.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\freetype\src\base\ftxf86.c">
+ <Filter>libfreetype\base</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith_iaid.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_arith_int.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_generic.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_halftone.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_huffman.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_image.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_metadata.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_mmr.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_page.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_refinement.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_segment.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_symbol_dict.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jbig2dec\jbig2_text.c">
+ <Filter>libjbig2dec</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jaricom.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jcomapi.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdapimin.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdapistd.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdarith.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdatadst.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdatasrc.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdcoefct.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdcolor.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jddctmgr.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdhuff.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdinput.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdmainct.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdmarker.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdmaster.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdmerge.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdpostct.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdsample.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jdtrans.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jerror.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jfdctflt.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jfdctfst.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jfdctint.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jidctflt.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jidctfst.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jidctint.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jmemmgr.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jmemnobs.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jquant1.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jquant2.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\jpeg\jutils.c">
+ <Filter>libjpeg</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\adler32.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\compress.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\crc32.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\deflate.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\inffast.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\inflate.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\inftrees.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\trees.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\uncompr.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\zlib\zutil.c">
+ <Filter>libz</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\phix_manager.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\pi.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\ppix_manager.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\raw.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t1.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t1_generate_luts.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\t2.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tcd.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tgt.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\thix_manager.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\tpix_manager.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\mct.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\mqc.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\dwt.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\event.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\function_list.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\image.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\invert.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\j2k.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\jp2.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\bio.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\thirdparty\openjpeg\src\lib\openjp2\cio.c">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\thirdparty\freetype\include\ft2build.h">
+ <Filter>libfreetype\include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\freetype.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftadvanc.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbbox.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbdf.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbitmap.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftbzip2.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftcache.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftchapters.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftcid.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fterrdef.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fterrors.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgasp.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftglyph.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgxval.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftgzip.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftimage.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftincrem.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlcdfil.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlist.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftlzw.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmac.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmm.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmodapi.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftmoderr.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftotval.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftoutln.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftpfr.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftrender.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsizes.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsnames.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftstroke.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsynth.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftsystem.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fttrigon.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\fttypes.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftwinfnt.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ftxf86.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\t1tables.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ttnameid.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\tttables.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\tttags.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\ttunpat.h">
+ <Filter>libfreetype\include\freetype</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftconfig.h">
+ <Filter>libfreetype\include\freetype\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftheader.h">
+ <Filter>libfreetype\include\freetype\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftmodule.h">
+ <Filter>libfreetype\include\freetype\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftoption.h">
+ <Filter>libfreetype\include\freetype\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\config\ftstdlib.h">
+ <Filter>libfreetype\include\freetype\config</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\autohint.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftcalc.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftdebug.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftdriver.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftgloadr.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftmemory.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftobjs.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftpic.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftrfork.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftserv.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftstream.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\fttrace.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\ftvalid.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\internal.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\psaux.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\pshints.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\sfnt.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\t1types.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\tttypes.h">
+ <Filter>libfreetype\include\freetype\internal</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svbdf.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svcid.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svgldict.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svgxval.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svkern.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svmm.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svotval.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpfr.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpostnm.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpscmap.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svpsinfo.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svsfnt.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svttcmap.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svtteng.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svttglyf.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svwinfnt.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\freetype\include\freetype\internal\services\svxf86nm.h">
+ <Filter>libfreetype\include\freetype\internal\services</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_includes.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_intmath.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_inttypes.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_malloc.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_stdint.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\pi.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\raw.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t1.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t1_luts.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\t2.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\tcd.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\tgt.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\mct.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\mqc.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\openjpeg.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\opj_clock.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\dwt.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\event.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\function_list.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\image.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\indexbox_manager.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\invert.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\j2k.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\jp2.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\bio.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\cidx_manager.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\thirdparty\openjpeg\src\lib\openjp2\cio.h">
+ <Filter>libopenjpeg\openjp2</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/mupdf.sln b/platform/winrt/mupdf.sln
new file mode 100644
index 00000000..b3abfadc
--- /dev/null
+++ b/platform/winrt/mupdf.sln
@@ -0,0 +1,266 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generated", "generated.vcxproj", "{A5053AA7-02E5-4903-B596-04F17AEB1526}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf_winRT", "libmupdf_winRT.vcxproj", "{0715F3CF-5D1B-4617-A331-6527371365B7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396} = {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}
+ {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf-nov8_winRT", "libmupdf-nov8_winRT.vcxproj", "{5AFFE821-C5C8-45FB-B834-10FED76E49A7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0715F3CF-5D1B-4617-A331-6527371365B7} = {0715F3CF-5D1B-4617-A331-6527371365B7}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthirdparty_winRT", "libthirdparty_winRT.vcxproj", "{C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdfwinrt", "mupdfwinrt\mupdfwinrt.vcxproj", "{9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7} = {5AFFE821-C5C8-45FB-B834-10FED76E49A7}
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396} = {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}
+ {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526}
+ {0715F3CF-5D1B-4617-A331-6527371365B7} = {0715F3CF-5D1B-4617-A331-6527371365B7}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf_cpp", "mupdf_cpp\mupdf_cpp.vcxproj", "{0204A4E7-F1B8-4268-A67C-A2C674B4742D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33} = {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Memento|Any CPU = Memento|Any CPU
+ Memento|ARM = Memento|ARM
+ Memento|Mixed Platforms = Memento|Mixed Platforms
+ Memento|Win32 = Memento|Win32
+ Memento|x64 = Memento|x64
+ Memento|x86 = Memento|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|ARM.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|ARM.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|Win32.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|x64.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|x86.ActiveCfg = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Debug|x86.Build.0 = Debug|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Any CPU.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|ARM.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Mixed Platforms.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Mixed Platforms.Build.0 = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|Win32.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|x64.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|x86.ActiveCfg = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Memento|x86.Build.0 = Memento|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Any CPU.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|ARM.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|ARM.Build.0 = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Win32.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|Win32.Build.0 = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|x64.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|x86.ActiveCfg = Release|Win32
+ {A5053AA7-02E5-4903-B596-04F17AEB1526}.Release|x86.Build.0 = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|ARM.ActiveCfg = Debug|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|ARM.Build.0 = Debug|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|Win32.Build.0 = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|x64.ActiveCfg = Debug|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|x64.Build.0 = Debug|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|x86.ActiveCfg = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Debug|x86.Build.0 = Debug|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|Any CPU.ActiveCfg = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|ARM.ActiveCfg = Memento|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|ARM.Build.0 = Memento|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|Mixed Platforms.ActiveCfg = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|Mixed Platforms.Build.0 = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|Win32.ActiveCfg = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|Win32.Build.0 = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|x64.ActiveCfg = Memento|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|x64.Build.0 = Memento|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|x86.ActiveCfg = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Memento|x86.Build.0 = Memento|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|Any CPU.ActiveCfg = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|ARM.ActiveCfg = Release|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|ARM.Build.0 = Release|ARM
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|Win32.ActiveCfg = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|Win32.Build.0 = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|x64.ActiveCfg = Release|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|x64.Build.0 = Release|x64
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|x86.ActiveCfg = Release|Win32
+ {0715F3CF-5D1B-4617-A331-6527371365B7}.Release|x86.Build.0 = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|ARM.ActiveCfg = Debug|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|ARM.Build.0 = Debug|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|Win32.Build.0 = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|x64.ActiveCfg = Debug|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|x64.Build.0 = Debug|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|x86.ActiveCfg = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Debug|x86.Build.0 = Debug|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|Any CPU.ActiveCfg = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|ARM.ActiveCfg = Memento|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|ARM.Build.0 = Memento|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|Mixed Platforms.ActiveCfg = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|Mixed Platforms.Build.0 = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|Win32.ActiveCfg = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|Win32.Build.0 = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|x64.ActiveCfg = Memento|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|x64.Build.0 = Memento|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|x86.ActiveCfg = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Memento|x86.Build.0 = Memento|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|Any CPU.ActiveCfg = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|ARM.ActiveCfg = Release|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|ARM.Build.0 = Release|ARM
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|Win32.ActiveCfg = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|Win32.Build.0 = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|x64.ActiveCfg = Release|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|x64.Build.0 = Release|x64
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|x86.ActiveCfg = Release|Win32
+ {5AFFE821-C5C8-45FB-B834-10FED76E49A7}.Release|x86.Build.0 = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|ARM.ActiveCfg = Debug|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|ARM.Build.0 = Debug|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|Win32.Build.0 = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|x64.ActiveCfg = Debug|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|x64.Build.0 = Debug|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|x86.ActiveCfg = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Debug|x86.Build.0 = Debug|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|Any CPU.ActiveCfg = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|ARM.ActiveCfg = Memento|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|ARM.Build.0 = Memento|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|Mixed Platforms.ActiveCfg = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|Mixed Platforms.Build.0 = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|Win32.ActiveCfg = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|Win32.Build.0 = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|x64.ActiveCfg = Memento|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|x64.Build.0 = Memento|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|x86.ActiveCfg = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Memento|x86.Build.0 = Memento|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|Any CPU.ActiveCfg = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|ARM.ActiveCfg = Release|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|ARM.Build.0 = Release|ARM
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|Win32.ActiveCfg = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|Win32.Build.0 = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|x64.ActiveCfg = Release|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|x64.Build.0 = Release|x64
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|x86.ActiveCfg = Release|Win32
+ {C0D1C355-1BEE-40E1-9EF4-FD9FFFDBF396}.Release|x86.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|ARM.ActiveCfg = Debug|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|ARM.Build.0 = Debug|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|Win32.Build.0 = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|x64.ActiveCfg = Debug|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|x64.Build.0 = Debug|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|x86.ActiveCfg = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Debug|x86.Build.0 = Debug|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|Any CPU.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|ARM.ActiveCfg = Release|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|ARM.Build.0 = Release|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|Mixed Platforms.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|Mixed Platforms.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|Win32.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|Win32.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|x64.ActiveCfg = Release|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|x64.Build.0 = Release|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|x86.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Memento|x86.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|Any CPU.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|ARM.ActiveCfg = Release|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|ARM.Build.0 = Release|ARM
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|Win32.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|Win32.Build.0 = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|x64.ActiveCfg = Release|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|x64.Build.0 = Release|x64
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|x86.ActiveCfg = Release|Win32
+ {9E6AB41D-09A7-45A6-A53B-1E4BF3AC5B33}.Release|x86.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|ARM.Build.0 = Debug|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|ARM.Deploy.0 = Debug|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Win32.Build.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|Win32.Deploy.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x64.ActiveCfg = Debug|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x64.Build.0 = Debug|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x64.Deploy.0 = Debug|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x86.ActiveCfg = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x86.Build.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Debug|x86.Deploy.0 = Debug|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Any CPU.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|ARM.ActiveCfg = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|ARM.Build.0 = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|ARM.Deploy.0 = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Mixed Platforms.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Mixed Platforms.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Mixed Platforms.Deploy.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Win32.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Win32.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|Win32.Deploy.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x64.ActiveCfg = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x64.Build.0 = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x64.Deploy.0 = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x86.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x86.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Memento|x86.Deploy.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Any CPU.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|ARM.ActiveCfg = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|ARM.Build.0 = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|ARM.Deploy.0 = Release|ARM
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Mixed Platforms.Deploy.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Win32.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Win32.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|Win32.Deploy.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x64.ActiveCfg = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x64.Build.0 = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x64.Deploy.0 = Release|x64
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x86.ActiveCfg = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x86.Build.0 = Release|Win32
+ {0204A4E7-F1B8-4268-A67C-A2C674B4742D}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/platform/winrt/mupdf_cpp/App.xaml b/platform/winrt/mupdf_cpp/App.xaml
new file mode 100644
index 00000000..dfb5d11c
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/App.xaml
@@ -0,0 +1,20 @@
+<Application
+ x:Class="mupdf_cpp.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="using:mupdf_cpp">
+
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+
+ <!--
+ Styles that define common aspects of the platform look and feel
+ Required by Visual Studio project and item templates
+ -->
+ <ResourceDictionary Source="Common/StandardStyles.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
diff --git a/platform/winrt/mupdf_cpp/App.xaml.cpp b/platform/winrt/mupdf_cpp/App.xaml.cpp
new file mode 100644
index 00000000..d0b9d8c7
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/App.xaml.cpp
@@ -0,0 +1,125 @@
+//
+// App.xaml.cpp
+// Implementation of the App class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+using namespace mupdf_cpp;
+
+using namespace Platform;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
+
+/// <summary>
+/// Initializes the singleton application object. This is the first line of authored code
+/// executed, and as such is the logical equivalent of main() or WinMain().
+/// </summary>
+App::App()
+{
+ InitializeComponent();
+ Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
+}
+
+/// <summary>
+/// Invoked when the application is launched normally by the end user. Other entry points
+/// will be used when the application is launched to open a specific file, to display
+/// search results, and so forth.
+/// </summary>
+/// <param name="args">Details about the launch request and process.</param>
+void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args)
+{
+ auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
+
+ // Do not repeat app initialization when the Window already has content,
+ // just ensure that the window is active
+ if (rootFrame == nullptr)
+ {
+ // Create a Frame to act as the navigation context and associate it with
+ // a SuspensionManager key
+ rootFrame = ref new Frame();
+
+ if (args->PreviousExecutionState == ApplicationExecutionState::Terminated)
+ {
+ // TODO: Restore the saved session state only when appropriate, scheduling the
+ // final launch steps after the restore is complete
+
+ }
+
+ if (rootFrame->Content == nullptr)
+ {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ if (!rootFrame->Navigate(TypeName(MainPage::typeid), args->Arguments))
+ {
+ throw ref new FailureException("Failed to create initial page");
+ }
+ }
+ // Place the frame in the current Window
+ Window::Current->Content = rootFrame;
+ auto rootPage = safe_cast<MainPage^>(rootFrame->Content);
+ rootPage->FileEvent = nullptr;
+ rootPage->ProtocolEvent = nullptr;
+
+ // Ensure the current window is active
+ Window::Current->Activate();
+ }
+ else
+ {
+ if (rootFrame->Content == nullptr)
+ {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ if (!rootFrame->Navigate(TypeName(MainPage::typeid), args->Arguments))
+ {
+ throw ref new FailureException("Failed to create initial page");
+ }
+ }
+ // Ensure the current window is active
+ Window::Current->Activate();
+ }
+}
+
+// Handle file activations.
+void App::OnFileActivated(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ args)
+{
+ auto rootFrame = ref new Frame();
+ TypeName pageType = { "mupdf_cpp.MainPage", TypeKind::Custom };
+ rootFrame->Navigate(pageType, args);
+ Window::Current->Content = rootFrame;
+ auto rootPage = safe_cast<MainPage^>(rootFrame->Content);
+ rootPage->FileEvent = args;
+ rootPage->ProtocolEvent = nullptr;
+
+ Window::Current->Activate();
+}
+
+/// <summary>
+/// Invoked when application execution is being suspended. Application state is saved
+/// without knowing whether the application will be terminated or resumed with the contents
+/// of memory still intact.
+/// </summary>
+/// <param name="sender">The source of the suspend request.</param>
+/// <param name="e">Details about the suspend request.</param>
+void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
+{
+ (void) sender; // Unused parameter
+ (void) e; // Unused parameter
+
+ //TODO: Save application state and stop any background activity
+}
diff --git a/platform/winrt/mupdf_cpp/App.xaml.h b/platform/winrt/mupdf_cpp/App.xaml.h
new file mode 100644
index 00000000..b62c9979
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/App.xaml.h
@@ -0,0 +1,24 @@
+//
+// App.xaml.h
+// Declaration of the App class.
+//
+
+#pragma once
+
+#include "App.g.h"
+
+namespace mupdf_cpp
+{
+ /// <summary>
+ /// Provides application-specific behavior to supplement the default Application class.
+ /// </summary>
+ ref class App sealed
+ {
+ public:
+ App();
+ virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ args) override;
+ virtual void App::OnFileActivated(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ args) override;
+ private:
+ void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
+ };
+}
diff --git a/platform/winrt/mupdf_cpp/Assets/Logo.Scale-100.png b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-100.png
new file mode 100644
index 00000000..821cb7d9
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-100.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/Logo.Scale-140.png b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-140.png
new file mode 100644
index 00000000..94eb9b67
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-140.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/Logo.Scale-180.png b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-180.png
new file mode 100644
index 00000000..44354901
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-180.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/Logo.Scale-80.png b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-80.png
new file mode 100644
index 00000000..165bda7a
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/Logo.Scale-80.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-100.png b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-100.png
new file mode 100644
index 00000000..5b5635e9
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-100.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-140.png b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-140.png
new file mode 100644
index 00000000..2813a863
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-140.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-180.png b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-180.png
new file mode 100644
index 00000000..1908837d
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/StoreLogo.scale-180.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-100.png b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-100.png
new file mode 100644
index 00000000..9497ffb5
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-100.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-140.png b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-140.png
new file mode 100644
index 00000000..1c6cd7a0
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-140.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-180.png b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-180.png
new file mode 100644
index 00000000..7d3391f8
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-180.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-80.png b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-80.png
new file mode 100644
index 00000000..471efbda
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/WideLogo.scale-80.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/mupdf_smallogo.png b/platform/winrt/mupdf_cpp/Assets/mupdf_smallogo.png
new file mode 100644
index 00000000..48746c87
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/mupdf_smallogo.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Assets/mupdf_splash.png b/platform/winrt/mupdf_cpp/Assets/mupdf_splash.png
new file mode 100644
index 00000000..624f9ae9
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Assets/mupdf_splash.png
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/Common/StandardStyles.xaml b/platform/winrt/mupdf_cpp/Common/StandardStyles.xaml
new file mode 100644
index 00000000..771d773c
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Common/StandardStyles.xaml
@@ -0,0 +1,1889 @@
+<!--
+ This file contains XAML styles that simplify application development.
+
+ These are not merely convenient, but are required by most Visual Studio project and item templates.
+ Removing, renaming, or otherwise modifying the content of these files may result in a project that
+ does not build, or that will not build once additional pages are added. If variations on these
+ styles are desired it is recommended that you copy the content under a new name and modify your
+ private copy.
+-->
+
+<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+ <!-- Non-brush values that vary across themes -->
+
+ <ResourceDictionary.ThemeDictionaries>
+ <ResourceDictionary x:Key="Default">
+ <x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
+ <x:String x:Key="BackButtonSnappedGlyph">&#xE0BA;</x:String>
+ </ResourceDictionary>
+
+ <ResourceDictionary x:Key="HighContrast">
+ <x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
+ <x:String x:Key="BackButtonSnappedGlyph">&#xE0C4;</x:String>
+ </ResourceDictionary>
+ </ResourceDictionary.ThemeDictionaries>
+
+ <x:String x:Key="ChevronGlyph">&#xE26B;</x:String>
+
+ <!-- RichTextBlock styles -->
+
+ <Style x:Key="BasicRichTextStyle" TargetType="RichTextBlock">
+ <Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
+ <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
+ <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
+ <Setter Property="TextTrimming" Value="WordEllipsis"/>
+ <Setter Property="TextWrapping" Value="Wrap"/>
+ <Setter Property="Typography.StylisticSet20" Value="True"/>
+ <Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
+ <Setter Property="Typography.CaseSensitiveForms" Value="True"/>
+ </Style>
+
+ <Style x:Key="BaselineRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BasicRichTextStyle}">
+ <Setter Property="LineHeight" Value="20"/>
+ <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
+ <!-- Properly align text along its baseline -->
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <TranslateTransform X="-1" Y="4"/>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="ItemRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}"/>
+
+ <Style x:Key="BodyRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}">
+ <Setter Property="FontWeight" Value="SemiLight"/>
+ </Style>
+
+ <!-- TextBlock styles -->
+
+ <Style x:Key="BasicTextStyle" TargetType="TextBlock">
+ <Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
+ <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
+ <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
+ <Setter Property="TextTrimming" Value="WordEllipsis"/>
+ <Setter Property="TextWrapping" Value="Wrap"/>
+ <Setter Property="Typography.StylisticSet20" Value="True"/>
+ <Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
+ <Setter Property="Typography.CaseSensitiveForms" Value="True"/>
+ </Style>
+
+ <Style x:Key="BaselineTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BasicTextStyle}">
+ <Setter Property="LineHeight" Value="20"/>
+ <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
+ <!-- Properly align text along its baseline -->
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <TranslateTransform X="-1" Y="4"/>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="HeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontSize" Value="56"/>
+ <Setter Property="FontWeight" Value="Light"/>
+ <Setter Property="LineHeight" Value="40"/>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <TranslateTransform X="-2" Y="8"/>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="SubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontSize" Value="26.667"/>
+ <Setter Property="FontWeight" Value="Light"/>
+ <Setter Property="LineHeight" Value="30"/>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <TranslateTransform X="-1" Y="6"/>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="TitleTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontWeight" Value="SemiBold"/>
+ </Style>
+
+ <Style x:Key="SubtitleTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontWeight" Value="Normal"/>
+ </Style>
+
+ <Style x:Key="ItemTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}"/>
+
+ <Style x:Key="BodyTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontWeight" Value="SemiLight"/>
+ </Style>
+
+ <Style x:Key="CaptionTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+ <Setter Property="FontSize" Value="12"/>
+ <Setter Property="Foreground" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
+ </Style>
+
+ <Style x:Key="GroupHeaderTextStyle" TargetType="TextBlock">
+ <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
+ <Setter Property="TextTrimming" Value="WordEllipsis"/>
+ <Setter Property="TextWrapping" Value="NoWrap"/>
+ <Setter Property="Typography.StylisticSet20" Value="True"/>
+ <Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
+ <Setter Property="Typography.CaseSensitiveForms" Value="True"/>
+ <Setter Property="FontSize" Value="26.667"/>
+ <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
+ <Setter Property="FontWeight" Value="Light"/>
+ <Setter Property="LineHeight" Value="30"/>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <TranslateTransform X="-1" Y="6"/>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!-- Button styles -->
+
+ <!--
+ TextButtonStyle is used to style a Button using subheader-styled text with no other adornment. There
+ are two styles that are based on TextButtonStyle (TextPrimaryButtonStyle and TextSecondaryButtonStyle)
+ which are used in the GroupedItemsPage as a group header and in the FileOpenPickerPage for triggering
+ commands.
+ -->
+ <Style x:Key="TextButtonStyle" TargetType="ButtonBase">
+ <Setter Property="MinWidth" Value="0"/>
+ <Setter Property="MinHeight" Value="0"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ButtonBase">
+ <Grid Background="Transparent">
+ <ContentPresenter x:Name="Text" Content="{TemplateBinding Content}" />
+ <Rectangle
+ x:Name="FocusVisualWhite"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="1.5"/>
+ <Rectangle
+ x:Name="FocusVisualBlack"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="0.5"/>
+ <VisualStateManager.VisualStateGroups>
+ <VisualStateGroup x:Name="CommonStates">
+ <VisualState x:Name="Normal"/>
+ <VisualState x:Name="PointerOver">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Pressed">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Disabled">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="FocusStates">
+ <VisualState x:Name="Focused">
+ <Storyboard>
+ <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity"/>
+ <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Unfocused"/>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="CheckStates">
+ <VisualState x:Name="Checked"/>
+ <VisualState x:Name="Unchecked">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Indeterminate"/>
+ </VisualStateGroup>
+ </VisualStateManager.VisualStateGroups>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="TextPrimaryButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource TextButtonStyle}">
+ <Setter Property="Foreground" Value="{StaticResource ApplicationHeaderForegroundThemeBrush}"/>
+ </Style>
+
+ <Style x:Key="TextSecondaryButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource TextButtonStyle}">
+ <Setter Property="Foreground" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
+ </Style>
+
+ <!--
+ TextRadioButtonStyle is used to style a RadioButton using subheader-styled text with no other adornment.
+ This style is used in the SearchResultsPage to allow selection among filters.
+ -->
+ <Style x:Key="TextRadioButtonStyle" TargetType="RadioButton" BasedOn="{StaticResource TextButtonStyle}">
+ <Setter Property="Margin" Value="0,0,30,0"/>
+ </Style>
+
+ <!--
+ AppBarButtonStyle is used to style a Button (or ToggleButton) for use in an App Bar. Content will be centered
+ and should fit within the 40 pixel radius glyph provided. 16-point Segoe UI Symbol is used for content text
+ to simplify the use of glyphs from that font. AutomationProperties.Name is used for the text below the glyph.
+ -->
+ <Style x:Key="AppBarButtonStyle" TargetType="ButtonBase">
+ <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+ <Setter Property="VerticalAlignment" Value="Stretch"/>
+ <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+ <Setter Property="FontWeight" Value="Normal"/>
+ <Setter Property="FontSize" Value="20"/>
+ <Setter Property="AutomationProperties.ItemType" Value="App Bar Button"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ButtonBase">
+ <Grid x:Name="RootGrid" Width="100" Background="Transparent">
+ <StackPanel VerticalAlignment="Top" Margin="0,12,0,11">
+ <Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
+ <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>
+ <TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
+ <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
+ </Grid>
+ <TextBlock
+ x:Name="TextLabel"
+ Text="{TemplateBinding AutomationProperties.Name}"
+ Foreground="{StaticResource AppBarItemForegroundThemeBrush}"
+ Margin="0,0,2,0"
+ FontSize="12"
+ TextAlignment="Center"
+ Width="88"
+ MaxHeight="32"
+ TextTrimming="WordEllipsis"
+ Style="{StaticResource BasicTextStyle}"/>
+ </StackPanel>
+ <Rectangle
+ x:Name="FocusVisualWhite"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="1.5"/>
+ <Rectangle
+ x:Name="FocusVisualBlack"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="0.5"/>
+
+ <VisualStateManager.VisualStateGroups>
+ <VisualStateGroup x:Name="ApplicationViewStates">
+ <VisualState x:Name="FullScreenLandscape"/>
+ <VisualState x:Name="Filled"/>
+ <VisualState x:Name="FullScreenPortrait">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Width">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Snapped">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Width">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="CommonStates">
+ <VisualState x:Name="Normal"/>
+ <VisualState x:Name="PointerOver">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Pressed">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Disabled">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="FocusStates">
+ <VisualState x:Name="Focused">
+ <Storyboard>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualWhite"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualBlack"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Unfocused" />
+ <VisualState x:Name="PointerFocused" />
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="CheckStates">
+ <VisualState x:Name="Checked">
+ <Storyboard>
+ <DoubleAnimation Duration="0" To="0" Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Opacity"/>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Visibility">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Unchecked"/>
+ <VisualState x:Name="Indeterminate"/>
+ </VisualStateGroup>
+ </VisualStateManager.VisualStateGroups>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!--
+ Standard AppBarButton Styles for use with Button and ToggleButton
+
+ An AppBarButton Style is provided for each of the glyphs in the Segoe UI Symbol font.
+ Uncomment any style you reference (as not all may be required).
+ -->
+ <Style x:Key="HelpAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Help"/>
+ <Setter Property="Content" Value="&#xE11B;"/>
+ </Style>
+ <Style x:Key="SearchAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SearchAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Search"/>
+ <Setter Property="Content" Value="&#xE11A;"/>
+ </Style>
+ <Style x:Key="OpenFileAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OpenFileAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Open File"/>
+ <Setter Property="Content" Value="&#xE1A5;"/>
+ </Style>
+ <Style x:Key="NextAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NextAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Next"/>
+ <Setter Property="Content" Value="&#xE111;"/>
+ </Style>
+ <Style x:Key="PreviousAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PreviousAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Previous"/>
+ <Setter Property="Content" Value="&#xE112;"/>
+ </Style>
+ <Style x:Key="NoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="No"/>
+ <Setter Property="Content" Value="&#xE10A;"/>
+ </Style>
+ <Style x:Key="SettingsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SettingsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Settings"/>
+ <Setter Property="Content" Value="&#xE115;"/>
+ </Style>
+ <Style x:Key="LinksAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LinksAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Links"/>
+ <Setter Property="Content" Value="&#xE167;"/>
+ </Style>
+ <Style x:Key="ContentsBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AllAppsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Contents"/>
+ <Setter Property="Content" Value="&#xE179;"/>
+ </Style>
+ <Style x:Key="ReflowAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ReflowAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Reflow"/>
+ <Setter Property="Content" Value="&#xE18B;"/>
+ </Style>
+ <Style x:Key="ZoomInAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZoomInAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zoom In"/>
+ <Setter Property="Content" Value="&#xE12E;"/>
+ </Style>
+ <Style x:Key="ZoomOutAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZoomOutAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zoom Out"/>
+ <Setter Property="Content" Value="&#xE1A4;"/>
+ </Style>
+
+ <!--
+
+ <Style x:Key="SkipBackAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SkipBackAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Skip Back"/>
+ <Setter Property="Content" Value="&#xE100;"/>
+ </Style>
+ <Style x:Key="SkipAheadAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SkipAheadAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Skip Ahead"/>
+ <Setter Property="Content" Value="&#xE101;"/>
+ </Style>
+ <Style x:Key="PlayAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Play"/>
+ <Setter Property="Content" Value="&#xE102;"/>
+ </Style>
+ <Style x:Key="PauseAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PauseAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Pause"/>
+ <Setter Property="Content" Value="&#xE103;"/>
+ </Style>
+ <Style x:Key="EditAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="EditAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Edit"/>
+ <Setter Property="Content" Value="&#xE104;"/>
+ </Style>
+ <Style x:Key="SaveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Save"/>
+ <Setter Property="Content" Value="&#xE105;"/>
+ </Style>
+ <Style x:Key="DeleteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DeleteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Delete"/>
+ <Setter Property="Content" Value="&#xE106;"/>
+ </Style>
+ <Style x:Key="DiscardAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DiscardAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Discard"/>
+ <Setter Property="Content" Value="&#xE107;"/>
+ </Style>
+ <Style x:Key="RemoveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RemoveAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Remove"/>
+ <Setter Property="Content" Value="&#xE108;"/>
+ </Style>
+ <Style x:Key="AddAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AddAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Add"/>
+ <Setter Property="Content" Value="&#xE109;"/>
+ </Style>
+ <Style x:Key="NoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="No"/>
+ <Setter Property="Content" Value="&#xE10A;"/>
+ </Style>
+ <Style x:Key="YesAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="YesAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Yes"/>
+ <Setter Property="Content" Value="&#xE10B;"/>
+ </Style>
+ <Style x:Key="MoreAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MoreAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="More"/>
+ <Setter Property="Content" Value="&#xE10C;"/>
+ </Style>
+ <Style x:Key="RedoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RedoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Redo"/>
+ <Setter Property="Content" Value="&#xE10D;"/>
+ </Style>
+ <Style x:Key="UndoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UndoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Undo"/>
+ <Setter Property="Content" Value="&#xE10E;"/>
+ </Style>
+ <Style x:Key="HomeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HomeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Home"/>
+ <Setter Property="Content" Value="&#xE10F;"/>
+ </Style>
+ <Style x:Key="OutAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OutAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Out"/>
+ <Setter Property="Content" Value="&#xE110;"/>
+ </Style>
+ <Style x:Key="NextAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NextAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Next"/>
+ <Setter Property="Content" Value="&#xE111;"/>
+ </Style>
+ <Style x:Key="PreviousAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PreviousAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Previous"/>
+ <Setter Property="Content" Value="&#xE112;"/>
+ </Style>
+ <Style x:Key="FavoriteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FavoriteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Favorite"/>
+ <Setter Property="Content" Value="&#xE113;"/>
+ </Style>
+ <Style x:Key="PhotoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PhotoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Photo"/>
+ <Setter Property="Content" Value="&#xE114;"/>
+ </Style>
+ <Style x:Key="SettingsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SettingsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Settings"/>
+ <Setter Property="Content" Value="&#xE115;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="VideoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="VideoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Video"/>
+ <Setter Property="Content" Value="&#xE116;"/>
+ </Style>
+ <Style x:Key="RefreshAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RefreshAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Refresh"/>
+ <Setter Property="Content" Value="&#xE117;"/>
+ </Style>
+ <Style x:Key="DownloadAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DownloadAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Download"/>
+ <Setter Property="Content" Value="&#xE118;"/>
+ </Style>
+ <Style x:Key="MailAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MailAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Mail"/>
+ <Setter Property="Content" Value="&#xE119;"/>
+ </Style>
+ <Style x:Key="SearchAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SearchAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Search"/>
+ <Setter Property="Content" Value="&#xE11A;"/>
+ </Style>
+ <Style x:Key="HelpAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Help"/>
+ <Setter Property="Content" Value="&#xE11B;"/>
+ </Style>
+ <Style x:Key="UploadAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UploadAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Upload"/>
+ <Setter Property="Content" Value="&#xE11C;"/>
+ </Style>
+ <Style x:Key="EmojiAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="EmojiAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Emoji"/>
+ <Setter Property="Content" Value="&#xE11D;"/>
+ </Style>
+ <Style x:Key="TwoPageAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TwoPageAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Two Page"/>
+ <Setter Property="Content" Value="&#xE11E;"/>
+ </Style>
+ <Style x:Key="LeaveChatAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LeaveChatAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Upload"/>
+ <Setter Property="Content" Value="&#xE11F;"/>
+ </Style>
+ <Style x:Key="MailForwardAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MailForwardAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Forward Mail"/>
+ <Setter Property="Content" Value="&#xE120;"/>
+ </Style>
+ <Style x:Key="ClockAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ClockAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Clock"/>
+ <Setter Property="Content" Value="&#xE121;"/>
+ </Style>
+ <Style x:Key="SendAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SendAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Send"/>
+ <Setter Property="Content" Value="&#xE122;"/>
+ </Style>
+ <Style x:Key="CropAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CropAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Crop"/>
+ <Setter Property="Content" Value="&#xE123;"/>
+ </Style>
+ <Style x:Key="RotateCameraAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RotateCameraAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Rotate Camera"/>
+ <Setter Property="Content" Value="&#xE124;"/>
+ </Style>
+ <Style x:Key="PeopleAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PeopleAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="People"/>
+ <Setter Property="Content" Value="&#xE125;"/>
+ </Style>
+ <Style x:Key="ClosePaneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ClosePaneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Close Pane"/>
+ <Setter Property="Content" Value="&#xE126;"/>
+ </Style>
+ <Style x:Key="OpenPaneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OpenPaneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Open Pane"/>
+ <Setter Property="Content" Value="&#xE127;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="WorldAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="WorldAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="World"/>
+ <Setter Property="Content" Value="&#xE128;"/>
+ </Style>
+ <Style x:Key="FlagAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FlagAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Flag"/>
+ <Setter Property="Content" Value="&#xE129;"/>
+ </Style>
+ <Style x:Key="PreviewLinkAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PreviewLinkAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Preview Link"/>
+ <Setter Property="Content" Value="&#xE12A;"/>
+ </Style>
+ <Style x:Key="GlobeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="GlobeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Globe"/>
+ <Setter Property="Content" Value="&#xE12B;"/>
+ </Style>
+ <Style x:Key="TrimAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TrimAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Trim"/>
+ <Setter Property="Content" Value="&#xE12C;"/>
+ </Style>
+ <Style x:Key="AttachCameraAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AttachCameraAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Attach Camera"/>
+ <Setter Property="Content" Value="&#xE12D;"/>
+ </Style>
+ <Style x:Key="ZoomInAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZoomInAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zoom In"/>
+ <Setter Property="Content" Value="&#xE12E;"/>
+ </Style>
+ <Style x:Key="BookmarksAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="BookmarksAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Bookmarks"/>
+ <Setter Property="Content" Value="&#xE12F;"/>
+ </Style>
+ <Style x:Key="DocumentAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DocumentAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Document"/>
+ <Setter Property="Content" Value="&#xE130;"/>
+ </Style>
+ <Style x:Key="ProtectedDocumentAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ProtectedDocumentAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Protected Document"/>
+ <Setter Property="Content" Value="&#xE131;"/>
+ </Style>
+ <Style x:Key="PageAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PageAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Page"/>
+ <Setter Property="Content" Value="&#xE132;"/>
+ </Style>
+ <Style x:Key="BulletsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="BulletsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Bullets"/>
+ <Setter Property="Content" Value="&#xE133;"/>
+ </Style>
+ <Style x:Key="CommentAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CommentAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Comment"/>
+ <Setter Property="Content" Value="&#xE134;"/>
+ </Style>
+ <Style x:Key="Mail2AppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="Mail2AppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Mail2"/>
+ <Setter Property="Content" Value="&#xE135;"/>
+ </Style>
+ <Style x:Key="ContactInfoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ContactInfoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Contact Info"/>
+ <Setter Property="Content" Value="&#xE136;"/>
+ </Style>
+ <Style x:Key="HangUpAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HangUpAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Hang Up"/>
+ <Setter Property="Content" Value="&#xE137;"/>
+ </Style>
+ <Style x:Key="ViewAllAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ViewAllAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="View All"/>
+ <Setter Property="Content" Value="&#xE138;"/>
+ </Style>
+ <Style x:Key="MapPinAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MapPinAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Map Pin"/>
+ <Setter Property="Content" Value="&#xE139;"/>
+ </Style>
+ <Style x:Key="PhoneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PhoneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Phone"/>
+ <Setter Property="Content" Value="&#xE13A;"/>
+ </Style>
+ <Style x:Key="VideoChatAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="VideoChatAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Video Chat"/>
+ <Setter Property="Content" Value="&#xE13B;"/>
+ </Style>
+ <Style x:Key="SwitchAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SwitchAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Switch"/>
+ <Setter Property="Content" Value="&#xE13C;"/>
+ </Style>
+ <Style x:Key="ContactAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ContactAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Contact"/>
+ <Setter Property="Content" Value="&#xE13D;"/>
+ </Style>
+
+ -->
+
+ <!--
+
+ <Style x:Key="RenameAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RenameAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Rename"/>
+ <Setter Property="Content" Value="&#xE13E;"/>
+ </Style>
+ <Style x:Key="PinAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PinAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Pin"/>
+ <Setter Property="Content" Value="&#xE141;"/>
+ </Style>
+ <Style x:Key="MusicInfoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MusicInfoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Music Info"/>
+ <Setter Property="Content" Value="&#xE142;"/>
+ </Style>
+ <Style x:Key="GoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="GoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Go"/>
+ <Setter Property="Content" Value="&#xE143;"/>
+ </Style>
+ <Style x:Key="KeyboardAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="KeyboardAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Keyboard"/>
+ <Setter Property="Content" Value="&#xE144;"/>
+ </Style>
+ <Style x:Key="DockLeftAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DockLeftAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Dock Left"/>
+ <Setter Property="Content" Value="&#xE145;"/>
+ </Style>
+ <Style x:Key="DockRightAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DockRightAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Dock Right"/>
+ <Setter Property="Content" Value="&#xE146;"/>
+ </Style>
+ <Style x:Key="DockBottomAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DockBottomAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Dock Bottom"/>
+ <Setter Property="Content" Value="&#xE147;"/>
+ </Style>
+ <Style x:Key="RemoteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RemoteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Remote"/>
+ <Setter Property="Content" Value="&#xE148;"/>
+ </Style>
+ <Style x:Key="SyncAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SyncAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Sync"/>
+ <Setter Property="Content" Value="&#xE149;"/>
+ </Style>
+ <Style x:Key="RotateAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RotateAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Rotate"/>
+ <Setter Property="Content" Value="&#xE14A;"/>
+ </Style>
+ <Style x:Key="ShuffleAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ShuffleAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Shuffle"/>
+ <Setter Property="Content" Value="&#xE14B;"/>
+ </Style>
+ <Style x:Key="ListAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ListAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="List"/>
+ <Setter Property="Content" Value="&#xE14C;"/>
+ </Style>
+ <Style x:Key="ShopAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ShopAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Shop"/>
+ <Setter Property="Content" Value="&#xE14D;"/>
+ </Style>
+ <Style x:Key="SelectAllAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SelectAllAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Select All"/>
+ <Setter Property="Content" Value="&#xE14E;"/>
+ </Style>
+ <Style x:Key="OrientationAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OrientationAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Orientation"/>
+ <Setter Property="Content" Value="&#xE14F;"/>
+ </Style>
+ <Style x:Key="ImportAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ImportAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Import"/>
+ <Setter Property="Content" Value="&#xE150;"/>
+ </Style>
+ <Style x:Key="ImportAllAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ImportAllAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Import All"/>
+ <Setter Property="Content" Value="&#xE151;"/>
+ </Style>
+ <Style x:Key="BrowsePhotosAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="BrowsePhotosAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Browse Photos"/>
+ <Setter Property="Content" Value="&#xE155;"/>
+ </Style>
+ <Style x:Key="WebcamAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="WebcamAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Webcam"/>
+ <Setter Property="Content" Value="&#xE156;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="PicturesAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PicturesAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Pictures"/>
+ <Setter Property="Content" Value="&#xE158;"/>
+ </Style>
+ <Style x:Key="SaveLocalAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SaveLocalAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Save Local"/>
+ <Setter Property="Content" Value="&#xE159;"/>
+ </Style>
+ <Style x:Key="CaptionAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CaptionAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Caption"/>
+ <Setter Property="Content" Value="&#xE15A;"/>
+ </Style>
+ <Style x:Key="StopAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="StopAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Stop"/>
+ <Setter Property="Content" Value="&#xE15B;"/>
+ </Style>
+ <Style x:Key="ShowResultsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ShowResultsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Show Results"/>
+ <Setter Property="Content" Value="&#xE15C;"/>
+ </Style>
+ <Style x:Key="VolumeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="VolumeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Volume"/>
+ <Setter Property="Content" Value="&#xE15D;"/>
+ </Style>
+ <Style x:Key="RepairAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RepairAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Repair"/>
+ <Setter Property="Content" Value="&#xE15E;"/>
+ </Style>
+ <Style x:Key="MessageAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MessageAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Message"/>
+ <Setter Property="Content" Value="&#xE15F;"/>
+ </Style>
+ <Style x:Key="Page2AppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="Page2AppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Page2"/>
+ <Setter Property="Content" Value="&#xE160;"/>
+ </Style>
+ <Style x:Key="CalendarDayAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CalendarDayAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Day"/>
+ <Setter Property="Content" Value="&#xE161;"/>
+ </Style>
+ <Style x:Key="CalendarWeekAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CalendarWeekAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Week"/>
+ <Setter Property="Content" Value="&#xE162;"/>
+ </Style>
+ <Style x:Key="CalendarAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CalendarAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Calendar"/>
+ <Setter Property="Content" Value="&#xE163;"/>
+ </Style>
+ <Style x:Key="CharactersAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CharactersAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Characters"/>
+ <Setter Property="Content" Value="&#xE164;"/>
+ </Style>
+ <Style x:Key="MailReplyAllAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MailReplyAllAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Reply All"/>
+ <Setter Property="Content" Value="&#xE165;"/>
+ </Style>
+ <Style x:Key="ReadAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ReadAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Read"/>
+ <Setter Property="Content" Value="&#xE166;"/>
+ </Style>
+ <Style x:Key="LinkAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LinkAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Link"/>
+ <Setter Property="Content" Value="&#xE167;"/>
+ </Style>
+ <Style x:Key="AccountsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AccountsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Accounts"/>
+ <Setter Property="Content" Value="&#xE168;"/>
+ </Style>
+ <Style x:Key="ShowBccAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ShowBccAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Show Bcc"/>
+ <Setter Property="Content" Value="&#xE169;"/>
+ </Style>
+ <Style x:Key="HideBccAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HideBccAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Hide Bcc"/>
+ <Setter Property="Content" Value="&#xE16A;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="CutAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CutAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Cut"/>
+ <Setter Property="Content" Value="&#xE16B;"/>
+ </Style>
+ <Style x:Key="AttachAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AttachAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Attach"/>
+ <Setter Property="Content" Value="&#xE16C;"/>
+ </Style>
+ <Style x:Key="PasteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PasteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Paste"/>
+ <Setter Property="Content" Value="&#xE16D;"/>
+ </Style>
+ <Style x:Key="FilterAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FilterAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Filter"/>
+ <Setter Property="Content" Value="&#xE16E;"/>
+ </Style>
+ <Style x:Key="CopyAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CopyAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Copy"/>
+ <Setter Property="Content" Value="&#xE16F;"/>
+ </Style>
+ <Style x:Key="Emoji2AppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="Emoji2AppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Emoji2"/>
+ <Setter Property="Content" Value="&#xE170;"/>
+ </Style>
+ <Style x:Key="ImportantAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ImportantAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Important"/>
+ <Setter Property="Content" Value="&#xE171;"/>
+ </Style>
+ <Style x:Key="MailReplyAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MailReplyAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Reply"/>
+ <Setter Property="Content" Value="&#xE172;"/>
+ </Style>
+ <Style x:Key="SlideShowAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SlideShowAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Slideshow"/>
+ <Setter Property="Content" Value="&#xE173;"/>
+ </Style>
+ <Style x:Key="SortAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SortAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Sort"/>
+ <Setter Property="Content" Value="&#xE174;"/>
+ </Style>
+ <Style x:Key="ManageAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ManageAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Manage"/>
+ <Setter Property="Content" Value="&#xE178;"/>
+ </Style>
+ <Style x:Key="AllAppsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AllAppsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="All Apps"/>
+ <Setter Property="Content" Value="&#xE179;"/>
+ </Style>
+ <Style x:Key="DisconnectDriveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DisconnectDriveAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Disconnect Drive"/>
+ <Setter Property="Content" Value="&#xE17A;"/>
+ </Style>
+ <Style x:Key="MapDriveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MapDriveAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Map Drive"/>
+ <Setter Property="Content" Value="&#xE17B;"/>
+ </Style>
+ <Style x:Key="NewWindowAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NewWindowAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="New Window"/>
+ <Setter Property="Content" Value="&#xE17C;"/>
+ </Style>
+ <Style x:Key="OpenWithAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OpenWithAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Open With"/>
+ <Setter Property="Content" Value="&#xE17D;"/>
+ </Style>
+ <Style x:Key="ContactPresenceAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ContactPresenceAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Presence"/>
+ <Setter Property="Content" Value="&#xE181;"/>
+ </Style>
+ <Style x:Key="PriorityAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PriorityAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Priority"/>
+ <Setter Property="Content" Value="&#xE182;"/>
+ </Style>
+ <Style x:Key="UploadSkyDriveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UploadSkyDriveAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Skydrive"/>
+ <Setter Property="Content" Value="&#xE183;"/>
+ </Style>
+ <Style x:Key="GoToTodayAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="GoToTodayAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Today"/>
+ <Setter Property="Content" Value="&#xE184;"/>
+ </Style>
+ <Style x:Key="FontAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FontAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Font"/>
+ <Setter Property="Content" Value="&#xE185;"/>
+ </Style>
+
+ -->
+
+ <!--
+
+ <Style x:Key="FontColorAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FontColorAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Font Color"/>
+ <Setter Property="Content" Value="&#xE186;"/>
+ </Style>
+ <Style x:Key="Contact2AppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="Contact2AppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Contact"/>
+ <Setter Property="Content" Value="&#xE187;"/>
+ </Style>
+ <Style x:Key="FolderppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FolderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Folder"/>
+ <Setter Property="Content" Value="&#xE188;"/>
+ </Style>
+ <Style x:Key="AudioAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AudioAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Audio"/>
+ <Setter Property="Content" Value="&#xE189;"/>
+ </Style>
+ <Style x:Key="PlaceholderAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PlaceholderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Placeholder"/>
+ <Setter Property="Content" Value="&#xE18A;"/>
+ </Style>
+ <Style x:Key="ViewAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ViewAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="View"/>
+ <Setter Property="Content" Value="&#xE18B;"/>
+ </Style>
+ <Style x:Key="SetLockScreenAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SetLockscreenAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Set Lockscreen"/>
+ <Setter Property="Content" Value="&#xE18C;"/>
+ </Style>
+ <Style x:Key="SetTitleAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SetTitleAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Set Title"/>
+ <Setter Property="Content" Value="&#xE18D;"/>
+ </Style>
+ <Style x:Key="CcAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CcAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Cc"/>
+ <Setter Property="Content" Value="&#xE190;"/>
+ </Style>
+ <Style x:Key="StopSlideShowAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="StopSlideshowAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Stop Slideshow"/>
+ <Setter Property="Content" Value="&#xE191;"/>
+ </Style>
+ <Style x:Key="PermissionsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PermissionsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Permisions"/>
+ <Setter Property="Content" Value="&#xE192;"/>
+ </Style>
+ <Style x:Key="HighlightAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="HighlightAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Highlight"/>
+ <Setter Property="Content" Value="&#xE193;"/>
+ </Style>
+ <Style x:Key="DisableUpdatesAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DisableUpdatesAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Disable Updates"/>
+ <Setter Property="Content" Value="&#xE194;"/>
+ </Style>
+ <Style x:Key="UnfavoriteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UnfavoriteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Unfavorite"/>
+ <Setter Property="Content" Value="&#xE195;"/>
+ </Style>
+ <Style x:Key="UnPinAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UnPinAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Unpin"/>
+ <Setter Property="Content" Value="&#xE196;"/>
+ </Style>
+ <Style x:Key="OpenLocalAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OpenLocalAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Open Loal"/>
+ <Setter Property="Content" Value="&#xE197;"/>
+ </Style>
+ <Style x:Key="MuteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MuteAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Mute"/>
+ <Setter Property="Content" Value="&#xE198;"/>
+ </Style>
+ <Style x:Key="ItalicAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ItalicAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Italic"/>
+ <Setter Property="Content" Value="&#xE199;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="UnderlineAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UnderlineAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Underline"/>
+ <Setter Property="Content" Value="&#xE19A;"/>
+ </Style>
+ <Style x:Key="BoldAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="BoldAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Bold"/>
+ <Setter Property="Content" Value="&#xE19B;"/>
+ </Style>
+ <Style x:Key="MoveToFolderAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MoveToFolderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Move to Folder"/>
+ <Setter Property="Content" Value="&#xE19C;"/>
+ </Style>
+ <Style x:Key="LikeDislikeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LikeDislikeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Like/Dislike"/>
+ <Setter Property="Content" Value="&#xE19D;"/>
+ </Style>
+ <Style x:Key="DislikeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DislikeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Dislike"/>
+ <Setter Property="Content" Value="&#xE19E;"/>
+ </Style>
+ <Style x:Key="LikeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LikeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Like"/>
+ <Setter Property="Content" Value="&#xE19F;"/>
+ </Style>
+ <Style x:Key="AlignRightAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AlignRightAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Align Right"/>
+ <Setter Property="Content" Value="&#xE1A0;"/>
+ </Style>
+ <Style x:Key="AlignCenterAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AlignCenterAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Align Center"/>
+ <Setter Property="Content" Value="&#xE1A1;"/>
+ </Style>
+ <Style x:Key="AlignLeftAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AlignLeftAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Align Left"/>
+ <Setter Property="Content" Value="&#xE1A2;"/>
+ </Style>
+ <Style x:Key="ZoomAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZoomAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zoom"/>
+ <Setter Property="Content" Value="&#xE1A3;"/>
+ </Style>
+ <Style x:Key="ZoomOutAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZoomOutAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zoom Out"/>
+ <Setter Property="Content" Value="&#xE1A4;"/>
+ </Style>
+ <Style x:Key="OpenFileAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OpenFileAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Open File"/>
+ <Setter Property="Content" Value="&#xE1A5;"/>
+ </Style>
+ <Style x:Key="OtherUserAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OtherUserAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Other User"/>
+ <Setter Property="Content" Value="&#xE1A6;"/>
+ </Style>
+ <Style x:Key="AdminAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AdminAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Admin"/>
+ <Setter Property="Content" Value="&#xE1A7;"/>
+ </Style>
+ <Style x:Key="StreetAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="StreetAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Street"/>
+ <Setter Property="Content" Value="&#xE1C3;"/>
+ </Style>
+ <Style x:Key="MapAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MapAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Map"/>
+ <Setter Property="Content" Value="&#xE1C4;"/>
+ </Style>
+ <Style x:Key="ClearSelectionAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ClearSelectionAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Clear Selection"/>
+ <Setter Property="Content" Value="&#xE1C5;"/>
+ </Style>
+ <Style x:Key="FontDecreaseAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FontDecreaseAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Decrease Font"/>
+ <Setter Property="Content" Value="&#xE1C6;"/>
+ </Style>
+ <Style x:Key="FontIncreaseAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FontIncreaseAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Increase Font"/>
+ <Setter Property="Content" Value="&#xE1C7;"/>
+ </Style>
+ <Style x:Key="FontSizeAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FontSizeAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Font Size"/>
+ <Setter Property="Content" Value="&#xE1C8;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="CellphoneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CellphoneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Cellphone"/>
+ <Setter Property="Content" Value="&#xE1C9;"/>
+ </Style>
+ <Style x:Key="ReshareAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ReshareAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Reshare"/>
+ <Setter Property="Content" Value="&#xE1CA;"/>
+ </Style>
+ <Style x:Key="TagAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TagAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Tag"/>
+ <Setter Property="Content" Value="&#xE1CB;"/>
+ </Style>
+ <Style x:Key="RepeatOneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RepeatOneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Repeat Once"/>
+ <Setter Property="Content" Value="&#xE1CC;"/>
+ </Style>
+ <Style x:Key="RepeatAllAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="RepeatAllAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Repeat All"/>
+ <Setter Property="Content" Value="&#xE1CD;"/>
+ </Style>
+ <Style x:Key="OutlineStarAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OutlineStarAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Outline Star"/>
+ <Setter Property="Content" Value="&#xE1CE;"/>
+ </Style>
+ <Style x:Key="SolidStarAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SolidStarAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Solid Star"/>
+ <Setter Property="Content" Value="&#xE1CF;"/>
+ </Style>
+ <Style x:Key="CalculatorAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CalculatorAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Calculator"/>
+ <Setter Property="Content" Value="&#xE1D0;"/>
+ </Style>
+ <Style x:Key="DirectionsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="DirectionsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Directions"/>
+ <Setter Property="Content" Value="&#xE1D1;"/>
+ </Style>
+ <Style x:Key="TargetAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TargetAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Target"/>
+ <Setter Property="Content" Value="&#xE1D2;"/>
+ </Style>
+ <Style x:Key="LibraryAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="LibraryAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Library"/>
+ <Setter Property="Content" Value="&#xE1D3;"/>
+ </Style>
+ <Style x:Key="PhonebookAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PhonebookAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Phonebook"/>
+ <Setter Property="Content" Value="&#xE1D4;"/>
+ </Style>
+ <Style x:Key="MemoAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MemoAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Memo"/>
+ <Setter Property="Content" Value="&#xE1D5;"/>
+ </Style>
+ <Style x:Key="MicrophoneAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="MicrophoneAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Microphone"/>
+ <Setter Property="Content" Value="&#xE1D6;"/>
+ </Style>
+ <Style x:Key="PostUpdateAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="PostUpdateAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Post Update"/>
+ <Setter Property="Content" Value="&#xE1D7;"/>
+ </Style>
+ <Style x:Key="BackToWindowAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="BackToWindowAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Back to Window"/>
+ <Setter Property="Content" Value="&#xE1D8;"/>
+ </Style>
+ -->
+
+ <!--
+ <Style x:Key="FullScreenAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FullScreenAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Full Screen"/>
+ <Setter Property="Content" Value="&#xE1D9;"/>
+ </Style>
+ <Style x:Key="NewFolderAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="NewFolderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="New Folder"/>
+ <Setter Property="Content" Value="&#xE1DA;"/>
+ </Style>
+ <Style x:Key="CalendarReplyAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="CalendarReplyAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Calendar Reply"/>
+ <Setter Property="Content" Value="&#xE1DB;"/>
+ </Style>
+ <Style x:Key="UnsyncFolderAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="UnsyncFolderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Unsync Folder"/>
+ <Setter Property="Content" Value="&#xE1DD;"/>
+ </Style>
+ <Style x:Key="ReportHackedAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ReportHackedAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Report Hacked"/>
+ <Setter Property="Content" Value="&#xE1DE;"/>
+ </Style>
+ <Style x:Key="SyncFolderAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SyncFolderAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Sync Folder"/>
+ <Setter Property="Content" Value="&#xE1DF;"/>
+ </Style>
+ <Style x:Key="BlockContactAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="Block ContactAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="BlockContact"/>
+ <Setter Property="Content" Value="&#xE1E0;"/>
+ </Style>
+ <Style x:Key="SwitchAppsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="SwitchAppsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Switch Apps"/>
+ <Setter Property="Content" Value="&#xE1E1;"/>
+ </Style>
+ <Style x:Key="AddFriendAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="AddFriendAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Add Friend"/>
+ <Setter Property="Content" Value="&#xE1E2;"/>
+ </Style>
+ <Style x:Key="TouchPointerAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TouchPointerAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Touch Pointer"/>
+ <Setter Property="Content" Value="&#xE1E3;"/>
+ </Style>
+ <Style x:Key="GoToStartAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="GoToStartAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Go to Start"/>
+ <Setter Property="Content" Value="&#xE1E4;"/>
+ </Style>
+ <Style x:Key="ZeroBarsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ZeroBarsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Zero Bars"/>
+ <Setter Property="Content" Value="&#xE1E5;"/>
+ </Style>
+ <Style x:Key="OneBarAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="OneBarAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="One Bar"/>
+ <Setter Property="Content" Value="&#xE1E6;"/>
+ </Style>
+ <Style x:Key="TwoBarsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="TwoBarsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Two Bars"/>
+ <Setter Property="Content" Value="&#xE1E7;"/>
+ </Style>
+ <Style x:Key="ThreeBarsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="ThreeBarsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Three Bars"/>
+ <Setter Property="Content" Value="&#xE1E8;"/>
+ </Style>
+ <Style x:Key="FourBarsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
+ <Setter Property="AutomationProperties.AutomationId" Value="FourBarsAppBarButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Four Bars"/>
+ <Setter Property="Content" Value="&#xE1E9;"/>
+ </Style>
+
+ -->
+
+ <!-- Title area styles -->
+
+ <Style x:Key="PageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource HeaderTextStyle}">
+ <Setter Property="TextWrapping" Value="NoWrap"/>
+ <Setter Property="VerticalAlignment" Value="Bottom"/>
+ <Setter Property="Margin" Value="0,0,30,40"/>
+ </Style>
+
+ <Style x:Key="PageSubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource SubheaderTextStyle}">
+ <Setter Property="TextWrapping" Value="NoWrap"/>
+ <Setter Property="VerticalAlignment" Value="Bottom"/>
+ <Setter Property="Margin" Value="0,0,0,40"/>
+ </Style>
+
+ <Style x:Key="SnappedPageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource PageSubheaderTextStyle}">
+ <Setter Property="Margin" Value="0,0,18,40"/>
+ </Style>
+
+ <!--
+ BackButtonStyle is used to style a Button for use in the title area of a page. Margins appropriate for
+ the conventional page layout are included as part of the style.
+ -->
+ <Style x:Key="BackButtonStyle" TargetType="Button">
+ <Setter Property="MinWidth" Value="0"/>
+ <Setter Property="Width" Value="48"/>
+ <Setter Property="Height" Value="48"/>
+ <Setter Property="Margin" Value="36,0,36,36"/>
+ <Setter Property="VerticalAlignment" Value="Bottom"/>
+ <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+ <Setter Property="FontWeight" Value="Normal"/>
+ <Setter Property="FontSize" Value="56"/>
+ <Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Back"/>
+ <Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Grid x:Name="RootGrid">
+ <Grid Margin="-1,-16,0,0">
+ <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
+ <TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
+ <TextBlock x:Name="ArrowGlyph" Text="&#xE0A6;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
+ </Grid>
+ <Rectangle
+ x:Name="FocusVisualWhite"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="1.5"/>
+ <Rectangle
+ x:Name="FocusVisualBlack"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="0.5"/>
+
+ <VisualStateManager.VisualStateGroups>
+ <VisualStateGroup x:Name="CommonStates">
+ <VisualState x:Name="Normal" />
+ <VisualState x:Name="PointerOver">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Pressed">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <DoubleAnimation
+ Storyboard.TargetName="ArrowGlyph"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ <DoubleAnimation
+ Storyboard.TargetName="NormalGlyph"
+ Storyboard.TargetProperty="Opacity"
+ To="0"
+ Duration="0"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Disabled">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="FocusStates">
+ <VisualState x:Name="Focused">
+ <Storyboard>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualWhite"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualBlack"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Unfocused" />
+ <VisualState x:Name="PointerFocused" />
+ </VisualStateGroup>
+ </VisualStateManager.VisualStateGroups>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!--
+ PortraitBackButtonStyle is used to style a Button for use in the title area of a portrait page. Margins appropriate
+ for the conventional page layout are included as part of the style.
+ -->
+ <Style x:Key="PortraitBackButtonStyle" TargetType="Button" BasedOn="{StaticResource BackButtonStyle}">
+ <Setter Property="Margin" Value="26,0,26,36"/>
+ </Style>
+
+ <!--
+ SnappedBackButtonStyle is used to style a Button for use in the title area of a snapped page. Margins appropriate
+ for the conventional page layout are included as part of the style.
+
+ The obvious duplication here is necessary as the glyphs used in snapped are not merely smaller versions of the same
+ glyph but are actually distinct.
+ -->
+ <Style x:Key="SnappedBackButtonStyle" TargetType="Button">
+ <Setter Property="MinWidth" Value="0"/>
+ <Setter Property="Margin" Value="20,0,0,0"/>
+ <Setter Property="VerticalAlignment" Value="Bottom"/>
+ <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+ <Setter Property="FontWeight" Value="Normal"/>
+ <Setter Property="FontSize" Value="26.66667"/>
+ <Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
+ <Setter Property="AutomationProperties.Name" Value="Back"/>
+ <Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Grid x:Name="RootGrid" Width="36" Height="36" Margin="-3,0,7,33">
+ <Grid Margin="-1,-1,0,0">
+ <TextBlock x:Name="BackgroundGlyph" Text="&#xE0D4;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
+ <TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonSnappedGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
+ <TextBlock x:Name="ArrowGlyph" Text="&#xE0C4;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
+ </Grid>
+ <Rectangle
+ x:Name="FocusVisualWhite"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="1.5"/>
+ <Rectangle
+ x:Name="FocusVisualBlack"
+ IsHitTestVisible="False"
+ Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+ StrokeEndLineCap="Square"
+ StrokeDashArray="1,1"
+ Opacity="0"
+ StrokeDashOffset="0.5"/>
+
+ <VisualStateManager.VisualStateGroups>
+ <VisualStateGroup x:Name="CommonStates">
+ <VisualState x:Name="Normal" />
+ <VisualState x:Name="PointerOver">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Pressed">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <DoubleAnimation
+ Storyboard.TargetName="ArrowGlyph"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ <DoubleAnimation
+ Storyboard.TargetName="NormalGlyph"
+ Storyboard.TargetProperty="Opacity"
+ To="0"
+ Duration="0"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Disabled">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ <VisualStateGroup x:Name="FocusStates">
+ <VisualState x:Name="Focused">
+ <Storyboard>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualWhite"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ <DoubleAnimation
+ Storyboard.TargetName="FocusVisualBlack"
+ Storyboard.TargetProperty="Opacity"
+ To="1"
+ Duration="0"/>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Unfocused" />
+ <VisualState x:Name="PointerFocused" />
+ </VisualStateGroup>
+ </VisualStateManager.VisualStateGroups>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <!-- Item templates -->
+
+ <!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
+ <DataTemplate x:Key="Standard250x250ItemTemplate">
+ <Grid HorizontalAlignment="Left" Width="250" Height="250">
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
+ <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
+ </Border>
+ <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
+ <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
+ <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!-- Grid-appropriate 500 by 130 pixel item template as seen in the GroupDetailPage -->
+ <DataTemplate x:Key="Standard500x130ItemTemplate">
+ <Grid Height="110" Width="480" Margin="10">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
+ <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
+ </Border>
+ <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
+ <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!-- List-appropriate 130 pixel high item template as seen in the SplitPage -->
+ <DataTemplate x:Key="Standard130ItemTemplate">
+ <Grid Height="110" Margin="6">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
+ <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
+ </Border>
+ <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
+ <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!--
+ List-appropriate 80 pixel high item template as seen in the SplitPage when Filled, and
+ the following pages when snapped: GroupedItemsPage, GroupDetailPage, and ItemsPage
+ -->
+ <DataTemplate x:Key="Standard80ItemTemplate">
+ <Grid Margin="6">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
+ <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+ </Border>
+ <StackPanel Grid.Column="1" Margin="10,0,0,0">
+ <TextBlock Text="{Binding Title}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/>
+ <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!-- Grid-appropriate 300 by 70 pixel item template as seen in the SearchResultsPage -->
+ <DataTemplate x:Key="StandardSmallIcon300x70ItemTemplate">
+ <Grid Width="294" Margin="6">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,0,0,10" Width="40" Height="40">
+ <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+ </Border>
+ <StackPanel Grid.Column="1" Margin="10,-10,0,0">
+ <TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" TextWrapping="NoWrap"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!-- List-appropriate 70 pixel high item template as seen in the SearchResultsPage when Snapped -->
+ <DataTemplate x:Key="StandardSmallIcon70ItemTemplate">
+ <Grid Margin="6">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,0,0,10" Width="40" Height="40">
+ <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+ </Border>
+ <StackPanel Grid.Column="1" Margin="10,-10,0,0">
+ <TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" TextWrapping="NoWrap"/>
+ <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" TextWrapping="NoWrap"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <!--
+ 190x130 pixel item template for displaying file previews as seen in the FileOpenPickerPage
+ Includes an elaborate tooltip to display title and description text
+ -->
+ <DataTemplate x:Key="StandardFileWithTooltip190x130ItemTemplate">
+ <Grid>
+ <Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
+ <Image
+ Source="{Binding Image}"
+ Width="190"
+ Height="130"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Stretch="Uniform"/>
+ </Grid>
+ <ToolTipService.Placement>Mouse</ToolTipService.Placement>
+ <ToolTipService.ToolTip>
+ <ToolTip>
+ <ToolTip.Style>
+ <Style TargetType="ToolTip">
+ <Setter Property="BorderBrush" Value="{StaticResource ToolTipBackgroundThemeBrush}" />
+ <Setter Property="Padding" Value="0" />
+ </Style>
+ </ToolTip.Style>
+
+ <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="20">
+ <Image
+ Source="{Binding Image}"
+ Width="160"
+ Height="160"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Stretch="Uniform"/>
+ </Grid>
+ <StackPanel Width="200" Grid.Column="1" Margin="0,20,20,20">
+ <TextBlock Text="{Binding Title}" TextWrapping="NoWrap" Style="{StaticResource BodyTextStyle}"/>
+ <TextBlock Text="{Binding Description}" MaxHeight="140" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Style="{StaticResource BodyTextStyle}"/>
+ </StackPanel>
+ </Grid>
+ </ToolTip>
+ </ToolTipService.ToolTip>
+ </Grid>
+ </DataTemplate>
+
+ <!-- ScrollViewer styles -->
+
+ <Style x:Key="HorizontalScrollViewerStyle" TargetType="ScrollViewer">
+ <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
+ <Setter Property="VerticalScrollBarVisibility" Value="Disabled"/>
+ <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled" />
+ <Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
+ <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
+ </Style>
+
+ <Style x:Key="VerticalScrollViewerStyle" TargetType="ScrollViewer">
+ <Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
+ <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
+ <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
+ <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
+ <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
+ </Style>
+
+ <!-- Page layout roots typically use entrance animations and a theme-appropriate background color -->
+
+ <Style x:Key="LayoutRootStyle" TargetType="Panel">
+ <Setter Property="Background" Value="{StaticResource ApplicationPageBackgroundThemeBrush}"/>
+ <Setter Property="ChildrenTransitions">
+ <Setter.Value>
+ <TransitionCollection>
+ <EntranceThemeTransition/>
+ </TransitionCollection>
+ </Setter.Value>
+ </Setter>
+ </Style>
+</ResourceDictionary>
diff --git a/platform/winrt/mupdf_cpp/DocumentPage.cpp b/platform/winrt/mupdf_cpp/DocumentPage.cpp
new file mode 100644
index 00000000..3ee99dcd
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/DocumentPage.cpp
@@ -0,0 +1,15 @@
+#include "pch.h"
+#include "DocumentPage.h"
+
+namespace mupdf_cpp
+{
+ DocumentPage::DocumentPage(void)
+ {
+ this->Image = nullptr;
+ this->Height = 0;
+ this->Width = 0;
+ this->Zoom = 1.0;
+ this->Content = NOTSET;
+ _isPropertyChangedObserved = false;
+ }
+}
diff --git a/platform/winrt/mupdf_cpp/DocumentPage.h b/platform/winrt/mupdf_cpp/DocumentPage.h
new file mode 100644
index 00000000..41c83bc3
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/DocumentPage.h
@@ -0,0 +1,195 @@
+#pragma once
+
+#include "RectList.h"
+#include <collection.h>
+
+/* Used for binding to the xaml in the scroll view. */
+using namespace Windows::UI::Xaml::Media::Imaging;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml::Data;
+
+typedef enum {
+ FULL_RESOLUTION = 0,
+ THUMBNAIL,
+ DUMMY,
+ OLD_RESOLUTION,
+ NOTSET
+} Page_Content_t;
+
+namespace mupdf_cpp
+{
+ // enables data binding with this class
+ [Windows::UI::Xaml::Data::Bindable]
+ public ref class DocumentPage sealed : Windows::UI::Xaml::Data::INotifyPropertyChanged
+ {
+ private:
+ int height;
+ int width;
+ double zoom;
+ WriteableBitmap^ image;
+ Page_Content_t content;
+ IVector<RectList^>^ textbox;
+ IVector<RectList^>^ linkbox;
+ public:
+ DocumentPage(void);
+
+ /* Note IVector needed for WinRT interface */
+ property IVector<RectList^>^ TextBox
+ {
+ IVector<RectList^>^ get()
+ {
+ return (textbox);
+ }
+
+ void set(IVector<RectList^>^ value)
+ {
+ textbox = value;
+ DocumentPage::OnPropertyChanged("TextBox");
+ }
+ }
+
+ property IVector<RectList^>^ LinkBox
+ {
+ IVector<RectList^>^ get()
+ {
+ return (linkbox);
+ }
+
+ void set(IVector<RectList^>^ value)
+ {
+ linkbox = value;
+ DocumentPage::OnPropertyChanged("LinkBox");
+ }
+ }
+
+ property int Content
+ {
+ int get()
+ {
+ return ((int) content);
+ }
+
+ void set(int value)
+ {
+ if (value > NOTSET)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ content = (Page_Content_t) value;
+ }
+ }
+
+ property int Height
+ {
+ int get()
+ {
+ return height;
+ }
+
+ void set(int value)
+ {
+ if (value < 0)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ height = value;
+ }
+ }
+
+ property int Width
+ {
+ int get()
+ {
+ return width;
+ }
+
+ void set(int value)
+ {
+ if (value < 0)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ width = value;
+ }
+ }
+
+ property double Zoom
+ {
+ double get()
+ {
+ return zoom;
+ }
+
+ void set(double value)
+ {
+ if (value < 0)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ zoom = value;
+ }
+ }
+
+ property WriteableBitmap^ Image
+ {
+ WriteableBitmap^ get()
+ {
+ return image;
+ }
+
+ void set(WriteableBitmap^ value)
+ {
+ image = value;
+ DocumentPage::OnPropertyChanged("Image");
+ }
+ }
+
+ private:
+ bool _isPropertyChangedObserved;
+ event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ _privatePropertyChanged;
+
+ protected:
+ /// <summary>
+ /// Notifies listeners that a property value has changed.
+ /// </summary>
+ /// <param name="propertyName">Name of the property used to notify listeners.</param>
+ void OnPropertyChanged(String^ propertyName)
+ {
+ if (_isPropertyChangedObserved)
+ {
+ PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ public:
+
+ // in c++, it is not neccessary to include definitions
+ // of add, remove, and raise. These definitions have
+ // been made explicitly here so that we can check if
+ // the event has listeners before firing the event.
+ virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged
+ {
+ virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Data::PropertyChangedEventHandler^ e)
+ {
+ _isPropertyChangedObserved = true;
+ return _privatePropertyChanged += e;
+ }
+
+ virtual void remove(Windows::Foundation::EventRegistrationToken t)
+ {
+ _privatePropertyChanged -= t;
+ }
+
+ protected:
+ virtual void raise(Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e)
+ {
+ if (_isPropertyChangedObserved)
+ {
+ _privatePropertyChanged(sender, e);
+ }
+ }
+ }
+#pragma endregion
+ };
+}
diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml b/platform/winrt/mupdf_cpp/MainPage.xaml
new file mode 100644
index 00000000..22fbe5da
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/MainPage.xaml
@@ -0,0 +1,276 @@
+<Page
+ x:Class="mupdf_cpp.MainPage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="using:winapp"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d">
+
+ <Page.BottomAppBar>
+ <AppBar>
+ <Grid Margin="38,0,0,0">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*"/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <Slider x:Name="xaml_PageSlider" Minimum="0" Maximum="10" ValueChanged="Slider_ValueChanged" Grid.Column="0" Margin="10,0" VerticalAlignment="Center" />
+ <Button x:Name="Find_File" Style="{StaticResource OpenFileAppBarButtonStyle}" Tag="OpenFile" HorizontalAlignment="Right" Grid.Column="1" Click="Picker"/>
+ </Grid>
+ </AppBar>
+ </Page.BottomAppBar>
+ <Page.TopAppBar>
+ <AppBar x:Name="TopAppBar1" AutomationProperties.Name="Top App Bar" Loaded="topAppBar_Loaded">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <StackPanel x:Name="LeftPanel" Orientation="Horizontal" HorizontalAlignment="Left" >
+ <TextBox x:Name="FindBox" Width="200" Height="20" Visibility="Collapsed"/>
+ <Button x:Name="PrevSearch" Style="{StaticResource PreviousAppBarButtonStyle}" Visibility="Collapsed" Click="SearchPrev"/>
+ <Button x:Name="NextSearch" Style="{StaticResource NextAppBarButtonStyle}" Visibility="Collapsed" Click="SearchNext"/>
+
+ </StackPanel>
+ <StackPanel x:Name="RightPanel" Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button x:Name="Search" Style="{StaticResource SearchAppBarButtonStyle}" Tag="Search" Click="Searcher"/>
+ <Button x:Name="ZoomIn" Style="{StaticResource ZoomInAppBarButtonStyle}" Tag="ZoomIn" Click="ZoomInPress"/>
+ <Button x:Name="ZoomOut" Style="{StaticResource ZoomOutAppBarButtonStyle}" Tag="ZoomOut" Click="ZoomOutPress"/>
+ <Button x:Name="Contents" Style="{StaticResource ContentsBarButtonStyle}" Tag="Contents" Click="ContentDisplay"/>
+ <Button x:Name="Links" Style="{StaticResource LinksAppBarButtonStyle}" Tag="Links" Click="Linker"/>
+ <Button x:Name="Reflow" Style="{StaticResource ReflowAppBarButtonStyle}" Tag="Reflow" Click="Reflower"/>
+ </StackPanel>
+ </Grid>
+ </AppBar>
+ </Page.TopAppBar>
+
+ <Grid x:Name="xaml_OutsideGrid">
+ <Grid.Background>
+ <LinearGradientBrush EndPoint="-0.074,-0.068" StartPoint="1.027,1.024">
+ <GradientStop Color="Black"/>
+ <GradientStop Color="White"/>
+ <GradientStop Color="White" Offset="0.919"/>
+ <GradientStop Color="#FFCDCDCD" Offset="0.741"/>
+ <GradientStop Color="#FF909090" Offset="0.524"/>
+ <GradientStop Color="#FF737373" Offset="0.421"/>
+ <GradientStop Color="#FF2A2A2A" Offset="0.155"/>
+ <GradientStop Color="#FF1A1A1A" Offset="0.097"/>
+ <GradientStop Color="#FF040404" Offset="0.018"/>
+ <GradientStop Color="#FFB3B3B3" Offset="0.651"/>
+ <GradientStop Color="#FF989898" Offset="0.556"/>
+ <GradientStop Color="#FF666666" Offset="0.375"/>
+ <GradientStop Color="#FF4B4B4B" Offset="0.278"/>
+ <GradientStop Color="#FF3A3A3A" Offset="0.215"/>
+ </LinearGradientBrush>
+ </Grid.Background>
+
+ <Grid x:Name="xaml_MainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SizeChanged="GridSizeChanged">
+ <Canvas x:Name="xaml_zoomCanvas" HorizontalAlignment="Center" VerticalAlignment="Center" ManipulationMode="All" >
+ <!-- Horizontal flip view -->
+ <FlipView x:Name="xaml_horiz_flipView" SelectionChanged="FlipView_SelectionChanged" VerticalAlignment="Center"
+ HorizontalAlignment="Center">
+ <FlipView.ItemsPanel>
+ <ItemsPanelTemplate>
+ <VirtualizingStackPanel Orientation="Horizontal"/>
+ </ItemsPanelTemplate>
+ </FlipView.ItemsPanel>
+ <FlipView.ItemTemplate>
+ <DataTemplate>
+ <ScrollViewer
+ Name="xaml_ScrollView_h"
+ ZoomMode="Enabled"
+ ViewChanged="ScrollChanged"
+ HorizontalScrollMode="Auto"
+ VerticalScrollMode="Auto"
+ VerticalSnapPointsType="None"
+ HorizontalSnapPointsType="None"
+ HorizontalScrollBarVisibility="Auto"
+ VerticalScrollBarVisibility="Auto"
+ MinZoomFactor="0.25"
+ MaxZoomFactor="4">
+ <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="{Binding Height}" Width="{Binding Width}">
+ <Image Source="{Binding Image}" Width="{Binding Width}" Height="{Binding Height}"
+ Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0"/>
+ <!-- After much work, figured out how to have a binding for the rectangles. TextBox and LinkBox are
+ a collection that is in the other main collection used for the scroll viewer. It works
+ nicely and cleanly once you figure out how to set up all the templates and the bindings -->
+ <ItemsControl ItemsSource="{Binding Path=TextBox}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <Canvas/>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="ContentPresenter">
+ <Setter Property="Canvas.Left" Value="{Binding Left}"/>
+ <Setter Property="Canvas.Top" Value="{Binding Top}"/>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}">
+ <Rectangle.RenderTransform>
+ <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
+ </Rectangle.RenderTransform>
+ </Rectangle>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ <ItemsControl ItemsSource="{Binding Path=LinkBox}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <Canvas/>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="ContentPresenter">
+ <Setter Property="Canvas.Left" Value="{Binding Left}"/>
+ <Setter Property="Canvas.Top" Value="{Binding Top}"/>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}" IsTapEnabled="True" Tapped="LinkTapped">
+ <Rectangle.RenderTransform>
+ <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
+ </Rectangle.RenderTransform>
+ </Rectangle>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ </Canvas>
+ </ScrollViewer>
+ </DataTemplate>
+ </FlipView.ItemTemplate>
+ </FlipView>
+ <!-- Vertical flip view -->
+ <FlipView x:Name="xaml_vert_flipView" SelectionChanged="FlipView_SelectionChanged" VerticalAlignment="Center"
+ HorizontalAlignment="Center" IsEnabled="False" Opacity="0">
+ <FlipView.ItemsPanel>
+ <ItemsPanelTemplate>
+ <VirtualizingStackPanel Orientation="Vertical"/>
+ </ItemsPanelTemplate>
+ </FlipView.ItemsPanel>
+ <FlipView.ItemTemplate>
+ <DataTemplate>
+ <ScrollViewer
+ Name="xaml_ScrollView_v"
+ ZoomMode="Enabled"
+ ViewChanged="ScrollChanged"
+ HorizontalScrollMode="Auto"
+ VerticalScrollMode="Auto"
+ VerticalSnapPointsType="None"
+ HorizontalSnapPointsType="None"
+ HorizontalScrollBarVisibility="Auto"
+ VerticalScrollBarVisibility="Auto"
+ MinZoomFactor="0.25"
+ MaxZoomFactor="4">
+ <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="{Binding Height}" Width="{Binding Width}">
+ <Image Source="{Binding Image}" Width="{Binding Width}" Height="{Binding Height}"
+ Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0"/>
+ <ItemsControl ItemsSource="{Binding Path=TextBox}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <Canvas/>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="ContentPresenter">
+ <Setter Property="Canvas.Left" Value="{Binding Left}"/>
+ <Setter Property="Canvas.Top" Value="{Binding Top}"/>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}" IsTapEnabled="True" Tapped="LinkTapped">
+ <Rectangle.RenderTransform>
+ <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
+ </Rectangle.RenderTransform>
+ </Rectangle>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ <ItemsControl ItemsSource="{Binding Path=LinkBox}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <Canvas/>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="ContentPresenter">
+ <Setter Property="Canvas.Left" Value="{Binding Left}"/>
+ <Setter Property="Canvas.Top" Value="{Binding Top}"/>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}">
+ <Rectangle.RenderTransform>
+ <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
+ </Rectangle.RenderTransform>
+ </Rectangle>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Canvas>
+ </ScrollViewer>
+ </DataTemplate>
+ </FlipView.ItemTemplate>
+ </FlipView>
+ </Canvas>
+ <ListView x:Name="xaml_ListView" Foreground="Black" HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch" Opacity="0" IsItemClickEnabled="True"
+ ItemClick="ContentSelected" SelectionMode="Single" IsEnabled="False">
+
+ <ListView.ItemTemplate>
+ <DataTemplate>
+ <StackPanel Margin="5,5,0,0" HorizontalAlignment="Left">
+ <TextBlock TextWrapping="Wrap" Text="{Binding StringMargin}" FontFamily="Segoe UI" FontSize="20" />
+ </StackPanel>
+ </DataTemplate>
+ </ListView.ItemTemplate>
+
+ <ListView.Background>
+ <SolidColorBrush Color="LightGray"></SolidColorBrush>
+ </ListView.Background>
+ </ListView>
+ </Grid>
+ <WebView x:Name="xaml_WebView" HorizontalAlignment="Stretch" Width="Auto" Height="Auto"
+ VerticalAlignment="Stretch" Visibility="Collapsed"
+ ScrollViewer.HorizontalScrollBarVisibility="Visible"
+ ScrollViewer.VerticalScrollBarVisibility="Visible"
+ ScrollViewer.VerticalScrollMode="Enabled"
+ ScrollViewer.HorizontalScrollMode="Enabled"
+ ScrollViewer.ZoomMode="Enabled"/>
+
+ <StackPanel x:Name="xaml_ProgressStack" Opacity="1" VerticalAlignment="Center" Margin="0,15" HorizontalAlignment="Center" Visibility="Collapsed">
+ <Border BorderThickness="5" BorderBrush="Black" >
+ <StackPanel Background="LightGray" HorizontalAlignment="Left" Width="756" >
+ <TextBlock HorizontalAlignment="Center" Margin="10"
+ Text="Text Search Progress" FontSize="20"/>
+ <ProgressBar x:Name="xaml_Progress" Margin="5" Height="15"
+ IsIndeterminate="False" Maximum="100" VerticalAlignment="Stretch" />
+ <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10" Click="CancelSearch" Height="39">
+ <TextBlock HorizontalAlignment="Center" Text="Cancel"/>
+ </Button>
+ </StackPanel>
+ </Border>
+ </StackPanel>
+
+ <StackPanel x:Name="xaml_PasswordStack" Opacity="1" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="Collapsed">
+ <Border BorderThickness="5" BorderBrush="Black" >
+ <StackPanel Background="LightGray" >
+ <TextBlock HorizontalAlignment="Center" Margin="10"
+ Text="Password Required" FontSize="20"/>
+ <PasswordBox x:Name="xaml_password" Height="35" Width="400" Margin="20"/>
+ <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10" Click="PasswordOK" Height="39">
+ <TextBlock HorizontalAlignment="Center" Text="OK"/>
+ </Button>
+ </StackPanel>
+ </Border>
+ </StackPanel>
+ </Grid>
+</Page>
diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.cpp b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp
new file mode 100644
index 00000000..d31c2b94
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/MainPage.xaml.cpp
@@ -0,0 +1,1479 @@
+//
+// MainPage.xaml.cpp
+// Implementation of the MainPage class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+#define LOOK_AHEAD 0 /* A +/- count on the pages to pre-render */
+#define THUMB_PREADD 10
+#define MIN_SCALE 0.5
+
+#define SCALE_THUMB 0.1
+
+#define BLANK_WIDTH 17
+#define BLANK_HEIGHT 22
+
+#define KEYBOARD_ZOOM_STEP 0.25
+#define ZOOM_MAX 4
+#define ZOOM_MIN 0.25
+
+#define KEY_PLUS 0xbb
+#define KEY_MINUS 0xbd
+#define ZOOM_IN 0
+#define ZOOM_OUT 1
+
+static float screenScale = 1;
+
+using namespace mupdf_cpp;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+using namespace Windows::Graphics::Display;
+
+//****************** Added *****************
+using namespace Windows::Storage::Pickers;
+using namespace Windows::Devices::Enumeration;
+using namespace concurrency;
+using namespace Windows::Graphics::Imaging;
+//****************** End Add ****************
+
+#ifndef NDEBUG
+unsigned int _mainThreadId = 0U;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ // The IsMainThread function returns true if the current thread is the app's main thread and false otherwise.
+ bool IsMainThread()
+ {
+ return (_mainThreadId == GetCurrentThreadId());
+ }
+
+ // The IsBackgroundThread function returns false if the current thread is the app's main thread and true otherwise.
+ bool IsBackgroundThread()
+ {
+ return (_mainThreadId != GetCurrentThreadId());
+ }
+
+ // The RecordMainThread function registers the main thread ID for use by the IsMainThread and IsBackgroundThread functions.
+ void RecordMainThread()
+ {
+ _mainThreadId = GetCurrentThreadId();
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not NDEBUG */
+
+mupdf_cpp::MainPage::MainPage()
+{
+ InitializeComponent();
+ Application::Current->Suspending +=
+ ref new SuspendingEventHandler(this, &MainPage::App_Suspending);
+ m_textcolor="#402572AC";
+ m_linkcolor="#40AC7225";
+ mu_doc = nullptr;
+ m_docPages = ref new Platform::Collections::Vector<DocumentPage^>();
+ m_thumbnails = ref new Platform::Collections::Vector<DocumentPage^>();
+ m_page_link_list = ref new Platform::Collections::Vector<IVector<RectList^>^>();
+ m_text_list = ref new Platform::Collections::Vector<RectList^>();
+ m_linkset = ref new Platform::Collections::Vector<int>();
+ CleanUp();
+ RecordMainThread();
+ /* So that we can catch special loading events (e.g. open with) */
+ _pageLoadedHandlerToken = Loaded += ref new RoutedEventHandler(this, &MainPage::Page_Loaded);
+}
+
+/* Used during launch of application from file */
+void MainPage::Page_Loaded(Object^ sender, RoutedEventArgs^ e)
+{
+ MainPage^ rootPage = dynamic_cast<MainPage^>(sender);
+ if (rootPage->FileEvent != nullptr)
+ {
+ /* Launched with an "open with", or as default app */
+ if (rootPage->FileEvent->Files->Size > 0)
+ {
+ IStorageItem ^file = rootPage->FileEvent->Files->GetAt(0);
+ StorageFile ^sfile = safe_cast<StorageFile^>(file);
+
+ OpenDocumentPrep(sfile);
+ }
+ }
+}
+
+/// <summary>
+/// Invoked when this page is about to be displayed in a Frame.
+/// </summary>
+/// <param name="e">Event data that describes how this page was reached. The Parameter
+/// property is typically used to configure the page.</param>
+void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
+{
+
+}
+
+void mupdf_cpp::MainPage::App_Suspending(Object^ sender, SuspendingEventArgs^ e)
+{
+
+}
+
+void mupdf_cpp::MainPage::ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command)
+{
+
+}
+
+void mupdf_cpp::MainPage::OKInvokedHandler(Windows::UI::Popups::IUICommand^ command)
+{
+
+}
+
+void mupdf_cpp::MainPage::NotifyUser(String^ strMessage, NotifyType_t type)
+{
+ MessageDialog^ msg = ref new MessageDialog(strMessage);
+ UICommand^ ExitCommand = nullptr;
+ UICommand^ OKCommand = nullptr;
+
+ switch (type)
+ {
+ case StatusMessage:
+ OKCommand = ref new UICommand("OK",
+ ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::OKInvokedHandler));
+ msg->Commands->Append(OKCommand);
+ /// Set the command that will be invoked by default
+ msg->DefaultCommandIndex = 0;
+ // Set the command to be invoked when escape is pressed
+ msg->CancelCommandIndex = 1;
+ break;
+ case ErrorMessage:
+ ExitCommand = ref new UICommand("Exit",
+ ref new UICommandInvokedHandler(this, &mupdf_cpp::MainPage::ExitInvokedHandler));
+ msg->Commands->Append(ExitCommand);
+ /// Set the command that will be invoked by default
+ msg->DefaultCommandIndex = 0;
+ // Set the command to be invoked when escape is pressed
+ msg->CancelCommandIndex = 1;
+ break;
+ default:
+ break;
+ }
+ // Show the message dialog
+ msg->ShowAsync();
+}
+
+bool mupdf_cpp::MainPage::EnsureUnsnapped()
+{
+ // FilePicker APIs will not work if the application is in a snapped state.
+ // If an app wants to show a FilePicker while snapped, it must attempt to unsnap first
+
+ bool unsnapped = (ApplicationView::Value != ApplicationViewState::Snapped ||
+ ApplicationView::TryUnsnap());
+ if (!unsnapped)
+ {
+ NotifyUser("Cannot unsnap the application", StatusMessage);
+ }
+ return unsnapped;
+}
+
+void mupdf_cpp::MainPage::Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (!EnsureUnsnapped())
+ return;
+
+ FileOpenPicker^ openPicker = ref new FileOpenPicker();
+ openPicker->ViewMode = PickerViewMode::List;
+ openPicker->SuggestedStartLocation = PickerLocationId::DocumentsLibrary;
+ openPicker->FileTypeFilter->Append(".pdf");
+ openPicker->FileTypeFilter->Append(".xps");
+ openPicker->FileTypeFilter->Append(".cbz");
+ openPicker->FileTypeFilter->Append(".oxps");
+
+ create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
+ {
+ if (file)
+ {
+ this->OpenDocumentPrep(file);
+ }
+ else
+ {
+ /* Nothing selected */
+ }
+ });
+}
+
+/* Set the page with the new raster information */
+void MainPage::UpdatePage(int page_num, InMemoryRandomAccessStream^ ras,
+ Point ras_size, Page_Content_t content_type)
+{
+ assert(IsMainThread());
+
+ WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y);
+ bmp->SetSource(ras);
+
+ DocumentPage^ doc_page = ref new DocumentPage();
+ doc_page->Image = bmp;
+
+ if (content_type == THUMBNAIL)
+ {
+ doc_page->Height = ras_size.Y / SCALE_THUMB;
+ doc_page->Width = ras_size.X / SCALE_THUMB;
+ }
+ else
+ {
+ doc_page->Height = ras_size.Y;
+ doc_page->Width = ras_size.X;
+ }
+ doc_page->Content = content_type;
+
+ /* We do not want flipview change notification to occur for ourselves */
+ m_page_update = true;
+ this->m_docPages->SetAt(page_num, doc_page);
+ m_page_update = false;
+}
+
+/* Set the page with the new raster information but only the image data */
+void MainPage::ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras,
+ Point ras_size)
+{
+ assert(IsMainThread());
+
+ WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y);
+ bmp->SetSource(ras);
+
+ DocumentPage^ doc_page = this->m_docPages->GetAt(page_num);
+ doc_page->Image = bmp;
+
+ doc_page->Height = ras_size.Y;
+ doc_page->Width = ras_size.X;
+}
+
+Point MainPage::ComputePageSize(spatial_info_t spatial_info, int page_num)
+{
+ Point screenSize;
+ Point pageSize;
+ Point size = mu_doc->GetPageSize(page_num);
+
+ screenSize = spatial_info.size;
+ screenSize.Y *= screenScale;
+ screenSize.X *= screenScale;
+
+ float hscale = screenSize.X / size.X;
+ float vscale = screenSize.Y / size.Y;
+ float scale = min(hscale, vscale);
+ pageSize.X = size.X * scale * spatial_info.scale_factor;
+ pageSize.Y = size.Y * scale * spatial_info.scale_factor;
+
+ return pageSize;
+}
+
+static Point fitPageToScreen(Point page, Point screen)
+{
+ Point pageSize;
+
+ float hscale = screen.X / page.X;
+ float vscale = screen.Y / page.Y;
+ float scale = min(hscale, vscale);
+ pageSize.X = floorf(page.X * scale) / page.X;
+ pageSize.Y = floorf(page.Y * scale) / page.Y;
+
+ return pageSize;
+}
+
+spatial_info_t MainPage::InitSpatial(double scale)
+{
+ spatial_info_t value;
+
+ value.size.Y = this->ActualHeight;
+ value.size.X = this->ActualWidth;
+ value.scale_factor = scale;
+
+ return value;
+}
+
+void Prepare_bmp(int width, int height, DataWriter ^dw)
+{
+ int row_size = width * 4;
+ int bmp_size = row_size * height + 54;
+
+ dw->WriteString("BM");
+ dw->ByteOrder = ByteOrder::LittleEndian;
+ dw->WriteInt32(bmp_size);
+ dw->WriteInt16(0);
+ dw->WriteInt16(0);
+ dw->WriteInt32(54);
+ dw->WriteInt32(40);
+ dw->WriteInt32(width);
+ dw->WriteInt32(height);
+ dw->WriteInt16(1);
+ dw->WriteInt16(32);
+ dw->WriteInt32(0);
+ dw->WriteInt32(row_size * height);
+ dw->WriteInt32(2835);
+ dw->WriteInt32(2835);
+ dw->WriteInt32(0);
+ dw->WriteInt32(0);
+}
+
+void MainPage::ReleasePages(int old_page, int new_page)
+{
+ if (old_page == new_page) return;
+ /* To keep from having memory issue reset the page back to
+ the thumb if we are done rendering the thumbnails */
+ for (int k = old_page - LOOK_AHEAD; k <= old_page + LOOK_AHEAD; k++)
+ {
+ if (k < new_page - LOOK_AHEAD || k > new_page + LOOK_AHEAD)
+ {
+ if (k >= 0 && k < this->m_num_pages)
+ {
+ SetThumb(k, true);
+ }
+ }
+ }
+}
+
+/* Return this page from a full res image to the thumb image or only set
+ to thumb if it has not already been set */
+void MainPage::SetThumb(int page_num, bool replace)
+{
+ /* See what is there now */
+ auto doc = this->m_docPages->GetAt(page_num);
+ if (doc->Content == THUMBNAIL) return;
+ if (doc->Content == FULL_RESOLUTION && replace == false) return;
+
+ if (this->m_thumbnails->Size > page_num)
+ {
+ m_page_update = true;
+ this->m_docPages->SetAt(page_num, this->m_thumbnails->GetAt(page_num));
+ m_page_update = false;
+ }
+}
+
+/* Create white image for us to use as place holder in large document for flip
+ view filling instead of the thumbnail image */
+void MainPage::CreateBlank(int width, int height)
+{
+ Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(height * 4 * width);
+ /* Set up the memory stream */
+ WriteableBitmap ^bmp = ref new WriteableBitmap(width, height);
+ InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream();
+ DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0));
+ /* Go ahead and write our header data into the memory stream */
+ Prepare_bmp(width, height, dw);
+
+ /* Set the data to all white */
+ memset(bmp_data->Data, 255, height * 4 * width);
+
+ /* Write the data */
+ dw->WriteBytes(bmp_data);
+
+ DataWriterStoreOperation^ result = dw->StoreAsync();
+ /* Block on the Async call */
+ while(result->Status != AsyncStatus::Completed) {
+ }
+ /* And store in a the image brush */
+ bmp->SetSource(ras);
+ m_BlankBmp = bmp;
+}
+
+void mupdf_cpp::MainPage::SetFlipView()
+{
+ int height = this->ActualHeight;
+ int width = this->ActualWidth;
+
+ CreateBlank(BLANK_WIDTH, BLANK_HEIGHT);
+ /* Set the current flip view mode */
+ if (height > width)
+ this->m_curr_flipView = xaml_vert_flipView;
+ else
+ this->m_curr_flipView = xaml_horiz_flipView;
+}
+
+/* Clean up everything as we are opening a new document after having another
+ one open */
+void mupdf_cpp::MainPage::CleanUp()
+{
+ m_init_done = false;
+ /* Remove current pages in the flipviews */
+ if (m_docPages != nullptr && m_docPages->Size > 0)
+ m_docPages->Clear();
+ if (m_thumbnails != nullptr && m_thumbnails->Size > 0)
+ m_thumbnails->Clear();
+ /* With the ref counting this should not leak */
+ if (m_page_link_list != nullptr && m_page_link_list->Size > 0)
+ m_page_link_list->Clear();
+ if (m_text_list->Size > 0)
+ m_text_list->Clear();
+ if (m_linkset != nullptr && m_linkset->Size > 0)
+ m_linkset->Clear();
+
+ if (this->mu_doc != nullptr)
+ mu_doc->CleanUp();
+
+ mu_doc = ref new mudocument();
+ if (mu_doc == nullptr)
+ throw ref new FailureException("Document allocation failed!");
+
+ this->m_curr_flipView = nullptr;
+ m_currpage = -1;
+ m_file_open = false;
+ m_slider_min = 0;
+ m_slider_max = 0;
+ m_memory_use = 0;
+ m_insearch = false;
+ m_search_active = false;
+ m_sliderchange = false;
+ m_flip_from_searchlink = false;
+ m_num_pages = -1;
+ m_search_rect_count = 0;
+ m_ren_status = REN_AVAILABLE;
+ m_links_on = false;
+ m_rectlist_page = -1;
+ m_Progress = 0.0;
+
+ this->xaml_PageSlider->Minimum = m_slider_min;
+ this->xaml_PageSlider->Maximum = m_slider_max;
+ this->xaml_PageSlider->IsEnabled = false;
+}
+
+/* Create the thumbnail images */
+void mupdf_cpp::MainPage::RenderThumbs()
+{
+ spatial_info_t spatial_info = this->InitSpatial(1);
+ int num_pages = this->m_num_pages;
+ cancellation_token_source cts;
+ auto token = cts.get_token();
+ m_ThumbCancel = cts;
+ auto ui = task_continuation_context::use_current();
+
+ this->m_ren_status = REN_THUMBS;
+ Vector<DocumentPage^>^ thumbnails = m_thumbnails;
+ auto task_thumb = create_task([spatial_info, num_pages, thumbnails, this, ui, token]()-> int
+ {
+ spatial_info_t spatial_info_local = spatial_info;
+ spatial_info_local.scale_factor = SCALE_THUMB;
+
+ for (int k = 0; k < num_pages; k++)
+ {
+ Point ras_size = ComputePageSize(spatial_info_local, k);
+ auto task2 = create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, false));
+
+ task2.then([this, k, thumbnails, ras_size](InMemoryRandomAccessStream^ ras)
+ {
+ assert(IsMainThread());
+ WriteableBitmap ^bmp = ref new WriteableBitmap(ras_size.X, ras_size.Y);
+ bmp->SetSource(ras);
+ DocumentPage^ doc_page = ref new DocumentPage();
+ doc_page->Image = bmp;
+ doc_page->Height = ras_size.Y / SCALE_THUMB;
+ doc_page->Width = ras_size.X / SCALE_THUMB;
+ doc_page->Content = THUMBNAIL;
+ doc_page->TextBox = nullptr;
+ doc_page->LinkBox = nullptr;
+ if (m_init_done)
+ {
+ m_thumbnails->SetAt(k, doc_page); /* This avoids out of order returns from task */
+ if (k < THUMB_PREADD) /* Flip view gets overwhelmed if I don't do this */
+ SetThumb(k, false);
+ }
+ }, ui).then([this] (task<void> t)
+ {
+ try
+ {
+ t.get();
+ }
+ catch(Platform::InvalidArgumentException^ e)
+ {
+ //TODO handle error.
+ }
+ }, token); //end task chain */
+
+ /* If cancelled then save the last one as the continuation will not
+ have occured. */
+ if (is_task_cancellation_requested())
+ {
+ cancel_current_task();
+ }
+ }
+ return num_pages; /* all done with thumbnails! */
+ }, token).then([this](task<int> the_task)
+ {
+ /* Finish adding them, but not if we were cancelled. */
+ bool is_cancelled = false;
+ try
+ {
+ the_task.get();
+ }
+ catch (const task_canceled& e)
+ {
+ (void) e; // Unused parameter
+ is_cancelled = true;
+ }
+ if (!is_cancelled)
+ {
+ for (int k = THUMB_PREADD; k < m_num_pages; k++)
+ SetThumb(k, false);
+ }
+ this->m_ren_status = REN_AVAILABLE;
+ }, task_continuation_context::use_current());
+
+}
+
+void mupdf_cpp::MainPage::OpenDocumentPrep(StorageFile^ file)
+{
+ if (this->m_num_pages != -1)
+ {
+ m_init_done = false;
+
+ /* Set the index to the start of the document */
+ this->xaml_vert_flipView->SelectedIndex = 0;
+ this->xaml_horiz_flipView->SelectedIndex = 0;
+
+ /* If the thumbnail thread is running then we need to end that first */
+ RenderingStatus_t *ren_status = &m_ren_status;
+ cancellation_token_source *ThumbCancel = &m_ThumbCancel;
+
+ /* Create a task to wait until the renderer is available, then clean up then open */
+ auto t = create_task([ren_status, ThumbCancel]()->int
+ {
+ if (*ren_status == REN_THUMBS)
+ ThumbCancel->cancel();
+ while (*ren_status != REN_AVAILABLE) {
+ }
+ return 0;
+ }).then([this](task<int> the_task)
+ {
+ CleanUp();
+ return 0;
+ }, task_continuation_context::use_current()).then([this, file](task<int> the_task)
+ {
+ OpenDocument(file);
+ }, task_continuation_context::use_current());
+ }
+ else
+ {
+ OpenDocument(file);
+ }
+}
+
+void mupdf_cpp::MainPage::OpenDocument(StorageFile^ file)
+{
+ this->SetFlipView();
+
+ /* Open document and when open, push on */
+ auto open_task = create_task(mu_doc->OpenFileAsync(file));
+ open_task.then([this](int code) -> int
+ {
+ assert(IsMainThread());
+ if (code != S_ISOK)
+ {
+ return code;
+ }
+ /* We need to check if password is required */
+ if (mu_doc->RequiresPassword())
+ {
+ xaml_PasswordStack->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ return E_NEEDPASSWORD;
+ }
+ else
+ {
+ xaml_PasswordStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ return S_ISOK;
+ }
+ }).then([this](int code)->int
+ {
+ assert(IsMainThread());
+ if (code == S_ISOK)
+ InitialRender();
+ return code;
+ }, task_continuation_context::use_current()).then([this](int code)
+ {
+ if (code == S_ISOK)
+ RenderThumbs();
+ else
+ {
+ if (code != E_NEEDPASSWORD)
+ {
+ NotifyUser("Sorry, an issue was encountered in opening file",
+ StatusMessage);
+ }
+ }
+ }, task_continuation_context::use_current());
+}
+
+void mupdf_cpp::MainPage::InitialRender()
+{
+ assert(IsMainThread());
+ m_num_pages = mu_doc->GetNumPages();
+
+ if ((m_currpage) >= m_num_pages)
+ {
+ m_currpage = m_num_pages - 1;
+ }
+ else if (m_currpage < 0)
+ {
+ m_currpage = 0;
+ }
+
+ /* Initialize all the flipvew items with blanks and the thumbnails. */
+ for (int k = 0; k < m_num_pages; k++)
+ {
+ /* Blank pages */
+ DocumentPage^ doc_page = ref new DocumentPage();
+ doc_page->Image = m_BlankBmp;
+ doc_page->Height = BLANK_HEIGHT;
+ doc_page->Width = BLANK_WIDTH;
+ doc_page->Content = DUMMY;
+ doc_page->TextBox = nullptr;
+ doc_page->LinkBox = nullptr;
+ m_docPages->Append(doc_page);
+ m_thumbnails->Append(doc_page);
+ /* Create empty lists for our links and specify that they have
+ not been computed for these pages */
+ Vector<RectList^>^ temp_link = ref new Vector<RectList^>();
+ m_page_link_list->Append(temp_link);
+ m_linkset->Append(false);
+ }
+
+ this->xaml_horiz_flipView->ItemsSource = m_docPages;
+ this->xaml_vert_flipView->ItemsSource = m_docPages;
+
+ /* Do the first few pages, then start the thumbs */
+ spatial_info_t spatial_info = InitSpatial(1);
+ for (int k = 0; k < LOOK_AHEAD + 2; k++)
+ {
+ if (m_num_pages > k )
+ {
+ Point ras_size = ComputePageSize(spatial_info, k);
+
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, true));
+
+ render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras)
+ {
+ UpdatePage(k, ras, ras_size, FULL_RESOLUTION);
+ }, task_continuation_context::use_current());
+ }
+ }
+
+ /* Update the slider settings, if more than one page */
+ if (m_num_pages > 1)
+ {
+ this->xaml_PageSlider->Maximum = m_num_pages;
+ this->xaml_PageSlider->Minimum = 1;
+ this->xaml_PageSlider->IsEnabled = true;
+ }
+ else
+ {
+ this->xaml_PageSlider->Maximum = 0;
+ this->xaml_PageSlider->Minimum = 0;
+ this->xaml_PageSlider->IsEnabled = false;
+ }
+
+ /* All done with initial pages */
+ this->m_init_done = true;
+}
+
+void mupdf_cpp::MainPage::RenderRange(int curr_page)
+{
+ /* Render +/- the look ahead from where we are if blank page is present */
+ spatial_info_t spatial_info = InitSpatial(1);
+ bool curr_page_rendered = true;
+ int range = LOOK_AHEAD;
+
+ assert(IsMainThread());
+ if (m_flip_from_searchlink)
+ range = 0;
+ for (int k = curr_page - LOOK_AHEAD; k <= curr_page + LOOK_AHEAD; k++)
+ {
+ if (k >= 0 && k < m_num_pages)
+ {
+ /* Check if page is already rendered */
+ auto doc = this->m_docPages->GetAt(k);
+ if (doc->Content != FULL_RESOLUTION)
+ {
+ Point ras_size = ComputePageSize(spatial_info, k);
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(k, ras_size.X, ras_size.Y, true));
+
+ render_task.then([this, k, ras_size] (InMemoryRandomAccessStream^ ras)
+ {
+ UpdatePage(k, ras, ras_size, FULL_RESOLUTION);
+ }, task_continuation_context::use_current()).then([this, k, curr_page]()
+ {
+ if (k == curr_page && this->m_links_on)
+ AddLinkCanvas();
+ if (k == curr_page && this->m_text_list->Size > 0 &&
+ m_flip_from_searchlink)
+ {
+ AddTextCanvas();
+ m_flip_from_searchlink = false;
+ }
+ },task_continuation_context::use_current());
+ }
+ else
+ {
+ /* We did not need to render the curr_page, so add links below if
+ needed. Otherwise, we need to wait for the task above to
+ complete before we add the links. */
+ if (k == curr_page)
+ curr_page_rendered = false;
+ }
+ }
+ }
+ m_currpage = curr_page;
+ if (this->m_links_on && !curr_page_rendered)
+ AddLinkCanvas();
+ if (this->m_text_list->Size > 0 && !curr_page_rendered && m_flip_from_searchlink)
+ {
+ AddTextCanvas();
+ m_flip_from_searchlink = false;
+ }
+}
+
+void mupdf_cpp::MainPage::Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
+{
+ int newValue = (int) this->xaml_PageSlider->Value - 1; /* zero based */
+
+ if (IsNotStandardView())
+ return;
+
+ if (m_update_flip)
+ {
+ m_update_flip = false;
+ return;
+ }
+ if (m_init_done && this->xaml_PageSlider->IsEnabled)
+ {
+ /* Make sure to clear any text search */
+ auto doc_old = this->m_docPages->GetAt(m_currpage);
+ doc_old->TextBox = nullptr;
+
+ auto doc = this->m_docPages->GetAt(newValue);
+ if (doc->Content != FULL_RESOLUTION)
+ {
+ spatial_info_t spatial_info = InitSpatial(1);
+ Point ras_size = ComputePageSize(spatial_info, newValue);
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(newValue, ras_size.X, ras_size.Y, true));
+
+ render_task.then([this, newValue, ras_size] (InMemoryRandomAccessStream^ ras)
+ {
+ UpdatePage(newValue, ras, ras_size, FULL_RESOLUTION);
+ this->m_currpage = newValue;
+ m_sliderchange = true;
+ this->m_curr_flipView->SelectedIndex = newValue;
+ }, task_continuation_context::use_current());
+ }
+ else
+ {
+ this->m_curr_flipView->SelectedIndex = newValue;
+ }
+ }
+}
+
+void mupdf_cpp::MainPage::FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e)
+{
+ if (m_init_done && !m_page_update)
+ {
+ int pos = this->m_curr_flipView->SelectedIndex;
+
+ if (pos >= 0)
+ {
+ m_update_flip = true;
+ if (xaml_PageSlider->IsEnabled)
+ {
+ xaml_PageSlider->Value = pos;
+ }
+ if (m_sliderchange)
+ {
+ m_sliderchange = false;
+ return;
+ }
+ else
+ {
+ /* Make sure to clear any text search */
+ auto doc_old = this->m_docPages->GetAt(m_currpage);
+ doc_old->TextBox = nullptr;
+ }
+ /* Get the current page */
+ int curr_page = this->m_currpage;
+ this->RenderRange(pos);
+ this->ReleasePages(curr_page, pos);
+ }
+ }
+}
+
+/* Search Related Code */
+void mupdf_cpp::MainPage::Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ ShowSearchBox();
+ UpdateAppBarButtonViewState();
+}
+
+void mupdf_cpp::MainPage::ShowSearchBox()
+{
+ /* Update the app bar so that we can do the search */
+ StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel");
+
+ if (leftPanel != nullptr && m_insearch)
+ {
+ m_insearch = false;
+ FindBox->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ PrevSearch->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ NextSearch->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ }
+ else if (leftPanel != nullptr && !m_insearch)
+ {
+ /* Search is not going to work in snapped view for now to simplify UI
+ in this cramped case. So see if we can get out of snapped mode. */
+ if (!EnsureUnsnapped())
+ return;
+
+ m_insearch = true;
+ FindBox->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ PrevSearch->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ NextSearch->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ }
+}
+
+void mupdf_cpp::MainPage::ClearTextSearch()
+{
+ /* Clear out any old search result */
+ if (m_text_list->Size > 0)
+ m_text_list->Clear();
+}
+
+void mupdf_cpp::MainPage::ShowSearchResults(int page_num, int box_count)
+{
+ int old_page = this->m_currpage;
+ int new_page = page_num;
+
+ ClearTextSearch();
+
+ /* Compute any scalings */
+ Point screenSize;
+ Point pageSize;
+ Point scale;
+
+ screenSize.Y = this->ActualHeight;
+ screenSize.X = this->ActualWidth;
+ screenSize.X *= screenScale;
+ screenSize.Y *= screenScale;
+ pageSize = mu_doc->GetPageSize(m_currpage);
+ scale = fitPageToScreen(pageSize, screenSize);
+ auto doc_page = this->m_docPages->GetAt(old_page);
+
+ /* Construct our list of rectangles */
+ for (int k = 0; k < box_count; k++)
+ {
+ RectList^ rect_item = ref new RectList();
+ auto curr_box = mu_doc->GetTextSearch(k);
+
+ rect_item->Color = m_textcolor;
+ rect_item->Height = curr_box->LowerRight.Y - curr_box->UpperLeft.Y;
+ rect_item->Width = curr_box->LowerRight.X - curr_box->UpperLeft.X;
+ rect_item->X = curr_box->UpperLeft.X * scale.X;
+ rect_item->Y = curr_box->UpperLeft.Y * scale.Y;
+ rect_item->Width *= (scale.X * doc_page->Zoom);
+ rect_item->Height *= (scale.Y * doc_page->Zoom);
+ rect_item->Index = k.ToString();
+ m_text_list->Append(rect_item);
+ }
+ /* Make sure the current page has its text results cleared */
+ doc_page->TextBox = nullptr;
+
+ /* Go ahead and set our doc item to this in the vertical and horizontal view */
+ m_searchpage = new_page;
+ m_flip_from_searchlink = true;
+
+ if (old_page == new_page)
+ {
+ FlipView_SelectionChanged(nullptr, nullptr);
+ }
+ else
+ {
+ this->m_curr_flipView->SelectedIndex = new_page;
+ }
+ return;
+}
+
+void mupdf_cpp::MainPage::SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (IsNotStandardView())
+ return;
+
+ StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel");
+ TextBox^ findBox = (TextBox^) leftPanel->FindName("FindBox");
+ String^ textToFind = findBox->Text;
+
+ if (this->m_search_active == false && textToFind != nullptr)
+ SearchInDirection(1, textToFind);
+}
+
+void mupdf_cpp::MainPage::SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (IsNotStandardView())
+ return;
+
+ StackPanel^ leftPanel = (StackPanel^) this->TopAppBar->FindName("LeftPanel");
+ TextBox^ findBox = (TextBox^) leftPanel->FindName("FindBox");
+ String^ textToFind = findBox->Text;
+
+ if (this->m_search_active == false && textToFind != nullptr)
+ SearchInDirection(-1, textToFind);
+}
+
+void mupdf_cpp::MainPage::CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ m_searchcts.cancel();
+ xaml_ProgressStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ this->m_search_active = false;
+}
+
+void mupdf_cpp::MainPage::AddTextCanvas()
+{
+ /* Go ahead and set our doc item to this in the vertical and horizontal view */
+ auto doc_page = this->m_docPages->GetAt(m_currpage);
+ assert(doc_page->Content == FULL_RESOLUTION);
+ if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails
+ {
+ doc_page->TextBox = m_text_list;
+ }
+ this->m_search_active = false;
+}
+
+void mupdf_cpp::MainPage::SearchProgress(IAsyncOperationWithProgress<int, double>^ operation, double status)
+{
+ xaml_Progress->Value = status;
+}
+
+void mupdf_cpp::MainPage::SearchInDirection(int dir, String^ textToFind)
+{
+ cancellation_token_source cts;
+ auto token = cts.get_token();
+ m_searchcts = cts;
+ int pos = m_currpage;
+ int start;
+
+ if (m_searchpage == pos)
+ start = pos + dir;
+ else
+ start = pos;
+
+ if (start < 0)
+ return;
+ if (start > this->m_num_pages - 1)
+ return;
+ this->m_search_active = true;
+
+ ProgressBar^ my_xaml_Progress = (ProgressBar^) (this->FindName("xaml_Progress"));
+ xaml_ProgressStack->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ auto temp = mu_doc->SearchDocumentWithProgressAsync(textToFind, dir, start);
+ temp->Progress = ref new AsyncOperationProgressHandler<int, double>(this, &MainPage::SearchProgress);
+
+ auto search_task = create_task(temp, token);
+
+ /* Do the continuation on the ui thread */
+ auto con_task = search_task.then([this, textToFind](int page_num)
+ {
+ xaml_ProgressStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ if (page_num == TEXT_NOT_FOUND)
+ {
+ auto str1 = "\"" + textToFind + "\" Was Not Found In The Search";
+ NotifyUser(str1, StatusMessage);
+ this->m_search_active = false;
+ }
+ else
+ {
+ int box_count = mu_doc->TextSearchCount();
+
+ if (box_count > 0)
+ {
+ this->ShowSearchResults(page_num, box_count);
+ }
+ }
+ }, task_continuation_context::use_current());
+}
+
+/* This is here to handle when we rotate or go into the snapview mode */
+void mupdf_cpp::MainPage::GridSizeChanged()
+{
+ int height = this->ActualHeight;
+ int width = this->ActualWidth;
+ FlipView^ old_flip = m_curr_flipView;
+
+ if (TopAppBar1->IsOpen)
+ {
+ UpdateAppBarButtonViewState();
+ }
+
+ if (height > width)
+ {
+ m_curr_flipView = this->xaml_vert_flipView;
+ this->xaml_zoomCanvas->Height = height;
+ this->xaml_zoomCanvas->Width = width;
+ this->m_curr_flipView->Height = height;
+ this->m_curr_flipView->Width = width;
+
+ xaml_vert_flipView->IsEnabled = true;
+ xaml_vert_flipView->Opacity = 1;
+ xaml_horiz_flipView->IsEnabled = false;
+ xaml_horiz_flipView->Opacity = 0;
+ }
+ else
+ {
+ m_curr_flipView = this->xaml_horiz_flipView;
+ this->xaml_zoomCanvas->Height = height;
+ this->xaml_zoomCanvas->Width = width;
+ this->m_curr_flipView->Height = height;
+ this->m_curr_flipView->Width = width;
+
+ xaml_horiz_flipView->IsEnabled = true;
+ xaml_horiz_flipView->Opacity = 1;
+ xaml_vert_flipView->IsEnabled = false;
+ xaml_vert_flipView->Opacity = 0;
+ }
+
+ if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible)
+ {
+ int height = xaml_OutsideGrid->ActualHeight;
+ int height_app = TopAppBar1->ActualHeight;
+
+ xaml_WebView->Height = height - height_app;
+ }
+
+ UpDatePageSizes();
+
+ if (m_num_pages > 0 && old_flip != m_curr_flipView && old_flip != nullptr)
+ {
+ /* If links are on or off, we need to invalidate */
+ ClearLinks();
+ InvalidateLinks();
+ auto doc = this->m_docPages->GetAt(m_currpage);
+ doc->Content = OLD_RESOLUTION; /* To force a rerender */
+ this->m_curr_flipView->SelectedIndex = this->m_currpage;
+ FlipView_SelectionChanged(nullptr, nullptr);
+ }
+}
+
+void mupdf_cpp::MainPage::UpDatePageSizes()
+{
+ /* Reset the thumb view scaling value */
+ if (m_num_pages > 0)
+ {
+ int num_items = m_thumbnails->Size;
+ for (int i = 0; i < num_items; i++)
+ {
+ DocumentPage ^thumb_page = m_thumbnails->GetAt(i);
+ if (thumb_page != nullptr && thumb_page->Image != nullptr)
+ {
+ int curr_height = thumb_page->Height;
+ int curr_width = thumb_page->Width;
+
+ double scale_x = (double) curr_height / (double) this->xaml_zoomCanvas->Height;
+ double scale_y = (double) curr_width / (double) this->xaml_zoomCanvas->Width;
+
+ double min_scale = max(scale_x, scale_y);
+ thumb_page->Height = curr_height / min_scale;
+ thumb_page->Width = curr_width / min_scale;
+ }
+ }
+ }
+};
+
+/* Link related code */
+void mupdf_cpp::MainPage::Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ m_links_on = !m_links_on;
+
+ if (!m_init_done || IsNotStandardView())
+ return;
+ if (m_links_on)
+ AddLinkCanvas();
+ else
+ ClearLinks();
+}
+
+void mupdf_cpp::MainPage::ClearLinks()
+{
+ /* Make sure surrounding render pages lose their links */
+ for (int k = m_currpage - LOOK_AHEAD; k <= m_currpage + LOOK_AHEAD; k++)
+ {
+ if (k >= 0 && k < m_num_pages)
+ {
+ auto doc_page = this->m_docPages->GetAt(k);
+ if (doc_page->Content == FULL_RESOLUTION)
+ {
+ doc_page->LinkBox = nullptr;
+ }
+ }
+ }
+}
+
+void mupdf_cpp::MainPage::InvalidateLinks()
+{
+ for (int k = 0; k < m_num_pages; k++)
+ m_linkset->SetAt(k, false);
+}
+
+/* Add in the link rects. If we have not already computed them then do that now */
+void mupdf_cpp::MainPage::AddLinkCanvas()
+{
+ /* See if the link object for this page has already been computed */
+ int link_page = m_linkset->GetAt(m_currpage);
+ auto doc_page = this->m_docPages->GetAt(m_currpage);
+
+ if (!link_page)
+ {
+ m_linkset->SetAt(m_currpage, true);
+ int num_links = mu_doc->ComputeLinks(m_currpage);
+ if (num_links == 0) return;
+
+ Point screenSize;
+ Point pageSize;
+ Point scale;
+
+ screenSize.Y = this->ActualHeight;
+ screenSize.X = this->ActualWidth;
+ screenSize.X *= screenScale;
+ screenSize.Y *= screenScale;
+ pageSize = mu_doc->GetPageSize(m_currpage);
+ scale = fitPageToScreen(pageSize, screenSize);
+
+ /* Create a new RectList collection */
+ auto link_list = ref new Platform::Collections::Vector<RectList^>();
+
+ /* Now add the rects */
+ for (int k = 0; k < num_links; k++)
+ {
+ auto curr_link = mu_doc->GetLink(k);
+ if (curr_link->Type != NOT_SET)
+ {
+ RectList^ rect_item = ref new RectList();
+ rect_item->Color = m_linkcolor;
+ rect_item->Height = curr_link->LowerRight.Y - curr_link->UpperLeft.Y;
+ rect_item->Width = curr_link->LowerRight.X - curr_link->UpperLeft.X;
+ rect_item->X = curr_link->UpperLeft.X * scale.X;
+ rect_item->Y = curr_link->UpperLeft.Y * scale.Y;
+ rect_item->Width *= (scale.X * doc_page->Zoom);
+ rect_item->Height *= (scale.Y * doc_page->Zoom);
+ rect_item->Type = curr_link->Type;
+ rect_item->Urilink = curr_link->Uri;
+ rect_item->PageNum = curr_link->PageNum;
+ rect_item->Index = k.ToString();
+ link_list->Append(rect_item);
+ }
+ }
+ /* Now set it in our list of links */
+ m_page_link_list->SetAt(m_currpage, link_list);
+ }
+ /* Go ahead and set our doc item to this in the vertical and horizontal view */
+ if (doc_page->LinkBox == nullptr)
+ {
+ if (doc_page->Content == FULL_RESOLUTION) // We should not be doing links for thumbnails
+ {
+ doc_page->LinkBox = m_page_link_list->GetAt(m_currpage);
+ }
+ }
+}
+
+/* A link was tapped */
+void mupdf_cpp::MainPage::LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)
+{
+ Rectangle^ rect = safe_cast<Rectangle^>(e->OriginalSource);
+ String^ str_index = safe_cast<String^>(rect->Tag);
+ int index = _wtof(str_index->Data());
+
+ if (index >= 0 && index < m_num_pages)
+ {
+ auto link_list = m_page_link_list->GetAt(m_currpage);
+ auto link = link_list->GetAt(index);
+
+ if (link->Type == LINK_GOTO)
+ {
+ this->m_curr_flipView->SelectedIndex = link->PageNum;
+ }
+ else if (link->Type == LINK_URI)
+ {
+ // Set the option to show a warning
+ auto launchOptions = ref new Windows::System::LauncherOptions();
+ launchOptions->TreatAsUntrusted = true;
+
+ // Launch the URI with a warning prompt
+ concurrency::task<bool> launchUriOperation(Windows::System::Launcher::LaunchUriAsync(link->Urilink, launchOptions));
+ launchUriOperation.then([](bool success)
+ {
+ if (success)
+ {
+ // URI launched
+ }
+ else
+ {
+ // URI launch failed
+ }
+ });
+ }
+ }
+}
+
+/* Bring up the contents */
+void mupdf_cpp::MainPage::ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (this->m_num_pages < 0)
+ return;
+
+ if (IsNotStandardView() && !this->xaml_ListView->IsEnabled)
+ return;
+
+ if (this->xaml_ListView->IsEnabled)
+ {
+ this->xaml_ListView->Opacity = 0.0;
+ this->xaml_ListView->IsEnabled = false;
+ this->m_curr_flipView->Opacity = 1.0;
+ this->m_curr_flipView->IsEnabled = true;
+ this->xaml_PageSlider->IsEnabled = true;
+ }
+ else
+ {
+ if (xaml_ListView->Items->Size == 0)
+ {
+ int size_content = mu_doc->ComputeContents();
+ /* Bring up the content now */
+ for (int k = 0; k < size_content; k++)
+ {
+ ContentItem^ item = mu_doc->GetContent(k);
+ this->xaml_ListView->Items->Append(item);
+ }
+ if (size_content > 0)
+ {
+ this->xaml_ListView->Opacity = 1.0;
+ this->xaml_ListView->IsEnabled = true;
+ this->m_curr_flipView->Opacity = 0.0;
+ this->m_curr_flipView->IsEnabled = false;
+ this->xaml_PageSlider->IsEnabled = false;
+ }
+ }
+ else
+ {
+ this->xaml_ListView->Opacity = 1.0;
+ this->xaml_ListView->IsEnabled = true;
+ this->m_curr_flipView->Opacity = 0.0;
+ this->m_curr_flipView->IsEnabled = false;
+ this->xaml_PageSlider->IsEnabled = false;
+ }
+ }
+}
+
+void mupdf_cpp::MainPage::ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e)
+{
+ ContentItem^ b = safe_cast<ContentItem^>(e->ClickedItem);
+ int newpage = b->Page;
+
+ if (newpage > -1 && newpage < this->m_num_pages)
+ {
+ this->xaml_ListView->Opacity = 0.0;
+ this->xaml_ListView->IsEnabled = false;
+ this->m_curr_flipView->Opacity = 1.0;
+ this->m_curr_flipView->IsEnabled = true;
+ this->xaml_PageSlider->IsEnabled = true;
+
+ int old_page = this->m_currpage;
+ this->m_curr_flipView->SelectedIndex = newpage;
+ this->m_currpage = newpage;
+ }
+}
+
+void mupdf_cpp::MainPage::Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (this->m_num_pages < 0) return;
+
+ if (xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible)
+ {
+ /* Go back to flip view */
+ xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ this->xaml_MainGrid->Opacity = 1.0;
+ this->m_curr_flipView->IsEnabled = true;
+ this->xaml_PageSlider->IsEnabled = true;
+ xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ xaml_WebView->Opacity = 0.0;
+
+ }
+ else if (this->m_curr_flipView->IsEnabled)
+ {
+ String^ html_string = mu_doc->ComputeHTML(this->m_currpage);
+ xaml_WebView->Visibility = Windows::UI::Xaml::Visibility::Visible;
+ this->xaml_MainGrid->Opacity = 0.0;
+ this->m_curr_flipView->IsEnabled = false;
+ this->xaml_PageSlider->IsEnabled = false;
+ this->xaml_WebView->NavigateToString(html_string);
+ this->xaml_WebView->Height = this->ActualHeight - 2 * this->BottomAppBar->ActualHeight;
+ /* Check if thumb rendering is done. If not then restart */
+ }
+}
+
+/* Need to handle resizing of app bar to make sure everything fits */
+void mupdf_cpp::MainPage::topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ /* Remove search box in snapped view as we don't have the room for it */
+ if (ApplicationView::Value == ApplicationViewState::Snapped && m_insearch)
+ ShowSearchBox();
+ UpdateAppBarButtonViewState();
+}
+
+void mupdf_cpp::MainPage::UpdateAppBarButtonViewState()
+{
+ String ^viewState = Windows::UI::ViewManagement::ApplicationView::Value.ToString();
+ VisualStateManager::GoToState(Search, viewState, true);
+ VisualStateManager::GoToState(Contents, viewState, true);
+ VisualStateManager::GoToState(Links, viewState, true);
+ VisualStateManager::GoToState(Reflow, viewState, true);
+ VisualStateManager::GoToState(ZoomIn, viewState, true);
+ VisualStateManager::GoToState(ZoomOut, viewState, true);
+ VisualStateManager::GoToState(PrevSearch, viewState, true);
+ VisualStateManager::GoToState(NextSearch, viewState, true);
+}
+
+/* Manipulation zooming with touch input */
+void mupdf_cpp::MainPage::ScrollChanged(Platform::Object^ sender,
+ Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e)
+{
+ ScrollViewer^ scrollviewer = safe_cast<ScrollViewer^> (sender);
+ auto doc_page = this->m_docPages->GetAt(m_currpage);
+
+ if (scrollviewer->ZoomFactor == doc_page->Zoom)
+ return;
+
+ if (!e->IsIntermediate)
+ {
+ doc_page->Zoom = scrollviewer->ZoomFactor;
+ int page = m_currpage;
+
+ /* Render at new resolution */
+ spatial_info_t spatial_info = InitSpatial(doc_page->Zoom);
+ Point ras_size = ComputePageSize(spatial_info, page);
+
+ /* Go ahead and create display list if we dont have one for this page */
+ auto render_task =
+ create_task(mu_doc->RenderPageAsync(page, ras_size.X, ras_size.Y, true));
+ render_task.then([this, page, ras_size] (InMemoryRandomAccessStream^ ras)
+ {
+ ReplaceImage(page, ras, ras_size);
+ }, task_continuation_context::use_current());
+ }
+}
+
+/* Needed to find scrollviewer child from template of flipview item */
+Windows::UI::Xaml::FrameworkElement^ FindVisualChildByName(DependencyObject^ obj, String^ name)
+{
+ FrameworkElement^ ret;
+ if (obj == nullptr) return nullptr;
+
+ int numChildren = VisualTreeHelper::GetChildrenCount(obj);
+
+ for (int i = 0; i < numChildren; i++)
+ {
+ auto objChild = VisualTreeHelper::GetChild(obj, i);
+ auto child = safe_cast<FrameworkElement^>(objChild);
+ if (child != nullptr && child->Name == name)
+ {
+ return child;
+ }
+ ret = FindVisualChildByName(objChild, name);
+ if (ret != nullptr)
+ break;
+ }
+ return ret;
+}
+
+void mupdf_cpp::MainPage::ZoomInPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (!m_init_done || IsNotStandardView()) return;
+ NonTouchZoom(ZOOM_IN);
+}
+
+void mupdf_cpp::MainPage::ZoomOutPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ if (!m_init_done || IsNotStandardView()) return;
+ NonTouchZoom(ZOOM_OUT);
+}
+
+void MainPage::NonTouchZoom(int zoom)
+{
+ ScrollViewer^ scrollviewer;
+ FlipViewItem^ item = safe_cast<FlipViewItem^>
+ (m_curr_flipView->ItemContainerGenerator->ContainerFromIndex(m_currpage));
+ auto item2 = m_curr_flipView->ItemContainerGenerator->ContainerFromIndex(m_currpage);
+
+ /* We don't know which one so check for both */
+ ScrollViewer^ t1 =
+ safe_cast<ScrollViewer^> (FindVisualChildByName(item2, "xaml_ScrollView_v"));
+ ScrollViewer^ t2 =
+ safe_cast<ScrollViewer^> (FindVisualChildByName(item2, "xaml_ScrollView_h"));
+
+ if (t1 != nullptr)
+ scrollviewer = t1;
+ else
+ scrollviewer = t2;
+
+ if (scrollviewer == nullptr)
+ return;
+
+ double curr_zoom = scrollviewer->ZoomFactor;
+ if (zoom == ZOOM_IN)
+ {
+ curr_zoom = curr_zoom + KEYBOARD_ZOOM_STEP;
+ if (curr_zoom > ZOOM_MAX) curr_zoom = ZOOM_MAX;
+ }
+ else if (zoom == ZOOM_OUT)
+ {
+ curr_zoom = curr_zoom - KEYBOARD_ZOOM_STEP;
+ if (curr_zoom < ZOOM_MIN) curr_zoom = ZOOM_MIN;
+ } else
+ return;
+
+ scrollviewer->ZoomToFactor(curr_zoom);
+}
+
+/* Zoom in and out for keyboard only case. */
+void MainPage::OnKeyDown(KeyRoutedEventArgs^ e)
+{
+ if (!m_init_done || IsNotStandardView()) return;
+
+ long val = (long) (e->Key);
+
+ if (val == KEY_PLUS)
+ NonTouchZoom(ZOOM_IN);
+ else if (val == KEY_MINUS)
+ NonTouchZoom(ZOOM_OUT);
+ else
+ return;
+}
+
+void mupdf_cpp::MainPage::PasswordOK(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+ /* If password checks out then go ahead and start rendering */
+ if (mu_doc->ApplyPassword(xaml_password->Password))
+ {
+ xaml_password->Password = nullptr;
+ xaml_PasswordStack->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+ InitialRender();
+ RenderThumbs();
+ }
+ else
+ NotifyUser("Incorrect Password", StatusMessage);
+}
+
+/* So that we know if we are in a standard view case and not in reflow, or
+ * content type */
+bool mupdf_cpp::MainPage::IsNotStandardView()
+{
+ return (this->xaml_ListView->Opacity == 1.0 ||
+ xaml_WebView->Visibility == Windows::UI::Xaml::Visibility::Visible);
+}
diff --git a/platform/winrt/mupdf_cpp/MainPage.xaml.h b/platform/winrt/mupdf_cpp/MainPage.xaml.h
new file mode 100644
index 00000000..80978bc8
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/MainPage.xaml.h
@@ -0,0 +1,177 @@
+//
+// MainPage.xaml.h
+// Declaration of the MainPage class.
+//
+
+#pragma once
+
+#include "MainPage.g.h"
+#include "ppl.h"
+#include "ppltasks.h"
+#include <collection.h>
+#include <algorithm>
+#include <assert.h>
+#include "DocumentPage.h"
+#include "status.h"
+
+using namespace Platform;
+using namespace Concurrency;
+using namespace Windows::Storage;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Media::Imaging;
+using namespace Windows::Storage::Streams;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Shapes;
+using namespace Windows::Foundation::Collections;
+using namespace Platform::Collections;
+using namespace Windows::UI::ViewManagement;
+using namespace Windows::UI::Popups;
+using namespace Windows::UI::Xaml::Navigation;
+using namespace Windows::ApplicationModel;
+using namespace mupdfwinrt;
+
+typedef enum
+{
+ StatusMessage,
+ ErrorMessage
+} NotifyType_t;
+
+typedef enum {
+ REN_AVAILABLE = 0,
+ REN_THUMBS,
+ REN_UPDATE_THUMB_CANVAS,
+ REN_PAGE /* Used to ignore value when source based setting */
+} RenderingStatus_t;
+
+typedef struct spatial_info_s
+{
+ Point size;
+ double scale_factor;
+} spatial_info_t;
+
+namespace mupdf_cpp
+{
+ /// <summary>
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ /// </summary>
+ public ref class MainPage sealed
+ {
+ public:
+ MainPage();
+
+ property Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^ ProtocolEvent
+ {
+ Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^ get() { return _protocolEventArgs; }
+ void set(Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^ value) { _protocolEventArgs = value; }
+ }
+
+ property Windows::ApplicationModel::Activation::FileActivatedEventArgs^ FileEvent
+ {
+ Windows::ApplicationModel::Activation::FileActivatedEventArgs^ get() { return _fileEventArgs; }
+ void set(Windows::ApplicationModel::Activation::FileActivatedEventArgs^ value) { _fileEventArgs = value; }
+ }
+
+ protected:
+ virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
+ virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) override;
+
+ private:
+ Windows::Foundation::EventRegistrationToken _pageLoadedHandlerToken;
+ Vector<DocumentPage^>^ m_docPages;
+ Vector<DocumentPage^>^ m_thumbnails;
+ Vector<IVector<RectList^>^>^ m_page_link_list;
+ Vector<int>^ m_linkset;
+ Vector<RectList^>^ m_text_list;
+ int m_rectlist_page;
+ mudocument^ mu_doc;
+ bool m_file_open;
+ int m_currpage;
+ int m_searchpage;
+ int m_num_pages;
+ int m_slider_min;
+ int m_slider_max;
+ bool m_init_done;
+ bool m_flip_from_searchlink;
+ bool m_links_on;
+ int m_search_rect_count;
+ cancellation_token_source m_searchcts;
+ bool m_page_update;
+ long long m_memory_use;
+ WriteableBitmap ^m_BlankBmp;
+ String^ m_textcolor;
+ String^ m_linkcolor;
+ FlipView^ m_curr_flipView;
+ RenderingStatus_t m_ren_status;
+ cancellation_token_source m_ThumbCancel;
+ bool m_insearch; /* Used for UI display */
+ bool m_search_active; /* Used to avoid multiple UI clicks */
+ bool m_sliderchange;
+ bool m_update_flip;
+ double m_Progress;
+
+ void ReplaceImage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size);
+ void Picker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void Searcher(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void OpenDocumentPrep(StorageFile^ file);
+ void OpenDocument(StorageFile^ file);
+ void InitialRender();
+ void RenderRange(int curr_page);
+ void CleanUp();
+ void UpdatePage(int page_num, InMemoryRandomAccessStream^ ras, Point ras_size, Page_Content_t content_type);
+ void CreateBlank(int width, int height);
+ void HandleFileNotFoundException(Platform::COMException^ e);
+ void NotifyUserFileNotExist();
+ void SetFlipView();
+ void Slider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e);
+ void Slider_Released(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e);
+ void FlipView_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e);
+ void SearchNext(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void SearchPrev(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void CancelSearch(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void SearchInDirection(int dir, String^ textToFind);
+ void ShowSearchResults(int page_num, int box_count);
+ void ClearTextSearch();
+ void AddTextCanvas();
+ void GridSizeChanged();
+ void UpDatePageSizes();
+ void ShowThumbnail();
+ void Canvas_ManipulationCompleted(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationCompletedRoutedEventArgs^ e);
+ void AddThumbNail(int page_num, FlipView^ flip_view);
+ spatial_info_t InitSpatial(double scale);
+ void RenderThumbs();
+ void SetThumb(int page_num, bool replace);
+ void ReleasePages(int old_page, int new_page);
+ void Linker(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void AddLinkCanvas();
+ void ClearLinks();
+ void InvalidateLinks();
+ void ContentDisplay(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void ListView_Single_Tap(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e);
+ void ContentSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ e);
+ void ContentChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
+ void Reflower(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void topAppBar_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void UpdateAppBarButtonViewState();
+ bool EnsureUnsnapped();
+ void NotifyUser(String^ strMessage, NotifyType_t type);
+ void ExitInvokedHandler(Windows::UI::Popups::IUICommand^ command);
+ void OKInvokedHandler(Windows::UI::Popups::IUICommand^ command);
+ Point ComputePageSize(spatial_info_t spatial_info, int page_num);
+ void ScrollChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs^ e);
+ void LinkTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e);
+ void SearchProgress(IAsyncOperationWithProgress<int, double>^ operation, double status);
+ void PasswordOK(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void App_Suspending(Object^ sender, SuspendingEventArgs^ e);
+ void ZoomInPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void ZoomOutPress(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+ void NonTouchZoom(int zoom);
+ void ShowSearchBox();
+ bool IsNotStandardView();
+ void Page_Loaded(Object^ sender, RoutedEventArgs^ e);
+ Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^ _protocolEventArgs;
+ Windows::ApplicationModel::Activation::FileActivatedEventArgs^ _fileEventArgs;
+ };
+}
diff --git a/platform/winrt/mupdf_cpp/Package.appxmanifest b/platform/winrt/mupdf_cpp/Package.appxmanifest
new file mode 100644
index 00000000..862154f8
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/Package.appxmanifest
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+ <Identity Name="ArtifexSoftware.MuPDF" Publisher="CN=B93265AA-82AD-458A-A08E-7069B8ED88B5" Version="1.0.0.0" />
+ <Properties>
+ <DisplayName>MuPDF</DisplayName>
+ <PublisherDisplayName>Artifex Software</PublisherDisplayName>
+ <Logo>Assets\StoreLogo.png</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.2.1</OSMinVersion>
+ <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language="x-generate" />
+ </Resources>
+ <Applications>
+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="mupdf_cpp.App">
+ <VisualElements DisplayName="MuPDF" Logo="Assets\Logo.png" SmallLogo="assets/mupdf_smallogo.png" Description="A lightweight, high quality PDF/XPS/CBZ viewer for Windows 8 devices." ForegroundText="light" BackgroundColor="#464646">
+ <DefaultTile ShowName="allLogos" />
+ <SplashScreen Image="Assets\mupdf_splash.png" />
+ </VisualElements>
+ <Extensions>
+ <Extension Category="windows.fileTypeAssociation">
+ <FileTypeAssociation Name=".pdf">
+ <EditFlags OpenIsSafe="true" />
+ <SupportedFileTypes>
+ <FileType>.pdf</FileType>
+ <FileType>.xps</FileType>
+ <FileType>.cbz</FileType>
+ <FileType>.oxps</FileType>
+ </SupportedFileTypes>
+ </FileTypeAssociation>
+ </Extension>
+ </Extensions>
+ </Application>
+ </Applications>
+</Package> \ No newline at end of file
diff --git a/platform/winrt/mupdf_cpp/RectList.cpp b/platform/winrt/mupdf_cpp/RectList.cpp
new file mode 100644
index 00000000..b9c1560d
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/RectList.cpp
@@ -0,0 +1,9 @@
+#include "pch.h"
+#include "RectList.h"
+
+namespace mupdf_cpp
+{
+ RectList::RectList(void)
+ {
+ }
+}
diff --git a/platform/winrt/mupdf_cpp/RectList.h b/platform/winrt/mupdf_cpp/RectList.h
new file mode 100644
index 00000000..999fe3d2
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/RectList.h
@@ -0,0 +1,153 @@
+#pragma once
+
+/* WinRT RectList class for binding a collection of rects to the xaml ui */
+using namespace Windows::UI::Xaml::Media::Imaging;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Platform; /* For String */
+
+namespace mupdf_cpp
+{
+ [Windows::UI::Xaml::Data::Bindable] // in c++, adding this attribute to ref classes enables data binding for more info search for 'Bindable' on the page http://go.microsoft.com/fwlink/?LinkId=254639
+
+ public ref class RectList sealed
+ {
+ private:
+ int height;
+ int width;
+ int x;
+ int y;
+ String^ color;
+ /* These are used to store the link infomation */
+ int type;
+ int pagenum;
+ Windows::Foundation::Uri ^uri;
+ String^ index; // For identify which rectangle was tapped
+ public:
+ RectList(void);
+
+ property String^ Index
+ {
+ String^ get()
+ {
+ return ((String^) index);
+ }
+
+ void set(String^ value)
+ {
+ index = value;
+ }
+ }
+
+ property String^ Color
+ {
+ String^ get()
+ {
+ return (color);
+ }
+
+ void set(String^ value)
+ {
+ color = value;
+ }
+ }
+
+ property int Height
+ {
+ int get()
+ {
+ return ((int) height);
+ }
+
+ void set(int value)
+ {
+ if (value < 0)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ height = value;
+ }
+ }
+
+ property int Width
+ {
+ int get()
+ {
+ return width;
+ }
+
+ void set(int value)
+ {
+ if (value < 0)
+ {
+ throw ref new Platform::InvalidArgumentException();
+ }
+ width = value;
+ }
+ }
+
+ property int X
+ {
+ int get()
+ {
+ return x;
+ }
+
+ void set(int value)
+ {
+ x = value;
+ }
+ }
+
+ property int Y
+ {
+ int get()
+ {
+ return y;
+ }
+
+ void set(int value)
+ {
+ y = value;
+ }
+ }
+
+ property int Type
+ {
+ int get()
+ {
+ return type;
+ }
+
+ void set(int value)
+ {
+ type = value;
+ }
+ }
+
+ property int PageNum
+ {
+ int get()
+ {
+ return pagenum;
+ }
+
+ void set(int value)
+ {
+ pagenum = value;
+ }
+ }
+
+ property Windows::Foundation::Uri^ Urilink
+ {
+ Windows::Foundation::Uri^ get()
+ {
+ return uri;
+ }
+
+ void set(Windows::Foundation::Uri^ value)
+ {
+ uri = value;
+ }
+ }
+ };
+}
diff --git a/platform/winrt/mupdf_cpp/mupdf_cpp.rc b/platform/winrt/mupdf_cpp/mupdf_cpp.rc
new file mode 100644
index 00000000..0d7c7a75
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/mupdf_cpp.rc
Binary files differ
diff --git a/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj b/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj
new file mode 100644
index 00000000..b5da02da
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0204a4e7-f1b8-4268-a67c-a2c674b4742d}</ProjectGuid>
+ <RootNamespace>mupdf_cpp</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <PackageCertificateKeyFile>mupdf_cpp_StoreKey.pfx</PackageCertificateKeyFile>
+ <PackageCertificateThumbprint>CD9F039F746ECFA4533010958399D3B0FFB6B3B5</PackageCertificateThumbprint>
+ <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <AdditionalOptions>/APPCONTAINER /SAFESEH %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <SectionAlignment>
+ </SectionAlignment>
+ <AdditionalOptions>/APPCONTAINER %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <AdditionalOptions>/APPCONTAINER /SAFESEH %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <SectionAlignment>
+ </SectionAlignment>
+ <AdditionalOptions>/APPCONTAINER /SAFESEH %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <AdditionalOptions>/APPCONTAINER /SAFESEH %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../../include/;../mupdfwinrt/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies);../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib;../$(Platform)/$(Configuration)/mupdfwinrt.lib</AdditionalDependencies>
+ <SectionAlignment>
+ </SectionAlignment>
+ <AdditionalOptions>/APPCONTAINER %(AdditionalOptions)</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\mupdfwinrt\status.h" />
+ <ClInclude Include="DocumentPage.h" />
+ <ClInclude Include="pch.h" />
+ <ClInclude Include="App.xaml.h">
+ <DependentUpon>App.xaml</DependentUpon>
+ </ClInclude>
+ <ClInclude Include="MainPage.xaml.h">
+ <DependentUpon>MainPage.xaml</DependentUpon>
+ </ClInclude>
+ <ClInclude Include="RectList.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Page Include="Common\StandardStyles.xaml">
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="MainPage.xaml">
+ <SubType>Designer</SubType>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <AppxManifest Include="Package.appxmanifest">
+ <SubType>Designer</SubType>
+ </AppxManifest>
+ <None Include="mupdf_cpp_StoreKey.pfx" />
+ <None Include="mupdf_cpp_TemporaryKey.pfx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="App.xaml.cpp">
+ <DependentUpon>App.xaml</DependentUpon>
+ </ClCompile>
+ <ClCompile Include="DocumentPage.cpp" />
+ <ClCompile Include="MainPage.xaml.cpp">
+ <DependentUpon>MainPage.xaml</DependentUpon>
+ </ClCompile>
+ <ClCompile Include="pch.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="RectList.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="Assets\Logo.Scale-100.png" />
+ <Image Include="Assets\Logo.Scale-140.png" />
+ <Image Include="Assets\Logo.Scale-180.png" />
+ <Image Include="Assets\Logo.Scale-80.png">
+ <DeploymentContent>true</DeploymentContent>
+ </Image>
+ <Image Include="Assets\mupdf_smallogo.png" />
+ <Image Include="Assets\mupdf_splash.png" />
+ <Image Include="Assets\StoreLogo.scale-100.png">
+ <DeploymentContent>true</DeploymentContent>
+ </Image>
+ <Image Include="Assets\StoreLogo.scale-140.png">
+ <DeploymentContent>true</DeploymentContent>
+ </Image>
+ <Image Include="Assets\StoreLogo.scale-180.png">
+ <DeploymentContent>true</DeploymentContent>
+ </Image>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\mupdfwinrt\mupdfwinrt.vcxproj">
+ <Project>{9e6ab41d-09a7-45a6-a53b-1e4bf3ac5b33}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Package.StoreAssociation.xml" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj.filters b/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj.filters
new file mode 100644
index 00000000..c1791b26
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/mupdf_cpp.vcxproj.filters
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Common">
+ <UniqueIdentifier>0204a4e7-f1b8-4268-a67c-a2c674b4742d</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Assets">
+ <UniqueIdentifier>a297f943-f0d7-4847-867e-a7aa1ef7f484</UniqueIdentifier>
+ </Filter>
+ <Page Include="Common\StandardStyles.xaml">
+ <Filter>Common</Filter>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="App.xaml.cpp" />
+ <ClCompile Include="MainPage.xaml.cpp" />
+ <ClCompile Include="pch.cpp" />
+ <ClCompile Include="DocumentPage.cpp" />
+ <ClCompile Include="RectList.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="pch.h" />
+ <ClInclude Include="App.xaml.h" />
+ <ClInclude Include="MainPage.xaml.h" />
+ <ClInclude Include="DocumentPage.h" />
+ <ClInclude Include="RectList.h" />
+ <ClInclude Include="..\mupdfwinrt\status.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <AppxManifest Include="Package.appxmanifest" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="mupdf_cpp_TemporaryKey.pfx" />
+ <None Include="Package.StoreAssociation.xml" />
+ <None Include="mupdf_cpp_StoreKey.pfx" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="MainPage.xaml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="Assets\mupdf_smallogo.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\Logo.Scale-80.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\Logo.Scale-100.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\Logo.Scale-140.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\Logo.Scale-180.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\mupdf_splash.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\StoreLogo.scale-100.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\StoreLogo.scale-140.png">
+ <Filter>Assets</Filter>
+ </Image>
+ <Image Include="Assets\StoreLogo.scale-180.png">
+ <Filter>Assets</Filter>
+ </Image>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/mupdf_cpp/pch.cpp b/platform/winrt/mupdf_cpp/pch.cpp
new file mode 100644
index 00000000..01484ff5
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/pch.cpp
@@ -0,0 +1,6 @@
+//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"
diff --git a/platform/winrt/mupdf_cpp/pch.h b/platform/winrt/mupdf_cpp/pch.h
new file mode 100644
index 00000000..fadf910d
--- /dev/null
+++ b/platform/winrt/mupdf_cpp/pch.h
@@ -0,0 +1,9 @@
+//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
+
+#include <collection.h>
+#include "App.xaml.h"
diff --git a/platform/winrt/mupdfwinrt/Cache.cpp b/platform/winrt/mupdfwinrt/Cache.cpp
new file mode 100644
index 00000000..77e253f0
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/Cache.cpp
@@ -0,0 +1,114 @@
+#include "pch.h"
+#include "Cache.h"
+
+Cache::Cache(void)
+{
+ this->size = 0;
+ this->head = NULL;
+ this->tail = NULL;
+}
+
+Cache::~Cache(void)
+{
+}
+
+void Cache::Empty(fz_context *mu_ctx)
+{
+ if (this != nullptr) {
+ cache_entry_t *curr_entry = this->head;
+
+ while (curr_entry != NULL)
+ {
+ cache_entry_t *old_entry = curr_entry;
+ curr_entry = old_entry->next;
+ fz_drop_display_list(mu_ctx, old_entry->dlist);
+ delete old_entry;
+ }
+ this->size = 0;
+ this->head = NULL;
+ this->tail = NULL;
+ }
+}
+
+void Cache::AddEntry(int value, fz_display_list *dlist, fz_context *mu_ctx)
+{
+ std::lock_guard<std::mutex> lock(cache_lock);
+
+ /* If full, then delete the tail */
+ if (size >= MAX_DISPLAY_CACHE_SIZE)
+ {
+ cache_entry_t *curr_entry = this->tail;
+ cache_entry_t *prev_entry = curr_entry->prev;
+
+ if (prev_entry != NULL)
+ prev_entry->next = NULL;
+ else
+ head = NULL;
+
+ tail = prev_entry;
+
+ /* Decrement the caches rc of this list */
+ fz_drop_display_list(mu_ctx, curr_entry->dlist);
+ delete curr_entry;
+ size--;
+ }
+
+ /* Make a new entry and stick at head */
+ cache_entry_t *new_entry = new cache_entry_t;
+
+ new_entry->dlist = dlist;
+ new_entry->index = value;
+ new_entry->prev = NULL;
+ if (head == NULL)
+ {
+ new_entry->next = NULL;
+ head = new_entry;
+ tail = new_entry;
+ }
+ else
+ {
+ new_entry->next = head;
+ head->prev = new_entry;
+ head = new_entry;
+ }
+ size++;
+ /* We are going to use this item now */
+ fz_keep_display_list(mu_ctx, new_entry->dlist);
+}
+
+fz_display_list* Cache::UseEntry(int value, fz_context *mu_ctx)
+{
+ std::lock_guard<std::mutex> lock(cache_lock);
+ cache_entry_t *curr_entry = this->head;
+
+ while (curr_entry != NULL)
+ {
+ if (curr_entry->index == value)
+ break;
+ curr_entry = curr_entry->next;
+ }
+ if (curr_entry != NULL)
+ {
+ fz_keep_display_list(mu_ctx, curr_entry->dlist);
+ /* Move this to the front */
+ if (curr_entry != head)
+ {
+ cache_entry_t *prev_entry = curr_entry->prev;
+ cache_entry_t *next_entry = curr_entry->next;
+ prev_entry->next = next_entry;
+
+ if (next_entry != NULL)
+ next_entry->prev = prev_entry;
+ else
+ tail = prev_entry;
+
+ curr_entry->prev = NULL;
+ curr_entry->next = head;
+ head->prev = curr_entry;
+ head = curr_entry;
+ }
+ return curr_entry->dlist;
+ }
+ else
+ return NULL;
+}
diff --git a/platform/winrt/mupdfwinrt/Cache.h b/platform/winrt/mupdfwinrt/Cache.h
new file mode 100644
index 00000000..0763dba4
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/Cache.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <mutex>
+extern "C" {
+ #include "mupdf/fitz.h"
+}
+
+#define MAX_DISPLAY_CACHE_SIZE 3
+
+typedef struct cache_entry_s cache_entry_t;
+
+struct cache_entry_s
+{
+ fz_display_list *dlist;
+ cache_entry_t *next;
+ cache_entry_t *prev;
+ int index;
+};
+
+class Cache
+{
+private:
+ int size;
+ cache_entry_t *head;
+ cache_entry_t *tail;
+ std::mutex cache_lock;
+
+public:
+ Cache(void);
+ ~Cache(void);
+ fz_display_list* UseEntry(int value, fz_context *mu_ctx);
+ void AddEntry(int value, fz_display_list *dlist, fz_context *mu_ctx);
+ void Empty(fz_context *mu_ctx);
+};
diff --git a/platform/winrt/mupdfwinrt/ContentItem.cpp b/platform/winrt/mupdfwinrt/ContentItem.cpp
new file mode 100644
index 00000000..eff1f58b
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/ContentItem.cpp
@@ -0,0 +1,11 @@
+#include "pch.h"
+#include "ContentItem.h"
+
+using namespace mupdfwinrt;
+
+ContentItem::ContentItem(void)
+{
+ StringOrig = nullptr;
+ StringMargin = nullptr;
+ Page = 0;
+}
diff --git a/platform/winrt/mupdfwinrt/ContentItem.h b/platform/winrt/mupdfwinrt/ContentItem.h
new file mode 100644
index 00000000..90069459
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/ContentItem.h
@@ -0,0 +1,58 @@
+#pragma once
+
+using namespace Platform; /* For String */
+
+namespace mupdfwinrt {
+ [Windows::UI::Xaml::Data::Bindable]
+ public ref class ContentItem sealed
+ {
+ private:
+ int page;
+ String^ string_orig;
+ String^ string_margin;
+
+ public:
+ ContentItem(void);
+
+ property int Page
+ {
+ int get()
+ {
+ return (page);
+ }
+
+ void set(int value)
+ {
+ if (value < 0)
+ throw ref new Platform::InvalidArgumentException();
+ page = value;
+ }
+ }
+
+ property String^ StringOrig
+ {
+ String^ get()
+ {
+ return (string_orig);
+ }
+
+ void set(String^ value)
+ {
+ string_orig = value;
+ }
+ }
+
+ property String^ StringMargin
+ {
+ String^ get()
+ {
+ return (string_margin);
+ }
+
+ void set(String^ value)
+ {
+ string_margin = value;
+ }
+ }
+ };
+}
diff --git a/platform/winrt/mupdfwinrt/Links.cpp b/platform/winrt/mupdfwinrt/Links.cpp
new file mode 100644
index 00000000..50db8ff2
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/Links.cpp
@@ -0,0 +1,12 @@
+#include "pch.h"
+#include "Links.h"
+#include "status.h"
+
+using namespace mupdfwinrt;
+
+Links::Links(void)
+{
+ this->uri = nullptr;
+ this->page_num = -1;
+ this->type = NOT_SET;
+}
diff --git a/platform/winrt/mupdfwinrt/Links.h b/platform/winrt/mupdfwinrt/Links.h
new file mode 100644
index 00000000..39ebfc0b
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/Links.h
@@ -0,0 +1,88 @@
+#pragma once
+
+#include "utils.h"
+#include "status.h"
+
+using namespace Windows::Foundation;
+
+namespace mupdfwinrt
+{
+ public ref class Links sealed
+ {
+ private:
+ int type;
+ Point upper_left;
+ Point lower_right;
+ Windows::Foundation::Uri ^uri;
+ int page_num;
+ public:
+ Links(void);
+
+ property int Type
+ {
+ int get()
+ {
+ return (type);
+ }
+
+ void set(int value)
+ {
+ if (value > NOT_SET)
+ throw ref new Platform::InvalidArgumentException();
+ type = value;
+ }
+ }
+
+ property Point UpperLeft
+ {
+ Point get()
+ {
+ return upper_left;
+ }
+
+ void set(Point value)
+ {
+ upper_left = value;
+ }
+ }
+
+ property Point LowerRight
+ {
+ Point get()
+ {
+ return lower_right;
+ }
+
+ void set(Point value)
+ {
+ lower_right = value;
+ }
+ }
+
+ property int PageNum
+ {
+ int get()
+ {
+ return page_num;
+ }
+
+ void set(int value)
+ {
+ page_num = value;
+ }
+ }
+
+ property Windows::Foundation::Uri^ Uri
+ {
+ Windows::Foundation::Uri^ get()
+ {
+ return uri;
+ }
+
+ void set(Windows::Foundation::Uri^ value)
+ {
+ uri = value;
+ }
+ }
+ };
+}
diff --git a/platform/winrt/mupdfwinrt/muctx.cpp b/platform/winrt/mupdfwinrt/muctx.cpp
new file mode 100644
index 00000000..56c6f3a9
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/muctx.cpp
@@ -0,0 +1,569 @@
+#pragma once
+
+#include "pch.h"
+#include "muctx.h"
+
+/* This class interfaces to mupdf API with minimal windows objects
+ * (other than the file streaming stuff) */
+
+/* File streaming set up for mupdf */
+
+/* win_read_file etc. Reading of windows managed stream. This is
+ * not ideal as I have to read into a managed buffer and then transfer
+ * to the actual buffer I want. I would like a more direct approach.
+ * Alternate approach is to push this off outside the winrt and read
+ * from a memory buffer. */
+static int win_read_file(fz_stream *stm, unsigned char *buf, int len)
+{
+ void *temp = stm->state;
+ win_stream_struct *stream = reinterpret_cast <win_stream_struct*> (temp);
+ IRandomAccessStream^ Stream = stream->stream;
+ unsigned long long curr_pos = Stream->Position;
+ unsigned long long length = Stream->Size;
+ DataReader^ local_reader = ref new DataReader(Stream);
+ DataReaderLoadOperation^ result = local_reader->LoadAsync(len);
+
+ /* Block on the Async call. This is not on the UI thread. */
+ while(result->Status != AsyncStatus::Completed) {
+
+ }
+ result->GetResults();
+ int curr_len2 = local_reader->UnconsumedBufferLength;
+ if (curr_len2 < len)
+ len = curr_len2;
+
+ Platform::Array<unsigned char>^ arrByte = ref new Platform::Array<unsigned char>(len);
+ local_reader->ReadBytes(arrByte);
+
+ memcpy(buf, arrByte->Data, len);
+ local_reader->DetachStream();
+
+ return len;
+}
+
+static void win_seek_file(fz_stream *stm, int offset, int whence)
+{
+ void *temp = stm->state;
+ win_stream_struct *stream = reinterpret_cast <win_stream_struct*> (temp);
+ IRandomAccessStream^ Stream = stream->stream;
+ unsigned long long curr_pos = Stream->Position;
+ unsigned long long length = Stream->Size;
+ unsigned long long n;
+
+ if (whence == SEEK_END)
+ {
+ n = length + offset;
+ }
+ else if (whence == SEEK_CUR)
+ {
+ n = curr_pos + offset;
+ }
+ else if (whence == SEEK_SET)
+ {
+ n = offset;
+ }
+ Stream->Seek(n);
+ curr_pos = Stream->Position;
+ stm->pos = n;
+ stm->rp = stm->bp;
+ stm->wp = stm->bp;
+}
+
+static void win_close_file(fz_context *ctx, void *state)
+{
+ win_stream_struct *win_stream = reinterpret_cast <win_stream_struct*> (state);
+ IRandomAccessStream^ stream = win_stream->stream;
+ delete stream;
+}
+
+/* mutext functions see mupdf readme for details */
+static void lock_mutex(void *user, int lock)
+{
+ LPCRITICAL_SECTION locks = (LPCRITICAL_SECTION)user;
+ EnterCriticalSection(&locks[lock]);
+}
+
+static void unlock_mutex(void *user, int lock)
+{
+ LPCRITICAL_SECTION locks = (LPCRITICAL_SECTION)user;
+ LeaveCriticalSection(&locks[lock]);
+}
+
+void muctx::CleanUp(void)
+{
+ fz_free_outline(mu_ctx, mu_outline);
+ fz_close_document(mu_doc);
+ display_list_cache->Empty(mu_ctx);
+ fz_free_context(mu_ctx);
+
+ delete display_list_cache;
+ display_list_cache = NULL;
+ this->mu_ctx = NULL;
+ this->mu_doc = NULL;
+ this->mu_outline = NULL;
+}
+
+/* Set up the context, mutex and cookie */
+status_t muctx::InitializeContext()
+{
+ int i;
+
+ /* Get the mutexes set up */
+ for (i = 0; i < FZ_LOCK_MAX; i++)
+ InitializeCriticalSectionEx(&mu_criticalsec[i], 0, 0);
+ mu_locks.user = &mu_criticalsec[0];
+ mu_locks.lock = lock_mutex;
+ mu_locks.unlock = unlock_mutex;
+
+ /* Allocate the context */
+ this->mu_ctx = fz_new_context(NULL, &mu_locks, FZ_STORE_DEFAULT);
+ if (this->mu_ctx == NULL)
+ {
+ return E_OUTOFMEM;
+ }
+ else
+ {
+ return S_ISOK;
+ }
+}
+
+/* Initializer */
+muctx::muctx(void)
+{
+ mu_ctx = NULL;
+ mu_doc = NULL;
+ mu_outline = NULL;
+ display_list_cache = new Cache();
+}
+
+/* Destructor */
+muctx::~muctx(void)
+{
+ fz_free_outline(mu_ctx, mu_outline);
+ fz_close_document(mu_doc);
+ display_list_cache->Empty(mu_ctx);
+ fz_free_context(mu_ctx);
+
+ mu_ctx = NULL;
+ mu_doc = NULL;
+ mu_outline = NULL;
+ delete display_list_cache;
+ display_list_cache = NULL;
+}
+
+/* Set up the stream access */
+status_t muctx::InitializeStream(IRandomAccessStream^ readStream, char *ext)
+{
+ win_stream.stream = readStream;
+ fz_stream *mu_stream = fz_new_stream(mu_ctx, 0, win_read_file, win_close_file);
+ mu_stream->seek = win_seek_file;
+ mu_stream->state = reinterpret_cast <void*> (&win_stream);
+
+ /* Now lets see if we can open the file */
+ fz_try(mu_ctx)
+ {
+ mu_doc = fz_open_document_with_stream(mu_ctx, ext, mu_stream);
+ }
+ fz_always(mu_ctx)
+ {
+ fz_close(mu_stream);
+ }
+ fz_catch(mu_ctx)
+ {
+ return E_FAILURE;
+ }
+ return S_ISOK;
+}
+
+/* Return the documents page count */
+int muctx::GetPageCount()
+{
+ if (this->mu_doc == NULL)
+ return -1;
+ else
+ return this->mu_doc->count_pages(this->mu_doc);
+}
+
+/* Get page size */
+Point muctx::MeasurePage(int page_num)
+{
+ Point pageSize;
+ fz_rect rect;
+ fz_page *page;
+ fz_rect *bounds;
+
+ page = fz_load_page(mu_doc, page_num);
+ bounds = fz_bound_page(mu_doc, page, &rect);
+ pageSize.X = bounds->x1 - bounds->x0;
+ pageSize.Y = bounds->y1 - bounds->y0;
+
+ return pageSize;
+}
+
+/* Get page size */
+Point muctx::MeasurePage(fz_page *page)
+{
+ Point pageSize;
+ fz_rect rect;
+ fz_rect *bounds;
+
+ bounds = fz_bound_page(mu_doc, page, &rect);
+ pageSize.X = bounds->x1 - bounds->x0;
+ pageSize.Y = bounds->y1 - bounds->y0;
+
+ return pageSize;
+}
+
+void muctx::FlattenOutline(fz_outline *outline, int level,
+ sh_vector_content contents_vec)
+{
+ char indent[8*4+1];
+ if (level > 8)
+ level = 8;
+ memset(indent, ' ', level * 4);
+ indent[level * 4] = 0;
+
+ String^ indent_str = char_to_String(indent);
+ String^ str_indent;
+
+ while (outline)
+ {
+ if (outline->dest.kind == FZ_LINK_GOTO)
+ {
+ int page = outline->dest.ld.gotor.page;
+ if (page >= 0 && outline->title)
+ {
+ /* Add to the contents std:vec */
+ sh_content content_item(new content_t());
+ content_item->page = page;
+ content_item->string_orig = char_to_String(outline->title);
+ content_item->string_margin =
+ str_indent->Concat(indent_str, content_item->string_orig);
+ contents_vec->push_back(content_item);
+ }
+ }
+ FlattenOutline(outline->down, level + 1, contents_vec);
+ outline = outline->next;
+ }
+}
+
+int muctx::GetContents(sh_vector_content contents_vec)
+{
+ fz_outline *root = NULL;
+ fz_context *ctx_clone = NULL;
+ int has_content = 0;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(root);
+ fz_try(ctx_clone)
+ {
+ root = fz_load_outline(mu_doc);
+ if (root != NULL)
+ {
+ has_content = 1;
+ FlattenOutline(root, 0, contents_vec);
+ }
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_outline(ctx_clone, root);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ return E_FAIL;
+ }
+ fz_free_context(ctx_clone);
+ return has_content;
+}
+
+int muctx::GetTextSearch(int page_num, char* needle, sh_vector_text texts_vec)
+{
+ fz_page *page = NULL;
+ fz_text_sheet *sheet = NULL;
+ fz_device *dev = NULL;
+ fz_context *ctx_clone = NULL;
+ fz_text_page *text = NULL;
+ int hit_count = 0;
+ int k;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(page);
+ fz_var(sheet);
+ fz_var(dev);
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+ sheet = fz_new_text_sheet(ctx_clone);
+ text = fz_new_text_page(ctx_clone);
+ dev = fz_new_text_device(ctx_clone, sheet, text);
+ fz_run_page(mu_doc, page, dev, &fz_identity, NULL);
+ fz_free_device(dev); /* Why does this need to be done here? Seems odd */
+ dev = NULL;
+ hit_count = fz_search_text_page(ctx_clone, text, needle, mu_hit_bbox, nelem(mu_hit_bbox));
+
+ for (k = 0; k < hit_count; k++)
+ {
+ sh_text text_search(new text_search_t());
+ text_search->upper_left.X = mu_hit_bbox[k].x0;
+ text_search->upper_left.Y = mu_hit_bbox[k].y0;
+ text_search->lower_right.X = mu_hit_bbox[k].x1;
+ text_search->lower_right.Y = mu_hit_bbox[k].y1;
+ texts_vec->push_back(text_search);
+ }
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_page(mu_doc, page);
+ fz_free_device(dev);
+ fz_free_text_sheet(ctx_clone, sheet);
+ fz_free_text_page(ctx_clone, text);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ return E_FAIL;
+ }
+ fz_free_context(ctx_clone);
+ return hit_count;
+}
+
+/* Get the links and pack into a smart pointer structure */
+int muctx::GetLinks(int page_num, sh_vector_link links_vec)
+{
+ fz_page *page = NULL;
+ fz_link *links = NULL;
+ fz_context *ctx_clone = NULL;
+ int k = 0;
+ int num_links = 0;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(page);
+ fz_var(links);
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+ links = fz_load_links(mu_doc, page);
+
+ fz_link *curr_link = links;
+ if (curr_link != NULL)
+ {
+ /* Get our smart pointer structure filled */
+ while (curr_link != NULL)
+ {
+ fz_rect curr_rect = curr_link->rect;
+ sh_link link(new document_link_t());
+
+ link->upper_left.X = curr_rect.x0;
+ link->upper_left.Y = curr_rect.y0;
+ link->lower_right.X = curr_rect.x1;
+ link->lower_right.Y = curr_rect.y1;
+
+ switch (curr_link->dest.kind)
+ {
+ case FZ_LINK_GOTO:
+
+ link->type = LINK_GOTO;
+ link->page_num = curr_link->dest.ld.gotor.page;
+ break;
+
+ case FZ_LINK_URI:
+ {
+ int lenstr = strlen(curr_link->dest.ld.uri.uri);
+ std::unique_ptr<char[]> uri(new char[lenstr + 1]);
+ strcpy_s(uri.get(), lenstr + 1, curr_link->dest.ld.uri.uri);
+ link->uri.swap(uri);
+ link->type = LINK_URI;
+ break;
+ }
+
+ default:
+ link->type = NOT_SET;
+
+ }
+ links_vec->push_back(link);
+ curr_link = curr_link->next;
+ num_links += 1;
+ }
+ }
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_page(mu_doc, page);
+ fz_drop_link(ctx_clone, links);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ return E_FAIL;
+ }
+ fz_free_context(ctx_clone);
+ return num_links;
+}
+
+fz_display_list * muctx::CreateDisplayList(int page_num)
+{
+ fz_context *ctx_clone = NULL;
+ fz_device *dev = NULL;
+ fz_page *page = NULL;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ /* First see if we have this one in the cache */
+ fz_display_list *dlist = display_list_cache->UseEntry(page_num, ctx_clone);
+ if (dlist != NULL)
+ return dlist;
+
+ /* Apparently not, lets go ahead and create and add to cache */
+ fz_var(dev);
+ fz_var(page);
+ fz_var(dlist);
+
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+
+ /* Create a new list */
+ dlist = fz_new_display_list(ctx_clone);
+ dev = fz_new_list_device(ctx_clone, dlist);
+ fz_run_page_contents(mu_doc, page, dev, &fz_identity, NULL);
+ /* Add it to the cache and set that it is in use */
+ display_list_cache->AddEntry(page_num, dlist, ctx_clone);
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_device(dev);
+ fz_free_page(mu_doc, page);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_drop_display_list(ctx_clone, dlist);
+ fz_free_context(ctx_clone);
+ return NULL;
+ }
+ return dlist;
+}
+
+/* Render page_num to size width by height into bmp_data buffer */
+status_t muctx::RenderPage(int page_num, int width, int height,
+ unsigned char *bmp_data, bool use_dlist)
+{
+ fz_device *dev = NULL;
+ fz_pixmap *pix = NULL;
+ fz_page *page = NULL;
+ fz_matrix ctm, *pctm = &ctm;
+ Point page_size;
+ fz_context *ctx_clone = NULL;
+ fz_display_list *dlist = NULL;
+
+ if (use_dlist)
+ if ((dlist = CreateDisplayList(page_num)) == NULL)
+ return E_FAILURE;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(dev);
+ fz_var(pix);
+ fz_var(page);
+ fz_var(dlist);
+
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+ page_size = MeasurePage(page);
+
+ /* Figure out scale factors so that we get the desired size */
+ pctm = fz_scale(pctm, (float) width / page_size.X, (float) height / page_size.Y);
+ /* Flip on Y */
+ ctm.f = height;
+ ctm.d = -ctm.d;
+ pix = fz_new_pixmap_with_data(ctx_clone, fz_device_bgr(ctx_clone), width, height, bmp_data);
+ fz_clear_pixmap_with_value(ctx_clone, pix, 255);
+ dev = fz_new_draw_device(ctx_clone, pix);
+ if (use_dlist)
+ fz_run_display_list(dlist, dev, pctm, NULL, NULL);
+ else
+ fz_run_page(mu_doc, page, dev, pctm, NULL);
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_device(dev);
+ fz_drop_pixmap(ctx_clone, pix);
+ fz_free_page(mu_doc, page);
+ if (use_dlist)
+ fz_drop_display_list(ctx_clone, dlist);
+
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ return E_FAILURE;
+ }
+
+ fz_free_context(ctx_clone);
+ return S_ISOK;
+}
+
+bool muctx::RequiresPassword(void)
+{
+ return fz_needs_password(mu_doc);
+}
+
+bool muctx::ApplyPassword(char* password)
+{
+ return fz_authenticate_password(mu_doc, password);
+}
+
+String^ muctx::GetHTML(int page_num)
+{
+ fz_output *out = NULL;
+ fz_device *dev = NULL;
+ fz_page *page = NULL;
+ fz_text_sheet *sheet = NULL;
+ fz_text_page *text = NULL;
+ fz_context *ctx_clone = NULL;
+ fz_buffer *buf = NULL;
+ String^ html;
+
+ ctx_clone = fz_clone_context(mu_ctx);
+
+ fz_var(dev);
+ fz_var(page);
+ fz_var(sheet);
+ fz_var(text);
+ fz_var(buf);
+ fz_try(ctx_clone)
+ {
+ page = fz_load_page(mu_doc, page_num);
+ sheet = fz_new_text_sheet(ctx_clone);
+ text = fz_new_text_page(ctx_clone);
+ dev = fz_new_text_device(ctx_clone, sheet, text);
+ fz_run_page(mu_doc, page, dev, &fz_identity, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ fz_analyze_text(ctx_clone, sheet, text);
+ buf = fz_new_buffer(ctx_clone, 256);
+ out = fz_new_output_with_buffer(ctx_clone, buf);
+ fz_print_text_page_html(ctx_clone, out, text);
+ html = char_to_String((char*) buf->data);
+ }
+ fz_always(ctx_clone)
+ {
+ fz_free_device(dev);
+ fz_free_page(mu_doc, page);
+ fz_free_text_sheet(ctx_clone, sheet);
+ fz_free_text_page(ctx_clone, text);
+ fz_drop_buffer(ctx_clone, buf);
+ }
+ fz_catch(ctx_clone)
+ {
+ fz_free_context(ctx_clone);
+ return nullptr;
+ }
+
+ fz_free_context(ctx_clone);
+ return html;
+}
diff --git a/platform/winrt/mupdfwinrt/muctx.h b/platform/winrt/mupdfwinrt/muctx.h
new file mode 100644
index 00000000..826fa45b
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/muctx.h
@@ -0,0 +1,99 @@
+#pragma once
+
+#include <memory>
+#include <functional>
+#include <vector>
+#include <windows.h>
+#include <mutex>
+#include "utils.h"
+#include "Cache.h"
+#include "status.h"
+
+extern "C" {
+ #include "mupdf/fitz.h"
+}
+
+#define MAX_SEARCH 500
+
+using namespace Platform; /* For String */
+using namespace Windows::Foundation; /* For Point */
+
+/* These are the std objects used to interface to muctx. We do use windows
+ String and Point types however */
+
+/* Links */
+typedef struct document_link_s
+{
+ link_t type;
+ Point upper_left;
+ Point lower_right;
+ std::unique_ptr<char[]> uri;
+ int page_num;
+} document_link_t;
+#define sh_link std::shared_ptr<document_link_t>
+#define sh_vector_link std::shared_ptr<std::vector<sh_link>>
+
+/* Text Search */
+typedef struct text_search_s
+{
+ Point upper_left;
+ Point lower_right;
+} text_search_t;
+#define sh_text std::shared_ptr<text_search_t>
+#define sh_vector_text std::shared_ptr<std::vector<sh_text>>
+
+/* Content Results */
+typedef struct content_s
+{
+ int page;
+ String^ string_orig;
+ String^ string_margin;
+} content_t;
+#define sh_content std::shared_ptr<content_t>
+#define sh_vector_content std::shared_ptr<std::vector<sh_content>>
+
+/* Used for HTML return */
+#define sh_vector_char std::shared_ptr<std::vector<char>>
+
+/* Needed for file handling */
+using namespace Windows::Storage::Streams;
+using namespace Windows::Foundation;
+
+typedef struct win_stream_struct_s
+{
+ IRandomAccessStream^ stream;
+} win_stream_struct;
+
+class muctx
+{
+private:
+ CRITICAL_SECTION mu_criticalsec[FZ_LOCK_MAX];
+ win_stream_struct win_stream;
+ fz_locks_context mu_locks;
+ fz_context *mu_ctx;
+ fz_document *mu_doc;
+ fz_outline *mu_outline;
+ fz_rect mu_hit_bbox[MAX_SEARCH];
+ void FlattenOutline(fz_outline *outline, int level,
+ sh_vector_content contents_vec);
+ Cache *display_list_cache;
+ fz_display_list* CreateDisplayList(int page_num);
+
+public:
+ muctx(void);
+ ~muctx(void);
+ void CleanUp(void);
+ status_t InitializeStream(IRandomAccessStream^ readStream, char *ext);
+ int GetPageCount();
+ status_t InitializeContext();
+ status_t RenderPage(int page_num, int width, int height, unsigned char *bmp_data,
+ bool use_dlist);
+ Point MeasurePage(int page_num);
+ Point MeasurePage(fz_page *page);
+ int GetLinks(int page_num, sh_vector_link links_vec);
+ int GetTextSearch(int page_num, char* needle, sh_vector_text texts_vec);
+ int GetContents(sh_vector_content contents_vec);
+ String^ GetHTML(int page_num);
+ bool RequiresPassword(void);
+ bool ApplyPassword(char* password);
+};
diff --git a/platform/winrt/mupdfwinrt/mudocument.cpp b/platform/winrt/mupdfwinrt/mudocument.cpp
new file mode 100644
index 00000000..92c24e24
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/mudocument.cpp
@@ -0,0 +1,320 @@
+// mudocument.cpp
+
+/* This file contains the interface between the muctx class, which
+ implements the mupdf calls and the WinRT objects enabling calling from
+ C#, C++, Visual Basic, JavaScript applications */
+
+#include "pch.h"
+#include "mudocument.h"
+#include "status.h"
+
+using namespace mupdfwinrt;
+using namespace concurrency;
+using namespace Platform::Collections;
+
+mudocument::mudocument()
+{
+ this->mu_object.InitializeContext();
+ this->links = nullptr;
+}
+
+bool mudocument::RequiresPassword()
+{
+ return mu_object.RequiresPassword();
+}
+
+bool mudocument::ApplyPassword(String^ password)
+{
+ char* pass_char = String_to_char(password);
+ bool ok = mu_object.ApplyPassword(pass_char);
+ delete []pass_char;
+ return ok;
+}
+
+void mudocument::CleanUp()
+{
+ this->mu_object.CleanUp();
+}
+
+int mudocument::GetNumPages()
+{
+ return this->mu_object.GetPageCount();
+}
+
+Point mudocument::GetPageSize(int page_num)
+{
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ return this->mu_object.MeasurePage(page_num);
+}
+
+Windows::Foundation::IAsyncOperation<int>^ mudocument::OpenFileAsync(StorageFile^ file)
+{
+ return create_async([this, file]()
+ {
+ String^ filetype = file->FileType;
+ const wchar_t *w = filetype->Data();
+ int cb = WideCharToMultiByte(CP_UTF8, 0, w, -1, nullptr, 0, nullptr, nullptr);
+ char* name = new char[cb];
+
+ WideCharToMultiByte(CP_UTF8, 0, w ,-1 ,name ,cb ,nullptr, nullptr);
+ char *ext = strrchr(name, '.');
+
+ auto t = create_task(file->OpenAsync(FileAccessMode::Read));
+
+ return t.then([this, file, ext](task<IRandomAccessStream^> task)
+ {
+ try
+ {
+ IRandomAccessStream^ readStream = task.get();
+ UINT64 const size = readStream->Size;
+
+ if (size <= MAXUINT32)
+ {
+ status_t code = this->mu_object.InitializeStream(readStream, ext);
+ if (code != S_ISOK)
+ delete readStream;
+ return (int) code;
+ }
+ else
+ {
+ delete readStream;
+ return (int) E_FAILURE;
+ }
+ }
+ catch(COMException^ ex) {
+ /* Need to do something useful here */
+ throw ex;
+ }
+ });
+ });
+}
+
+/* Header info for bmp stream so that we can use the image brush */
+static void Prepare_bmp(int width, int height, DataWriter ^dw)
+{
+ int row_size = width * 4;
+ int bmp_size = row_size * height + 54;
+
+ dw->WriteString("BM");
+ dw->ByteOrder = ByteOrder::LittleEndian;
+ dw->WriteInt32(bmp_size);
+ dw->WriteInt16(0);
+ dw->WriteInt16(0);
+ dw->WriteInt32(54);
+ dw->WriteInt32(40);
+ dw->WriteInt32(width);
+ dw->WriteInt32(height);
+ dw->WriteInt16(1);
+ dw->WriteInt16(32);
+ dw->WriteInt32(0);
+ dw->WriteInt32(row_size * height);
+ dw->WriteInt32(2835);
+ dw->WriteInt32(2835);
+ dw->WriteInt32(0);
+ dw->WriteInt32(0);
+}
+
+/* Do the search through the pages with an async task with progress callback */
+Windows::Foundation::IAsyncOperationWithProgress<int, double>^
+ mudocument::SearchDocumentWithProgressAsync(String^ textToFind, int dir, int start_page)
+{
+ return create_async([this, textToFind, dir, start_page](progress_reporter<double> reporter) -> int
+ {
+ int num_pages = this->GetNumPages();
+ double progress;
+ int box_count, result;
+
+ for (int i = start_page; i >= 0 && i < num_pages; i += dir)
+ {
+ box_count = this->ComputeTextSearch(textToFind, i);
+ result = i;
+ if (dir == SEARCH_FORWARD)
+ {
+ progress = 100.0 * (double) (i + 1) / (double) num_pages;
+ }
+ else
+ {
+ progress = 100.0 * (double) (num_pages - i) / (double) num_pages;
+ }
+ /* We could have it only update with certain percentage changes but
+ we are just looping over the pages here so it is not too bad */
+ reporter.report(progress);
+
+ if (is_task_cancellation_requested())
+ {
+ // Cancel the current task.
+ cancel_current_task();
+ }
+
+ if (box_count > 0)
+ {
+ return result;
+ }
+ if (is_task_cancellation_requested())
+ {
+ }
+ }
+ reporter.report(100.0);
+ /* Todo no matches found alert */
+ if (box_count == 0)
+ return TEXT_NOT_FOUND;
+ else
+ return result;
+ });
+}
+
+/* Pack the page into a bmp stream */
+Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^
+ mudocument::RenderPageAsync(int page_num, int width, int height, bool use_dlist)
+{
+ return create_async([this, width, height, page_num, use_dlist](cancellation_token ct) -> InMemoryRandomAccessStream^
+ {
+ /* Allocate space for bmp */
+ Array<unsigned char>^ bmp_data = ref new Array<unsigned char>(height * 4 * width);
+ /* Set up the memory stream */
+ InMemoryRandomAccessStream ^ras = ref new InMemoryRandomAccessStream();
+ DataWriter ^dw = ref new DataWriter(ras->GetOutputStreamAt(0));
+
+ /* Go ahead and write our header data into the memory stream */
+ Prepare_bmp(width, height, dw);
+
+ std::lock_guard<std::mutex> lock(mutex_lock);
+
+ /* Get raster bitmap stream */
+ status_t code = mu_object.RenderPage(page_num, width, height, &(bmp_data[0]),
+ use_dlist);
+ if (code != S_ISOK)
+ {
+ throw ref new FailureException("Page Rendering Failed");
+ }
+ /* Now the data into the memory stream */
+ dw->WriteBytes(bmp_data);
+ DataWriterStoreOperation^ result = dw->StoreAsync();
+ /* Block on this Async call? */
+ while(result->Status != AsyncStatus::Completed) {
+ }
+ /* Return raster stream */
+ return ras;
+ });
+}
+
+int mudocument::ComputeLinks(int page_num)
+{
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ /* We get back a standard smart pointer from muctx interface and go to WinRT
+ type here */
+ sh_vector_link link_smart_ptr_vec(new std::vector<sh_link>());
+ int num_items = mu_object.GetLinks(page_num, link_smart_ptr_vec);
+ if (num_items == 0)
+ return 0;
+ /* Pack into winRT type*/
+ this->links = ref new Platform::Collections::Vector<Links^>();
+ for (int k = 0; k < num_items; k++)
+ {
+ auto new_link = ref new Links();
+ sh_link muctx_link = link_smart_ptr_vec->at(k);
+ new_link->LowerRight = muctx_link->lower_right;
+ new_link->UpperLeft = muctx_link->upper_left;
+ new_link->PageNum = muctx_link->page_num;
+ new_link->Type = muctx_link->type;
+ if (new_link->Type == LINK_URI)
+ {
+ String^ str = char_to_String(muctx_link->uri.get());
+ // The URI to launch
+ new_link->Uri = ref new Windows::Foundation::Uri(str);
+ }
+ this->links->Append(new_link);
+ }
+ return num_items;
+}
+
+Links^ mudocument::GetLink(int k)
+{
+ if (k >= this->links->Size)
+ return nullptr;
+ return this->links->GetAt(k);
+}
+
+int mudocument::ComputeTextSearch(String^ text, int page_num)
+{
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ /* We get back a standard smart pointer from muctx interface and go to
+ * WinRT type here */
+ char* text_char = String_to_char(text);
+ sh_vector_text text_smart_ptr_vec(new std::vector<sh_text>());
+
+ int num_items = mu_object.GetTextSearch(page_num, text_char, text_smart_ptr_vec);
+ if (num_items == 0)
+ return 0;
+ /* Pack into winRT type*/
+ this->textsearch = ref new Platform::Collections::Vector<Links^>();
+ for (int k = 0; k < num_items; k++)
+ {
+ auto new_link = ref new Links();
+ sh_text muctx_text = text_smart_ptr_vec->at(k);
+ new_link->LowerRight = muctx_text->lower_right;
+ new_link->UpperLeft = muctx_text->upper_left;
+ new_link->Type = TEXTBOX;
+ this->textsearch->Append(new_link);
+ }
+ delete []text_char;
+ return num_items;
+}
+
+/* Return number of hits found on most recent page */
+int mudocument::TextSearchCount(void)
+{
+ if (this->textsearch != nullptr)
+ return this->textsearch->Size;
+ else
+ return 0;
+}
+
+/* Returns the kth item for a page after a text search query */
+Links^ mudocument::GetTextSearch(int k)
+{
+ if (k >= this->textsearch->Size)
+ return nullptr;
+ return this->textsearch->GetAt(k);
+}
+
+int mudocument::ComputeContents()
+{
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ /* We get back a standard smart pointer from muctx interface and go to
+ * WinRT type here */
+
+ sh_vector_content content_smart_ptr_vec(new std::vector<sh_content>());
+
+ int has_content = mu_object.GetContents(content_smart_ptr_vec);
+
+ if (!has_content)
+ return 0;
+ /* Pack into winRT type*/
+ this->contents = ref new Platform::Collections::Vector<ContentItem^>();
+ int num_items = content_smart_ptr_vec->size();
+
+ for (int k = 0; k < num_items; k++)
+ {
+ auto new_content = ref new ContentItem();
+ sh_content muctx_content = content_smart_ptr_vec->at(k);
+ new_content->Page = muctx_content->page;
+ new_content->StringMargin = muctx_content->string_margin;
+ new_content->StringOrig = muctx_content->string_orig;
+ this->contents->Append(new_content);
+ }
+ return num_items;
+}
+
+ContentItem^ mudocument::GetContent(int k)
+{
+ if (k >= this->contents->Size)
+ return nullptr;
+ return this->contents->GetAt(k);
+}
+
+String^ mudocument::ComputeHTML(int page_num)
+{
+ std::lock_guard<std::mutex> lock(mutex_lock);
+ return mu_object.GetHTML(page_num);
+}
diff --git a/platform/winrt/mupdfwinrt/mudocument.h b/platform/winrt/mupdfwinrt/mudocument.h
new file mode 100644
index 00000000..bb4de722
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/mudocument.h
@@ -0,0 +1,50 @@
+#pragma once
+
+/* This file contains the interface between the muctx class, which
+ implements the mupdf calls and the WinRT objects enabling calling from
+ C#, C++, and JavaScript applications */
+
+#include "muctx.h"
+#include "Links.h"
+#include "ppltasks.h"
+#include "ContentItem.h"
+#include <winnt.h>
+#include <collection.h>
+
+using namespace Windows::Storage;
+using namespace Platform;
+using namespace Concurrency;
+using namespace Platform::Collections;
+
+namespace mupdfwinrt
+{
+ public ref class mudocument sealed
+ {
+ private:
+ muctx mu_object;
+ std::mutex mutex_lock;
+ Platform::Collections::Vector<Links^>^ links;
+ Platform::Collections::Vector<Links^>^ textsearch;
+ Platform::Collections::Vector<ContentItem^>^ contents;
+ public:
+ mudocument();
+ void CleanUp();
+ Windows::Foundation::IAsyncOperation<int>^ OpenFileAsync(StorageFile^ file);
+ int GetNumPages(void);
+ Point GetPageSize(int page_num);
+ Windows::Foundation::IAsyncOperation<InMemoryRandomAccessStream^>^
+ RenderPageAsync(int page_num, int width, int height, bool use_dlist);
+ Windows::Foundation::IAsyncOperationWithProgress<int, double>^
+ SearchDocumentWithProgressAsync(String^ textToFind, int dir, int start_page);
+ String^ ComputeHTML(int page_num);
+ int ComputeTextSearch(String^ text, int page_num);
+ Links^ GetTextSearch(int k);
+ int TextSearchCount(void);
+ int ComputeContents(void);
+ ContentItem^ GetContent(int k);
+ int ComputeLinks(int page_num);
+ Links^ GetLink(int k);
+ bool RequiresPassword();
+ bool ApplyPassword(String^ password);
+ };
+}
diff --git a/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj b/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj
new file mode 100644
index 00000000..01b99ea6
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9e6ab41d-09a7-45a6-a53b-1e4bf3ac5b33}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>mupdfwinrt</ProjectName>
+ <RootNamespace>mupdfwinrt</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>..\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>..\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+ <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+ <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>runtimeobject.lib;../$(Platform)/$(Configuration)/libmupdf_winRT.lib;../$(Platform)/$(Configuration)/libthirdparty_winRT.lib;../$(Platform)/$(Configuration)/libmupdf-nov8_winRT.lib</AdditionalDependencies>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="Cache.h" />
+ <ClInclude Include="Links.h" />
+ <ClInclude Include="ContentItem.h" />
+ <ClInclude Include="muctx.h" />
+ <ClInclude Include="pch.h" />
+ <ClInclude Include="mudocument.h" />
+ <ClInclude Include="status.h" />
+ <ClInclude Include="utils.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Cache.cpp" />
+ <ClCompile Include="Links.cpp" />
+ <ClCompile Include="ContentItem.cpp" />
+ <ClCompile Include="muctx.cpp" />
+ <ClCompile Include="pch.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="mudocument.cpp" />
+ <ClCompile Include="utils.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj.filters b/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj.filters
new file mode 100644
index 00000000..7598f3e5
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/mupdfwinrt.vcxproj.filters
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Resources">
+ <UniqueIdentifier>16ec6626-1276-4cf1-b7af-8d28de2c8f75</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="pch.cpp" />
+ <ClCompile Include="mudocument.cpp" />
+ <ClCompile Include="muctx.cpp" />
+ <ClCompile Include="Links.cpp" />
+ <ClCompile Include="ContentItem.cpp" />
+ <ClCompile Include="utils.cpp" />
+ <ClCompile Include="Cache.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="pch.h" />
+ <ClInclude Include="mudocument.h" />
+ <ClInclude Include="muctx.h" />
+ <ClInclude Include="Links.h" />
+ <ClInclude Include="utils.h" />
+ <ClInclude Include="ContentItem.h" />
+ <ClInclude Include="Cache.h" />
+ <ClInclude Include="status.h" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/platform/winrt/mupdfwinrt/pch.cpp b/platform/winrt/mupdfwinrt/pch.cpp
new file mode 100644
index 00000000..01484ff5
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/pch.cpp
@@ -0,0 +1,6 @@
+//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"
diff --git a/platform/winrt/mupdfwinrt/pch.h b/platform/winrt/mupdfwinrt/pch.h
new file mode 100644
index 00000000..f815ac97
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/pch.h
@@ -0,0 +1,6 @@
+//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
diff --git a/platform/winrt/mupdfwinrt/utils.cpp b/platform/winrt/mupdfwinrt/utils.cpp
new file mode 100644
index 00000000..38e11ada
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/utils.cpp
@@ -0,0 +1,28 @@
+#include "pch.h"
+#include "utils.h"
+
+/* Window string hurdles.... */
+String^ char_to_String(char *char_in)
+{
+ size_t size = MultiByteToWideChar(CP_UTF8, 0, char_in, -1, NULL, 0);
+ wchar_t *pw;
+ pw = new wchar_t[size];
+ if (!pw)
+ {
+ delete []pw;
+ return nullptr;
+ }
+ MultiByteToWideChar(CP_UTF8, 0, char_in, -1, pw, size );
+ String^ str_out = ref new String(pw);
+ delete []pw;
+ return str_out;
+}
+
+char* String_to_char(String^ text)
+{
+ const wchar_t *w = text->Data();
+ int cb = WideCharToMultiByte(CP_UTF8, 0, text->Data(), -1, nullptr, 0, nullptr, nullptr);
+ char* charout = new char[cb];
+ WideCharToMultiByte(CP_UTF8, 0, text->Data() ,-1 ,charout ,cb ,nullptr, nullptr);
+ return charout;
+}
diff --git a/platform/winrt/mupdfwinrt/utils.h b/platform/winrt/mupdfwinrt/utils.h
new file mode 100644
index 00000000..6ffc7e20
--- /dev/null
+++ b/platform/winrt/mupdfwinrt/utils.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "Windows.h"
+using namespace Platform;
+
+String^ char_to_String(char *char_in);
+char* String_to_char(String^ text);
diff --git a/platform/x11/jstest_main.c b/platform/x11/jstest_main.c
new file mode 100644
index 00000000..2003ad55
--- /dev/null
+++ b/platform/x11/jstest_main.c
@@ -0,0 +1,424 @@
+#include "pdfapp.h"
+
+#include <ctype.h>
+
+/*
+ A useful bit of bash script to call this is:
+ for f in ../ghostpcl/tests_private/pdf/forms/v1.3/ *.pdf ; do g=${f%.*} ; echo $g ; win32/debug/mujstest-v8.exe -o $g-%d.png -p ../ghostpcl/ $g.mjs > $g.log 2>&1 ; done
+
+ Remove the space from "/ *.pdf" before running - can't leave that
+ in here, as it causes a warning about a possibly malformed comment.
+*/
+
+static pdfapp_t gapp;
+static int file_open = 0;
+static char filename[1024] = "";
+static char *scriptname;
+static char *output = NULL;
+static char *prefix = NULL;
+static int shotcount = 0;
+static int verbosity = 0;
+
+#define LONGLINE 4096
+
+static char getline_buffer[LONGLINE];
+
+void winwarn(pdfapp_t *app, char *msg)
+{
+ fprintf(stderr, "warning: %s\n", msg);
+}
+
+void winerror(pdfapp_t *app, char *msg)
+{
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+void winalert(pdfapp_t *app, pdf_alert_event *alert)
+{
+ fprintf(stderr, "Alert %s: %s", alert->title, alert->message);
+ switch (alert->button_group_type)
+ {
+ case PDF_ALERT_BUTTON_GROUP_OK:
+ case PDF_ALERT_BUTTON_GROUP_OK_CANCEL:
+ alert->button_pressed = PDF_ALERT_BUTTON_OK;
+ break;
+ case PDF_ALERT_BUTTON_GROUP_YES_NO:
+ case PDF_ALERT_BUTTON_GROUP_YES_NO_CANCEL:
+ alert->button_pressed = PDF_ALERT_BUTTON_YES;
+ break;
+ }
+}
+
+void winadvancetimer(pdfapp_t *app, float duration)
+{
+}
+
+void winprint(pdfapp_t *app)
+{
+ fprintf(stderr, "The MuPDF library supports printing, but this application currently does not");
+}
+
+static char pd_password[256] = "";
+static char td_textinput[LONGLINE] = "";
+
+char *winpassword(pdfapp_t *app, char *filename)
+{
+ if (pd_password[0] == 0)
+ return NULL;
+ return pd_password;
+}
+
+char *wintextinput(pdfapp_t *app, char *inittext, int retry)
+{
+ if (retry)
+ return NULL;
+
+ if (td_textinput[0] != 0)
+ return td_textinput;
+ return inittext;
+}
+
+int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[])
+{
+ return 0;
+}
+
+void winhelp(pdfapp_t*app)
+{
+}
+
+void winclose(pdfapp_t *app)
+{
+ pdfapp_close(app);
+ exit(0);
+}
+
+int winsavequery(pdfapp_t *app)
+{
+ return DISCARD;
+}
+
+int wingetsavepath(pdfapp_t *app, char *buf, int len)
+{
+ return 0;
+}
+
+void winreplacefile(char *source, char *target)
+{
+}
+
+void wincursor(pdfapp_t *app, int curs)
+{
+}
+
+void wintitle(pdfapp_t *app, char *title)
+{
+}
+
+void windrawrect(pdfapp_t *app, int x0, int y0, int x1, int y1)
+{
+}
+
+void windrawstring(pdfapp_t *app, int x, int y, char *s)
+{
+}
+
+void winresize(pdfapp_t *app, int w, int h)
+{
+}
+
+void winrepaint(pdfapp_t *app)
+{
+}
+
+void winrepaintsearch(pdfapp_t *app)
+{
+}
+
+void winfullscreen(pdfapp_t *app, int state)
+{
+}
+
+/*
+ * Event handling
+ */
+
+void windocopy(pdfapp_t *app)
+{
+}
+
+void winreloadfile(pdfapp_t *app)
+{
+ pdfapp_close(app);
+ pdfapp_open(app, filename, 1);
+}
+
+void winopenuri(pdfapp_t *app, char *buf)
+{
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "mujstest: Scriptable tester for mupdf + js\n");
+ fprintf(stderr, "\nSyntax: mujstest -o <filename> [ -p <prefix> ] [-v] <scriptfile>\n");
+ fprintf(stderr, "\n<filename> should sensibly be of the form file-%%d.png\n");
+ fprintf(stderr, "\n<prefix> is a path prefix to apply to filenames within the script\n");
+ fprintf(stderr, "\n-v\tverbose\n");
+ fprintf(stderr, "\nscriptfile contains a list of commands:\n");
+ fprintf(stderr, "\tPASSWORD <password>\tSet the password\n");
+ fprintf(stderr, "\tOPEN <filename>\tOpen a file\n");
+ fprintf(stderr, "\tGOTO <page>\tJump to a particular page\n");
+ fprintf(stderr, "\tSCREENSHOT\tSave a screenshot\n");
+ fprintf(stderr, "\tRESIZE <w> <h>\tResize the screen to a given size\n");
+ fprintf(stderr, "\tCLICK <x> <y> <btn>\tClick at a given position\n");
+ fprintf(stderr, "\tTEXT <string>\tSet a value to be entered\n");
+ exit(1);
+}
+
+static char *
+my_getline(FILE *file)
+{
+ int c;
+ char *d = getline_buffer;
+ int space = sizeof(getline_buffer)-1;
+
+ /* Skip over any prefix of whitespace */
+ do
+ {
+ c = fgetc(file);
+ }
+ while (isspace(c));
+
+ if (c < 0)
+ return NULL;
+
+ /* Read the line in */
+ do
+ {
+ *d++ = (char)c;
+ c = fgetc(file);
+ }
+ while (c >= 32 && space--);
+
+ /* If we ran out of space, skip the rest of the line */
+ if (space == 0)
+ {
+ while (c >= 32)
+ c = fgetc(file);
+ }
+
+ *d = 0;
+
+ return getline_buffer;
+}
+
+static int
+match(char **line, const char *match)
+{
+ char *s = *line;
+
+ if (s == NULL)
+ return 0;
+
+ while (isspace(*(unsigned char *)s))
+ s++;
+
+ while (*s == *match)
+ {
+ if (*s == 0)
+ {
+ *line = s;
+ return 1;
+ }
+ s++;
+ match++;
+ }
+
+ if (*match != 0)
+ return 0;
+
+ /* We matched! Skip over any whitespace */
+ while (isspace(*(unsigned char *)s))
+ s++;
+
+ *line = s;
+
+ /* Trim whitespace off the end of the line */
+ /* Run to the end of the line */
+ while (*s)
+ s++;
+
+ /* Run back until we find where we started, or non whitespace */
+ while (s != *line && isspace((unsigned char)s[-1]))
+ s--;
+
+ /* Remove the suffix of whitespace */
+ *s = 0;
+
+ return 1;
+}
+
+static void unescape_string(char *d, const char *s)
+{
+ char c;
+
+ while ((c = *s++) != 0)
+ {
+ if (c == '\\')
+ {
+ c = *s++;
+ switch(c)
+ {
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ }
+ }
+ *d++ = c;
+ }
+ *d = 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ fz_context *ctx;
+ FILE *script = NULL;
+ int c;
+
+ while ((c = fz_getopt(argc, argv, "o:p:v")) != -1)
+ {
+ switch(c)
+ {
+ case 'o': output = fz_optarg; break;
+ case 'p': prefix = fz_optarg; break;
+ case 'v': verbosity ^= 1; break;
+ default: usage(); break;
+ }
+ }
+
+ if (fz_optind == argc)
+ usage();
+
+ ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
+ if (!ctx)
+ {
+ fprintf(stderr, "cannot initialise context\n");
+ exit(1);
+ }
+ pdfapp_init(ctx, &gapp);
+ gapp.scrw = 640;
+ gapp.scrh = 480;
+ gapp.colorspace = fz_device_rgb(ctx);
+
+ fz_try(ctx)
+ {
+ while (fz_optind < argc)
+ {
+ scriptname = argv[fz_optind++];
+ script = fopen(scriptname, "rb");
+ if (script == NULL)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open script: %s", scriptname);
+
+ do
+ {
+ char *line = my_getline(script);
+ if (line == NULL)
+ continue;
+ if (verbosity)
+ fprintf(stderr, "'%s'\n", line);
+ if (match(&line, "%"))
+ {
+ /* Comment */
+ }
+ else if (match(&line, "PASSWORD"))
+ {
+ strcpy(pd_password, line);
+ }
+ else if (match(&line, "OPEN"))
+ {
+ char path[1024];
+ if (file_open)
+ pdfapp_close(&gapp);
+ strcpy(filename, line);
+ if (prefix)
+ {
+ sprintf(path, "%s%s", prefix, line);
+ }
+ else
+ {
+ strcpy(path, line);
+ }
+ pdfapp_open(&gapp, path, 0);
+ file_open = 1;
+ }
+ else if (match(&line, "GOTO"))
+ {
+ pdfapp_gotopage(&gapp, atoi(line)-1);
+ }
+ else if (match(&line, "SCREENSHOT"))
+ {
+ char text[1024];
+
+ sprintf(text, output, ++shotcount);
+ if (strstr(text, ".pgm") || strstr(text, ".ppm") || strstr(text, ".pnm"))
+ fz_write_pnm(ctx, gapp.image, text);
+ else
+ fz_write_png(ctx, gapp.image, text, 0);
+ }
+ else if (match(&line, "RESIZE"))
+ {
+ int w, h;
+ sscanf(line, "%d %d", &w, &h);
+ pdfapp_onresize(&gapp, w, h);
+ }
+ else if (match(&line, "CLICK"))
+ {
+ float x, y, b;
+ int n;
+ n = sscanf(line, "%f %f %f", &x, &y, &b);
+ if (n < 1)
+ x = 0.0f;
+ if (n < 2)
+ y = 0.0f;
+ if (n < 3)
+ b = 1;
+ /* state = 1 = transition down */
+ pdfapp_onmouse(&gapp, (int)x, (int)y, b, 0, 1);
+ /* state = -1 = transition up */
+ pdfapp_onmouse(&gapp, (int)x, (int)y, b, 0, -1);
+ }
+ else if (match(&line, "TEXT"))
+ {
+ unescape_string(td_textinput, line);
+ }
+ else
+ {
+ fprintf(stderr, "Unmatched: %s\n", line);
+ }
+ }
+ while (!feof(script));
+
+ fclose(script);
+ }
+ }
+ fz_catch(ctx)
+ {
+ fprintf(stderr, "error: cannot execute '%s'\n", scriptname);
+ }
+
+ if (file_open)
+ pdfapp_close(&gapp);
+
+ fz_free_context(ctx);
+
+ return 0;
+}
diff --git a/platform/x11/mupdf.ico b/platform/x11/mupdf.ico
new file mode 100644
index 00000000..80deb8ea
--- /dev/null
+++ b/platform/x11/mupdf.ico
Binary files differ
diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c
new file mode 100644
index 00000000..e76c6c7c
--- /dev/null
+++ b/platform/x11/pdfapp.c
@@ -0,0 +1,1545 @@
+#include "pdfapp.h"
+
+#include <ctype.h> /* for tolower() */
+
+#define ZOOMSTEP 1.142857
+#define BEYOND_THRESHHOLD 40
+#ifndef PATH_MAX
+#define PATH_MAX (1024)
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+enum panning
+{
+ DONT_PAN = 0,
+ PAN_TO_TOP,
+ PAN_TO_BOTTOM
+};
+
+static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint, int transition);
+static void pdfapp_updatepage(pdfapp_t *app);
+
+static void pdfapp_warn(pdfapp_t *app, const char *fmt, ...)
+{
+ char buf[1024];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ buf[sizeof(buf)-1] = 0;
+ winwarn(app, buf);
+}
+
+static void pdfapp_error(pdfapp_t *app, char *msg)
+{
+ winerror(app, msg);
+}
+
+char *pdfapp_version(pdfapp_t *app)
+{
+ return
+ "MuPDF 1.2\n"
+ "Copyright 2006-2013 Artifex Software, Inc.\n";
+}
+
+char *pdfapp_usage(pdfapp_t *app)
+{
+ return
+ "L\t\t-- rotate left\n"
+ "R\t\t-- rotate right\n"
+ "h\t\t-- scroll left\n"
+ "j down\t\t-- scroll down\n"
+ "k up\t\t-- scroll up\n"
+ "l\t\t-- scroll right\n"
+ "+\t\t-- zoom in\n"
+ "-\t\t-- zoom out\n"
+ "W\t\t-- zoom to fit window width\n"
+ "H\t\t-- zoom to fit window height\n"
+ "w\t\t-- shrinkwrap\n"
+ "f\t\t-- fullscreen\n"
+ "r\t\t-- reload file\n"
+ ". pgdn right spc\t-- next page\n"
+ ", pgup left b bkspc\t-- previous page\n"
+ ">\t\t-- next 10 pages\n"
+ "<\t\t-- back 10 pages\n"
+ "m\t\t-- mark page for snap back\n"
+ "t\t\t-- pop back to latest mark\n"
+ "1m\t\t-- mark page in register 1\n"
+ "1t\t\t-- go to page in register 1\n"
+ "G\t\t-- go to last page\n"
+ "123g\t\t-- go to page 123\n"
+ "/\t\t-- search forwards for text\n"
+ "?\t\t-- search backwards for text\n"
+ "n\t\t-- find next search result\n"
+ "N\t\t-- find previous search result\n"
+ "c\t\t-- toggle between color and grayscale\n"
+ "i\t\t-- toggle inverted color mode\n"
+ "q\t\t-- quit\n"
+ ;
+}
+
+void pdfapp_init(fz_context *ctx, pdfapp_t *app)
+{
+ memset(app, 0, sizeof(pdfapp_t));
+ app->scrw = 640;
+ app->scrh = 480;
+ app->resolution = 72;
+ app->ctx = ctx;
+#ifdef _WIN32
+ app->colorspace = fz_device_bgr(ctx);
+#else
+ app->colorspace = fz_device_rgb(ctx);
+#endif
+}
+
+void pdfapp_invert(pdfapp_t *app, const fz_rect *rect)
+{
+ fz_irect b;
+ fz_invert_pixmap_rect(app->image, fz_round_rect(&b, rect));
+}
+
+static void event_cb(pdf_doc_event *event, void *data)
+{
+ pdfapp_t *app = (pdfapp_t *)data;
+
+ switch (event->type)
+ {
+ case PDF_DOCUMENT_EVENT_ALERT:
+ {
+ pdf_alert_event *alert = pdf_access_alert_event(event);
+ winalert(app, alert);
+ }
+ break;
+
+ case PDF_DOCUMENT_EVENT_PRINT:
+ winprint(app);
+ break;
+
+ case PDF_DOCUMENT_EVENT_EXEC_MENU_ITEM:
+ {
+ char *item = pdf_access_exec_menu_item_event(event);
+
+ if (!strcmp(item, "Print"))
+ winprint(app);
+ else
+ pdfapp_warn(app, "The document attempted to execute menu item: %s. (Not supported)", item);
+ }
+ break;
+
+ case PDF_DOCUMENT_EVENT_EXEC_DIALOG:
+ pdfapp_warn(app, "The document attempted to open a dialog box. (Not supported)");
+ break;
+
+ case PDF_DOCUMENT_EVENT_LAUNCH_URL:
+ {
+ pdf_launch_url_event *launch_url = pdf_access_launch_url_event(event);
+
+ pdfapp_warn(app, "The document attempted to open url: %s. (Not supported by app)", launch_url->url);
+ }
+ break;
+
+ case PDF_DOCUMENT_EVENT_MAIL_DOC:
+ {
+ pdf_mail_doc_event *mail_doc = pdf_access_mail_doc_event(event);
+
+ pdfapp_warn(app, "The document attmepted to mail the document%s%s%s%s%s%s%s%s (Not supported)",
+ mail_doc->to[0]?", To: ":"", mail_doc->to,
+ mail_doc->cc[0]?", Cc: ":"", mail_doc->cc,
+ mail_doc->bcc[0]?", Bcc: ":"", mail_doc->bcc,
+ mail_doc->subject[0]?", Subject: ":"", mail_doc->subject);
+ }
+ break;
+ }
+}
+
+void pdfapp_open(pdfapp_t *app, char *filename, int reload)
+{
+ fz_context *ctx = app->ctx;
+ char *password = "";
+
+ fz_try(ctx)
+ {
+ pdf_document *idoc;
+
+ app->doc = fz_open_document(ctx, filename);
+
+ idoc = pdf_specifics(app->doc);
+
+ if (idoc)
+ pdf_set_doc_event_callback(idoc, event_cb, app);
+
+ if (fz_needs_password(app->doc))
+ {
+ int okay = fz_authenticate_password(app->doc, password);
+ while (!okay)
+ {
+ password = winpassword(app, filename);
+ if (!password)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Needs a password");
+ okay = fz_authenticate_password(app->doc, password);
+ if (!okay)
+ pdfapp_warn(app, "Invalid password.");
+ }
+ }
+
+ app->docpath = fz_strdup(ctx, filename);
+ app->doctitle = filename;
+ if (strrchr(app->doctitle, '\\'))
+ app->doctitle = strrchr(app->doctitle, '\\') + 1;
+ if (strrchr(app->doctitle, '/'))
+ app->doctitle = strrchr(app->doctitle, '/') + 1;
+ app->doctitle = fz_strdup(ctx, app->doctitle);
+
+ app->pagecount = fz_count_pages(app->doc);
+ app->outline = fz_load_outline(app->doc);
+ }
+ fz_catch(ctx)
+ {
+ pdfapp_error(app, "cannot open document");
+ }
+
+ if (app->pageno < 1)
+ app->pageno = 1;
+ if (app->pageno > app->pagecount)
+ app->pageno = app->pagecount;
+ if (app->resolution < MINRES)
+ app->resolution = MINRES;
+ if (app->resolution > MAXRES)
+ app->resolution = MAXRES;
+
+ if (!reload)
+ {
+ app->shrinkwrap = 1;
+ app->rotate = 0;
+ app->panx = 0;
+ app->pany = 0;
+ }
+
+ pdfapp_showpage(app, 1, 1, 1, 0);
+}
+
+void pdfapp_close(pdfapp_t *app)
+{
+ fz_drop_display_list(app->ctx, app->page_list);
+ app->page_list = NULL;
+
+ fz_drop_display_list(app->ctx, app->annotations_list);
+ app->annotations_list = NULL;
+
+ fz_free_text_page(app->ctx, app->page_text);
+ app->page_text = NULL;
+
+ fz_free_text_sheet(app->ctx, app->page_sheet);
+ app->page_sheet = NULL;
+
+ fz_drop_link(app->ctx, app->page_links);
+ app->page_links = NULL;
+
+ fz_free(app->ctx, app->doctitle);
+ app->doctitle = NULL;
+
+ fz_free(app->ctx, app->docpath);
+ app->docpath = NULL;
+
+ fz_drop_pixmap(app->ctx, app->image);
+ app->image = NULL;
+
+ fz_drop_pixmap(app->ctx, app->new_image);
+ app->new_image = NULL;
+
+ fz_drop_pixmap(app->ctx, app->old_image);
+ app->old_image = NULL;
+
+ fz_free_outline(app->ctx, app->outline);
+ app->outline = NULL;
+
+ fz_free_page(app->doc, app->page);
+ app->page = NULL;
+
+ fz_close_document(app->doc);
+ app->doc = NULL;
+
+ fz_flush_warnings(app->ctx);
+}
+
+static int gen_tmp_file(char *buf, int len)
+{
+ int i;
+ char *name = strrchr(buf, '/');
+
+ if (name == NULL)
+ name = strrchr(buf, '\\');
+
+ if (name != NULL)
+ name++;
+ else
+ name = buf;
+
+ for (i = 0; i < 10000; i++)
+ {
+ FILE *f;
+ snprintf(name, buf+len-name, "tmp%04d", i);
+ f = fopen(buf, "r");
+ if (f == NULL)
+ return 1;
+ fclose(f);
+ }
+
+ return 0;
+}
+
+static int pdfapp_save(pdfapp_t *app)
+{
+ char buf[PATH_MAX];
+
+ if (wingetsavepath(app, buf, PATH_MAX))
+ {
+ fz_write_options opts;
+
+ opts.do_ascii = 1;
+ opts.do_expand = 0;
+ opts.do_garbage = 1;
+ opts.do_linear = 0;
+
+ if (strcmp(buf, app->docpath) != 0)
+ {
+ fz_write_document(app->doc, buf, &opts);
+ return 1;
+ }
+
+ if (gen_tmp_file(buf, PATH_MAX))
+ {
+ int written;
+
+ fz_try(app->ctx)
+ {
+ fz_write_document(app->doc, buf, &opts);
+ written = 1;
+ }
+ fz_catch(app->ctx)
+ {
+ written = 0;
+ }
+
+ if (written)
+ {
+ char buf2[PATH_MAX];
+ fz_strlcpy(buf2, app->docpath, PATH_MAX);
+ pdfapp_close(app);
+ winreplacefile(buf, buf2);
+ pdfapp_open(app, buf2, 1);
+
+ return written;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int pdfapp_preclose(pdfapp_t *app)
+{
+ pdf_document *idoc = pdf_specifics(app->doc);
+
+ if (idoc && pdf_has_unsaved_changes(idoc))
+ {
+ switch (winsavequery(app))
+ {
+ case DISCARD:
+ return 1;
+
+ case CANCEL:
+ return 0;
+
+ case SAVE:
+ return pdfapp_save(app);
+ }
+ }
+
+ return 1;
+}
+
+static void pdfapp_viewctm(fz_matrix *mat, pdfapp_t *app)
+{
+ fz_pre_rotate(fz_scale(mat, app->resolution/72.0f, app->resolution/72.0f), app->rotate);
+}
+
+static void pdfapp_panview(pdfapp_t *app, int newx, int newy)
+{
+ int image_w = fz_pixmap_width(app->ctx, app->image);
+ int image_h = fz_pixmap_height(app->ctx, app->image);
+
+ if (newx > 0)
+ newx = 0;
+ if (newy > 0)
+ newy = 0;
+
+ if (newx + image_w < app->winw)
+ newx = app->winw - image_w;
+ if (newy + image_h < app->winh)
+ newy = app->winh - image_h;
+
+ if (app->winw >= image_w)
+ newx = (app->winw - image_w) / 2;
+ if (app->winh >= image_h)
+ newy = (app->winh - image_h) / 2;
+
+ if (newx != app->panx || newy != app->pany)
+ winrepaint(app);
+
+ app->panx = newx;
+ app->pany = newy;
+}
+
+static void pdfapp_loadpage(pdfapp_t *app)
+{
+ fz_device *mdev = NULL;
+ int errored = 0;
+ fz_cookie cookie = { 0 };
+
+ fz_var(mdev);
+
+ fz_drop_display_list(app->ctx, app->page_list);
+ fz_drop_display_list(app->ctx, app->annotations_list);
+ fz_free_text_page(app->ctx, app->page_text);
+ fz_free_text_sheet(app->ctx, app->page_sheet);
+ fz_drop_link(app->ctx, app->page_links);
+ fz_free_page(app->doc, app->page);
+
+ app->page_list = NULL;
+ app->annotations_list = NULL;
+ app->page_text = NULL;
+ app->page_sheet = NULL;
+ app->page_links = NULL;
+ app->page = NULL;
+ app->page_bbox.x0 = 0;
+ app->page_bbox.y0 = 0;
+ app->page_bbox.x1 = 100;
+ app->page_bbox.y1 = 100;
+
+ fz_try(app->ctx)
+ {
+ app->page = fz_load_page(app->doc, app->pageno - 1);
+
+ fz_bound_page(app->doc, app->page, &app->page_bbox);
+ }
+ fz_catch(app->ctx)
+ {
+ pdfapp_warn(app, "Cannot load page");
+ return;
+ }
+
+ fz_try(app->ctx)
+ {
+ fz_annot *annot;
+ /* Create display lists */
+ app->page_list = fz_new_display_list(app->ctx);
+ mdev = fz_new_list_device(app->ctx, app->page_list);
+ fz_run_page_contents(app->doc, app->page, mdev, &fz_identity, &cookie);
+ fz_free_device(mdev);
+ mdev = NULL;
+ app->annotations_list = fz_new_display_list(app->ctx);
+ mdev = fz_new_list_device(app->ctx, app->annotations_list);
+ for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
+ fz_run_annot(app->doc, app->page, annot, mdev, &fz_identity, &cookie);
+ if (cookie.errors)
+ {
+ pdfapp_warn(app, "Errors found on page");
+ errored = 1;
+ }
+ }
+ fz_always(app->ctx)
+ {
+ fz_free_device(mdev);
+ }
+ fz_catch(app->ctx)
+ {
+ pdfapp_warn(app, "Cannot load page");
+ errored = 1;
+ }
+
+ fz_try(app->ctx)
+ {
+ app->page_links = fz_load_links(app->doc, app->page);
+ }
+ fz_catch(app->ctx)
+ {
+ if (!errored)
+ pdfapp_warn(app, "Cannot load page");
+ }
+
+ app->errored = errored;
+}
+
+static void pdfapp_recreate_annotationslist(pdfapp_t *app)
+{
+ fz_device *mdev = NULL;
+ int errored = 0;
+ fz_cookie cookie = { 0 };
+
+ fz_var(mdev);
+
+ fz_drop_display_list(app->ctx, app->annotations_list);
+ app->annotations_list = NULL;
+
+ fz_try(app->ctx)
+ {
+ fz_annot *annot;
+ /* Create display list */
+ app->annotations_list = fz_new_display_list(app->ctx);
+ mdev = fz_new_list_device(app->ctx, app->annotations_list);
+ for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
+ fz_run_annot(app->doc, app->page, annot, mdev, &fz_identity, &cookie);
+ if (cookie.errors)
+ {
+ pdfapp_warn(app, "Errors found on page");
+ errored = 1;
+ }
+ }
+ fz_always(app->ctx)
+ {
+ fz_free_device(mdev);
+ }
+ fz_catch(app->ctx)
+ {
+ pdfapp_warn(app, "Cannot load page");
+ errored = 1;
+ }
+
+ app->errored = errored;
+}
+
+static void pdfapp_runpage(pdfapp_t *app, fz_device *dev, const fz_matrix *ctm, const fz_rect *rect, fz_cookie *cookie)
+{
+ fz_begin_page(dev, rect, ctm);
+ if (app->page_list)
+ fz_run_display_list(app->page_list, dev, ctm, rect, cookie);
+ if (app->annotations_list)
+ fz_run_display_list(app->annotations_list, dev, ctm, rect, cookie);
+ fz_end_page(dev);
+}
+
+#define MAX_TITLE 256
+
+static void pdfapp_updatepage(pdfapp_t *app)
+{
+ pdf_document *idoc = pdf_specifics(app->doc);
+ fz_device *idev;
+ fz_matrix ctm;
+ fz_annot *annot;
+
+ pdfapp_viewctm(&ctm, app);
+ pdf_update_page(idoc, (pdf_page *)app->page);
+ pdfapp_recreate_annotationslist(app);
+
+ while ((annot = (fz_annot *)pdf_poll_changed_annot(idoc, (pdf_page *)app->page)) != NULL)
+ {
+ fz_rect bounds;
+ fz_irect ibounds;
+ fz_transform_rect(fz_bound_annot(app->doc, annot, &bounds), &ctm);
+ fz_rect_from_irect(&bounds, fz_round_rect(&ibounds, &bounds));
+ fz_clear_pixmap_rect_with_value(app->ctx, app->image, 255, &ibounds);
+ idev = fz_new_draw_device_with_bbox(app->ctx, app->image, &ibounds);
+ pdfapp_runpage(app, idev, &ctm, &bounds, NULL);
+ fz_free_device(idev);
+ }
+
+ pdfapp_showpage(app, 0, 0, 1, 0);
+}
+
+static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint, int transition)
+{
+ char buf[MAX_TITLE];
+ fz_device *idev;
+ fz_device *tdev;
+ fz_colorspace *colorspace;
+ fz_matrix ctm;
+ fz_rect bounds;
+ fz_irect ibounds;
+ fz_cookie cookie = { 0 };
+
+ if (!app->nowaitcursor)
+ wincursor(app, WAIT);
+
+ if (!app->transitions_enabled || !app->presentation_mode)
+ transition = 0;
+
+ if (transition)
+ {
+ app->old_image = app->image;
+ app->image = NULL;
+ }
+
+ if (loadpage)
+ {
+ pdfapp_loadpage(app);
+
+ /* Zero search hit position */
+ app->hit_count = 0;
+
+ /* Extract text */
+ app->page_sheet = fz_new_text_sheet(app->ctx);
+ app->page_text = fz_new_text_page(app->ctx);
+
+ if (app->page_list || app->annotations_list)
+ {
+ tdev = fz_new_text_device(app->ctx, app->page_sheet, app->page_text);
+ pdfapp_runpage(app, tdev, &fz_identity, &fz_infinite_rect, &cookie);
+ fz_free_device(tdev);
+ }
+ }
+
+ if (drawpage)
+ {
+ char buf2[64];
+ int len;
+
+ sprintf(buf2, " - %d/%d (%d dpi)",
+ app->pageno, app->pagecount, app->resolution);
+ len = MAX_TITLE-strlen(buf2);
+ if ((int)strlen(app->doctitle) > len)
+ {
+ snprintf(buf, len-3, "%s", app->doctitle);
+ strcat(buf, "...");
+ strcat(buf, buf2);
+ }
+ else
+ sprintf(buf, "%s%s", app->doctitle, buf2);
+ wintitle(app, buf);
+
+ pdfapp_viewctm(&ctm, app);
+ bounds = app->page_bbox;
+ fz_round_rect(&ibounds, fz_transform_rect(&bounds, &ctm));
+ fz_rect_from_irect(&bounds, &ibounds);
+
+ /* Draw */
+ if (app->image)
+ fz_drop_pixmap(app->ctx, app->image);
+ if (app->grayscale)
+ colorspace = fz_device_gray(app->ctx);
+ else
+ colorspace = app->colorspace;
+ app->image = NULL;
+ app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds);
+ fz_clear_pixmap_with_value(app->ctx, app->image, 255);
+ if (app->page_list || app->annotations_list)
+ {
+ idev = fz_new_draw_device(app->ctx, app->image);
+ pdfapp_runpage(app, idev, &ctm, &bounds, &cookie);
+ fz_free_device(idev);
+ }
+ if (app->invert)
+ fz_invert_pixmap(app->ctx, app->image);
+ }
+
+ if (transition)
+ {
+ fz_transition *new_trans;
+ app->new_image = app->image;
+ app->image = NULL;
+ app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds);
+ app->duration = 0;
+ new_trans = fz_page_presentation(app->doc, app->page, &app->duration);
+ if (new_trans)
+ app->transition = *new_trans;
+ else
+ {
+ /* If no transition specified, use a default one */
+ memset(&app->transition, 0, sizeof(*new_trans));
+ app->transition.duration = 1.0;
+ app->transition.type = FZ_TRANSITION_WIPE;
+ app->transition.vertical = 0;
+ app->transition.direction = 0;
+ }
+ if (app->duration == 0)
+ app->duration = 5;
+ app->in_transit = fz_generate_transition(app->image, app->old_image, app->new_image, 0, &app->transition);
+ if (!app->in_transit)
+ {
+ if (app->duration != 0)
+ winadvancetimer(app, app->duration);
+ }
+ app->start_time = clock();
+ }
+
+ if (repaint)
+ {
+ pdfapp_panview(app, app->panx, app->pany);
+
+ if (app->shrinkwrap)
+ {
+ int w = fz_pixmap_width(app->ctx, app->image);
+ int h = fz_pixmap_height(app->ctx, app->image);
+ if (app->winw == w)
+ app->panx = 0;
+ if (app->winh == h)
+ app->pany = 0;
+ if (w > app->scrw * 90 / 100)
+ w = app->scrw * 90 / 100;
+ if (h > app->scrh * 90 / 100)
+ h = app->scrh * 90 / 100;
+ if (w != app->winw || h != app->winh)
+ winresize(app, w, h);
+ }
+
+ winrepaint(app);
+
+ wincursor(app, ARROW);
+ }
+
+ if (cookie.errors && app->errored == 0)
+ {
+ app->errored = 1;
+ pdfapp_warn(app, "Errors found on page. Page rendering may be incomplete.");
+ }
+
+ fz_flush_warnings(app->ctx);
+}
+
+static void pdfapp_gotouri(pdfapp_t *app, char *uri)
+{
+ winopenuri(app, uri);
+}
+
+void pdfapp_gotopage(pdfapp_t *app, int number)
+{
+ app->isediting = 0;
+ winrepaint(app);
+
+ if (app->histlen + 1 == 256)
+ {
+ memmove(app->hist, app->hist + 1, sizeof(int) * 255);
+ app->histlen --;
+ }
+ app->hist[app->histlen++] = app->pageno;
+ app->pageno = number + 1;
+ pdfapp_showpage(app, 1, 1, 1, 0);
+}
+
+void pdfapp_inverthit(pdfapp_t *app)
+{
+ fz_rect bbox;
+ fz_matrix ctm;
+ int i;
+
+ pdfapp_viewctm(&ctm, app);
+
+ for (i = 0; i < app->hit_count; i++)
+ {
+ bbox = app->hit_bbox[i];
+ pdfapp_invert(app, fz_transform_rect(&bbox, &ctm));
+ }
+}
+
+static void pdfapp_search_in_direction(pdfapp_t *app, enum panning *panto, int dir)
+{
+ int firstpage, page;
+
+ wincursor(app, WAIT);
+
+ firstpage = app->pageno;
+ if (app->searchpage == app->pageno)
+ page = app->pageno + dir;
+ else
+ page = app->pageno;
+
+ if (page < 1) page = app->pagecount;
+ if (page > app->pagecount) page = 1;
+
+ do
+ {
+ if (page != app->pageno)
+ {
+ app->pageno = page;
+ pdfapp_showpage(app, 1, 0, 0, 0);
+ }
+
+ app->hit_count = fz_search_text_page(app->ctx, app->page_text, app->search, app->hit_bbox, nelem(app->hit_bbox));
+ if (app->hit_count > 0)
+ {
+ *panto = dir == 1 ? PAN_TO_TOP : PAN_TO_BOTTOM;
+ app->searchpage = app->pageno;
+ wincursor(app, HAND);
+ winrepaint(app);
+ return;
+ }
+
+ page += dir;
+ if (page < 1) page = app->pagecount;
+ if (page > app->pagecount) page = 1;
+ } while (page != firstpage);
+
+ pdfapp_warn(app, "String '%s' not found.", app->search);
+
+ app->pageno = firstpage;
+ pdfapp_showpage(app, 1, 0, 0, 0);
+ wincursor(app, HAND);
+ winrepaint(app);
+}
+
+void pdfapp_onresize(pdfapp_t *app, int w, int h)
+{
+ if (app->winw != w || app->winh != h)
+ {
+ app->winw = w;
+ app->winh = h;
+ pdfapp_panview(app, app->panx, app->pany);
+ winrepaint(app);
+ }
+}
+
+void pdfapp_onkey(pdfapp_t *app, int c)
+{
+ int oldpage = app->pageno;
+ enum panning panto = PAN_TO_TOP;
+ int loadpage = 1;
+
+ if (app->isediting)
+ {
+ int n = strlen(app->search);
+ if (c < ' ')
+ {
+ if (c == '\b' && n > 0)
+ {
+ app->search[n - 1] = 0;
+ winrepaintsearch(app);
+ }
+ if (c == '\n' || c == '\r')
+ {
+ app->isediting = 0;
+ if (n > 0)
+ {
+ winrepaintsearch(app);
+
+ if (app->searchdir < 0)
+ {
+ if (app->pageno == 1)
+ app->pageno = app->pagecount;
+ else
+ app->pageno--;
+ pdfapp_showpage(app, 1, 1, 0, 0);
+ }
+
+ pdfapp_onkey(app, 'n');
+ }
+ else
+ winrepaint(app);
+ }
+ if (c == '\033')
+ {
+ app->isediting = 0;
+ winrepaint(app);
+ }
+ }
+ else
+ {
+ if (n + 2 < sizeof app->search)
+ {
+ app->search[n] = c;
+ app->search[n + 1] = 0;
+ winrepaintsearch(app);
+ }
+ }
+ return;
+ }
+
+ /*
+ * Save numbers typed for later
+ */
+
+ if (c >= '0' && c <= '9')
+ {
+ app->number[app->numberlen++] = c;
+ app->number[app->numberlen] = '\0';
+ }
+
+ switch (c)
+ {
+
+ case 'q':
+ winclose(app);
+ break;
+
+ /*
+ * Zoom and rotate
+ */
+
+ case '+':
+ case '=':
+ app->resolution *= ZOOMSTEP;
+ if (app->resolution > MAXRES)
+ app->resolution = MAXRES;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+ case '-':
+ app->resolution /= ZOOMSTEP;
+ if (app->resolution < MINRES)
+ app->resolution = MINRES;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+
+ case 'W':
+ app->resolution *= (double) app->winw / (double) fz_pixmap_width(app->ctx, app->image);
+ if (app->resolution > MAXRES)
+ app->resolution = MAXRES;
+ else if (app->resolution < MINRES)
+ app->resolution = MINRES;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+ case 'H':
+ app->resolution *= (double) app->winh / (double) fz_pixmap_height(app->ctx, app->image);
+ if (app->resolution > MAXRES)
+ app->resolution = MAXRES;
+ else if (app->resolution < MINRES)
+ app->resolution = MINRES;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+
+ case 'L':
+ app->rotate -= 90;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+ case 'R':
+ app->rotate += 90;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+
+ case 'c':
+ app->grayscale ^= 1;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+
+ case 'i':
+ app->invert ^= 1;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+
+#ifndef NDEBUG
+ case 'a':
+ app->rotate -= 15;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+ case 's':
+ app->rotate += 15;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ break;
+#endif
+
+ /*
+ * Pan view, but don't need to repaint image
+ */
+
+ case 'f':
+ app->shrinkwrap = 0;
+ winfullscreen(app, !app->fullscreen);
+ app->fullscreen = !app->fullscreen;
+ break;
+
+ case 'w':
+ if (app->fullscreen)
+ {
+ winfullscreen(app, 0);
+ app->fullscreen = 0;
+ }
+ app->shrinkwrap = 1;
+ app->panx = app->pany = 0;
+ pdfapp_showpage(app, 0, 0, 1, 0);
+ break;
+
+ case 'h':
+ app->panx += fz_pixmap_width(app->ctx, app->image) / 10;
+ pdfapp_showpage(app, 0, 0, 1, 0);
+ break;
+
+ case 'j':
+ app->pany -= fz_pixmap_height(app->ctx, app->image) / 10;
+ pdfapp_showpage(app, 0, 0, 1, 0);
+ break;
+
+ case 'k':
+ app->pany += fz_pixmap_height(app->ctx, app->image) / 10;
+ pdfapp_showpage(app, 0, 0, 1, 0);
+ break;
+
+ case 'l':
+ app->panx -= fz_pixmap_width(app->ctx, app->image) / 10;
+ pdfapp_showpage(app, 0, 0, 1, 0);
+ break;
+
+ /*
+ * Page navigation
+ */
+
+ case 'g':
+ case '\n':
+ case '\r':
+ if (app->numberlen > 0)
+ app->pageno = atoi(app->number);
+ else
+ app->pageno = 1;
+ break;
+
+ case 'G':
+ app->pageno = app->pagecount;
+ break;
+
+ case 'm':
+ if (app->numberlen > 0)
+ {
+ int idx = atoi(app->number);
+
+ if (idx >= 0 && idx < nelem(app->marks))
+ app->marks[idx] = app->pageno;
+ }
+ else
+ {
+ if (app->histlen + 1 == 256)
+ {
+ memmove(app->hist, app->hist + 1, sizeof(int) * 255);
+ app->histlen --;
+ }
+ app->hist[app->histlen++] = app->pageno;
+ }
+ break;
+
+ case 't':
+ if (app->numberlen > 0)
+ {
+ int idx = atoi(app->number);
+
+ if (idx >= 0 && idx < nelem(app->marks))
+ if (app->marks[idx] > 0)
+ app->pageno = app->marks[idx];
+ }
+ else if (app->histlen > 0)
+ app->pageno = app->hist[--app->histlen];
+ break;
+
+ case 'p':
+ app->presentation_mode = !app->presentation_mode;
+ break;
+
+ /*
+ * Back and forth ...
+ */
+
+ case ',':
+ panto = PAN_TO_BOTTOM;
+ if (app->numberlen > 0)
+ app->pageno -= atoi(app->number);
+ else
+ app->pageno--;
+ break;
+
+ case '.':
+ panto = PAN_TO_TOP;
+ if (app->numberlen > 0)
+ app->pageno += atoi(app->number);
+ else
+ app->pageno++;
+ break;
+
+ case '\b':
+ case 'b':
+ panto = DONT_PAN;
+ if (app->numberlen > 0)
+ app->pageno -= atoi(app->number);
+ else
+ app->pageno--;
+ break;
+
+ case ' ':
+ panto = DONT_PAN;
+ if (app->numberlen > 0)
+ app->pageno += atoi(app->number);
+ else
+ app->pageno++;
+ break;
+
+ case '<':
+ panto = PAN_TO_TOP;
+ app->pageno -= 10;
+ break;
+ case '>':
+ panto = PAN_TO_TOP;
+ app->pageno += 10;
+ break;
+
+ /*
+ * Saving the file
+ */
+ case 'S':
+ pdfapp_save(app);
+ break;
+
+ /*
+ * Reloading the file...
+ */
+
+ case 'r':
+ panto = DONT_PAN;
+ oldpage = -1;
+ winreloadfile(app);
+ break;
+
+ /*
+ * Searching
+ */
+
+ case '?':
+ app->isediting = 1;
+ app->searchdir = -1;
+ app->search[0] = 0;
+ app->hit_count = 0;
+ app->searchpage = -1;
+ winrepaintsearch(app);
+ break;
+
+ case '/':
+ app->isediting = 1;
+ app->searchdir = 1;
+ app->search[0] = 0;
+ app->hit_count = 0;
+ app->searchpage = -1;
+ winrepaintsearch(app);
+ break;
+
+ case 'n':
+ if (app->searchdir > 0)
+ pdfapp_search_in_direction(app, &panto, 1);
+ else
+ pdfapp_search_in_direction(app, &panto, -1);
+ loadpage = 0;
+ break;
+
+ case 'N':
+ if (app->searchdir > 0)
+ pdfapp_search_in_direction(app, &panto, -1);
+ else
+ pdfapp_search_in_direction(app, &panto, 1);
+ loadpage = 0;
+ break;
+
+ }
+
+ if (c < '0' || c > '9')
+ app->numberlen = 0;
+
+ if (app->pageno < 1)
+ app->pageno = 1;
+ if (app->pageno > app->pagecount)
+ app->pageno = app->pagecount;
+
+ if (app->pageno != oldpage)
+ {
+ switch (panto)
+ {
+ case PAN_TO_TOP:
+ app->pany = 0;
+ break;
+ case PAN_TO_BOTTOM:
+ app->pany = -2000;
+ break;
+ case DONT_PAN:
+ break;
+ }
+ pdfapp_showpage(app, loadpage, 1, 1, 1);
+ }
+}
+
+void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state)
+{
+ fz_context *ctx = app->ctx;
+ fz_irect irect;
+ fz_link *link;
+ fz_matrix ctm;
+ fz_point p;
+ int processed = 0;
+
+ fz_pixmap_bbox(app->ctx, app->image, &irect);
+ p.x = x - app->panx + irect.x0;
+ p.y = y - app->pany + irect.y0;
+
+ pdfapp_viewctm(&ctm, app);
+ fz_invert_matrix(&ctm, &ctm);
+
+ fz_transform_point(&p, &ctm);
+
+ if (btn == 1 && (state == 1 || state == -1))
+ {
+ pdf_ui_event event;
+ pdf_document *idoc = pdf_specifics(app->doc);
+
+ event.etype = PDF_EVENT_TYPE_POINTER;
+ event.event.pointer.pt = p;
+ if (state == 1)
+ event.event.pointer.ptype = PDF_POINTER_DOWN;
+ else /* state == -1 */
+ event.event.pointer.ptype = PDF_POINTER_UP;
+
+ if (idoc && pdf_pass_event(idoc, (pdf_page *)app->page, &event))
+ {
+ pdf_widget *widget;
+
+ widget = pdf_focused_widget(idoc);
+
+ app->nowaitcursor = 1;
+ pdfapp_updatepage(app);
+
+ if (widget)
+ {
+ switch (pdf_widget_get_type(widget))
+ {
+ case PDF_WIDGET_TYPE_TEXT:
+ {
+ char *text = pdf_text_widget_text(idoc, widget);
+ char *current_text = text;
+ int retry = 0;
+
+ do
+ {
+ current_text = wintextinput(app, current_text, retry);
+ retry = 1;
+ }
+ while (current_text && !pdf_text_widget_set_text(idoc, widget, current_text));
+
+ fz_free(app->ctx, text);
+ pdfapp_updatepage(app);
+ }
+ break;
+
+ case PDF_WIDGET_TYPE_LISTBOX:
+ case PDF_WIDGET_TYPE_COMBOBOX:
+ {
+ int nopts;
+ int nvals;
+ char **opts = NULL;
+ char **vals = NULL;
+
+ fz_var(opts);
+ fz_var(vals);
+
+ fz_try(ctx)
+ {
+ nopts = pdf_choice_widget_options(idoc, widget, NULL);
+ opts = fz_malloc(ctx, nopts * sizeof(*opts));
+ (void)pdf_choice_widget_options(idoc, widget, opts);
+
+ nvals = pdf_choice_widget_value(idoc, widget, NULL);
+ vals = fz_malloc(ctx, MAX(nvals,nopts) * sizeof(*vals));
+ (void)pdf_choice_widget_value(idoc, widget, vals);
+
+ if (winchoiceinput(app, nopts, opts, &nvals, vals))
+ {
+ pdf_choice_widget_set_value(idoc, widget, nvals, vals);
+ pdfapp_updatepage(app);
+ }
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, opts);
+ fz_free(ctx, vals);
+ }
+ fz_catch(ctx)
+ {
+ pdfapp_warn(app, "setting of choice failed");
+ }
+ }
+ break;
+
+ case PDF_WIDGET_TYPE_SIGNATURE:
+ {
+ char ebuf[256];
+
+ ebuf[0] = 0;
+ if (pdf_check_signature(ctx, idoc, widget, app->docpath, ebuf, sizeof(ebuf)))
+ {
+ winwarn(app, "Signature is valid");
+ }
+ else
+ {
+ if (ebuf[0] == 0)
+ winwarn(app, "Signature check failed for unknown reason");
+ else
+ winwarn(app, ebuf);
+ }
+ }
+ break;
+ }
+ }
+
+ app->nowaitcursor = 0;
+ processed = 1;
+ }
+ }
+
+ for (link = app->page_links; link; link = link->next)
+ {
+ if (p.x >= link->rect.x0 && p.x <= link->rect.x1)
+ if (p.y >= link->rect.y0 && p.y <= link->rect.y1)
+ break;
+ }
+
+ if (link)
+ {
+ wincursor(app, HAND);
+ if (btn == 1 && state == 1 && !processed)
+ {
+ if (link->dest.kind == FZ_LINK_URI)
+ pdfapp_gotouri(app, link->dest.ld.uri.uri);
+ else if (link->dest.kind == FZ_LINK_GOTO)
+ pdfapp_gotopage(app, link->dest.ld.gotor.page);
+ return;
+ }
+ }
+ else
+ {
+ fz_annot *annot;
+ for (annot = fz_first_annot(app->doc, app->page); annot; annot = fz_next_annot(app->doc, annot))
+ {
+ fz_rect rect;
+ fz_bound_annot(app->doc, annot, &rect);
+ if (x >= rect.x0 && x < rect.x1)
+ if (y >= rect.y0 && y < rect.y1)
+ break;
+ }
+ if (annot)
+ wincursor(app, CARET);
+ else
+ wincursor(app, ARROW);
+ }
+
+ if (state == 1 && !processed)
+ {
+ if (btn == 1 && !app->iscopying)
+ {
+ app->ispanning = 1;
+ app->selx = x;
+ app->sely = y;
+ app->beyondy = 0;
+ }
+ if (btn == 3 && !app->ispanning)
+ {
+ app->iscopying = 1;
+ app->selx = x;
+ app->sely = y;
+ app->selr.x0 = x;
+ app->selr.x1 = x;
+ app->selr.y0 = y;
+ app->selr.y1 = y;
+ }
+ if (btn == 4 || btn == 5) /* scroll wheel */
+ {
+ int dir = btn == 4 ? 1 : -1;
+ app->ispanning = app->iscopying = 0;
+ if (modifiers & (1<<2))
+ {
+ /* zoom in/out if ctrl is pressed */
+ if (dir > 0)
+ app->resolution *= ZOOMSTEP;
+ else
+ app->resolution /= ZOOMSTEP;
+ if (app->resolution > MAXRES)
+ app->resolution = MAXRES;
+ if (app->resolution < MINRES)
+ app->resolution = MINRES;
+ pdfapp_showpage(app, 0, 1, 1, 0);
+ }
+ else
+ {
+ /* scroll up/down, or left/right if
+ shift is pressed */
+ int isx = (modifiers & (1<<0));
+ int xstep = isx ? 20 * dir : 0;
+ int ystep = !isx ? 20 * dir : 0;
+ pdfapp_panview(app, app->panx + xstep, app->pany + ystep);
+ }
+ }
+ }
+
+ else if (state == -1)
+ {
+ if (app->iscopying)
+ {
+ app->iscopying = 0;
+ app->selr.x0 = fz_mini(app->selx, x) - app->panx + irect.x0;
+ app->selr.x1 = fz_maxi(app->selx, x) - app->panx + irect.x0;
+ app->selr.y0 = fz_mini(app->sely, y) - app->pany + irect.y0;
+ app->selr.y1 = fz_maxi(app->sely, y) - app->pany + irect.y0;
+ winrepaint(app);
+ if (app->selr.x0 < app->selr.x1 && app->selr.y0 < app->selr.y1)
+ windocopy(app);
+ }
+ app->ispanning = 0;
+ }
+
+ else if (app->ispanning)
+ {
+ int newx = app->panx + x - app->selx;
+ int newy = app->pany + y - app->sely;
+ /* Scrolling beyond limits implies flipping pages */
+ /* Are we requested to scroll beyond limits? */
+ if (newy + fz_pixmap_height(app->ctx, app->image) < app->winh || newy > 0)
+ {
+ /* Yes. We can assume that deltay != 0 */
+ int deltay = y - app->sely;
+ /* Check whether the panning has occurred in the
+ * direction that we are already crossing the
+ * limit it. If not, we can conclude that we
+ * have switched ends of the page and will thus
+ * start over counting.
+ */
+ if( app->beyondy == 0 || (app->beyondy ^ deltay) >= 0 )
+ {
+ /* Updating how far we are beyond and
+ * flipping pages if beyond threshold
+ */
+ app->beyondy += deltay;
+ if (app->beyondy > BEYOND_THRESHHOLD)
+ {
+ if( app->pageno > 1 )
+ {
+ app->pageno--;
+ pdfapp_showpage(app, 1, 1, 1, 0);
+ newy = -fz_pixmap_height(app->ctx, app->image);
+ }
+ app->beyondy = 0;
+ }
+ else if (app->beyondy < -BEYOND_THRESHHOLD)
+ {
+ if( app->pageno < app->pagecount )
+ {
+ app->pageno++;
+ pdfapp_showpage(app, 1, 1, 1, 0);
+ newy = 0;
+ }
+ app->beyondy = 0;
+ }
+ }
+ else
+ app->beyondy = 0;
+ }
+ /* Although at this point we've already determined that
+ * or that no scrolling will be performed in
+ * y-direction, the x-direction has not yet been taken
+ * care off. Therefore
+ */
+ pdfapp_panview(app, newx, newy);
+
+ app->selx = x;
+ app->sely = y;
+ }
+
+ else if (app->iscopying)
+ {
+ app->selr.x0 = fz_mini(app->selx, x) - app->panx + irect.x0;
+ app->selr.x1 = fz_maxi(app->selx, x) - app->panx + irect.x0;
+ app->selr.y0 = fz_mini(app->sely, y) - app->pany + irect.y0;
+ app->selr.y1 = fz_maxi(app->sely, y) - app->pany + irect.y0;
+ winrepaint(app);
+ }
+
+}
+
+void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
+{
+ fz_rect hitbox;
+ fz_matrix ctm;
+ fz_text_page *page = app->page_text;
+ int c, i, p;
+ int seen = 0;
+ int block_num;
+
+ int x0 = app->selr.x0;
+ int x1 = app->selr.x1;
+ int y0 = app->selr.y0;
+ int y1 = app->selr.y1;
+
+ pdfapp_viewctm(&ctm, app);
+
+ p = 0;
+
+ for (block_num = 0; block_num < page->len; block_num++)
+ {
+ fz_text_line *line;
+ fz_text_block *block;
+ fz_text_span *span;
+
+ if (page->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT)
+ continue;
+ block = page->blocks[block_num].u.text;
+
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->first_span; span; span = span->next)
+ {
+ if (seen)
+ {
+#ifdef _WIN32
+ if (p < ucslen - 1)
+ ucsbuf[p++] = '\r';
+#endif
+ if (p < ucslen - 1)
+ ucsbuf[p++] = '\n';
+ }
+
+ seen = 0;
+
+ for (i = 0; i < span->len; i++)
+ {
+ fz_text_char_bbox(&hitbox, span, i);
+ fz_transform_rect(&hitbox, &ctm);
+ c = span->text[i].c;
+ if (c < 32)
+ c = '?';
+ if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1)
+ {
+ if (p < ucslen - 1)
+ ucsbuf[p++] = c;
+ seen = 1;
+ }
+ }
+
+ seen = (seen && span == line->last_span);
+ }
+ }
+ }
+
+ ucsbuf[p] = 0;
+}
+
+void pdfapp_postblit(pdfapp_t *app)
+{
+ clock_t time;
+ float seconds;
+ int llama;
+
+ app->transitions_enabled = 1;
+ if (!app->in_transit)
+ return;
+ time = clock();
+ seconds = (float)(time - app->start_time) / CLOCKS_PER_SEC;
+ llama = seconds * 256 / app->transition.duration;
+ if (llama >= 256)
+ {
+ /* Completed. */
+ fz_drop_pixmap(app->ctx, app->image);
+ app->image = app->new_image;
+ app->new_image = NULL;
+ fz_drop_pixmap(app->ctx, app->old_image);
+ app->old_image = NULL;
+ if (app->duration != 0)
+ winadvancetimer(app, app->duration);
+ }
+ else
+ fz_generate_transition(app->image, app->old_image, app->new_image, llama, &app->transition);
+ winrepaint(app);
+ if (llama >= 256)
+ {
+ /* Completed. */
+ app->in_transit = 0;
+ }
+}
diff --git a/platform/x11/pdfapp.h b/platform/x11/pdfapp.h
new file mode 100644
index 00000000..3e40e0c4
--- /dev/null
+++ b/platform/x11/pdfapp.h
@@ -0,0 +1,149 @@
+#ifndef PDFAPP_H
+#define PDFAPP_H
+
+#include "mupdf/fitz.h"
+#include "mupdf/pdf.h"
+
+/*
+ * Utility object for handling a pdf application / view
+ * Takes care of PDF loading and displaying and navigation,
+ * uses a number of callbacks to the GUI app.
+ */
+
+#define MINRES 54
+#define MAXRES 300
+
+typedef struct pdfapp_s pdfapp_t;
+
+enum { ARROW, HAND, WAIT, CARET };
+
+enum { DISCARD, SAVE, CANCEL };
+
+extern void winwarn(pdfapp_t*, char *s);
+extern void winerror(pdfapp_t*, char *s);
+extern void wintitle(pdfapp_t*, char *title);
+extern void winresize(pdfapp_t*, int w, int h);
+extern void winrepaint(pdfapp_t*);
+extern void winrepaintsearch(pdfapp_t*);
+extern char *winpassword(pdfapp_t*, char *filename);
+extern char *wintextinput(pdfapp_t*, char *inittext, int retry);
+extern int winchoiceinput(pdfapp_t*, int nopts, char *opts[], int *nvals, char *vals[]);
+extern void winopenuri(pdfapp_t*, char *s);
+extern void wincursor(pdfapp_t*, int curs);
+extern void windocopy(pdfapp_t*);
+extern void winreloadfile(pdfapp_t*);
+extern void windrawstring(pdfapp_t*, int x, int y, char *s);
+extern void winclose(pdfapp_t*);
+extern void winhelp(pdfapp_t*);
+extern void winfullscreen(pdfapp_t*, int state);
+extern int winsavequery(pdfapp_t*);
+extern int wingetsavepath(pdfapp_t*, char *buf, int len);
+extern void winalert(pdfapp_t *, pdf_alert_event *alert);
+extern void winprint(pdfapp_t *);
+extern void winadvancetimer(pdfapp_t *, float duration);
+extern void winreplacefile(char *source, char *target);
+
+struct pdfapp_s
+{
+ /* current document params */
+ fz_document *doc;
+ char *docpath;
+ char *doctitle;
+ fz_outline *outline;
+
+ int pagecount;
+
+ /* current view params */
+ int resolution;
+ int rotate;
+ fz_pixmap *image;
+ int grayscale;
+ fz_colorspace *colorspace;
+ int invert;
+
+ /* presentation mode */
+ int presentation_mode;
+ int transitions_enabled;
+ fz_pixmap *old_image;
+ fz_pixmap *new_image;
+ clock_t start_time;
+ int in_transit;
+ float duration;
+ fz_transition transition;
+
+ /* current page params */
+ int pageno;
+ fz_page *page;
+ fz_rect page_bbox;
+ fz_display_list *page_list;
+ fz_display_list *annotations_list;
+ fz_text_page *page_text;
+ fz_text_sheet *page_sheet;
+ fz_link *page_links;
+ int errored;
+
+ /* snapback history */
+ int hist[256];
+ int histlen;
+ int marks[10];
+
+ /* window system sizes */
+ int winw, winh;
+ int scrw, scrh;
+ int shrinkwrap;
+ int fullscreen;
+
+ /* event handling state */
+ char number[256];
+ int numberlen;
+
+ int ispanning;
+ int panx, pany;
+
+ int iscopying;
+ int selx, sely;
+ /* TODO - While sely keeps track of the relative change in
+ * cursor position between two ticks/events, beyondy shall keep
+ * track of the relative change in cursor position from the
+ * point where the user hits a scrolling limit. This is ugly.
+ * Used in pdfapp.c:pdfapp_onmouse.
+ */
+ int beyondy;
+ fz_rect selr;
+
+ int nowaitcursor;
+
+ /* search state */
+ int isediting;
+ int searchdir;
+ char search[512];
+ int searchpage;
+ fz_rect hit_bbox[512];
+ int hit_count;
+
+ /* client context storage */
+ void *userdata;
+
+ fz_context *ctx;
+};
+
+void pdfapp_init(fz_context *ctx, pdfapp_t *app);
+void pdfapp_open(pdfapp_t *app, char *filename, int reload);
+void pdfapp_close(pdfapp_t *app);
+int pdfapp_preclose(pdfapp_t *app);
+
+char *pdfapp_version(pdfapp_t *app);
+char *pdfapp_usage(pdfapp_t *app);
+
+void pdfapp_onkey(pdfapp_t *app, int c);
+void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state);
+void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen);
+void pdfapp_onresize(pdfapp_t *app, int w, int h);
+void pdfapp_gotopage(pdfapp_t *app, int number);
+
+void pdfapp_invert(pdfapp_t *app, const fz_rect *rect);
+void pdfapp_inverthit(pdfapp_t *app);
+
+void pdfapp_postblit(pdfapp_t *app);
+
+#endif
diff --git a/platform/x11/win_main.c b/platform/x11/win_main.c
new file mode 100644
index 00000000..bf765d6b
--- /dev/null
+++ b/platform/x11/win_main.c
@@ -0,0 +1,1163 @@
+#include "pdfapp.h"
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <commdlg.h>
+#include <shellapi.h>
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x020A
+#endif
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+#define ID_ABOUT 0x1000
+#define ID_DOCINFO 0x1001
+
+static HWND hwndframe = NULL;
+static HWND hwndview = NULL;
+static HDC hdc;
+static HBRUSH bgbrush;
+static HBRUSH shbrush;
+static BITMAPINFO *dibinf;
+static HCURSOR arrowcurs, handcurs, waitcurs, caretcurs;
+static LRESULT CALLBACK frameproc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT CALLBACK viewproc(HWND, UINT, WPARAM, LPARAM);
+static int timer_pending = 0;
+
+static int justcopied = 0;
+
+static pdfapp_t gapp;
+
+#define PATH_MAX (1024)
+
+static wchar_t wbuf[PATH_MAX];
+static char filename[PATH_MAX];
+
+/*
+ * Create registry keys to associate MuPDF with PDF and XPS files.
+ */
+
+#define OPEN_KEY(parent, name, ptr) \
+ RegCreateKeyExA(parent, name, 0, 0, 0, KEY_WRITE, 0, &ptr, 0)
+
+#define SET_KEY(parent, name, value) \
+ RegSetValueExA(parent, name, 0, REG_SZ, (const BYTE *)(value), strlen(value) + 1)
+
+void install_app(char *argv0)
+{
+ char buf[512];
+ HKEY software, classes, mupdf, dotpdf, dotxps;
+ HKEY shell, open, command, supported_types;
+ HKEY pdf_progids, xps_progids;
+
+ OPEN_KEY(HKEY_CURRENT_USER, "Software", software);
+ OPEN_KEY(software, "Classes", classes);
+ OPEN_KEY(classes, ".pdf", dotpdf);
+ OPEN_KEY(dotpdf, "OpenWithProgids", pdf_progids);
+ OPEN_KEY(classes, ".xps", dotxps);
+ OPEN_KEY(dotxps, "OpenWithProgids", xps_progids);
+ OPEN_KEY(classes, "MuPDF", mupdf);
+ OPEN_KEY(mupdf, "SupportedTypes", supported_types);
+ OPEN_KEY(mupdf, "shell", shell);
+ OPEN_KEY(shell, "open", open);
+ OPEN_KEY(open, "command", command);
+
+ sprintf(buf, "\"%s\" \"%%1\"", argv0);
+
+ SET_KEY(open, "FriendlyAppName", "MuPDF");
+ SET_KEY(command, "", buf);
+ SET_KEY(supported_types, ".pdf", "");
+ SET_KEY(supported_types, ".xps", "");
+ SET_KEY(pdf_progids, "MuPDF", "");
+ SET_KEY(xps_progids, "MuPDF", "");
+
+ RegCloseKey(dotxps);
+ RegCloseKey(dotpdf);
+ RegCloseKey(mupdf);
+ RegCloseKey(classes);
+ RegCloseKey(software);
+}
+
+/*
+ * Dialog boxes
+ */
+
+void winwarn(pdfapp_t *app, char *msg)
+{
+ MessageBoxA(hwndframe, msg, "MuPDF: Warning", MB_ICONWARNING);
+}
+
+void winerror(pdfapp_t *app, char *msg)
+{
+ MessageBoxA(hwndframe, msg, "MuPDF: Error", MB_ICONERROR);
+ exit(1);
+}
+
+void winalert(pdfapp_t *app, pdf_alert_event *alert)
+{
+ int buttons = MB_OK;
+ int icon = MB_ICONWARNING;
+ int pressed = PDF_ALERT_BUTTON_NONE;
+
+ switch (alert->icon_type)
+ {
+ case PDF_ALERT_ICON_ERROR:
+ icon = MB_ICONERROR;
+ break;
+ case PDF_ALERT_ICON_WARNING:
+ icon = MB_ICONWARNING;
+ break;
+ case PDF_ALERT_ICON_QUESTION:
+ icon = MB_ICONQUESTION;
+ break;
+ case PDF_ALERT_ICON_STATUS:
+ icon = MB_ICONINFORMATION;
+ break;
+ }
+
+ switch (alert->button_group_type)
+ {
+ case PDF_ALERT_BUTTON_GROUP_OK:
+ buttons = MB_OK;
+ break;
+ case PDF_ALERT_BUTTON_GROUP_OK_CANCEL:
+ buttons = MB_OKCANCEL;
+ break;
+ case PDF_ALERT_BUTTON_GROUP_YES_NO:
+ buttons = MB_YESNO;
+ break;
+ case PDF_ALERT_BUTTON_GROUP_YES_NO_CANCEL:
+ buttons = MB_YESNOCANCEL;
+ break;
+ }
+
+ pressed = MessageBoxA(hwndframe, alert->message, alert->title, icon|buttons);
+
+ switch (pressed)
+ {
+ case IDOK:
+ alert->button_pressed = PDF_ALERT_BUTTON_OK;
+ break;
+ case IDCANCEL:
+ alert->button_pressed = PDF_ALERT_BUTTON_CANCEL;
+ break;
+ case IDNO:
+ alert->button_pressed = PDF_ALERT_BUTTON_NO;
+ break;
+ case IDYES:
+ alert->button_pressed = PDF_ALERT_BUTTON_YES;
+ }
+}
+
+void winprint(pdfapp_t *app)
+{
+ MessageBoxA(hwndframe, "The MuPDF library supports printing, but this application currently does not", "Print document", MB_ICONWARNING);
+}
+
+int winsavequery(pdfapp_t *app)
+{
+ switch(MessageBoxA(hwndframe, "File has unsaved changes. Do you want to save", "MuPDF", MB_YESNOCANCEL))
+ {
+ case IDYES: return SAVE;
+ case IDNO: return DISCARD;
+ default: return CANCEL;
+ }
+}
+
+int winfilename(wchar_t *buf, int len)
+{
+ OPENFILENAME ofn;
+ buf[0] = 0;
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwndframe;
+ ofn.lpstrFile = buf;
+ ofn.nMaxFile = len;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = L"MuPDF: Open PDF file";
+ ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.zip;*.png;*.jpg;*.tif)\0*.zip;*.cbz;*.xps;*.pdf;*.jpe;*.jpg;*.jpeg;*.jfif;*.tif;*.tiff\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0Image Files (*.png;*.jpe;*.tif)\0*.png;*.jpg;*.jpe;*.jpeg;*.jfif;*.tif;*.tiff\0All Files\0*\0\0";
+ ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
+ return GetOpenFileNameW(&ofn);
+}
+
+int wingetsavepath(pdfapp_t *app, char *buf, int len)
+{
+ wchar_t twbuf[PATH_MAX];
+ OPENFILENAME ofn;
+
+ wcscpy(twbuf, wbuf);
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwndframe;
+ ofn.lpstrFile = twbuf;
+ ofn.nMaxFile = PATH_MAX;
+ ofn.lpstrInitialDir = NULL;
+ ofn.lpstrTitle = L"MuPDF: Save PDF file";
+ ofn.lpstrFilter = L"Documents (*.pdf;*.xps;*.cbz;*.zip;*.png;*.jpg;*.tif)\0*.zip;*.cbz;*.xps;*.pdf;*.jpe;*.jpg;*.jpeg;*.jfif;*.tif;*.tiff\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0CBZ Files (*.cbz;*.zip)\0*.zip;*.cbz\0Image Files (*.png;*.jpe;*.tif)\0*.png;*.jpg;*.jpe;*.jpeg;*.jfif;*.tif;*.tiff\0All Files\0*\0\0";
+ ofn.Flags = OFN_HIDEREADONLY;
+ if (GetSaveFileName(&ofn))
+ {
+ int code = WideCharToMultiByte(CP_UTF8, 0, twbuf, -1, buf, MIN(PATH_MAX, len), NULL, NULL);
+ if (code == 0)
+ {
+ winerror(&gapp, "cannot convert filename to utf-8");
+ return 0;
+ }
+
+ wcscpy(wbuf, twbuf);
+ strcpy(filename, buf);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void winreplacefile(char *source, char *target)
+{
+ wchar_t wsource[PATH_MAX];
+ wchar_t wtarget[PATH_MAX];
+
+ int sz = MultiByteToWideChar(CP_UTF8, 0, source, -1, wsource, PATH_MAX);
+ if (sz == 0)
+ {
+ winerror(&gapp, "cannot convert filename to Unicode");
+ return;
+ }
+
+ sz = MultiByteToWideChar(CP_UTF8, 0, target, -1, wtarget, PATH_MAX);
+ if (sz == 0)
+ {
+ winerror(&gapp, "cannot convert filename to Unicode");
+ return;
+ }
+
+#if (_WIN32_WINNT >= 0x0500)
+ ReplaceFile(wtarget, wsource, NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL);
+#else
+ DeleteFile(wtarget);
+ MoveFile(wsource, wtarget);
+#endif
+}
+
+static char pd_filename[256] = "The file is encrypted.";
+static char pd_password[256] = "";
+static wchar_t pd_passwordw[256] = {0};
+static char td_textinput[1024] = "";
+static int td_retry = 0;
+static int cd_nopts;
+static int *cd_nvals;
+static char **cd_opts;
+static char **cd_vals;
+static int pd_okay = 0;
+
+INT CALLBACK
+dlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemTextA(hwnd, 4, pd_filename);
+ return TRUE;
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case 1:
+ pd_okay = 1;
+ GetDlgItemTextW(hwnd, 3, pd_passwordw, nelem(pd_passwordw));
+ EndDialog(hwnd, 1);
+ WideCharToMultiByte(CP_UTF8, 0, pd_passwordw, -1, pd_password, sizeof pd_password, NULL, NULL);
+ return TRUE;
+ case 2:
+ pd_okay = 0;
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT CALLBACK
+dlogtextproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemTextA(hwnd, 3, td_textinput);
+ if (!td_retry)
+ ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE);
+ return TRUE;
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case 1:
+ pd_okay = 1;
+ GetDlgItemTextA(hwnd, 3, td_textinput, sizeof td_textinput);
+ EndDialog(hwnd, 1);
+ return TRUE;
+ case 2:
+ pd_okay = 0;
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ break;
+ case WM_CTLCOLORSTATIC:
+ if ((HWND)lParam == GetDlgItem(hwnd, 4))
+ {
+ SetTextColor((HDC)wParam, RGB(255,0,0));
+ SetBkMode((HDC)wParam, TRANSPARENT);
+
+ return (INT)GetStockObject(NULL_BRUSH);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT CALLBACK
+dlogchoiceproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND listbox;
+ int i;
+ int item;
+ int sel;
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ listbox = GetDlgItem(hwnd, 3);
+ for (i = 0; i < cd_nopts; i++)
+ SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)cd_opts[i]);
+
+ /* FIXME: handle multiple select */
+ if (*cd_nvals > 0)
+ {
+ item = SendMessageA(listbox, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)cd_vals[0]);
+ if (item != LB_ERR)
+ SendMessageA(listbox, LB_SETCURSEL, item, 0);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(wParam)
+ {
+ case 1:
+ listbox = GetDlgItem(hwnd, 3);
+ *cd_nvals = 0;
+ for (i = 0; i < cd_nopts; i++)
+ {
+ item = SendMessageA(listbox, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)cd_opts[i]);
+ sel = SendMessageA(listbox, LB_GETSEL, item, 0);
+ if (sel && sel != LB_ERR)
+ cd_vals[(*cd_nvals)++] = cd_opts[i];
+ }
+ pd_okay = 1;
+ EndDialog(hwnd, 1);
+ return TRUE;
+ case 2:
+ pd_okay = 0;
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+char *winpassword(pdfapp_t *app, char *filename)
+{
+ char buf[1024], *s;
+ int code;
+ strcpy(buf, filename);
+ s = buf;
+ if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1;
+ if (strrchr(s, '/')) s = strrchr(s, '/') + 1;
+ if (strlen(s) > 32)
+ strcpy(s + 30, "...");
+ sprintf(pd_filename, "The file \"%s\" is encrypted.", s);
+ code = DialogBoxW(NULL, L"IDD_DLOGPASS", hwndframe, dlogpassproc);
+ if (code <= 0)
+ winerror(app, "cannot create password dialog");
+ if (pd_okay)
+ return pd_password;
+ return NULL;
+}
+
+char *wintextinput(pdfapp_t *app, char *inittext, int retry)
+{
+ int code;
+ td_retry = retry;
+ fz_strlcpy(td_textinput, inittext ? inittext : "", sizeof td_textinput);
+ code = DialogBoxW(NULL, L"IDD_DLOGTEXT", hwndframe, dlogtextproc);
+ if (code <= 0)
+ winerror(app, "cannot create text input dialog");
+ if (pd_okay)
+ return td_textinput;
+ return NULL;
+}
+
+int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[])
+{
+ int code;
+ cd_nopts = nopts;
+ cd_nvals = nvals;
+ cd_opts = opts;
+ cd_vals = vals;
+ code = DialogBoxW(NULL, L"IDD_DLOGLIST", hwndframe, dlogchoiceproc);
+ if (code <= 0)
+ winerror(app, "cannot create text input dialog");
+ return pd_okay;
+}
+
+INT CALLBACK
+dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ char buf[256];
+ fz_document *doc = gapp.doc;
+
+ switch(message)
+ {
+ case WM_INITDIALOG:
+
+ SetDlgItemTextW(hwnd, 0x10, wbuf);
+
+ if (fz_meta(doc, FZ_META_FORMAT_INFO, buf, 256) < 0)
+ {
+ SetDlgItemTextA(hwnd, 0x11, "Unknown");
+ SetDlgItemTextA(hwnd, 0x12, "None");
+ SetDlgItemTextA(hwnd, 0x13, "n/a");
+ return TRUE;
+ }
+
+ SetDlgItemTextA(hwnd, 0x11, buf);
+
+ if (fz_meta(doc, FZ_META_CRYPT_INFO, buf, 256) == 0)
+ {
+ SetDlgItemTextA(hwnd, 0x12, buf);
+ }
+ else
+ {
+ SetDlgItemTextA(hwnd, 0x12, "None");
+ }
+ buf[0] = 0;
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_PRINT) == 0)
+ strcat(buf, "print, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_CHANGE) == 0)
+ strcat(buf, "modify, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_COPY) == 0)
+ strcat(buf, "copy, ");
+ if (fz_meta(doc, FZ_META_HAS_PERMISSION, NULL, FZ_PERMISSION_NOTES) == 0)
+ strcat(buf, "annotate, ");
+ if (strlen(buf) > 2)
+ buf[strlen(buf)-2] = 0;
+ else
+ strcpy(buf, "None");
+ SetDlgItemTextA(hwnd, 0x13, buf);
+
+#define SETUTF8(ID, STRING) \
+ { \
+ *(char **)buf = STRING; \
+ if (fz_meta(doc, FZ_META_INFO, buf, 256) <= 0) \
+ buf[0] = 0; \
+ SetDlgItemTextA(hwnd, ID, buf); \
+ }
+
+ SETUTF8(0x20, "Title");
+ SETUTF8(0x21, "Author");
+ SETUTF8(0x22, "Subject");
+ SETUTF8(0x23, "Keywords");
+ SETUTF8(0x24, "Creator");
+ SETUTF8(0x25, "Producer");
+ SETUTF8(0x26, "CreationDate");
+ SETUTF8(0x27, "ModDate");
+ return TRUE;
+
+ case WM_COMMAND:
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void info()
+{
+ int code = DialogBoxW(NULL, L"IDD_DLOGINFO", hwndframe, dloginfoproc);
+ if (code <= 0)
+ winerror(&gapp, "cannot create info dialog");
+}
+
+INT CALLBACK
+dlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemTextA(hwnd, 2, pdfapp_version(&gapp));
+ SetDlgItemTextA(hwnd, 3, pdfapp_usage(&gapp));
+ return TRUE;
+ case WM_COMMAND:
+ EndDialog(hwnd, 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void winhelp(pdfapp_t*app)
+{
+ int code = DialogBoxW(NULL, L"IDD_DLOGABOUT", hwndframe, dlogaboutproc);
+ if (code <= 0)
+ winerror(&gapp, "cannot create help dialog");
+}
+
+/*
+ * Main window
+ */
+
+void winopen()
+{
+ WNDCLASS wc;
+ HMENU menu;
+ RECT r;
+ ATOM a;
+
+ /* Create and register window frame class */
+ memset(&wc, 0, sizeof(wc));
+ wc.style = 0;
+ wc.lpfnWndProc = frameproc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIconA(wc.hInstance, "IDI_ICONAPP");
+ wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = L"FrameWindow";
+ a = RegisterClassW(&wc);
+ if (!a)
+ winerror(&gapp, "cannot register frame window class");
+
+ /* Create and register window view class */
+ memset(&wc, 0, sizeof(wc));
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = viewproc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = L"ViewWindow";
+ a = RegisterClassW(&wc);
+ if (!a)
+ winerror(&gapp, "cannot register view window class");
+
+ /* Get screen size */
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+ gapp.scrw = r.right - r.left;
+ gapp.scrh = r.bottom - r.top;
+
+ /* Create cursors */
+ arrowcurs = LoadCursor(NULL, IDC_ARROW);
+ handcurs = LoadCursor(NULL, IDC_HAND);
+ waitcurs = LoadCursor(NULL, IDC_WAIT);
+ caretcurs = LoadCursor(NULL, IDC_IBEAM);
+
+ /* And a background color */
+ bgbrush = CreateSolidBrush(RGB(0x70,0x70,0x70));
+ shbrush = CreateSolidBrush(RGB(0x40,0x40,0x40));
+
+ /* Init DIB info for buffer */
+ dibinf = malloc(sizeof(BITMAPINFO) + 12);
+ assert(dibinf);
+ dibinf->bmiHeader.biSize = sizeof(dibinf->bmiHeader);
+ dibinf->bmiHeader.biPlanes = 1;
+ dibinf->bmiHeader.biBitCount = 32;
+ dibinf->bmiHeader.biCompression = BI_RGB;
+ dibinf->bmiHeader.biXPelsPerMeter = 2834;
+ dibinf->bmiHeader.biYPelsPerMeter = 2834;
+ dibinf->bmiHeader.biClrUsed = 0;
+ dibinf->bmiHeader.biClrImportant = 0;
+ dibinf->bmiHeader.biClrUsed = 0;
+
+ /* Create window */
+ hwndframe = CreateWindowW(L"FrameWindow", // window class name
+ NULL, // window caption
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+ CW_USEDEFAULT, CW_USEDEFAULT, // initial position
+ 300, // initial x size
+ 300, // initial y size
+ 0, // parent window handle
+ 0, // window menu handle
+ 0, // program instance handle
+ 0); // creation parameters
+ if (!hwndframe)
+ winerror(&gapp, "cannot create frame");
+
+ hwndview = CreateWindowW(L"ViewWindow", // window class name
+ NULL,
+ WS_VISIBLE | WS_CHILD,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ hwndframe, 0, 0, 0);
+ if (!hwndview)
+ winerror(&gapp, "cannot create view");
+
+ hdc = NULL;
+
+ SetWindowTextW(hwndframe, L"MuPDF");
+
+ menu = GetSystemMenu(hwndframe, 0);
+ AppendMenuW(menu, MF_SEPARATOR, 0, NULL);
+ AppendMenuW(menu, MF_STRING, ID_ABOUT, L"About MuPDF...");
+ AppendMenuW(menu, MF_STRING, ID_DOCINFO, L"Document Properties...");
+
+ SetCursor(arrowcurs);
+}
+
+void winclose(pdfapp_t *app)
+{
+ if (pdfapp_preclose(app))
+ {
+ pdfapp_close(app);
+ exit(0);
+ }
+}
+
+void wincursor(pdfapp_t *app, int curs)
+{
+ if (curs == ARROW)
+ SetCursor(arrowcurs);
+ if (curs == HAND)
+ SetCursor(handcurs);
+ if (curs == WAIT)
+ SetCursor(waitcurs);
+ if (curs == CARET)
+ SetCursor(caretcurs);
+}
+
+void wintitle(pdfapp_t *app, char *title)
+{
+ wchar_t wide[256], *dp;
+ char *sp;
+ int rune;
+
+ dp = wide;
+ sp = title;
+ while (*sp && dp < wide + 255)
+ {
+ sp += fz_chartorune(&rune, sp);
+ *dp++ = rune;
+ }
+ *dp = 0;
+
+ SetWindowTextW(hwndframe, wide);
+}
+
+void windrawrect(pdfapp_t *app, int x0, int y0, int x1, int y1)
+{
+ RECT r;
+ r.left = x0;
+ r.top = y0;
+ r.right = x1;
+ r.bottom = y1;
+ FillRect(hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
+}
+
+void windrawstring(pdfapp_t *app, int x, int y, char *s)
+{
+ HFONT font = (HFONT)GetStockObject(ANSI_FIXED_FONT);
+ SelectObject(hdc, font);
+ TextOutA(hdc, x, y - 12, s, strlen(s));
+}
+
+void winblitsearch()
+{
+ if (gapp.isediting)
+ {
+ char buf[sizeof(gapp.search) + 50];
+ sprintf(buf, "Search: %s", gapp.search);
+ windrawrect(&gapp, 0, 0, gapp.winw, 30);
+ windrawstring(&gapp, 10, 20, buf);
+ }
+}
+
+void winblit()
+{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
+ int image_n = fz_pixmap_components(gapp.ctx, gapp.image);
+ unsigned char *samples = fz_pixmap_samples(gapp.ctx, gapp.image);
+ int x0 = gapp.panx;
+ int y0 = gapp.pany;
+ int x1 = gapp.panx + image_w;
+ int y1 = gapp.pany + image_h;
+ RECT r;
+
+ if (gapp.image)
+ {
+ if (gapp.iscopying || justcopied)
+ {
+ pdfapp_invert(&gapp, &gapp.selr);
+ justcopied = 1;
+ }
+
+ pdfapp_inverthit(&gapp);
+
+ dibinf->bmiHeader.biWidth = image_w;
+ dibinf->bmiHeader.biHeight = -image_h;
+ dibinf->bmiHeader.biSizeImage = image_h * 4;
+
+ if (image_n == 2)
+ {
+ int i = image_w * image_h;
+ unsigned char *color = malloc(i*4);
+ unsigned char *s = samples;
+ unsigned char *d = color;
+ for (; i > 0 ; i--)
+ {
+ d[2] = d[1] = d[0] = *s++;
+ d[3] = *s++;
+ d += 4;
+ }
+ SetDIBitsToDevice(hdc,
+ gapp.panx, gapp.pany, image_w, image_h,
+ 0, 0, 0, image_h, color,
+ dibinf, DIB_RGB_COLORS);
+ free(color);
+ }
+ if (image_n == 4)
+ {
+ SetDIBitsToDevice(hdc,
+ gapp.panx, gapp.pany, image_w, image_h,
+ 0, 0, 0, image_h, samples,
+ dibinf, DIB_RGB_COLORS);
+ }
+
+ pdfapp_inverthit(&gapp);
+
+ if (gapp.iscopying || justcopied)
+ {
+ pdfapp_invert(&gapp, &gapp.selr);
+ justcopied = 1;
+ }
+ }
+
+ /* Grey background */
+ r.top = 0; r.bottom = gapp.winh;
+ r.left = 0; r.right = x0;
+ FillRect(hdc, &r, bgbrush);
+ r.left = x1; r.right = gapp.winw;
+ FillRect(hdc, &r, bgbrush);
+ r.left = 0; r.right = gapp.winw;
+ r.top = 0; r.bottom = y0;
+ FillRect(hdc, &r, bgbrush);
+ r.top = y1; r.bottom = gapp.winh;
+ FillRect(hdc, &r, bgbrush);
+
+ /* Drop shadow */
+ r.left = x0 + 2;
+ r.right = x1 + 2;
+ r.top = y1;
+ r.bottom = y1 + 2;
+ FillRect(hdc, &r, shbrush);
+ r.left = x1;
+ r.right = x1 + 2;
+ r.top = y0 + 2;
+ r.bottom = y1;
+ FillRect(hdc, &r, shbrush);
+
+ winblitsearch();
+}
+
+void winresize(pdfapp_t *app, int w, int h)
+{
+ ShowWindow(hwndframe, SW_SHOWDEFAULT);
+ w += GetSystemMetrics(SM_CXFRAME) * 2;
+ h += GetSystemMetrics(SM_CYFRAME) * 2;
+ h += GetSystemMetrics(SM_CYCAPTION);
+ SetWindowPos(hwndframe, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);
+}
+
+void winrepaint(pdfapp_t *app)
+{
+ InvalidateRect(hwndview, NULL, 0);
+}
+
+void winrepaintsearch(pdfapp_t *app)
+{
+ // TODO: invalidate only search area and
+ // call only search redraw routine.
+ InvalidateRect(hwndview, NULL, 0);
+}
+
+void winfullscreen(pdfapp_t *app, int state)
+{
+ static WINDOWPLACEMENT savedplace;
+ static int isfullscreen = 0;
+ if (state && !isfullscreen)
+ {
+ GetWindowPlacement(hwndframe, &savedplace);
+ SetWindowLong(hwndframe, GWL_STYLE, WS_POPUP | WS_VISIBLE);
+ SetWindowPos(hwndframe, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ ShowWindow(hwndframe, SW_SHOWMAXIMIZED);
+ isfullscreen = 1;
+ }
+ if (!state && isfullscreen)
+ {
+ SetWindowLong(hwndframe, GWL_STYLE, WS_OVERLAPPEDWINDOW);
+ SetWindowPos(hwndframe, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ SetWindowPlacement(hwndframe, &savedplace);
+ isfullscreen = 0;
+ }
+}
+
+/*
+ * Event handling
+ */
+
+void windocopy(pdfapp_t *app)
+{
+ HGLOBAL handle;
+ unsigned short *ucsbuf;
+
+ if (!OpenClipboard(hwndframe))
+ return;
+ EmptyClipboard();
+
+ handle = GlobalAlloc(GMEM_MOVEABLE, 4096 * sizeof(unsigned short));
+ if (!handle)
+ {
+ CloseClipboard();
+ return;
+ }
+
+ ucsbuf = GlobalLock(handle);
+ pdfapp_oncopy(&gapp, ucsbuf, 4096);
+ GlobalUnlock(handle);
+
+ SetClipboardData(CF_UNICODETEXT, handle);
+ CloseClipboard();
+
+ justcopied = 1; /* keep inversion around for a while... */
+}
+
+void winreloadfile(pdfapp_t *app)
+{
+ pdfapp_close(app);
+ pdfapp_open(app, filename, 1);
+}
+
+void winopenuri(pdfapp_t *app, char *buf)
+{
+ ShellExecuteA(hwndframe, "open", buf, 0, 0, SW_SHOWNORMAL);
+}
+
+#define OUR_TIMER_ID 1
+
+void winadvancetimer(pdfapp_t *app, float delay)
+{
+ timer_pending = 1;
+ SetTimer(hwndview, OUR_TIMER_ID, (unsigned int)(1000*delay), NULL);
+}
+
+static void killtimer(pdfapp_t *app)
+{
+ timer_pending = 0;
+}
+
+void handlekey(int c)
+{
+ if (timer_pending)
+ killtimer(&gapp);
+
+ if (GetCapture() == hwndview)
+ return;
+
+ if (justcopied)
+ {
+ justcopied = 0;
+ winrepaint(&gapp);
+ }
+
+ /* translate VK into ASCII equivalents */
+ if (c > 256)
+ {
+ switch (c - 256)
+ {
+ case VK_F1: c = '?'; break;
+ case VK_ESCAPE: c = '\033'; break;
+ case VK_DOWN: c = 'j'; break;
+ case VK_UP: c = 'k'; break;
+ case VK_LEFT: c = 'b'; break;
+ case VK_RIGHT: c = ' '; break;
+ case VK_PRIOR: c = ','; break;
+ case VK_NEXT: c = '.'; break;
+ }
+ }
+
+ pdfapp_onkey(&gapp, c);
+ winrepaint(&gapp);
+}
+
+void handlemouse(int x, int y, int btn, int state)
+{
+ if (state != 0 && timer_pending)
+ killtimer(&gapp);
+
+ if (state != 0 && justcopied)
+ {
+ justcopied = 0;
+ winrepaint(&gapp);
+ }
+
+ if (state == 1)
+ SetCapture(hwndview);
+ if (state == -1)
+ ReleaseCapture();
+
+ pdfapp_onmouse(&gapp, x, y, btn, 0, state);
+}
+
+LRESULT CALLBACK
+frameproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case WM_SETFOCUS:
+ PostMessage(hwnd, WM_APP+5, 0, 0);
+ return 0;
+ case WM_APP+5:
+ SetFocus(hwndview);
+ return 0;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+
+ case WM_SYSCOMMAND:
+ if (wParam == ID_ABOUT)
+ {
+ winhelp(&gapp);
+ return 0;
+ }
+ if (wParam == ID_DOCINFO)
+ {
+ info();
+ return 0;
+ }
+ if (wParam == SC_MAXIMIZE)
+ gapp.shrinkwrap = 0;
+ break;
+
+ case WM_SIZE:
+ {
+ // More generally, you should use GetEffectiveClientRect
+ // if you have a toolbar etc.
+ RECT rect;
+ GetClientRect(hwnd, &rect);
+ MoveWindow(hwndview, rect.left, rect.top,
+ rect.right-rect.left, rect.bottom-rect.top, TRUE);
+ return 0;
+ }
+
+ case WM_SIZING:
+ gapp.shrinkwrap = 0;
+ break;
+
+ case WM_NOTIFY:
+ case WM_COMMAND:
+ return SendMessage(hwndview, message, wParam, lParam);
+
+ case WM_CLOSE:
+ if (!pdfapp_preclose(&gapp))
+ return 0;
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+LRESULT CALLBACK
+viewproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static int oldx = 0;
+ static int oldy = 0;
+ int x = (signed short) LOWORD(lParam);
+ int y = (signed short) HIWORD(lParam);
+
+ switch (message)
+ {
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED)
+ return 0;
+ if (wParam == SIZE_MAXIMIZED)
+ gapp.shrinkwrap = 0;
+ pdfapp_onresize(&gapp, LOWORD(lParam), HIWORD(lParam));
+ break;
+
+ /* Paint events are low priority and automagically catenated
+ * so we don't need to do any fancy waiting to defer repainting.
+ */
+ case WM_PAINT:
+ {
+ //puts("WM_PAINT");
+ PAINTSTRUCT ps;
+ hdc = BeginPaint(hwnd, &ps);
+ winblit();
+ hdc = NULL;
+ EndPaint(hwnd, &ps);
+ pdfapp_postblit(&gapp);
+ return 0;
+ }
+
+ case WM_ERASEBKGND:
+ return 1; // well, we don't need to erase to redraw cleanly
+
+ /* Mouse events */
+
+ case WM_LBUTTONDOWN:
+ SetFocus(hwndview);
+ oldx = x; oldy = y;
+ handlemouse(x, y, 1, 1);
+ return 0;
+ case WM_MBUTTONDOWN:
+ SetFocus(hwndview);
+ oldx = x; oldy = y;
+ handlemouse(x, y, 2, 1);
+ return 0;
+ case WM_RBUTTONDOWN:
+ SetFocus(hwndview);
+ oldx = x; oldy = y;
+ handlemouse(x, y, 3, 1);
+ return 0;
+
+ case WM_LBUTTONUP:
+ oldx = x; oldy = y;
+ handlemouse(x, y, 1, -1);
+ return 0;
+ case WM_MBUTTONUP:
+ oldx = x; oldy = y;
+ handlemouse(x, y, 2, -1);
+ return 0;
+ case WM_RBUTTONUP:
+ oldx = x; oldy = y;
+ handlemouse(x, y, 3, -1);
+ return 0;
+
+ case WM_MOUSEMOVE:
+ oldx = x; oldy = y;
+ handlemouse(x, y, 0, 0);
+ return 0;
+
+ /* Mouse wheel */
+
+ case WM_MOUSEWHEEL:
+ if ((signed short)HIWORD(wParam) > 0)
+ handlekey(LOWORD(wParam) & MK_SHIFT ? '+' : 'k');
+ else
+ handlekey(LOWORD(wParam) & MK_SHIFT ? '-' : 'j');
+ return 0;
+
+ /* Timer */
+ case WM_TIMER:
+ if (wParam == OUR_TIMER_ID && timer_pending && gapp.presentation_mode)
+ {
+ timer_pending = 0;
+ handlekey(VK_RIGHT + 256);
+ handlemouse(oldx, oldy, 0, 0); /* update cursor */
+ return 0;
+ }
+ break;
+
+ /* Keyboard events */
+
+ case WM_KEYDOWN:
+ /* only handle special keys */
+ switch (wParam)
+ {
+ case VK_F1:
+ case VK_LEFT:
+ case VK_UP:
+ case VK_PRIOR:
+ case VK_RIGHT:
+ case VK_DOWN:
+ case VK_NEXT:
+ case VK_ESCAPE:
+ handlekey(wParam + 256);
+ handlemouse(oldx, oldy, 0, 0); /* update cursor */
+ return 0;
+ }
+ return 1;
+
+ /* unicode encoded chars, including escape, backspace etc... */
+ case WM_CHAR:
+ if (wParam < 256)
+ {
+ handlekey(wParam);
+ handlemouse(oldx, oldy, 0, 0); /* update cursor */
+ }
+ return 0;
+ }
+
+ fflush(stdout);
+
+ /* Pass on unhandled events to Windows */
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+int WINAPI
+WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ int argc;
+ LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ char argv0[256];
+ MSG msg;
+ int code;
+ fz_context *ctx;
+
+ ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
+ if (!ctx)
+ {
+ fprintf(stderr, "cannot initialise context\n");
+ exit(1);
+ }
+ pdfapp_init(ctx, &gapp);
+
+ GetModuleFileNameA(NULL, argv0, sizeof argv0);
+ install_app(argv0);
+
+ winopen();
+
+ if (argc == 2)
+ {
+ wcscpy(wbuf, argv[1]);
+ }
+ else
+ {
+ if (!winfilename(wbuf, nelem(wbuf)))
+ exit(0);
+ }
+
+ code = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, filename, sizeof filename, NULL, NULL);
+ if (code == 0)
+ winerror(&gapp, "cannot convert filename to utf-8");
+
+ pdfapp_open(&gapp, filename, 0);
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ pdfapp_close(&gapp);
+
+ return 0;
+}
diff --git a/platform/x11/win_res.rc b/platform/x11/win_res.rc
new file mode 100644
index 00000000..fbf6915c
--- /dev/null
+++ b/platform/x11/win_res.rc
@@ -0,0 +1,82 @@
+IDI_ICONAPP ICON "mupdf.ico"
+
+IDD_DLOGPASS DIALOG 50, 50, 204, 60
+//STYLE DS_MODALFRAME | WS_POPUP
+STYLE 128 | 0x80000000
+CAPTION " MuPDF: Password "
+FONT 8, "MS Shell Dlg"
+BEGIN
+ EDITTEXT 3, 57, 20, 140, 12, 32
+ DEFPUSHBUTTON "Okay", 1, 90, 40, 50, 14, 0x50010001
+ PUSHBUTTON "Cancel", 2, 147, 40, 50, 14, 0x50010000
+ LTEXT "The file is encrypted.", 4, 10, 7, 180, 10, 0x00000
+ LTEXT "Password:", 5, 17, 22, 40, 10, 0x00000
+END
+
+IDD_DLOGINFO DIALOG 50, 50, 300, 145
+STYLE 128 | 0x80000000
+CAPTION " Document Properties "
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "Okay", 1, 300-10-50, 145-7-14, 50, 14, 0x50010001
+
+ LTEXT "File:", -1, 10, 10, 50, 10, 0
+ LTEXT "Format:", -1, 10, 20, 50, 10, 0
+ LTEXT "Encryption:", -1, 10, 30, 50, 10, 0
+ LTEXT "Permissions:", -1, 10, 40, 50, 10, 0
+
+ LTEXT "<file", 0x10, 60, 10, 230, 10, 0
+ LTEXT "<version", 0x11, 60, 20, 230, 10, 0
+ LTEXT "<encryption", 0x12, 60, 30, 230, 10, 0
+ LTEXT "<permissions", 0x13, 60, 40, 230, 10, 0
+
+ LTEXT "Title:", -1, 10, 55, 50, 10, 0
+ LTEXT "Author:", -1, 10, 65, 50, 10, 0
+ LTEXT "Subject:", -1, 10, 75, 50, 10, 0
+ LTEXT "Keywords:", -1, 10, 85, 50, 10, 0
+ LTEXT "Creator:", -1, 10, 95, 50, 10, 0
+ LTEXT "Producer:", -1, 10, 105, 50, 10, 0
+ LTEXT "Created:", -1, 10, 115, 50, 10, 0
+ LTEXT "Modified:", -1, 10, 125, 50, 10, 0
+
+ LTEXT "", 0x20, 60, 55, 230, 10, 0
+ LTEXT "", 0x21, 60, 65, 230, 10, 0
+ LTEXT "", 0x22, 60, 75, 230, 10, 0
+ LTEXT "", 0x23, 60, 85, 230, 10, 0
+ LTEXT "", 0x24, 60, 95, 230, 10, 0
+ LTEXT "", 0x25, 60, 105, 230, 10, 0
+ LTEXT "", 0x26, 60, 115, 100, 10, 0
+ LTEXT "", 0x27, 60, 125, 100, 10, 0
+END
+
+IDD_DLOGTEXT DIALOG 50, 50, 204, 85
+STYLE 128 | 0x80000000
+CAPTION " MuPDF: fill out form"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ EDITTEXT 3,8,7,183,50,0x1004
+ DEFPUSHBUTTON "Okay",1,89,64,50,14
+ PUSHBUTTON "Cancel",2,147,64,50,14
+ LTEXT "** Invalid value **",4,11,65,62,8
+END
+
+IDD_DLOGLIST DIALOG 50, 50, 204, 85
+STYLE 128 | 0x80000000
+CAPTION " MuPDF: select an item"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LISTBOX 3,8,7,183,50,0x210102
+ DEFPUSHBUTTON "Okay",1,89,64,50,14
+ PUSHBUTTON "Cancel",2,147,64,50,14
+END
+
+IDD_DLOGABOUT DIALOG 50, 50, 200, 300
+STYLE 128 | 0x80000000
+CAPTION " About MuPDF "
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "Okay", 1, 200-10-50, 300-7-14, 50, 14, 0x50010001
+ LTEXT "<copyright>", 2, 10, 10, 180, 20, 0
+ LTEXT "<usage>", 3, 10, 35, 180, 240, 0
+END
+
diff --git a/platform/x11/x11_image.c b/platform/x11/x11_image.c
new file mode 100644
index 00000000..4f2db2e8
--- /dev/null
+++ b/platform/x11/x11_image.c
@@ -0,0 +1,703 @@
+/*
+ * Blit RGBA images to X with X(Shm)Images
+ */
+
+#ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 1
+#endif
+
+#ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 1
+#endif
+
+#define noSHOWINFO
+
+#include "mupdf/fitz.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+
+extern int ffs(int);
+
+static int is_big_endian(void)
+{
+ static const int one = 1;
+ return *(char*)&one == 0;
+}
+
+typedef void (*ximage_convert_func_t)
+(
+ const unsigned char *src,
+ int srcstride,
+ unsigned char *dst,
+ int dststride,
+ int w,
+ int h
+ );
+
+#define POOLSIZE 4
+#define WIDTH 256
+#define HEIGHT 256
+
+enum {
+ ARGB8888,
+ BGRA8888,
+ RGBA8888,
+ ABGR8888,
+ RGB888,
+ BGR888,
+ RGB565,
+ RGB565_BR,
+ RGB555,
+ RGB555_BR,
+ BGR233,
+ UNKNOWN
+};
+
+#ifdef SHOWINFO
+static char *modename[] = {
+ "ARGB8888",
+ "BGRA8888",
+ "RGBA8888",
+ "ABGR8888",
+ "RGB888",
+ "BGR888",
+ "RGB565",
+ "RGB565_BR",
+ "RGB555",
+ "RGB555_BR",
+ "BGR233",
+ "UNKNOWN"
+};
+#endif
+
+extern ximage_convert_func_t ximage_convert_funcs[];
+
+static struct
+{
+ Display *display;
+ int screen;
+ XVisualInfo visual;
+ Colormap colormap;
+
+ int bitsperpixel;
+ int mode;
+
+ XColor rgbcube[256];
+
+ ximage_convert_func_t convert_func;
+
+ int useshm;
+ int shmcode;
+ XImage *pool[POOLSIZE];
+ /* MUST exist during the lifetime of the shared ximage according to the
+ xc/doc/hardcopy/Xext/mit-shm.PS.gz */
+ XShmSegmentInfo shminfo[POOLSIZE];
+ int lastused;
+} info;
+
+static XImage *
+createximage(Display *dpy, Visual *vis, XShmSegmentInfo *xsi, int depth, int w, int h)
+{
+ XImage *img;
+ Status status;
+
+ if (!XShmQueryExtension(dpy))
+ goto fallback;
+ if (!info.useshm)
+ goto fallback;
+
+ img = XShmCreateImage(dpy, vis, depth, ZPixmap, NULL, xsi, w, h);
+ if (!img)
+ {
+ fprintf(stderr, "warn: could not XShmCreateImage\n");
+ goto fallback;
+ }
+
+ xsi->shmid = shmget(IPC_PRIVATE,
+ img->bytes_per_line * img->height,
+ IPC_CREAT | 0777);
+ if (xsi->shmid < 0)
+ {
+ XDestroyImage(img);
+ fprintf(stderr, "warn: could not shmget\n");
+ goto fallback;
+ }
+
+ img->data = xsi->shmaddr = shmat(xsi->shmid, NULL, 0);
+ if (img->data == (char*)-1)
+ {
+ XDestroyImage(img);
+ fprintf(stderr, "warn: could not shmat\n");
+ goto fallback;
+ }
+
+ xsi->readOnly = False;
+ status = XShmAttach(dpy, xsi);
+ if (!status)
+ {
+ shmdt(xsi->shmaddr);
+ XDestroyImage(img);
+ fprintf(stderr, "warn: could not XShmAttach\n");
+ goto fallback;
+ }
+
+ XSync(dpy, False);
+
+ shmctl(xsi->shmid, IPC_RMID, NULL);
+
+ return img;
+
+fallback:
+ info.useshm = 0;
+
+ img = XCreateImage(dpy, vis, depth, ZPixmap, 0, NULL, w, h, 32, 0);
+ if (!img)
+ {
+ fprintf(stderr, "fail: could not XCreateImage");
+ abort();
+ }
+
+ img->data = malloc(h * img->bytes_per_line);
+ if (!img->data)
+ {
+ fprintf(stderr, "fail: could not malloc");
+ abort();
+ }
+
+ return img;
+}
+
+static void
+make_colormap(void)
+{
+ if (info.visual.class == PseudoColor && info.visual.depth == 8)
+ {
+ int i, r, g, b;
+ i = 0;
+ for (b = 0; b < 4; b++) {
+ for (g = 0; g < 8; g++) {
+ for (r = 0; r < 8; r++) {
+ info.rgbcube[i].pixel = i;
+ info.rgbcube[i].red = (r * 36) << 8;
+ info.rgbcube[i].green = (g * 36) << 8;
+ info.rgbcube[i].blue = (b * 85) << 8;
+ info.rgbcube[i].flags =
+ DoRed | DoGreen | DoBlue;
+ i++;
+ }
+ }
+ }
+ info.colormap = XCreateColormap(info.display,
+ RootWindow(info.display, info.screen),
+ info.visual.visual,
+ AllocAll);
+ XStoreColors(info.display, info.colormap, info.rgbcube, 256);
+ return;
+ }
+ else if (info.visual.class == TrueColor)
+ {
+ info.colormap = 0;
+ return;
+ }
+ fprintf(stderr, "Cannot handle visual class %d with depth: %d\n",
+ info.visual.class, info.visual.depth);
+ return;
+}
+
+static void
+select_mode(void)
+{
+
+ int byteorder;
+ int byterev;
+ unsigned long rm, gm, bm;
+ unsigned long rs, gs, bs;
+
+ byteorder = ImageByteOrder(info.display);
+ if (is_big_endian())
+ byterev = byteorder != MSBFirst;
+ else
+ byterev = byteorder != LSBFirst;
+
+ rm = info.visual.red_mask;
+ gm = info.visual.green_mask;
+ bm = info.visual.blue_mask;
+
+ rs = ffs(rm) - 1;
+ gs = ffs(gm) - 1;
+ bs = ffs(bm) - 1;
+
+#ifdef SHOWINFO
+ printf("ximage: mode %d/%d %08lx %08lx %08lx (%ld,%ld,%ld) %s%s\n",
+ info.visual.depth,
+ info.bitsperpixel,
+ rm, gm, bm, rs, gs, bs,
+ byteorder == MSBFirst ? "msb" : "lsb",
+ byterev ? " <swap>":"");
+#endif
+
+ info.mode = UNKNOWN;
+ if (info.bitsperpixel == 8) {
+ /* Either PseudoColor with BGR233 colormap, or TrueColor */
+ info.mode = BGR233;
+ }
+ else if (info.bitsperpixel == 16) {
+ if (rm == 0xF800 && gm == 0x07E0 && bm == 0x001F)
+ info.mode = !byterev ? RGB565 : RGB565_BR;
+ if (rm == 0x7C00 && gm == 0x03E0 && bm == 0x001F)
+ info.mode = !byterev ? RGB555 : RGB555_BR;
+ }
+ else if (info.bitsperpixel == 24) {
+ if (rs == 0 && gs == 8 && bs == 16)
+ info.mode = byteorder == MSBFirst ? RGB888 : BGR888;
+ if (rs == 16 && gs == 8 && bs == 0)
+ info.mode = byteorder == MSBFirst ? BGR888 : RGB888;
+ }
+ else if (info.bitsperpixel == 32) {
+ if (rs == 0 && gs == 8 && bs == 16)
+ info.mode = byteorder == MSBFirst ? ABGR8888 : RGBA8888;
+ if (rs == 8 && gs == 16 && bs == 24)
+ info.mode = byteorder == MSBFirst ? BGRA8888 : ARGB8888;
+ if (rs == 16 && gs == 8 && bs == 0)
+ info.mode = byteorder == MSBFirst ? ARGB8888 : BGRA8888;
+ if (rs == 24 && gs == 16 && bs == 8)
+ info.mode = byteorder == MSBFirst ? RGBA8888 : ABGR8888;
+ }
+
+#ifdef SHOWINFO
+ printf("ximage: RGBA8888 to %s\n", modename[info.mode]);
+#endif
+
+ /* select conversion function */
+ info.convert_func = ximage_convert_funcs[info.mode];
+}
+
+static int
+create_pool(void)
+{
+ int i;
+
+ info.lastused = 0;
+
+ for (i = 0; i < POOLSIZE; i++) {
+ info.pool[i] = NULL;
+ }
+
+ for (i = 0; i < POOLSIZE; i++) {
+ info.pool[i] = createximage(info.display,
+ info.visual.visual, &info.shminfo[i], info.visual.depth,
+ WIDTH, HEIGHT);
+ if (!info.pool[i]) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static XImage *
+next_pool_image(void)
+{
+ if (info.lastused + 1 >= POOLSIZE) {
+ if (info.useshm)
+ XSync(info.display, False);
+ else
+ XFlush(info.display);
+ info.lastused = 0;
+ }
+ return info.pool[info.lastused ++];
+}
+
+static int
+ximage_error_handler(Display *display, XErrorEvent *event)
+{
+ /* Turn off shared memory images if we get an error from the MIT-SHM extension */
+ if (event->request_code == info.shmcode)
+ {
+ char buf[80];
+ XGetErrorText(display, event->error_code, buf, sizeof buf);
+ fprintf(stderr, "ximage: disabling shared memory extension: %s\n", buf);
+ info.useshm = 0;
+ return 0;
+ }
+
+ XSetErrorHandler(NULL);
+ return (XSetErrorHandler(ximage_error_handler))(display, event);
+}
+
+int
+ximage_init(Display *display, int screen, Visual *visual)
+{
+ XVisualInfo template;
+ XVisualInfo *visuals;
+ int nvisuals;
+ XPixmapFormatValues *formats;
+ int nformats;
+ int ok;
+ int i;
+ int major;
+ int event;
+ int error;
+
+ info.display = display;
+ info.screen = screen;
+ info.colormap = 0;
+
+ /* Get XVisualInfo for this visual */
+ template.visualid = XVisualIDFromVisual(visual);
+ visuals = XGetVisualInfo(display, VisualIDMask, &template, &nvisuals);
+ if (nvisuals != 1) {
+ fprintf(stderr, "Visual not found!\n");
+ XFree(visuals);
+ return 0;
+ }
+ memcpy(&info.visual, visuals, sizeof (XVisualInfo));
+ XFree(visuals);
+
+ /* Get appropriate PixmapFormat for this visual */
+ formats = XListPixmapFormats(info.display, &nformats);
+ for (i = 0; i < nformats; i++) {
+ if (formats[i].depth == info.visual.depth) {
+ info.bitsperpixel = formats[i].bits_per_pixel;
+ break;
+ }
+ }
+ XFree(formats);
+ if (i == nformats) {
+ fprintf(stderr, "PixmapFormat not found!\n");
+ return 0;
+ }
+
+ /* extract mode */
+ select_mode();
+
+ /* prepare colormap */
+ make_colormap();
+
+ /* identify code for MIT-SHM extension */
+ if (XQueryExtension(display, "MIT-SHM", &major, &event, &error) &&
+ XShmQueryExtension(display))
+ info.shmcode = major;
+
+ /* intercept errors looking for SHM code */
+ XSetErrorHandler(ximage_error_handler);
+
+ /* prepare pool of XImages */
+ info.useshm = 1;
+ ok = create_pool();
+ if (!ok)
+ return 0;
+
+#ifdef SHOWINFO
+ printf("ximage: %sPutImage\n", info.useshm ? "XShm" : "X");
+#endif
+
+ return 1;
+}
+
+int
+ximage_get_depth(void)
+{
+ return info.visual.depth;
+}
+
+Visual *
+ximage_get_visual(void)
+{
+ return info.visual.visual;
+}
+
+Colormap
+ximage_get_colormap(void)
+{
+ return info.colormap;
+}
+
+void
+ximage_blit(Drawable d, GC gc,
+ int dstx, int dsty,
+ unsigned char *srcdata,
+ int srcx, int srcy,
+ int srcw, int srch,
+ int srcstride)
+{
+ XImage *image;
+ int ax, ay;
+ int w, h;
+ unsigned char *srcptr;
+
+ for (ay = 0; ay < srch; ay += HEIGHT)
+ {
+ h = fz_mini(srch - ay, HEIGHT);
+ for (ax = 0; ax < srcw; ax += WIDTH)
+ {
+ w = fz_mini(srcw - ax, WIDTH);
+
+ image = next_pool_image();
+
+ srcptr = srcdata +
+ (ay + srcy) * srcstride +
+ (ax + srcx) * 4;
+
+ info.convert_func(srcptr, srcstride,
+ (unsigned char *) image->data,
+ image->bytes_per_line, w, h);
+
+ if (info.useshm)
+ {
+ XShmPutImage(info.display, d, gc, image,
+ 0, 0, dstx + ax, dsty + ay,
+ w, h, False);
+ }
+ else
+ {
+ XPutImage(info.display, d, gc, image,
+ 0, 0,
+ dstx + ax,
+ dsty + ay,
+ w, h);
+ }
+ }
+ }
+}
+
+/*
+ * Primitive conversion functions
+ */
+
+#ifndef restrict
+#ifndef _C99
+#ifdef __GNUC__
+#define restrict __restrict__
+#else
+#define restrict
+#endif
+#endif
+#endif
+
+#define PARAMS \
+ const unsigned char * restrict src, \
+ int srcstride, \
+ unsigned char * restrict dst, \
+ int dststride, \
+ int w, \
+ int h
+
+/*
+ * Convert byte:RGBA8888 to various formats
+ */
+
+static void
+ximage_convert_argb8888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x ++) {
+ dst[x * 4 + 0] = src[x * 4 + 3]; /* a */
+ dst[x * 4 + 1] = src[x * 4 + 0]; /* r */
+ dst[x * 4 + 2] = src[x * 4 + 1]; /* g */
+ dst[x * 4 + 3] = src[x * 4 + 2]; /* b */
+ }
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void
+ximage_convert_bgra8888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ dst[x * 4 + 0] = src[x * 4 + 2];
+ dst[x * 4 + 1] = src[x * 4 + 1];
+ dst[x * 4 + 2] = src[x * 4 + 0];
+ dst[x * 4 + 3] = src[x * 4 + 3];
+ }
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void
+ximage_convert_abgr8888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ dst[x * 4 + 0] = src[x * 4 + 3];
+ dst[x * 4 + 1] = src[x * 4 + 2];
+ dst[x * 4 + 2] = src[x * 4 + 1];
+ dst[x * 4 + 3] = src[x * 4 + 0];
+ }
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void
+ximage_convert_rgba8888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ ((unsigned *)dst)[x] = ((unsigned *)src)[x];
+ }
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void
+ximage_convert_bgr888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ dst[3*x + 0] = src[4*x + 2];
+ dst[3*x + 1] = src[4*x + 1];
+ dst[3*x + 2] = src[4*x + 0];
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_rgb888(PARAMS)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ dst[3*x + 0] = src[4*x + 0];
+ dst[3*x + 1] = src[4*x + 1];
+ dst[3*x + 2] = src[4*x + 2];
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_rgb565(PARAMS)
+{
+ unsigned char r, g, b;
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ r = src[4*x + 0];
+ g = src[4*x + 1];
+ b = src[4*x + 2];
+ ((unsigned short *)dst)[x] =
+ ((r & 0xF8) << 8) |
+ ((g & 0xFC) << 3) |
+ (b >> 3);
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_rgb565_br(PARAMS)
+{
+ unsigned char r, g, b;
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ r = src[4*x + 0];
+ g = src[4*x + 1];
+ b = src[4*x + 2];
+ /* final word is:
+ g4 g3 g2 b7 b6 b5 b4 b3 : r7 r6 r5 r4 r3 g7 g6 g5
+ */
+ ((unsigned short *)dst)[x] =
+ (r & 0xF8) |
+ ((g & 0xE0) >> 5) |
+ ((g & 0x1C) << 11) |
+ ((b & 0xF8) << 5);
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_rgb555(PARAMS)
+{
+ unsigned char r, g, b;
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ r = src[4*x + 0];
+ g = src[4*x + 1];
+ b = src[4*x + 2];
+ ((unsigned short *)dst)[x] =
+ ((r & 0xF8) << 7) |
+ ((g & 0xF8) << 2) |
+ (b >> 3);
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_rgb555_br(PARAMS)
+{
+ unsigned char r, g, b;
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ r = src[4*x + 0];
+ g = src[4*x + 1];
+ b = src[4*x + 2];
+ /* final word is:
+ g5 g4 g3 b7 b6 b5 b4 b3 : 0 r7 r6 r5 r4 r3 g7 g6
+ */
+ ((unsigned short *)dst)[x] =
+ ((r & 0xF8) >> 1) |
+ ((g & 0xC0) >> 6) |
+ ((g & 0x38) << 10) |
+ ((b & 0xF8) << 5);
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void
+ximage_convert_bgr233(PARAMS)
+{
+ unsigned char r, g, b;
+ int x,y;
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ r = src[4*x + 0];
+ g = src[4*x + 1];
+ b = src[4*x + 2];
+ /* format: b7 b6 g7 g6 g5 r7 r6 r5 */
+ dst[x] = (b&0xC0) | ((g>>2)&0x38) | ((r>>5)&0x7);
+ }
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+ximage_convert_func_t ximage_convert_funcs[] = {
+ ximage_convert_argb8888,
+ ximage_convert_bgra8888,
+ ximage_convert_rgba8888,
+ ximage_convert_abgr8888,
+ ximage_convert_rgb888,
+ ximage_convert_bgr888,
+ ximage_convert_rgb565,
+ ximage_convert_rgb565_br,
+ ximage_convert_rgb555,
+ ximage_convert_rgb555_br,
+ ximage_convert_bgr233,
+};
diff --git a/platform/x11/x11_main.c b/platform/x11/x11_main.c
new file mode 100644
index 00000000..481adce1
--- /dev/null
+++ b/platform/x11/x11_main.c
@@ -0,0 +1,993 @@
+#include "pdfapp.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define mupdf_icon_bitmap_16_width 16
+#define mupdf_icon_bitmap_16_height 16
+static unsigned char mupdf_icon_bitmap_16_bits[] = {
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x2b, 0x80, 0x55, 0x8c, 0x62, 0x8c, 0x51,
+ 0x9c, 0x61, 0x1c, 0x35, 0x3c, 0x1f, 0x3c, 0x0f, 0xfc, 0x0f, 0xec, 0x0d,
+ 0xec, 0x0d, 0xcc, 0x0c, 0xcc, 0x0c, 0x00, 0x00 };
+
+#define mupdf_icon_bitmap_16_mask_width 16
+#define mupdf_icon_bitmap_16_mask_height 16
+static unsigned char mupdf_icon_bitmap_16_mask_bits[] = {
+ 0x00, 0x1e, 0x00, 0x3f, 0x80, 0x7f, 0xce, 0xff, 0xde, 0xff, 0xde, 0xff,
+ 0xfe, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
+ 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xce, 0x1c };
+
+#ifndef timeradd
+#define timeradd(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+ if ((result)->tv_usec >= 1000000) \
+ { \
+ ++(result)->tv_sec; \
+ (result)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#endif
+
+#ifndef timersub
+#define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
+extern int ximage_init(Display *display, int screen, Visual *visual);
+extern int ximage_get_depth(void);
+extern Visual *ximage_get_visual(void);
+extern Colormap ximage_get_colormap(void);
+extern void ximage_blit(Drawable d, GC gc, int dstx, int dsty,
+ unsigned char *srcdata,
+ int srcx, int srcy, int srcw, int srch, int srcstride);
+
+void windrawstringxor(pdfapp_t *app, int x, int y, char *s);
+void cleanup(pdfapp_t *app);
+
+static Display *xdpy;
+static Atom XA_CLIPBOARD;
+static Atom XA_TARGETS;
+static Atom XA_TIMESTAMP;
+static Atom XA_UTF8_STRING;
+static Atom WM_DELETE_WINDOW;
+static Atom NET_WM_STATE;
+static Atom NET_WM_STATE_FULLSCREEN;
+static int x11fd;
+static int xscr;
+static Window xwin;
+static Pixmap xicon, xmask;
+static GC xgc;
+static XEvent xevt;
+static int mapped = 0;
+static Cursor xcarrow, xchand, xcwait, xccaret;
+static int justcopied = 0;
+static int dirty = 0;
+static int transition_dirty = 0;
+static int dirtysearch = 0;
+static char *password = "";
+static XColor xbgcolor;
+static XColor xshcolor;
+static int reqw = 0;
+static int reqh = 0;
+static char copylatin1[1024 * 16] = "";
+static char copyutf8[1024 * 48] = "";
+static Time copytime;
+static char *filename;
+
+static pdfapp_t gapp;
+static int closing = 0;
+static int reloading = 0;
+static int showingpage = 0;
+
+static int advance_scheduled = 0;
+static struct timeval tmo_advance;
+
+/*
+ * Dialog boxes
+ */
+
+void winerror(pdfapp_t *app, char *msg)
+{
+ fprintf(stderr, "mupdf: error: %s\n", msg);
+ cleanup(app);
+ exit(1);
+}
+
+void winwarn(pdfapp_t *app, char *msg)
+{
+ fprintf(stderr, "mupdf: warning: %s\n", msg);
+}
+
+void winalert(pdfapp_t *app, pdf_alert_event *alert)
+{
+ fprintf(stderr, "Alert %s: %s", alert->title, alert->message);
+ switch (alert->button_group_type)
+ {
+ case PDF_ALERT_BUTTON_GROUP_OK:
+ case PDF_ALERT_BUTTON_GROUP_OK_CANCEL:
+ alert->button_pressed = PDF_ALERT_BUTTON_OK;
+ break;
+ case PDF_ALERT_BUTTON_GROUP_YES_NO:
+ case PDF_ALERT_BUTTON_GROUP_YES_NO_CANCEL:
+ alert->button_pressed = PDF_ALERT_BUTTON_YES;
+ break;
+ }
+}
+
+void winprint(pdfapp_t *app)
+{
+ fprintf(stderr, "The MuPDF library supports printing, but this application currently does not");
+}
+
+char *winpassword(pdfapp_t *app, char *filename)
+{
+ char *r = password;
+ password = NULL;
+ return r;
+}
+
+char *wintextinput(pdfapp_t *app, char *inittext, int retry)
+{
+ static char buf[256];
+
+ if (retry)
+ return NULL;
+
+ printf("> [%s] ", inittext);
+ fgets(buf, sizeof buf, stdin);
+ return buf;
+}
+
+int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[])
+{
+ /* FIXME: temporary dummy implementation */
+ return 0;
+}
+
+/*
+ * X11 magic
+ */
+
+static void winopen(void)
+{
+ XWMHints *wmhints;
+ XClassHint *classhint;
+
+ xdpy = XOpenDisplay(NULL);
+ if (!xdpy)
+ fz_throw(gapp.ctx, FZ_ERROR_GENERIC, "cannot open display");
+
+ XA_CLIPBOARD = XInternAtom(xdpy, "CLIPBOARD", False);
+ XA_TARGETS = XInternAtom(xdpy, "TARGETS", False);
+ XA_TIMESTAMP = XInternAtom(xdpy, "TIMESTAMP", False);
+ XA_UTF8_STRING = XInternAtom(xdpy, "UTF8_STRING", False);
+ WM_DELETE_WINDOW = XInternAtom(xdpy, "WM_DELETE_WINDOW", False);
+ NET_WM_STATE = XInternAtom(xdpy, "_NET_WM_STATE", False);
+ NET_WM_STATE_FULLSCREEN = XInternAtom(xdpy, "_NET_WM_STATE_FULLSCREEN", False);
+
+ xscr = DefaultScreen(xdpy);
+
+ ximage_init(xdpy, xscr, DefaultVisual(xdpy, xscr));
+
+ xcarrow = XCreateFontCursor(xdpy, XC_left_ptr);
+ xchand = XCreateFontCursor(xdpy, XC_hand2);
+ xcwait = XCreateFontCursor(xdpy, XC_watch);
+ xccaret = XCreateFontCursor(xdpy, XC_xterm);
+
+ xbgcolor.red = 0x7000;
+ xbgcolor.green = 0x7000;
+ xbgcolor.blue = 0x7000;
+
+ xshcolor.red = 0x4000;
+ xshcolor.green = 0x4000;
+ xshcolor.blue = 0x4000;
+
+ XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xbgcolor);
+ XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xshcolor);
+
+ xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy),
+ 10, 10, 200, 100, 0,
+ ximage_get_depth(),
+ InputOutput,
+ ximage_get_visual(),
+ 0,
+ NULL);
+ if (xwin == None)
+ fz_throw(gapp.ctx, FZ_ERROR_GENERIC, "cannot create window");
+
+ XSetWindowColormap(xdpy, xwin, ximage_get_colormap());
+ XSelectInput(xdpy, xwin,
+ StructureNotifyMask | ExposureMask | KeyPressMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
+
+ mapped = 0;
+
+ xgc = XCreateGC(xdpy, xwin, 0, NULL);
+
+ XDefineCursor(xdpy, xwin, xcarrow);
+
+ wmhints = XAllocWMHints();
+ if (wmhints)
+ {
+ wmhints->flags = IconPixmapHint | IconMaskHint;
+ xicon = XCreateBitmapFromData(xdpy, xwin,
+ (char*)mupdf_icon_bitmap_16_bits,
+ mupdf_icon_bitmap_16_width,
+ mupdf_icon_bitmap_16_height);
+ xmask = XCreateBitmapFromData(xdpy, xwin,
+ (char*)mupdf_icon_bitmap_16_mask_bits,
+ mupdf_icon_bitmap_16_mask_width,
+ mupdf_icon_bitmap_16_mask_height);
+ if (xicon && xmask)
+ {
+ wmhints->icon_pixmap = xicon;
+ wmhints->icon_mask = xmask;
+ XSetWMHints(xdpy, xwin, wmhints);
+ }
+ XFree(wmhints);
+ }
+
+ classhint = XAllocClassHint();
+ if (classhint)
+ {
+ classhint->res_name = "mupdf";
+ classhint->res_class = "MuPDF";
+ XSetClassHint(xdpy, xwin, classhint);
+ XFree(classhint);
+ }
+
+ XSetWMProtocols(xdpy, xwin, &WM_DELETE_WINDOW, 1);
+
+ x11fd = ConnectionNumber(xdpy);
+}
+
+void winclose(pdfapp_t *app)
+{
+ closing = 1;
+}
+
+int winsavequery(pdfapp_t *app)
+{
+ /* FIXME: temporary dummy implementation */
+ return DISCARD;
+}
+
+int wingetsavepath(pdfapp_t *app, char *buf, int len)
+{
+ /* FIXME: temporary dummy implementation */
+ return 0;
+}
+
+void winreplacefile(char *source, char *target)
+{
+ rename(source, target);
+}
+
+void cleanup(pdfapp_t *app)
+{
+ fz_context *ctx = app->ctx;
+
+ pdfapp_close(app);
+
+ XDestroyWindow(xdpy, xwin);
+
+ XFreePixmap(xdpy, xicon);
+
+ XFreeCursor(xdpy, xccaret);
+ XFreeCursor(xdpy, xcwait);
+ XFreeCursor(xdpy, xchand);
+ XFreeCursor(xdpy, xcarrow);
+
+ XFreeGC(xdpy, xgc);
+
+ XCloseDisplay(xdpy);
+
+ fz_free_context(ctx);
+}
+
+static int winresolution()
+{
+ return DisplayWidth(xdpy, xscr) * 25.4 /
+ DisplayWidthMM(xdpy, xscr) + 0.5;
+}
+
+void wincursor(pdfapp_t *app, int curs)
+{
+ if (curs == ARROW)
+ XDefineCursor(xdpy, xwin, xcarrow);
+ if (curs == HAND)
+ XDefineCursor(xdpy, xwin, xchand);
+ if (curs == WAIT)
+ XDefineCursor(xdpy, xwin, xcwait);
+ if (curs == CARET)
+ XDefineCursor(xdpy, xwin, xccaret);
+ XFlush(xdpy);
+}
+
+void wintitle(pdfapp_t *app, char *s)
+{
+ XStoreName(xdpy, xwin, s);
+#ifdef X_HAVE_UTF8_STRING
+ Xutf8SetWMProperties(xdpy, xwin, s, s, NULL, 0, NULL, NULL, NULL);
+#else
+ XmbSetWMProperties(xdpy, xwin, s, s, NULL, 0, NULL, NULL, NULL);
+#endif
+}
+
+void winhelp(pdfapp_t *app)
+{
+ fprintf(stderr, "%s\n%s", pdfapp_version(app), pdfapp_usage(app));
+}
+
+void winresize(pdfapp_t *app, int w, int h)
+{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
+ XWindowChanges values;
+ int mask, width, height;
+
+ mask = CWWidth | CWHeight;
+ values.width = w;
+ values.height = h;
+ XConfigureWindow(xdpy, xwin, mask, &values);
+
+ reqw = w;
+ reqh = h;
+
+ if (!mapped)
+ {
+ gapp.winw = w;
+ gapp.winh = h;
+ width = -1;
+ height = -1;
+
+ XMapWindow(xdpy, xwin);
+ XFlush(xdpy);
+
+ while (1)
+ {
+ XNextEvent(xdpy, &xevt);
+ if (xevt.type == ConfigureNotify)
+ {
+ width = xevt.xconfigure.width;
+ height = xevt.xconfigure.height;
+ }
+ if (xevt.type == MapNotify)
+ break;
+ }
+
+ XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr));
+ XFillRectangle(xdpy, xwin, xgc, 0, 0, image_w, image_h);
+ XFlush(xdpy);
+
+ if (width != reqw || height != reqh)
+ {
+ gapp.shrinkwrap = 0;
+ dirty = 1;
+ pdfapp_onresize(&gapp, width, height);
+ }
+
+ mapped = 1;
+ }
+}
+
+void winfullscreen(pdfapp_t *app, int state)
+{
+ XEvent xev;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = xwin;
+ xev.xclient.message_type = NET_WM_STATE;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = state;
+ xev.xclient.data.l[1] = NET_WM_STATE_FULLSCREEN;
+ xev.xclient.data.l[2] = 0;
+ XSendEvent(xdpy, DefaultRootWindow(xdpy), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+static void fillrect(int x, int y, int w, int h)
+{
+ if (w > 0 && h > 0)
+ XFillRectangle(xdpy, xwin, xgc, x, y, w, h);
+}
+
+static void winblitsearch(pdfapp_t *app)
+{
+ if (gapp.isediting)
+ {
+ char buf[sizeof(gapp.search) + 50];
+ sprintf(buf, "Search: %s", gapp.search);
+ XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr));
+ fillrect(0, 0, gapp.winw, 30);
+ windrawstring(&gapp, 10, 20, buf);
+ }
+}
+
+static void winblit(pdfapp_t *app)
+{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
+ int image_n = fz_pixmap_components(gapp.ctx, gapp.image);
+ unsigned char *image_samples = fz_pixmap_samples(gapp.ctx, gapp.image);
+ int x0 = gapp.panx;
+ int y0 = gapp.pany;
+ int x1 = gapp.panx + image_w;
+ int y1 = gapp.pany + image_h;
+
+ XSetForeground(xdpy, xgc, xbgcolor.pixel);
+ fillrect(0, 0, x0, gapp.winh);
+ fillrect(x1, 0, gapp.winw - x1, gapp.winh);
+ fillrect(0, 0, gapp.winw, y0);
+ fillrect(0, y1, gapp.winw, gapp.winh - y1);
+
+ XSetForeground(xdpy, xgc, xshcolor.pixel);
+ fillrect(x0+2, y1, image_w, 2);
+ fillrect(x1, y0+2, 2, image_h);
+
+ if (gapp.iscopying || justcopied)
+ {
+ pdfapp_invert(&gapp, &gapp.selr);
+ justcopied = 1;
+ }
+
+ pdfapp_inverthit(&gapp);
+
+ if (image_n == 4)
+ ximage_blit(xwin, xgc,
+ x0, y0,
+ image_samples,
+ 0, 0,
+ image_w,
+ image_h,
+ image_w * image_n);
+ else if (image_n == 2)
+ {
+ int i = image_w*image_h;
+ unsigned char *color = malloc(i*4);
+ if (color)
+ {
+ unsigned char *s = image_samples;
+ unsigned char *d = color;
+ for (; i > 0 ; i--)
+ {
+ d[2] = d[1] = d[0] = *s++;
+ d[3] = *s++;
+ d += 4;
+ }
+ ximage_blit(xwin, xgc,
+ x0, y0,
+ color,
+ 0, 0,
+ image_w,
+ image_h,
+ image_w * 4);
+ free(color);
+ }
+ }
+
+ pdfapp_inverthit(&gapp);
+
+ if (gapp.iscopying || justcopied)
+ {
+ pdfapp_invert(&gapp, &gapp.selr);
+ justcopied = 1;
+ }
+
+ winblitsearch(app);
+
+ if (showingpage)
+ {
+ char buf[42];
+ snprintf(buf, sizeof buf, "Page %d/%d", gapp.pageno, gapp.pagecount);
+ windrawstringxor(&gapp, 10, 20, buf);
+ }
+}
+
+void winrepaint(pdfapp_t *app)
+{
+ dirty = 1;
+ if (app->in_transit)
+ transition_dirty = 1;
+}
+
+void winrepaintsearch(pdfapp_t *app)
+{
+ dirtysearch = 1;
+}
+
+void winadvancetimer(pdfapp_t *app, float duration)
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ memset(&tmo_advance, 0, sizeof(tmo_advance));
+ tmo_advance.tv_sec = (int)duration;
+ tmo_advance.tv_usec = 1000000 * (duration - tmo_advance.tv_sec);
+ timeradd(&tmo_advance, &now, &tmo_advance);
+ advance_scheduled = 1;
+}
+
+void windrawstringxor(pdfapp_t *app, int x, int y, char *s)
+{
+ int prevfunction;
+ XGCValues xgcv;
+
+ XGetGCValues(xdpy, xgc, GCFunction, &xgcv);
+ prevfunction = xgcv.function;
+ xgcv.function = GXxor;
+ XChangeGC(xdpy, xgc, GCFunction, &xgcv);
+
+ XSetForeground(xdpy, xgc, WhitePixel(xdpy, DefaultScreen(xdpy)));
+
+ XDrawString(xdpy, xwin, xgc, x, y, s, strlen(s));
+ XFlush(xdpy);
+
+ XGetGCValues(xdpy, xgc, GCFunction, &xgcv);
+ xgcv.function = prevfunction;
+ XChangeGC(xdpy, xgc, GCFunction, &xgcv);
+}
+
+void windrawstring(pdfapp_t *app, int x, int y, char *s)
+{
+ XSetForeground(xdpy, xgc, BlackPixel(xdpy, DefaultScreen(xdpy)));
+ XDrawString(xdpy, xwin, xgc, x, y, s, strlen(s));
+}
+
+void docopy(pdfapp_t *app, Atom copy_target)
+{
+ unsigned short copyucs2[16 * 1024];
+ char *latin1 = copylatin1;
+ char *utf8 = copyutf8;
+ unsigned short *ucs2;
+ int ucs;
+
+ pdfapp_oncopy(&gapp, copyucs2, 16 * 1024);
+
+ for (ucs2 = copyucs2; ucs2[0] != 0; ucs2++)
+ {
+ ucs = ucs2[0];
+
+ utf8 += fz_runetochar(utf8, ucs);
+
+ if (ucs < 256)
+ *latin1++ = ucs;
+ else
+ *latin1++ = '?';
+ }
+
+ *utf8 = 0;
+ *latin1 = 0;
+
+ XSetSelectionOwner(xdpy, copy_target, xwin, copytime);
+
+ justcopied = 1;
+}
+
+void windocopy(pdfapp_t *app)
+{
+ docopy(app, XA_PRIMARY);
+}
+
+void onselreq(Window requestor, Atom selection, Atom target, Atom property, Time time)
+{
+ XEvent nevt;
+
+ advance_scheduled = 0;
+
+ if (property == None)
+ property = target;
+
+ nevt.xselection.type = SelectionNotify;
+ nevt.xselection.send_event = True;
+ nevt.xselection.display = xdpy;
+ nevt.xselection.requestor = requestor;
+ nevt.xselection.selection = selection;
+ nevt.xselection.target = target;
+ nevt.xselection.property = property;
+ nevt.xselection.time = time;
+
+ if (target == XA_TARGETS)
+ {
+ Atom atomlist[4];
+ atomlist[0] = XA_TARGETS;
+ atomlist[1] = XA_TIMESTAMP;
+ atomlist[2] = XA_STRING;
+ atomlist[3] = XA_UTF8_STRING;
+ XChangeProperty(xdpy, requestor, property, target,
+ 32, PropModeReplace,
+ (unsigned char *)atomlist, sizeof(atomlist)/sizeof(Atom));
+ }
+
+ else if (target == XA_STRING)
+ {
+ XChangeProperty(xdpy, requestor, property, target,
+ 8, PropModeReplace,
+ (unsigned char *)copylatin1, strlen(copylatin1));
+ }
+
+ else if (target == XA_UTF8_STRING)
+ {
+ XChangeProperty(xdpy, requestor, property, target,
+ 8, PropModeReplace,
+ (unsigned char *)copyutf8, strlen(copyutf8));
+ }
+
+ else
+ {
+ nevt.xselection.property = None;
+ }
+
+ XSendEvent(xdpy, requestor, False, 0, &nevt);
+}
+
+void winreloadfile(pdfapp_t *app)
+{
+ pdfapp_close(app);
+ pdfapp_open(app, filename, 1);
+}
+
+void winopenuri(pdfapp_t *app, char *buf)
+{
+ char *browser = getenv("BROWSER");
+ if (!browser)
+ {
+#ifdef __APPLE__
+ browser = "open";
+#else
+ browser = "xdg-open";
+#endif
+ }
+ if (fork() == 0)
+ {
+ execlp(browser, browser, buf, (char*)0);
+ fprintf(stderr, "cannot exec '%s'\n", browser);
+ exit(0);
+ }
+}
+
+static void onkey(int c)
+{
+ advance_scheduled = 0;
+
+ if (justcopied)
+ {
+ justcopied = 0;
+ winrepaint(&gapp);
+ }
+
+ if (!gapp.isediting && c == 'P')
+ {
+ showingpage = 1;
+ winrepaint(&gapp);
+ return;
+ }
+
+ pdfapp_onkey(&gapp, c);
+}
+
+static void onmouse(int x, int y, int btn, int modifiers, int state)
+{
+ if (state != 0)
+ advance_scheduled = 0;
+
+ if (state != 0 && justcopied)
+ {
+ justcopied = 0;
+ winrepaint(&gapp);
+ }
+
+ pdfapp_onmouse(&gapp, x, y, btn, modifiers, state);
+}
+
+static void signal_handler(int signal)
+{
+ if (signal == SIGHUP)
+ reloading = 1;
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: mupdf [options] file.pdf [page]\n");
+ fprintf(stderr, "\t-b -\tset anti-aliasing quality in bits (0=off, 8=best)\n");
+ fprintf(stderr, "\t-p -\tpassword\n");
+ fprintf(stderr, "\t-r -\tresolution\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int len;
+ char buf[128];
+ KeySym keysym;
+ int oldx = 0;
+ int oldy = 0;
+ int resolution = -1;
+ int pageno = 1;
+ fd_set fds;
+ int width = -1;
+ int height = -1;
+ fz_context *ctx;
+ struct timeval tmo_at;
+ struct timeval now;
+ struct timeval tmo;
+ struct timeval *timeout;
+ struct timeval tmo_advance_delay;
+
+ ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
+ if (!ctx)
+ {
+ fprintf(stderr, "cannot initialise context\n");
+ exit(1);
+ }
+
+ while ((c = fz_getopt(argc, argv, "p:r:b:")) != -1)
+ {
+ switch (c)
+ {
+ case 'p': password = fz_optarg; break;
+ case 'r': resolution = atoi(fz_optarg); break;
+ case 'b': fz_set_aa_level(ctx, atoi(fz_optarg)); break;
+ default: usage();
+ }
+ }
+
+ if (argc - fz_optind == 0)
+ usage();
+
+ filename = argv[fz_optind++];
+
+ if (argc - fz_optind == 1)
+ pageno = atoi(argv[fz_optind++]);
+
+ pdfapp_init(ctx, &gapp);
+
+ winopen();
+
+ if (resolution == -1)
+ resolution = winresolution();
+ if (resolution < MINRES)
+ resolution = MINRES;
+ if (resolution > MAXRES)
+ resolution = MAXRES;
+
+ gapp.transitions_enabled = 1;
+ gapp.scrw = DisplayWidth(xdpy, xscr);
+ gapp.scrh = DisplayHeight(xdpy, xscr);
+ gapp.resolution = resolution;
+ gapp.pageno = pageno;
+
+ pdfapp_open(&gapp, filename, 0);
+
+ FD_ZERO(&fds);
+
+ signal(SIGHUP, signal_handler);
+
+ tmo_at.tv_sec = 0;
+ tmo_at.tv_usec = 0;
+
+ while (!closing)
+ {
+ while (!closing && XPending(xdpy) && !transition_dirty)
+ {
+ XNextEvent(xdpy, &xevt);
+
+ switch (xevt.type)
+ {
+ case Expose:
+ dirty = 1;
+ break;
+
+ case ConfigureNotify:
+ if (gapp.image)
+ {
+ if (xevt.xconfigure.width != reqw ||
+ xevt.xconfigure.height != reqh)
+ gapp.shrinkwrap = 0;
+ }
+ width = xevt.xconfigure.width;
+ height = xevt.xconfigure.height;
+
+ break;
+
+ case KeyPress:
+ len = XLookupString(&xevt.xkey, buf, sizeof buf, &keysym, NULL);
+
+ if (!gapp.isediting)
+ switch (keysym)
+ {
+ case XK_Escape:
+ len = 1; buf[0] = '\033';
+ break;
+
+ case XK_Up:
+ len = 1; buf[0] = 'k';
+ break;
+ case XK_Down:
+ len = 1; buf[0] = 'j';
+ break;
+
+ case XK_Left:
+ len = 1; buf[0] = 'b';
+ break;
+ case XK_Right:
+ len = 1; buf[0] = ' ';
+ break;
+
+ case XK_Page_Up:
+ len = 1; buf[0] = ',';
+ break;
+ case XK_Page_Down:
+ len = 1; buf[0] = '.';
+ break;
+ }
+ if (xevt.xkey.state & ControlMask && keysym == XK_c)
+ docopy(&gapp, XA_CLIPBOARD);
+ else if (len)
+ onkey(buf[0]);
+
+ onmouse(oldx, oldy, 0, 0, 0);
+
+ break;
+
+ case MotionNotify:
+ oldx = xevt.xmotion.x;
+ oldy = xevt.xmotion.y;
+ onmouse(xevt.xmotion.x, xevt.xmotion.y, 0, xevt.xmotion.state, 0);
+ break;
+
+ case ButtonPress:
+ onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 1);
+ break;
+
+ case ButtonRelease:
+ copytime = xevt.xbutton.time;
+ onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, -1);
+ break;
+
+ case SelectionRequest:
+ onselreq(xevt.xselectionrequest.requestor,
+ xevt.xselectionrequest.selection,
+ xevt.xselectionrequest.target,
+ xevt.xselectionrequest.property,
+ xevt.xselectionrequest.time);
+ break;
+
+ case ClientMessage:
+ if (xevt.xclient.format == 32 && xevt.xclient.data.l[0] == WM_DELETE_WINDOW)
+ closing = 1;
+ break;
+ }
+ }
+
+ if (closing)
+ continue;
+
+ if (width != -1 || height != -1)
+ {
+ pdfapp_onresize(&gapp, width, height);
+ width = -1;
+ height = -1;
+ }
+
+ if (dirty || dirtysearch)
+ {
+ if (dirty)
+ winblit(&gapp);
+ else if (dirtysearch)
+ winblitsearch(&gapp);
+ dirty = 0;
+ transition_dirty = 0;
+ dirtysearch = 0;
+ pdfapp_postblit(&gapp);
+ }
+
+ if (showingpage && !tmo_at.tv_sec && !tmo_at.tv_usec)
+ {
+ tmo.tv_sec = 2;
+ tmo.tv_usec = 0;
+
+ gettimeofday(&now, NULL);
+ timeradd(&now, &tmo, &tmo_at);
+ }
+
+ if (XPending(xdpy) || transition_dirty)
+ continue;
+
+ timeout = NULL;
+
+ if (tmo_at.tv_sec || tmo_at.tv_usec)
+ {
+ gettimeofday(&now, NULL);
+ timersub(&tmo_at, &now, &tmo);
+ if (tmo.tv_sec <= 0)
+ {
+ tmo_at.tv_sec = 0;
+ tmo_at.tv_usec = 0;
+ timeout = NULL;
+ showingpage = 0;
+ winrepaint(&gapp);
+ }
+ else
+ timeout = &tmo;
+ }
+
+ if (advance_scheduled)
+ {
+ gettimeofday(&now, NULL);
+ timersub(&tmo_advance, &now, &tmo_advance_delay);
+ if (tmo_advance_delay.tv_sec <= 0)
+ {
+ /* Too late already */
+ onkey(' ');
+ onmouse(oldx, oldy, 0, 0, 0);
+ advance_scheduled = 0;
+ }
+ else if (timeout == NULL)
+ {
+ timeout = &tmo_advance_delay;
+ }
+ else
+ {
+ struct timeval tmp;
+ timersub(&tmo_advance_delay, timeout, &tmp);
+ if (tmp.tv_sec < 0)
+ {
+ timeout = &tmo_advance_delay;
+ }
+ }
+ }
+
+ FD_SET(x11fd, &fds);
+ if (select(x11fd + 1, &fds, NULL, NULL, timeout) < 0)
+ {
+ if (reloading)
+ {
+ winreloadfile(&gapp);
+ reloading = 0;
+ }
+ }
+ if (!FD_ISSET(x11fd, &fds))
+ {
+ if (timeout == &tmo_advance_delay)
+ {
+ onkey(' ');
+ onmouse(oldx, oldy, 0, 0, 0);
+ advance_scheduled = 0;
+ }
+ else
+ {
+ tmo_at.tv_sec = 0;
+ tmo_at.tv_usec = 0;
+ timeout = NULL;
+ showingpage = 0;
+ winrepaint(&gapp);
+ }
+ }
+ }
+
+ cleanup(&gapp);
+
+ return 0;
+}