├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── config.yml └── workflows │ ├── checks.yml │ ├── docs.yml │ └── publish.yml ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── AndroidProjectSystem.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml └── runConfigurations.xml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINING.md ├── Makefile ├── README.md ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ └── readium.library-conventions.gradle.kts ├── docs ├── guides │ ├── accessibility.md │ ├── assets │ │ └── settings-flow.svg │ ├── content.md │ ├── getting-started.md │ ├── lcp.md │ ├── navigator │ │ ├── epub-fonts.md │ │ ├── media-navigator.md │ │ ├── navigator.md │ │ └── preferences.md │ ├── open-publication.md │ ├── pdf.md │ └── tts.md ├── migration-guide.md └── readium_colors.css ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mkdocs.yml ├── readium ├── adapters │ ├── exoplayer │ │ ├── audio │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── org │ │ │ │ │ └── readium │ │ │ │ │ └── adapter │ │ │ │ │ └── exoplayer │ │ │ │ │ └── audio │ │ │ │ │ ├── DefaultExoPlayerCacheProvider.kt │ │ │ │ │ ├── ExoAudiobookPlayer.kt │ │ │ │ │ ├── ExoPlayerAliases.kt │ │ │ │ │ ├── ExoPlayerCacheProvider.kt │ │ │ │ │ ├── ExoPlayerDataSource.kt │ │ │ │ │ ├── ExoPlayerDefaults.kt │ │ │ │ │ ├── ExoPlayerEngine.kt │ │ │ │ │ ├── ExoPlayerEngineProvider.kt │ │ │ │ │ ├── ExoPlayerPreferences.kt │ │ │ │ │ ├── ExoPlayerPreferencesEditor.kt │ │ │ │ │ ├── ExoPlayerPreferencesSerializer.kt │ │ │ │ │ ├── ExoPlayerSettings.kt │ │ │ │ │ ├── ExoPlayerSettingsResolver.kt │ │ │ │ │ └── SmartSeeker.kt │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── adapter │ │ │ │ └── exoplayer │ │ │ │ └── audio │ │ │ │ └── SmartSeekerTest.kt │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src │ │ │ └── main │ │ │ └── AndroidManifest.xml │ ├── pdfium │ │ ├── README.md │ │ ├── build.gradle.kts │ │ ├── common │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ ├── libs │ │ │ │ └── pdfium-android-1.8.2.jar │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── jniLibs │ │ │ │ ├── arm64-v8a │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ │ │ ├── armeabi-v7a │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ │ │ ├── armeabi │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ │ │ ├── mips │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ │ │ ├── x86 │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ │ │ └── x86_64 │ │ │ │ ├── libjniPdfium.so │ │ │ │ ├── libmodft2.so │ │ │ │ ├── libmodpdfium.so │ │ │ │ └── libmodpng.so │ │ ├── document │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── adapter │ │ │ │ └── pdfium │ │ │ │ └── document │ │ │ │ └── PdfiumDocument.kt │ │ ├── gradle.properties │ │ ├── navigator │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ ├── libs │ │ │ │ └── android-pdf-viewer-2.8.2.jar │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── readium │ │ │ │ │ └── adapter │ │ │ │ │ └── pdfium │ │ │ │ │ └── navigator │ │ │ │ │ ├── PdfiumDefaults.kt │ │ │ │ │ ├── PdfiumDocumentFragment.kt │ │ │ │ │ ├── PdfiumEngineProvider.kt │ │ │ │ │ ├── PdfiumNavigator.kt │ │ │ │ │ ├── PdfiumPreferences.kt │ │ │ │ │ ├── PdfiumPreferencesEditor.kt │ │ │ │ │ ├── PdfiumPreferencesFilters.kt │ │ │ │ │ ├── PdfiumPreferencesSerializer.kt │ │ │ │ │ ├── PdfiumSettings.kt │ │ │ │ │ └── PdfiumSettingsResolver.kt │ │ │ │ └── res │ │ │ │ └── layout │ │ │ │ └── readium_pspdfkit_fragment.xml │ │ └── src │ │ │ └── main │ │ │ └── AndroidManifest.xml │ └── pspdfkit │ │ ├── README.md │ │ ├── build.gradle.kts │ │ ├── document │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── org │ │ │ └── readium │ │ │ └── adapter │ │ │ └── pspdfkit │ │ │ └── document │ │ │ ├── PsPdfKitDocument.kt │ │ │ └── ResourceDataProvider.kt │ │ ├── gradle.properties │ │ ├── navigator │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── adapter │ │ │ │ └── pspdfkit │ │ │ │ └── navigator │ │ │ │ ├── PsPdfKitDefaults.kt │ │ │ │ ├── PsPdfKitDocumentFragment.kt │ │ │ │ ├── PsPdfKitEngineProvider.kt │ │ │ │ ├── PsPdfKitNavigator.kt │ │ │ │ ├── PsPdfKitPreferences.kt │ │ │ │ ├── PsPdfKitPreferencesEditor.kt │ │ │ │ ├── PsPdfKitPreferencesFilters.kt │ │ │ │ ├── PsPdfKitPreferencesSerializer.kt │ │ │ │ ├── PsPdfKitSettings.kt │ │ │ │ └── PsPdfKitSettingsResolver.kt │ │ │ └── res │ │ │ └── values │ │ │ └── ids.xml │ │ └── src │ │ └── main │ │ └── AndroidManifest.xml ├── lcp │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ └── prod-license.lcpl │ │ ├── java │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── r2 │ │ │ │ └── lcp │ │ │ │ ├── LcpAuthenticating.kt │ │ │ │ ├── LcpContentProtection.kt │ │ │ │ ├── LcpContentProtectionService.kt │ │ │ │ ├── LcpDecryptor.kt │ │ │ │ ├── LcpDecryptorTest.kt │ │ │ │ ├── LcpError.kt │ │ │ │ ├── LcpLicense.kt │ │ │ │ ├── LcpService.kt │ │ │ │ ├── MaterialRenewListener.kt │ │ │ │ ├── auth │ │ │ │ ├── LcpDialogAuthentication.kt │ │ │ │ └── LcpPassphraseAuthentication.kt │ │ │ │ ├── license │ │ │ │ ├── License.kt │ │ │ │ ├── LicenseValidation.kt │ │ │ │ ├── StateMachine.kt │ │ │ │ ├── container │ │ │ │ │ ├── BytesLicenseContainer.kt │ │ │ │ │ ├── ContainerLicenseContainer.kt │ │ │ │ │ ├── ContentZipLicenseContainer.kt │ │ │ │ │ ├── FileUtil.kt │ │ │ │ │ ├── FileZipLicenseContainer.kt │ │ │ │ │ ├── LcplLicenseContainer.kt │ │ │ │ │ ├── LcplResourceLicenseContainer.kt │ │ │ │ │ ├── LicenseContainer.kt │ │ │ │ │ └── ZipUtil.kt │ │ │ │ └── model │ │ │ │ │ ├── LicenseDocument.kt │ │ │ │ │ ├── StatusDocument.kt │ │ │ │ │ └── components │ │ │ │ │ ├── Link.kt │ │ │ │ │ ├── Links.kt │ │ │ │ │ ├── lcp │ │ │ │ │ ├── ContentKey.kt │ │ │ │ │ ├── Encryption.kt │ │ │ │ │ ├── Rights.kt │ │ │ │ │ ├── Signature.kt │ │ │ │ │ ├── User.kt │ │ │ │ │ └── UserKey.kt │ │ │ │ │ └── lsd │ │ │ │ │ ├── Event.kt │ │ │ │ │ └── PotentialRights.kt │ │ │ │ ├── persistence │ │ │ │ ├── LcpDao.kt │ │ │ │ ├── LcpDatabase.kt │ │ │ │ ├── License.kt │ │ │ │ └── Passphrase.kt │ │ │ │ ├── service │ │ │ │ ├── CRLService.kt │ │ │ │ ├── DeviceRepository.kt │ │ │ │ ├── DeviceService.kt │ │ │ │ ├── LcpClient.kt │ │ │ │ ├── LicensesRepository.kt │ │ │ │ ├── LicensesService.kt │ │ │ │ ├── NetworkService.kt │ │ │ │ ├── PassphrasesRepository.kt │ │ │ │ └── PassphrasesService.kt │ │ │ │ └── util │ │ │ │ └── Digest.kt │ │ └── res │ │ │ ├── layout │ │ │ └── readium_lcp_auth_dialog.xml │ │ │ └── values │ │ │ └── strings.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── readium │ │ │ └── r2 │ │ │ └── lcp │ │ │ ├── LcpDecryptorTest.kt │ │ │ ├── license │ │ │ └── container │ │ │ │ └── ZipUtilTest.kt │ │ │ └── util │ │ │ └── DigestTest.kt │ │ └── resources │ │ └── org │ │ └── readium │ │ └── r2 │ │ └── lcp │ │ ├── license │ │ └── container │ │ │ ├── a-fc.jpg │ │ │ └── futuristic_tales.cbz │ │ └── util │ │ └── a-fc.jpg ├── navigator │ ├── build.gradle.kts │ ├── gradle.properties │ ├── libs │ │ └── PhotoView-2.3.0.jar │ └── src │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ ├── _scripts │ │ │ │ ├── .eslintrc.json │ │ │ │ ├── .gitignore │ │ │ │ ├── .prettierignore │ │ │ │ ├── .prettierrc.json │ │ │ │ ├── README.md │ │ │ │ ├── babel.config.json │ │ │ │ ├── package.json │ │ │ │ ├── pnpm-lock.yaml │ │ │ │ ├── src │ │ │ │ │ ├── decorator.js │ │ │ │ │ ├── dom.js │ │ │ │ │ ├── gestures.js │ │ │ │ │ ├── index-fixed.js │ │ │ │ │ ├── index-reflowable.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── keyboard.js │ │ │ │ │ ├── rect.js │ │ │ │ │ ├── selection.js │ │ │ │ │ ├── utils.js │ │ │ │ │ └── vendor │ │ │ │ │ │ └── hypothesis │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ └── anchoring │ │ │ │ │ │ ├── html.js │ │ │ │ │ │ ├── match-quote.js │ │ │ │ │ │ ├── pdf.js │ │ │ │ │ │ ├── placeholder.js │ │ │ │ │ │ ├── test │ │ │ │ │ │ ├── fake-pdf-viewer-application.js │ │ │ │ │ │ ├── html-anchoring-fixture.html │ │ │ │ │ │ ├── html-baselines │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── minimal.html │ │ │ │ │ │ │ ├── minimal.json │ │ │ │ │ │ │ ├── wikipedia-regression-testing.html │ │ │ │ │ │ │ └── wikipedia-regression-testing.json │ │ │ │ │ │ ├── html-test.js │ │ │ │ │ │ ├── match-quote-test.js │ │ │ │ │ │ ├── pdf-test.js │ │ │ │ │ │ ├── placeholder-test.js │ │ │ │ │ │ ├── text-range-test.js │ │ │ │ │ │ ├── types-test.js │ │ │ │ │ │ └── xpath-test.js │ │ │ │ │ │ ├── text-range.js │ │ │ │ │ │ ├── types.js │ │ │ │ │ │ └── xpath.js │ │ │ │ └── webpack.config.js │ │ │ └── readium │ │ │ │ ├── divina │ │ │ │ ├── divinaPlayer.html │ │ │ │ ├── divinaPlayer.js │ │ │ │ └── divinaTouchHandling.js │ │ │ │ ├── error.xhtml │ │ │ │ ├── fonts │ │ │ │ └── OpenDyslexic-Regular.otf │ │ │ │ ├── readium-css │ │ │ │ ├── ReadMe.md │ │ │ │ ├── ReadiumCSS-after.css │ │ │ │ ├── ReadiumCSS-before.css │ │ │ │ ├── ReadiumCSS-default.css │ │ │ │ ├── ReadiumCSS-ebpaj_fonts_patch.css │ │ │ │ ├── cjk-horizontal │ │ │ │ │ ├── ReadiumCSS-after.css │ │ │ │ │ ├── ReadiumCSS-before.css │ │ │ │ │ └── ReadiumCSS-default.css │ │ │ │ ├── cjk-vertical │ │ │ │ │ ├── ReadiumCSS-after.css │ │ │ │ │ ├── ReadiumCSS-before.css │ │ │ │ │ └── ReadiumCSS-default.css │ │ │ │ ├── fonts │ │ │ │ │ ├── AccessibleDfA.otf │ │ │ │ │ ├── LICENSE-AccessibleDfa │ │ │ │ │ ├── LICENSE-IaWriterDuospace.md │ │ │ │ │ └── iAWriterDuospace-Regular.ttf │ │ │ │ └── rtl │ │ │ │ │ ├── ReadiumCSS-after.css │ │ │ │ │ ├── ReadiumCSS-before.css │ │ │ │ │ └── ReadiumCSS-default.css │ │ │ │ └── scripts │ │ │ │ ├── .gitignore │ │ │ │ ├── readium-fixed.js │ │ │ │ └── readium-reflowable.js │ │ ├── java │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── r2 │ │ │ │ └── navigator │ │ │ │ ├── DecorableNavigator.kt │ │ │ │ ├── DummyPublication.kt │ │ │ │ ├── HyperlinkNavigator.kt │ │ │ │ ├── Navigator.kt │ │ │ │ ├── NavigatorFragment.kt │ │ │ │ ├── R2BasicWebView.kt │ │ │ │ ├── R2WebView.kt │ │ │ │ ├── SelectableNavigator.kt │ │ │ │ ├── SimpleOverflow.kt │ │ │ │ ├── VisualNavigator.kt │ │ │ │ ├── epub │ │ │ │ ├── EpubDefaults.kt │ │ │ │ ├── EpubNavigatorFactory.kt │ │ │ │ ├── EpubNavigatorFragment.kt │ │ │ │ ├── EpubNavigatorViewModel.kt │ │ │ │ ├── EpubPreferences.kt │ │ │ │ ├── EpubPreferencesEditor.kt │ │ │ │ ├── EpubPreferencesFilters.kt │ │ │ │ ├── EpubPreferencesSerializer.kt │ │ │ │ ├── EpubSettings.kt │ │ │ │ ├── EpubSettingsResolver.kt │ │ │ │ ├── HtmlInjector.kt │ │ │ │ ├── WebViewServer.kt │ │ │ │ ├── css │ │ │ │ │ ├── FontFamilyDeclaration.kt │ │ │ │ │ ├── Layout.kt │ │ │ │ │ ├── Properties.kt │ │ │ │ │ └── ReadiumCss.kt │ │ │ │ ├── extensions │ │ │ │ │ ├── Decoration.kt │ │ │ │ │ └── Language.kt │ │ │ │ └── fxl │ │ │ │ │ ├── R2FXLLayout.kt │ │ │ │ │ ├── R2FXLOnDoubleTapListener.kt │ │ │ │ │ ├── R2FXLScroller.kt │ │ │ │ │ └── R2FXLUtils.kt │ │ │ │ ├── extensions │ │ │ │ ├── ControlFlow.kt │ │ │ │ ├── Duration.kt │ │ │ │ ├── Extensions.kt │ │ │ │ ├── JSON.kt │ │ │ │ ├── Locator.kt │ │ │ │ ├── Number.kt │ │ │ │ ├── Publication.kt │ │ │ │ └── String.kt │ │ │ │ ├── html │ │ │ │ └── HtmlDecorationTemplate.kt │ │ │ │ ├── image │ │ │ │ └── ImageNavigatorFragment.kt │ │ │ │ ├── input │ │ │ │ ├── DragEvent.kt │ │ │ │ ├── InputListener.kt │ │ │ │ ├── InputModifier.kt │ │ │ │ ├── KeyEvent.kt │ │ │ │ ├── KeyInterceptorView.kt │ │ │ │ └── TapEvent.kt │ │ │ │ ├── pager │ │ │ │ ├── DelegatingPagerAdapter.java │ │ │ │ ├── R2CbzPageFragment.kt │ │ │ │ ├── R2EpubPageFragment.kt │ │ │ │ ├── R2FXLPageFragment.kt │ │ │ │ ├── R2FragmentPagerAdapter.kt │ │ │ │ ├── R2PagerAdapter.kt │ │ │ │ ├── R2RTLViewPager.java │ │ │ │ ├── R2ViewPager.kt │ │ │ │ └── RtlViewPager.java │ │ │ │ ├── pdf │ │ │ │ ├── PdfEngineProvider.kt │ │ │ │ ├── PdfNavigatorFactory.kt │ │ │ │ ├── PdfNavigatorFragment.kt │ │ │ │ └── PdfNavigatorViewModel.kt │ │ │ │ ├── preferences │ │ │ │ ├── Configurable.kt │ │ │ │ ├── MappedPreference.kt │ │ │ │ ├── Preference.kt │ │ │ │ ├── PreferenceDelegate.kt │ │ │ │ ├── ProgressionStrategy.kt │ │ │ │ └── Types.kt │ │ │ │ └── util │ │ │ │ ├── BaseActionModeCallback.kt │ │ │ │ ├── DirectionalNavigationAdapter.kt │ │ │ │ ├── FragmentFactory.kt │ │ │ │ └── ViewModelFactory.kt │ │ └── res │ │ │ ├── drawable │ │ │ ├── readium_media_notification_fastforward.xml │ │ │ └── readium_media_notification_rewind.xml │ │ │ ├── layout │ │ │ ├── readium_navigator_fragment_fxllayout_double.xml │ │ │ ├── readium_navigator_fragment_fxllayout_single.xml │ │ │ ├── readium_navigator_viewpager.xml │ │ │ ├── readium_navigator_viewpager_fragment_cbz.xml │ │ │ └── readium_navigator_viewpager_fragment_epub.xml │ │ │ ├── values-land │ │ │ └── dimens.xml │ │ │ └── values │ │ │ ├── dimens.xml │ │ │ ├── ids.xml │ │ │ └── strings.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── readium │ │ │ └── r2 │ │ │ └── navigator │ │ │ ├── DecorationTest.kt │ │ │ └── epub │ │ │ ├── EpubSettingsResolverTest.kt │ │ │ └── css │ │ │ ├── LayoutTest.kt │ │ │ ├── PropertiesTest.kt │ │ │ └── ReadiumCssTest.kt │ │ └── resources │ │ └── robolectric.properties ├── navigators │ ├── common │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── org │ │ │ └── readium │ │ │ └── navigator │ │ │ └── common │ │ │ ├── HyperlinkListener.kt │ │ │ ├── InputListener.kt │ │ │ ├── LocatorAdapter.kt │ │ │ ├── NavigationController.kt │ │ │ ├── OverflowController.kt │ │ │ ├── RenditionState.kt │ │ │ └── SettingsController.kt │ ├── demo │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── navigator │ │ │ │ └── demo │ │ │ │ ├── DemoActivity.kt │ │ │ │ ├── DemoUi.kt │ │ │ │ ├── DemoViewModel.kt │ │ │ │ ├── persistence │ │ │ │ └── LocatorRepository.kt │ │ │ │ ├── preferences │ │ │ │ ├── PreferenceViews.kt │ │ │ │ ├── PreferencesManager.kt │ │ │ │ └── UserPreferences.kt │ │ │ │ ├── reader │ │ │ │ ├── ReaderOpener.kt │ │ │ │ └── ReaderUi.kt │ │ │ │ └── util │ │ │ │ ├── Fullscreenable.kt │ │ │ │ ├── Theme.kt │ │ │ │ ├── ToggleButton.kt │ │ │ │ └── WebLauncher.kt │ │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ │ └── xml │ │ │ └── network_security_config.xml │ ├── media │ │ ├── audio │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── navigator │ │ │ │ └── media │ │ │ │ └── audio │ │ │ │ ├── AudioEngine.kt │ │ │ │ ├── AudioEngineProvider.kt │ │ │ │ ├── AudioNavigator.kt │ │ │ │ ├── AudioNavigatorFactory.kt │ │ │ │ └── MetadataRetriever.kt │ │ ├── build.gradle.kts │ │ ├── common │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── navigator │ │ │ │ └── media │ │ │ │ └── common │ │ │ │ ├── DefaultMediaMetadataFactory.kt │ │ │ │ ├── DefaultMediaMetadataProvider.kt │ │ │ │ ├── Media3Adapter.kt │ │ │ │ ├── MediaMetadataFactory.kt │ │ │ │ ├── MediaMetadataProvider.kt │ │ │ │ ├── MediaNavigator.kt │ │ │ │ ├── TextAwareMediaNavigator.kt │ │ │ │ └── TimeBasedMediaNavigator.kt │ │ ├── gradle.properties │ │ ├── src │ │ │ └── main │ │ │ │ └── AndroidManifest.xml │ │ └── tts │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── org │ │ │ └── readium │ │ │ └── navigator │ │ │ └── media │ │ │ └── tts │ │ │ ├── TtsAliases.kt │ │ │ ├── TtsEngine.kt │ │ │ ├── TtsEngineFacade.kt │ │ │ ├── TtsEngineProvider.kt │ │ │ ├── TtsNavigator.kt │ │ │ ├── TtsNavigatorFactory.kt │ │ │ ├── TtsPlayer.kt │ │ │ ├── TtsUtteranceIterator.kt │ │ │ ├── android │ │ │ ├── AndroidTtsDefaults.kt │ │ │ ├── AndroidTtsEngine.kt │ │ │ ├── AndroidTtsEngineProvider.kt │ │ │ ├── AndroidTtsPreferences.kt │ │ │ ├── AndroidTtsPreferencesEditor.kt │ │ │ ├── AndroidTtsPreferencesFilters.kt │ │ │ ├── AndroidTtsPreferencesSerializer.kt │ │ │ ├── AndroidTtsSettings.kt │ │ │ └── AndroidTtsSettingsResolver.kt │ │ │ └── session │ │ │ ├── AudioBecomingNoisyManager.kt │ │ │ ├── AudioFocusManager.kt │ │ │ ├── StreamVolumeManager.kt │ │ │ ├── TtsSessionAdapter.kt │ │ │ └── TtsTimeline.kt │ └── web │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── scripts │ │ ├── .eslintrc.json │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .prettierrc.json │ │ ├── README.md │ │ ├── babel.config.json │ │ ├── package.json │ │ ├── pnpm-lock.yaml │ │ ├── public │ │ │ ├── fixed-double-index.html │ │ │ └── fixed-single-index.html │ │ ├── src │ │ │ ├── bridge │ │ │ │ ├── fixed-double-bridge.ts │ │ │ │ ├── fixed-gestures-bridge.ts │ │ │ │ ├── fixed-initialization-bridge.ts │ │ │ │ └── fixed-single-bridge.ts │ │ │ ├── common │ │ │ │ ├── events.ts │ │ │ │ ├── gestures.ts │ │ │ │ └── types.ts │ │ │ ├── fixed │ │ │ │ ├── area-manager.ts │ │ │ │ ├── double-area-manager.ts │ │ │ │ ├── iframe-message.ts │ │ │ │ ├── page-manager.ts │ │ │ │ └── single-area-manager.ts │ │ │ ├── index-fixed-double.ts │ │ │ ├── index-fixed-injectable.ts │ │ │ ├── index-fixed-single.ts │ │ │ └── util │ │ │ │ ├── fit.ts │ │ │ │ └── viewport.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js │ │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── readium │ │ │ └── navigators │ │ │ └── web │ │ │ ├── error.xhtml │ │ │ ├── fixed-double-index.html │ │ │ ├── fixed-double-script.js │ │ │ ├── fixed-double-script.js.map │ │ │ ├── fixed-injectable-script.js │ │ │ ├── fixed-injectable-script.js.map │ │ │ ├── fixed-single-index.html │ │ │ ├── fixed-single-script.js │ │ │ ├── fixed-single-script.js.map │ │ │ ├── prepaginated-double-index.html │ │ │ └── prepaginated-single-index.html │ │ └── java │ │ └── org │ │ └── readium │ │ └── navigator │ │ └── web │ │ ├── FixedWebNavigatorFactory.kt │ │ ├── FixedWebRendition.kt │ │ ├── FixedWebRenditionState.kt │ │ ├── gestures │ │ ├── AndroidScrollable.android.kt │ │ ├── DragGestureDetector.kt │ │ ├── Draggable.kt │ │ ├── Fling2DBehavior.kt │ │ ├── Scrollable2D.kt │ │ └── Scrollable2DState.kt │ │ ├── layout │ │ ├── Layout.kt │ │ ├── LayoutResolver.kt │ │ └── ReadingOrder.kt │ │ ├── location │ │ ├── LocationTypes.kt │ │ └── LocatorAdapters.kt │ │ ├── pager │ │ ├── LoggingNestedScrollConnection.kt │ │ ├── LoggingTargetedFlingBehavior.kt │ │ ├── NavigatorPager.kt │ │ └── PagerNestedScrollConnection.kt │ │ ├── preferences │ │ ├── FixedWebDefaults.kt │ │ ├── FixedWebPreferences.kt │ │ ├── FixedWebPreferencesEditor.kt │ │ ├── FixedWebPreferencesFilters.kt │ │ ├── FixedWebSettings.kt │ │ └── FixedWebSettingsResolver.kt │ │ ├── spread │ │ ├── DoubleViewportSpread.kt │ │ ├── SingleViewportSpread.kt │ │ ├── SpreadNestedScrollConnection.kt │ │ └── SpreadWebView.kt │ │ ├── util │ │ ├── DisplayArea.kt │ │ ├── HtmlInjector.kt │ │ ├── HyperlinkProcessor.kt │ │ ├── WebViewClient.kt │ │ └── WebViewServer.kt │ │ ├── webapi │ │ ├── FixedDoubleApi.kt │ │ ├── FixedSingleApi.kt │ │ ├── GesturesApi.kt │ │ └── InitializationApi.kt │ │ └── webview │ │ ├── ComposableWebView.kt │ │ ├── RelaxedWebView.kt │ │ └── WebViewScrollable2DState.kt ├── opds │ ├── README.md │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── org │ │ │ └── readium │ │ │ └── r2 │ │ │ └── opds │ │ │ ├── OPDS1Parser.kt │ │ │ └── OPDS2Parser.kt │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── readium │ │ │ └── r2 │ │ │ └── opds │ │ │ ├── OPDS1ParserTest.kt │ │ │ └── TestUtils.kt │ │ └── resources │ │ ├── org │ │ └── readium │ │ │ └── r2 │ │ │ └── opds │ │ │ └── opds1 │ │ │ ├── acquisition-feed.atom │ │ │ ├── entry.atom │ │ │ └── nav-feed.atom │ │ └── robolectric.properties ├── shared │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── org │ │ │ │ └── readium │ │ │ │ └── r2 │ │ │ │ └── shared │ │ │ │ ├── JSONable.kt │ │ │ │ ├── MediaOverlayNode.kt │ │ │ │ ├── MediaOverlays.kt │ │ │ │ ├── OptIn.kt │ │ │ │ ├── accessibility │ │ │ │ ├── AccessibilityDisplayString.kt │ │ │ │ └── AccessibilityMetadataDisplayGuide.kt │ │ │ │ ├── extensions │ │ │ │ ├── Bitmap.kt │ │ │ │ ├── ByteArray.kt │ │ │ │ ├── ContentResolver.kt │ │ │ │ ├── Exception.kt │ │ │ │ ├── File.kt │ │ │ │ ├── Float.kt │ │ │ │ ├── Flow.kt │ │ │ │ ├── InputStream.kt │ │ │ │ ├── Iterable.kt │ │ │ │ ├── JSON.kt │ │ │ │ ├── LongRange.kt │ │ │ │ ├── Map.kt │ │ │ │ ├── String.kt │ │ │ │ └── URL.kt │ │ │ │ ├── opds │ │ │ │ ├── Acquisition.kt │ │ │ │ ├── Availability.kt │ │ │ │ ├── Copies.kt │ │ │ │ ├── Facet.kt │ │ │ │ ├── Feed.kt │ │ │ │ ├── Group.kt │ │ │ │ ├── Holds.kt │ │ │ │ ├── OpdsMetadata.kt │ │ │ │ └── Price.kt │ │ │ │ ├── publication │ │ │ │ ├── Accessibility.kt │ │ │ │ ├── Collection.kt │ │ │ │ ├── Contributor.kt │ │ │ │ ├── Href.kt │ │ │ │ ├── HrefNormalizer.kt │ │ │ │ ├── Link.kt │ │ │ │ ├── LocalizedString.kt │ │ │ │ ├── Locator.kt │ │ │ │ ├── Manifest.kt │ │ │ │ ├── ManifestTransformer.kt │ │ │ │ ├── Metadata.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Publication.kt │ │ │ │ ├── PublicationCollection.kt │ │ │ │ ├── PublicationServicesHolder.kt │ │ │ │ ├── ReadingProgression.kt │ │ │ │ ├── Subject.kt │ │ │ │ ├── Tdm.kt │ │ │ │ ├── encryption │ │ │ │ │ ├── Encryption.kt │ │ │ │ │ └── Properties.kt │ │ │ │ ├── epub │ │ │ │ │ ├── EpubEncryptionParser.kt │ │ │ │ │ ├── EpubLayout.kt │ │ │ │ │ ├── Presentation.kt │ │ │ │ │ ├── Properties.kt │ │ │ │ │ └── Publication.kt │ │ │ │ ├── html │ │ │ │ │ ├── DomRange.kt │ │ │ │ │ └── Locator.kt │ │ │ │ ├── opds │ │ │ │ │ ├── Properties.kt │ │ │ │ │ └── Publication.kt │ │ │ │ ├── presentation │ │ │ │ │ ├── Metadata.kt │ │ │ │ │ ├── Presentation.kt │ │ │ │ │ └── Properties.kt │ │ │ │ ├── protection │ │ │ │ │ ├── ContentProtection.kt │ │ │ │ │ └── FallbackContentProtection.kt │ │ │ │ └── services │ │ │ │ │ ├── CacheService.kt │ │ │ │ │ ├── ContentProtectionService.kt │ │ │ │ │ ├── CoverService.kt │ │ │ │ │ ├── LocatorService.kt │ │ │ │ │ ├── PositionsService.kt │ │ │ │ │ ├── content │ │ │ │ │ ├── Content.kt │ │ │ │ │ ├── ContentService.kt │ │ │ │ │ ├── ContentTokenizer.kt │ │ │ │ │ └── iterators │ │ │ │ │ │ ├── HtmlResourceContentIterator.kt │ │ │ │ │ │ └── PublicationContentIterator.kt │ │ │ │ │ └── search │ │ │ │ │ ├── SearchService.kt │ │ │ │ │ └── StringSearchService.kt │ │ │ │ └── util │ │ │ │ ├── Benchmarking.kt │ │ │ │ ├── Closeable.kt │ │ │ │ ├── CoroutineQueue.kt │ │ │ │ ├── CursorList.kt │ │ │ │ ├── Either.kt │ │ │ │ ├── Error.kt │ │ │ │ ├── Instant.kt │ │ │ │ ├── Language.kt │ │ │ │ ├── Lazy.kt │ │ │ │ ├── MapCompanion.kt │ │ │ │ ├── MemoryObserver.kt │ │ │ │ ├── SingleJob.kt │ │ │ │ ├── Try.kt │ │ │ │ ├── URITemplate.kt │ │ │ │ ├── Url.kt │ │ │ │ ├── archive │ │ │ │ ├── ArchiveOpener.kt │ │ │ │ └── ArchiveProperties.kt │ │ │ │ ├── asset │ │ │ │ ├── Asset.kt │ │ │ │ ├── AssetRetriever.kt │ │ │ │ ├── AssetSniffer.kt │ │ │ │ └── Defaults.kt │ │ │ │ ├── cache │ │ │ │ └── Cache.kt │ │ │ │ ├── content │ │ │ │ ├── ContentResolverError.kt │ │ │ │ ├── ContentResource.kt │ │ │ │ └── ContentResourceFactory.kt │ │ │ │ ├── data │ │ │ │ ├── Buffering.kt │ │ │ │ ├── Caching.kt │ │ │ │ ├── Container.kt │ │ │ │ ├── Decoding.kt │ │ │ │ ├── InputStream.kt │ │ │ │ └── Reading.kt │ │ │ │ ├── file │ │ │ │ ├── DirectoryContainer.kt │ │ │ │ ├── FileResource.kt │ │ │ │ ├── FileResourceFactory.kt │ │ │ │ └── FileSystemError.kt │ │ │ │ ├── format │ │ │ │ ├── Format.kt │ │ │ │ ├── Sniffers.kt │ │ │ │ └── Sniffing.kt │ │ │ │ ├── http │ │ │ │ ├── DefaultHttpClient.kt │ │ │ │ ├── HttpClient.kt │ │ │ │ ├── HttpContainer.kt │ │ │ │ ├── HttpError.kt │ │ │ │ ├── HttpHeaders.kt │ │ │ │ ├── HttpRequest.kt │ │ │ │ ├── HttpResource.kt │ │ │ │ ├── HttpResourceFactory.kt │ │ │ │ ├── HttpResponse.kt │ │ │ │ ├── HttpStatus.kt │ │ │ │ └── ProblemDetails.kt │ │ │ │ ├── io │ │ │ │ └── CountingInputStream.kt │ │ │ │ ├── logging │ │ │ │ └── WarningLogger.kt │ │ │ │ ├── mediatype │ │ │ │ └── MediaType.kt │ │ │ │ ├── pdf │ │ │ │ └── PdfDocument.kt │ │ │ │ ├── resource │ │ │ │ ├── BufferingResource.kt │ │ │ │ ├── FallbackResource.kt │ │ │ │ ├── FileProperties.kt │ │ │ │ ├── InMemoryResource.kt │ │ │ │ ├── LazyResource.kt │ │ │ │ ├── Resource.kt │ │ │ │ ├── ResourceFactory.kt │ │ │ │ ├── SingleResourceContainer.kt │ │ │ │ ├── StringResource.kt │ │ │ │ ├── SynchronizedResource.kt │ │ │ │ ├── TransformingContainer.kt │ │ │ │ ├── TransformingResource.kt │ │ │ │ └── content │ │ │ │ │ └── ResourceContentExtractor.kt │ │ │ │ ├── tokenizer │ │ │ │ ├── TextTokenizer.kt │ │ │ │ └── Tokenizer.kt │ │ │ │ ├── units │ │ │ │ └── Hertz.kt │ │ │ │ ├── xml │ │ │ │ └── XmlParser.kt │ │ │ │ └── zip │ │ │ │ ├── BufferedReadableChannel.kt │ │ │ │ ├── CachingReadableChannel.kt │ │ │ │ ├── FileChannelAdapter.java │ │ │ │ ├── FileZipArchiveProvider.kt │ │ │ │ ├── FileZipContainer.kt │ │ │ │ ├── ReadableChannelAdapter.kt │ │ │ │ ├── StreamingZipArchiveProvider.kt │ │ │ │ ├── StreamingZipContainer.kt │ │ │ │ ├── ZipArchiveOpener.kt │ │ │ │ ├── compress │ │ │ │ ├── archivers │ │ │ │ │ ├── ArchiveEntry.java │ │ │ │ │ ├── ArchiveInputStream.java │ │ │ │ │ ├── ArchiveOutputStream.java │ │ │ │ │ ├── EntryStreamOffsets.java │ │ │ │ │ └── zip │ │ │ │ │ │ ├── AbstractUnicodeExtraField.java │ │ │ │ │ │ ├── CharsetAccessor.java │ │ │ │ │ │ ├── ExtraFieldParsingBehavior.java │ │ │ │ │ │ ├── ExtraFieldUtils.java │ │ │ │ │ │ ├── GeneralPurposeBit.java │ │ │ │ │ │ ├── InflaterInputStreamWithStatistics.java │ │ │ │ │ │ ├── NioZipEncoding.java │ │ │ │ │ │ ├── ResourceAlignmentExtraField.java │ │ │ │ │ │ ├── ScatterStatistics.java │ │ │ │ │ │ ├── ScatterZipOutputStream.java │ │ │ │ │ │ ├── StreamCompressor.java │ │ │ │ │ │ ├── UnicodeCommentExtraField.java │ │ │ │ │ │ ├── UnicodePathExtraField.java │ │ │ │ │ │ ├── UnixStat.java │ │ │ │ │ │ ├── UnparseableExtraFieldBehavior.java │ │ │ │ │ │ ├── UnparseableExtraFieldData.java │ │ │ │ │ │ ├── UnrecognizedExtraField.java │ │ │ │ │ │ ├── UnsupportedZipFeatureException.java │ │ │ │ │ │ ├── Zip64ExtendedInformationExtraField.java │ │ │ │ │ │ ├── Zip64Mode.java │ │ │ │ │ │ ├── Zip64RequiredException.java │ │ │ │ │ │ ├── ZipArchiveEntry.java │ │ │ │ │ │ ├── ZipArchiveEntryPredicate.java │ │ │ │ │ │ ├── ZipArchiveEntryRequest.java │ │ │ │ │ │ ├── ZipArchiveOutputStream.java │ │ │ │ │ │ ├── ZipConstants.java │ │ │ │ │ │ ├── ZipEightByteInteger.java │ │ │ │ │ │ ├── ZipEncoding.java │ │ │ │ │ │ ├── ZipEncodingHelper.java │ │ │ │ │ │ ├── ZipExtraField.java │ │ │ │ │ │ ├── ZipFile.java │ │ │ │ │ │ ├── ZipLong.java │ │ │ │ │ │ ├── ZipMethod.java │ │ │ │ │ │ ├── ZipShort.java │ │ │ │ │ │ ├── ZipSplitOutputStream.java │ │ │ │ │ │ ├── ZipSplitReadOnlySeekableByteChannel.java │ │ │ │ │ │ └── ZipUtil.java │ │ │ │ ├── parallel │ │ │ │ │ ├── InputStreamSupplier.java │ │ │ │ │ ├── ScatterGatherBackingStore.java │ │ │ │ │ └── ScatterGatherBackingStoreSupplier.java │ │ │ │ └── utils │ │ │ │ │ ├── BoundedArchiveInputStream.java │ │ │ │ │ ├── BoundedInputStream.java │ │ │ │ │ ├── BoundedSeekableByteChannelInputStream.java │ │ │ │ │ ├── ByteUtils.java │ │ │ │ │ ├── CountingInputStream.java │ │ │ │ │ ├── FileNameUtils.java │ │ │ │ │ ├── IOUtils.java │ │ │ │ │ ├── InputStreamStatistics.java │ │ │ │ │ └── MultiReadOnlySeekableByteChannel.java │ │ │ │ └── jvm │ │ │ │ ├── AsynchronousCloseException.java │ │ │ │ ├── ByteChannel.java │ │ │ │ ├── Channel.java │ │ │ │ ├── ClosedByInterruptException.java │ │ │ │ ├── ClosedChannelException.java │ │ │ │ ├── NonReadableChannelException.java │ │ │ │ ├── NonWritableChannelException.java │ │ │ │ ├── ReadableByteChannel.java │ │ │ │ ├── SeekableByteChannel.java │ │ │ │ └── WritableByteChannel.java │ │ └── res │ │ │ └── values │ │ │ └── w3c_a11y_meta_display_guide_strings.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── readium │ │ │ └── r2 │ │ │ └── shared │ │ │ ├── TestUtils.kt │ │ │ ├── accessibility │ │ │ ├── AccessibilityDisplayStringTest.kt │ │ │ └── AccessibilityMetadataDisplayGuideTest.kt │ │ │ ├── extensions │ │ │ ├── BitmapTest.kt │ │ │ ├── JSONTest.kt │ │ │ ├── LongRangeTest.kt │ │ │ ├── StringTest.kt │ │ │ └── URLTest.kt │ │ │ ├── opds │ │ │ ├── AcquisitionTest.kt │ │ │ ├── AvailabilityTest.kt │ │ │ ├── CopiesTest.kt │ │ │ ├── HoldsTest.kt │ │ │ └── PriceTest.kt │ │ │ ├── publication │ │ │ ├── AccessibilityTest.kt │ │ │ ├── ContributorTest.kt │ │ │ ├── HrefTest.kt │ │ │ ├── LinkTest.kt │ │ │ ├── LocalizedStringTest.kt │ │ │ ├── LocatorTest.kt │ │ │ ├── ManifestTest.kt │ │ │ ├── MetadataTest.kt │ │ │ ├── PropertiesTest.kt │ │ │ ├── PublicationCollectionTest.kt │ │ │ ├── PublicationTest.kt │ │ │ ├── ReadingProgressionTest.kt │ │ │ ├── SubjectTest.kt │ │ │ ├── TdmTest.kt │ │ │ ├── encryption │ │ │ │ ├── EncryptionTest.kt │ │ │ │ └── PropertiesTest.kt │ │ │ ├── epub │ │ │ │ ├── EncryptionParserTest.kt │ │ │ │ ├── EpubLayoutTest.kt │ │ │ │ ├── PresentationTest.kt │ │ │ │ ├── PropertiesTest.kt │ │ │ │ └── PublicationTest.kt │ │ │ ├── html │ │ │ │ ├── DomRangeTest.kt │ │ │ │ └── LocatorTest.kt │ │ │ ├── opds │ │ │ │ ├── PropertiesTest.kt │ │ │ │ └── PublicationTest.kt │ │ │ ├── presentation │ │ │ │ ├── MetadataTest.kt │ │ │ │ ├── PresentationTest.kt │ │ │ │ └── PropertiesTest.kt │ │ │ └── services │ │ │ │ ├── CoverServiceTest.kt │ │ │ │ ├── LocatorServiceTest.kt │ │ │ │ ├── PositionsServiceTest.kt │ │ │ │ └── content │ │ │ │ └── iterators │ │ │ │ └── HtmlResourceContentIteratorTest.kt │ │ │ └── util │ │ │ ├── InstantTest.kt │ │ │ ├── URITemplateTest.kt │ │ │ ├── UrlTest.kt │ │ │ ├── asset │ │ │ └── AssetSnifferTest.kt │ │ │ ├── format │ │ │ ├── DefaultSniffersTest.kt │ │ │ └── TestContainer.kt │ │ │ ├── http │ │ │ └── ProblemDetailsTest.kt │ │ │ ├── mediatype │ │ │ └── MediaTypeTest.kt │ │ │ ├── resource │ │ │ ├── BufferingResourceTest.kt │ │ │ ├── DirectoryContainerTest.kt │ │ │ ├── PropertiesTest.kt │ │ │ ├── ReadableInputStreamAdapterTest.kt │ │ │ └── ZipContainerTest.kt │ │ │ ├── tokenizer │ │ │ ├── IcuTextTokenizerTest.kt │ │ │ └── NaiveTextTokenizerTest.kt │ │ │ └── xml │ │ │ └── XmlParserTest.kt │ │ └── resources │ │ ├── junit-platform.properties │ │ ├── org │ │ └── readium │ │ │ └── r2 │ │ │ └── shared │ │ │ ├── extensions │ │ │ └── image.jpg │ │ │ ├── publication │ │ │ ├── epub │ │ │ │ └── encryption │ │ │ │ │ ├── encryption-lcp-prefixes.xml │ │ │ │ │ ├── encryption-lcp-xmlns.xml │ │ │ │ │ └── encryption-unknown-method.xml │ │ │ └── services │ │ │ │ └── cover.jpg │ │ │ └── util │ │ │ ├── asset │ │ │ ├── any.json │ │ │ ├── audiobook-lcp.unknown │ │ │ ├── audiobook-package.unknown │ │ │ ├── audiobook-wrongtype.json │ │ │ ├── audiobook.json │ │ │ ├── cbz.unknown │ │ │ ├── divina-package.unknown │ │ │ ├── divina.json │ │ │ ├── epub.unknown │ │ │ ├── html-doctype-case.unknown │ │ │ ├── html.unknown │ │ │ ├── lcpl.unknown │ │ │ ├── lpf-index-html.unknown │ │ │ ├── lpf.unknown │ │ │ ├── opds-authentication.json │ │ │ ├── opds1-entry.unknown │ │ │ ├── opds1-feed.unknown │ │ │ ├── opds2-feed.json │ │ │ ├── opds2-publication.json │ │ │ ├── pdf-lcp.unknown │ │ │ ├── pdf.unknown │ │ │ ├── png.unknown │ │ │ ├── unknown │ │ │ ├── unknown.zip │ │ │ ├── w3c-wpub.json │ │ │ ├── webpub-lcp.unknown │ │ │ ├── webpub-package.unknown │ │ │ ├── webpub.json │ │ │ ├── xhtml.unknown │ │ │ └── zab.unknown │ │ │ └── resource │ │ │ ├── directory │ │ │ ├── subdirectory │ │ │ │ ├── hello.mp3 │ │ │ │ └── text2.txt │ │ │ └── text1.txt │ │ │ ├── epub.epub │ │ │ └── epub │ │ │ ├── EPUB │ │ │ ├── cover.xhtml │ │ │ ├── css │ │ │ │ ├── epub.css │ │ │ │ └── nav.css │ │ │ ├── images │ │ │ │ └── cover.png │ │ │ ├── nav.xhtml │ │ │ ├── package.opf │ │ │ ├── s04.xhtml │ │ │ └── toc.ncx │ │ │ ├── META-INF │ │ │ └── container.xml │ │ │ └── mimetype │ │ └── robolectric.properties └── streamer │ ├── build.gradle.kts │ ├── gradle.properties │ └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── org │ │ └── readium │ │ └── r2 │ │ └── streamer │ │ ├── PublicationOpener.kt │ │ ├── extensions │ │ ├── Container.kt │ │ ├── File.kt │ │ ├── StringExt.kt │ │ └── Url.kt │ │ └── parser │ │ ├── PublicationParser.kt │ │ ├── audio │ │ ├── AudioLocatorService.kt │ │ └── AudioParser.kt │ │ ├── epub │ │ ├── AccessibilityAdapter.kt │ │ ├── ClockValueParser.kt │ │ ├── Constants.kt │ │ ├── EpubDeobfuscator.kt │ │ ├── EpubParser.kt │ │ ├── EpubPositionsService.kt │ │ ├── ManifestAdapter.kt │ │ ├── MetadataAdapter.kt │ │ ├── MetadataListHelpers.kt │ │ ├── MetadataParser.kt │ │ ├── NavigationDocumentParser.kt │ │ ├── NcxParser.kt │ │ ├── PackageDocument.kt │ │ ├── PresentationAdapter.kt │ │ ├── PropertyDataType.kt │ │ ├── ResourceAdapter.kt │ │ └── SmilParser.kt │ │ ├── image │ │ └── ImageParser.kt │ │ ├── pdf │ │ ├── PdfParser.kt │ │ └── PdfPositionsService.kt │ │ └── readium │ │ ├── LcpdfPositionsService.kt │ │ └── ReadiumWebPubParser.kt │ └── test │ ├── java │ └── org │ │ └── readium │ │ └── r2 │ │ └── streamer │ │ ├── TestUtils.kt │ │ ├── extensions │ │ ├── ContainerTest.kt │ │ ├── FileTest.kt │ │ └── StringExtTest.kt │ │ └── parser │ │ ├── audio │ │ └── AudioLocatorServiceTest.kt │ │ ├── epub │ │ ├── ClockValueParserTest.kt │ │ ├── EpubDeobfuscatorTest.kt │ │ ├── EpubPositionsServiceTest.kt │ │ ├── MetadataTest.kt │ │ ├── NavigationDocumentParserTest.kt │ │ ├── NcxParserTest.kt │ │ ├── PackageDocumentTest.kt │ │ └── PropertyDataTypeTest.kt │ │ ├── image │ │ └── ImageParserTest.kt │ │ └── pdf │ │ └── PdfPositionsServiceTest.kt │ └── resources │ ├── junit-platform.properties │ ├── org │ └── readium │ │ └── r2 │ │ └── streamer │ │ └── parser │ │ ├── epub │ │ ├── deobfuscation │ │ │ ├── cut-cut.adb.woff │ │ │ ├── cut-cut.obf.woff │ │ │ └── cut-cut.woff │ │ ├── navigation │ │ │ ├── nav-children.xhtml │ │ │ ├── nav-complex.xhtml │ │ │ ├── nav-empty.xhtml │ │ │ ├── nav-section.xhtml │ │ │ └── nav-titles.xhtml │ │ ├── ncx │ │ │ ├── ncx-children.ncx │ │ │ ├── ncx-complex.ncx │ │ │ ├── ncx-empty.ncx │ │ │ └── ncx-titles.ncx │ │ └── package │ │ │ ├── accessibility-epub2.opf │ │ │ ├── accessibility-epub3.opf │ │ │ ├── collections-epub2.opf │ │ │ ├── collections-epub3.opf │ │ │ ├── contributors-epub2.opf │ │ │ ├── contributors-epub3.opf │ │ │ ├── cover-epub2.opf │ │ │ ├── cover-epub3.opf │ │ │ ├── cover-mix.opf │ │ │ ├── dates-epub2.opf │ │ │ ├── dates-epub3.opf │ │ │ ├── fallbacks-termination.opf │ │ │ ├── fallbacks.opf │ │ │ ├── guide-epub2.opf │ │ │ ├── identifier-unique.opf │ │ │ ├── languages-order-nomatch.opf │ │ │ ├── languages-order.opf │ │ │ ├── links-properties.opf │ │ │ ├── links.opf │ │ │ ├── meta-others.opf │ │ │ ├── meta-termination.opf │ │ │ ├── presentation-metadata.opf │ │ │ ├── progression-default.opf │ │ │ ├── progression-ltr.opf │ │ │ ├── progression-none.opf │ │ │ ├── progression-rtl.opf │ │ │ ├── subjects-complex.opf │ │ │ ├── subjects-multiple.opf │ │ │ ├── subjects-single.opf │ │ │ ├── tdm-epub2.opf │ │ │ ├── tdm-epub3.opf │ │ │ ├── title-localized.opf │ │ │ ├── title-main-precedence.opf │ │ │ ├── title-multiple-subtitles.opf │ │ │ ├── titles-epub2.opf │ │ │ ├── titles-epub3.opf │ │ │ ├── version-default.opf │ │ │ ├── version-epub2.opf │ │ │ └── version-epub3.opf │ │ └── image │ │ ├── futuristic_tales.cbz │ │ └── futuristic_tales.jpg │ └── robolectric.properties ├── scripts └── convert-a11y-display-guide-localizations.js ├── settings.gradle.kts └── test-app ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── build.gradle.kts └── src └── main ├── AndroidManifest.xml ├── assets ├── annotation-icon.svg ├── configs │ └── config.properties └── fonts │ ├── Literata-Italic-VariableFont_opsz,wght.ttf │ └── Literata-VariableFont_opsz,wght.ttf ├── ic_launcher-web.png ├── java └── org │ └── readium │ └── r2 │ └── testapp │ ├── Application.kt │ ├── MainActivity.kt │ ├── MainViewModel.kt │ ├── Readium.kt │ ├── about │ └── AboutFragment.kt │ ├── bookshelf │ ├── BookshelfAdapter.kt │ ├── BookshelfFragment.kt │ └── BookshelfViewModel.kt │ ├── catalogs │ ├── CatalogFeedListAdapter.kt │ ├── CatalogFeedListFragment.kt │ ├── CatalogFeedListViewModel.kt │ ├── CatalogFragment.kt │ ├── CatalogViewModel.kt │ ├── GroupAdapter.kt │ ├── NavigationAdapter.kt │ ├── PublicationAdapter.kt │ └── PublicationDetailFragment.kt │ ├── data │ ├── BookRepository.kt │ ├── CatalogRepository.kt │ ├── db │ │ ├── AppDatabase.kt │ │ ├── BooksDao.kt │ │ └── CatalogDao.kt │ └── model │ │ ├── Book.kt │ │ ├── Bookmark.kt │ │ ├── Catalog.kt │ │ └── Highlight.kt │ ├── domain │ ├── Bookshelf.kt │ ├── CoverStorage.kt │ ├── ImportError.kt │ ├── LcpUserError.kt │ ├── PublicationError.kt │ ├── PublicationRetriever.kt │ └── ReadUserError.kt │ ├── drm │ ├── DrmManagementContract.kt │ ├── DrmManagementFragment.kt │ ├── DrmManagementViewModel.kt │ └── LcpManagementViewModel.kt │ ├── opds │ └── GridAutoFitLayoutManager.kt │ ├── outline │ ├── BookmarksFragment.kt │ ├── HighlightsFragment.kt │ ├── NavigationFragment.kt │ ├── OutlineContract.kt │ └── OutlineFragment.kt │ ├── reader │ ├── AudioReaderFragment.kt │ ├── BaseReaderFragment.kt │ ├── EpubReaderFragment.kt │ ├── FullscreenReaderActivityDelegate.kt │ ├── ImageReaderFragment.kt │ ├── MediaService.kt │ ├── MediaServiceFacade.kt │ ├── OpeningError.kt │ ├── PdfReaderFragment.kt │ ├── PublicationMetadataDialogFragment.kt │ ├── ReaderActivity.kt │ ├── ReaderActivityContract.kt │ ├── ReaderInitData.kt │ ├── ReaderRepository.kt │ ├── ReaderViewModel.kt │ ├── VisualReaderFragment.kt │ ├── preferences │ │ ├── PreferencesManagers.kt │ │ ├── UserPreferences.kt │ │ ├── UserPreferencesBottomSheetDialogFragment.kt │ │ └── UserPreferencesViewModel.kt │ └── tts │ │ ├── TtsControls.kt │ │ ├── TtsError.kt │ │ ├── TtsPreferencesBottomSheetDialogFragment.kt │ │ ├── TtsPreferencesEditor.kt │ │ └── TtsViewModel.kt │ ├── search │ ├── SearchFragment.kt │ ├── SearchPagingSource.kt │ ├── SearchResultAdapter.kt │ └── SearchUserError.kt │ ├── shared │ └── views │ │ ├── Group.kt │ │ └── Preferences.kt │ └── utils │ ├── CoroutineQueue.kt │ ├── EventChannel.kt │ ├── Exception.kt │ ├── FileSystem.kt │ ├── ImportActivity.kt │ ├── SectionDecoration.kt │ ├── SingleClickListener.kt │ ├── SystemUiManagement.kt │ ├── UserError.kt │ ├── ViewLifecycleDelegates.kt │ ├── ViewModelFactory.kt │ ├── WebLauncher.kt │ ├── compose │ ├── AppTheme.kt │ ├── ColorPicker.kt │ ├── ComposeBottomSheetDialogFragment.kt │ ├── DropdownMenuButton.kt │ ├── EmphasisProvider.kt │ └── ToggleButton.kt │ └── extensions │ ├── Bitmap.kt │ ├── Context.kt │ ├── File.kt │ ├── Flow.kt │ ├── Intent.kt │ ├── Number.kt │ ├── String.kt │ ├── Uri.kt │ └── readium │ ├── LinkExt.kt │ └── MetadataExt.kt └── res ├── drawable ├── background_action_mode.xml ├── baseline_dashboard_24.xml ├── baseline_info_24.xml ├── baseline_local_library_24.xml ├── cover.png ├── ic_add_white_24dp.xml ├── ic_baseline_arrow_forward_24.xml ├── ic_baseline_bookmark_24.xml ├── ic_baseline_delete_24.xml ├── ic_baseline_edit_24.xml ├── ic_baseline_enhanced_encryption_24.xml ├── ic_baseline_headphones_24.xml ├── ic_baseline_info_24.xml ├── ic_baseline_pause_24.xml ├── ic_baseline_play_arrow_24.xml ├── ic_baseline_search_24.xml ├── ic_notch.xml ├── ic_outline_format_size_24.xml ├── ic_outline_menu_24.xml ├── icon_overflow.png ├── outline_forward_30_24.xml ├── outline_replay_30_24.xml ├── repfr.png ├── selector_blue.xml ├── selector_green.xml ├── selector_purple.xml ├── selector_red.xml └── selector_yellow.xml ├── layout ├── activity_main.xml ├── activity_reader.xml ├── add_catalog_dialog.xml ├── fragment_about.xml ├── fragment_audiobook.xml ├── fragment_bookshelf.xml ├── fragment_catalog.xml ├── fragment_catalog_feed_list.xml ├── fragment_drm_management.xml ├── fragment_listview.xml ├── fragment_outline.xml ├── fragment_publication_detail.xml ├── fragment_reader.xml ├── fragment_search.xml ├── item_group_view.xml ├── item_recycle_book.xml ├── item_recycle_bookmark.xml ├── item_recycle_button.xml ├── item_recycle_catalog.xml ├── item_recycle_highlight.xml ├── item_recycle_horizontal.xml ├── item_recycle_navigation.xml ├── item_recycle_search.xml ├── popup_footnote.xml ├── popup_note.xml ├── section_header.xml ├── view_action_mode.xml └── view_action_mode_reverse.xml ├── menu ├── bottom_nav_menu.xml ├── menu_action_mode.xml ├── menu_bookmark.xml └── menu_reader.xml ├── mipmap-anydpi-v26 └── ic_launcher.xml ├── mipmap-hdpi ├── ic_launcher.png ├── ic_launcher_background.png └── ic_launcher_foreground.png ├── mipmap-mdpi ├── ic_launcher.png ├── ic_launcher_background.png └── ic_launcher_foreground.png ├── mipmap-xhdpi ├── ic_launcher.png ├── ic_launcher_background.png └── ic_launcher_foreground.png ├── mipmap-xxhdpi ├── ic_launcher.png ├── ic_launcher_background.png └── ic_launcher_foreground.png ├── mipmap-xxxhdpi ├── ic_launcher.png ├── ic_launcher_background.png └── ic_launcher_foreground.png ├── navigation ├── about.xml ├── bookshelf.xml ├── catalogs.xml └── navigation.xml ├── values ├── arrays.xml ├── strings.xml └── styles.xml └── xml └── network_security_config.xml /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | ij_continuation_indent_size = 4 5 | 6 | [*.{kt,kts}] 7 | ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL 8 | # Imports must be ordered in lexicographic order without any empty lines in-between. 9 | # https://github.com/pinterest/ktlint/issues/1236 10 | ij_kotlin_imports_layout=* 11 | ktlint_code_style = intellij_idea 12 | ktlint_standard_no-wildcard-imports = disabled 13 | ktlint_standard_max-line-length = disabled 14 | 15 | ktlint_standard_class-naming = disabled 16 | ktlint_standard_comment-wrapping = disabled 17 | ktlint_standard_discouraged-comment-location = disabled 18 | ktlint_standard_function-naming = disabled 19 | ktlint_standard_property-naming = disabled 20 | ktlint_standard_trailing-comma-on-call-site = disabled 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [ released ] 7 | 8 | jobs: 9 | publish: 10 | name: Publish to Maven Central 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v3 15 | - name: Set up JDK 17 16 | uses: actions/setup-java@v3 17 | with: 18 | distribution: adopt 19 | java-version: 17 20 | 21 | - name: Publish to Maven Central 22 | run: ./gradlew publishToMavenCentral --no-configuration-cache 23 | env: 24 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }} 25 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }} 26 | ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }} 27 | ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} 28 | ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} 29 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # GitHub Copilot persisted chat sessions 5 | /copilot/chatSessions 6 | appInsightsSettings.xml 7 | deploymentTargetSelector.xml 8 | studiobot.xml 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Readium -------------------------------------------------------------------------------- /.idea/AndroidProjectSystem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | `kotlin-dsl` 9 | } 10 | 11 | repositories { 12 | gradlePluginPortal() 13 | google() 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | implementation(libs.plugin.android) 19 | implementation(libs.plugin.kotlin) 20 | implementation(libs.plugin.maven.publish) 21 | } -------------------------------------------------------------------------------- /buildSrc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | dependencyResolutionManagement { 8 | versionCatalogs { 9 | create("libs") { 10 | from(files("../gradle/libs.versions.toml")) 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /docs/readium_colors.css: -------------------------------------------------------------------------------- 1 | body { 2 | --md-primary-fg-color: #449d44; 3 | --md-primary-fg-color--light: #73b02c; 4 | --md-primary-fg-color--dark: #255625; 5 | --md-accent-fg-color: #73b02c; 6 | } 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | alias(libs.plugins.kotlin.serialization) 10 | } 11 | 12 | android { 13 | namespace = "org.readium.adapter.exoplayer.audio" 14 | } 15 | 16 | dependencies { 17 | api(project(":readium:readium-shared")) 18 | api(project(":readium:navigators:media:readium-navigator-media-audio")) 19 | 20 | implementation(libs.androidx.media3.common) 21 | implementation(libs.androidx.media3.exoplayer) 22 | implementation(libs.timber) 23 | implementation(libs.kotlinx.coroutines.android) 24 | implementation(libs.kotlinx.serialization.json) 25 | 26 | // Tests 27 | testImplementation(libs.junit) 28 | } 29 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-exoplayer-audio 2 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerAliases.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.exoplayer.audio 8 | 9 | import org.readium.navigator.media.audio.AudioNavigator 10 | import org.readium.navigator.media.audio.AudioNavigatorFactory 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | 13 | @OptIn(ExperimentalReadiumApi::class) 14 | public typealias ExoPlayerNavigatorFactory = AudioNavigatorFactory 15 | 16 | @OptIn(ExperimentalReadiumApi::class) 17 | public typealias ExoPlayerNavigator = AudioNavigator 18 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerDefaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.exoplayer.audio 8 | 9 | /** 10 | * Default values for the ExoPlayer engine. 11 | * 12 | * These values will be used as a last resort by [ExoPlayerSettingsResolver] 13 | * when no user preference takes precedence. 14 | * 15 | * @see ExoPlayerPreferences 16 | */ 17 | public data class ExoPlayerDefaults( 18 | val pitch: Double? = null, 19 | val speed: Double? = null, 20 | ) { 21 | init { 22 | require(pitch == null || pitch > 0) 23 | require(speed == null || speed > 0) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.exoplayer.audio 8 | 9 | import kotlinx.serialization.json.Json 10 | import org.readium.r2.navigator.preferences.PreferencesSerializer 11 | 12 | /** 13 | * JSON serializer of [ExoPlayerPreferences]. 14 | */ 15 | public class ExoPlayerPreferencesSerializer : PreferencesSerializer { 16 | 17 | override fun serialize(preferences: ExoPlayerPreferences): String = 18 | Json.encodeToString(ExoPlayerPreferences.serializer(), preferences) 19 | 20 | override fun deserialize(preferences: String): ExoPlayerPreferences = 21 | Json.decodeFromString(ExoPlayerPreferences.serializer(), preferences) 22 | } 23 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerSettings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.exoplayer.audio 8 | 9 | import org.readium.r2.navigator.preferences.Configurable 10 | 11 | /** 12 | * Settings values of the ExoPlayer engine. 13 | * 14 | * @see ExoPlayerPreferences 15 | */ 16 | public data class ExoPlayerSettings( 17 | val pitch: Double, 18 | val speed: Double, 19 | ) : Configurable.Settings 20 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerSettingsResolver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.exoplayer.audio 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | 11 | @OptIn(ExperimentalReadiumApi::class) 12 | internal class ExoPlayerSettingsResolver( 13 | private val defaults: ExoPlayerDefaults, 14 | ) : ExoPlayerEngine.SettingsResolver { 15 | 16 | override fun settings(preferences: ExoPlayerPreferences): ExoPlayerSettings { 17 | return ExoPlayerSettings( 18 | pitch = preferences.pitch ?: defaults.pitch ?: 1.0, 19 | speed = preferences.speed ?: defaults.speed ?: 1.0 20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.exoplayer" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:adapters:exoplayer:readium-adapter-exoplayer-audio")) 17 | } 18 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-exoplayer 2 | -------------------------------------------------------------------------------- /readium/adapters/exoplayer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.pdfium" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:adapters:pdfium:readium-adapter-pdfium-document")) 17 | api(project(":readium:adapters:pdfium:readium-adapter-pdfium-navigator")) 18 | } 19 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.pdfium.common" 13 | } 14 | 15 | dependencies { 16 | api(files("libs/pdfium-android-1.8.2.jar")) 17 | } 18 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pdfium-common 2 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/libs/pdfium-android-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/libs/pdfium-android-1.8.2.jar -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/arm64-v8a/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi-v7a/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/armeabi/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/mips/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/mips/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/mips/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libjniPdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libjniPdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodft2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodft2.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodpdfium.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodpdfium.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodpng.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/common/src/main/jniLibs/x86_64/libmodpng.so -------------------------------------------------------------------------------- /readium/adapters/pdfium/document/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.pdfium.document" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:readium-shared")) 17 | implementation(project(":readium:adapters:pdfium:readium-adapter-pdfium-common")) 18 | 19 | implementation(libs.timber) 20 | implementation(libs.kotlinx.coroutines.android) 21 | } 22 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/document/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pdfium-document 2 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/document/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pdfium 2 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pdfium-navigator 2 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/libs/android-pdf-viewer-2.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/adapters/pdfium/navigator/libs/android-pdf-viewer-2.8.2.jar -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/java/org/readium/adapter/pdfium/navigator/PdfiumDefaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pdfium.navigator 8 | 9 | import org.readium.r2.navigator.preferences.ReadingProgression 10 | 11 | /** 12 | * Default values for the PDF navigator with the PDFium adapter. 13 | * 14 | * These values will be used when no publication metadata or user preference takes precedence. 15 | * 16 | * @see PdfiumPreferences 17 | */ 18 | public data class PdfiumDefaults( 19 | val pageSpacing: Double? = null, 20 | val readingProgression: ReadingProgression? = null, 21 | ) 22 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/java/org/readium/adapter/pdfium/navigator/PdfiumNavigator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pdfium.navigator 8 | 9 | import org.readium.r2.navigator.pdf.PdfNavigatorFactory 10 | import org.readium.r2.navigator.pdf.PdfNavigatorFragment 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | 13 | @ExperimentalReadiumApi 14 | public typealias PdfiumNavigatorFragment = PdfNavigatorFragment 15 | 16 | @ExperimentalReadiumApi 17 | public typealias PdfiumNavigatorFactory = PdfNavigatorFactory 18 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/java/org/readium/adapter/pdfium/navigator/PdfiumPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pdfium.navigator 8 | 9 | import kotlinx.serialization.json.Json 10 | import org.readium.r2.navigator.preferences.PreferencesSerializer 11 | 12 | /** 13 | * JSON serializer of [PdfiumPreferences]. 14 | */ 15 | public class PdfiumPreferencesSerializer : PreferencesSerializer { 16 | 17 | override fun serialize(preferences: PdfiumPreferences): String = 18 | Json.encodeToString(PdfiumPreferences.serializer(), preferences) 19 | 20 | override fun deserialize(preferences: String): PdfiumPreferences = 21 | Json.decodeFromString(PdfiumPreferences.serializer(), preferences) 22 | } 23 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/java/org/readium/adapter/pdfium/navigator/PdfiumSettings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pdfium.navigator 8 | 9 | import org.readium.r2.navigator.preferences.* 10 | 11 | /** 12 | * Settings values of the PDF navigator with the PDFium adapter. 13 | * 14 | * @see PdfiumPreferences 15 | */ 16 | public data class PdfiumSettings( 17 | val fit: Fit, 18 | val pageSpacing: Double, 19 | val readingProgression: ReadingProgression, 20 | val scrollAxis: Axis, 21 | ) : Configurable.Settings 22 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/navigator/src/main/res/layout/readium_pspdfkit_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /readium/adapters/pdfium/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.pspdfkit" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:adapters:pspdfkit:readium-adapter-pspdfkit-document")) 17 | api(project(":readium:adapters:pspdfkit:readium-adapter-pspdfkit-navigator")) 18 | } 19 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/document/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.adapter.pspdfkit.document" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:readium-shared")) 17 | 18 | implementation(libs.timber) 19 | implementation(libs.pspdfkit) 20 | implementation(libs.kotlinx.coroutines.android) 21 | } 22 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/document/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pspdfkit-document 2 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/document/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pspdfkit 2 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | alias(libs.plugins.kotlin.serialization) 10 | } 11 | 12 | android { 13 | buildFeatures { 14 | viewBinding = true 15 | } 16 | namespace = "org.readium.adapter.pspdfkit.navigator" 17 | } 18 | 19 | dependencies { 20 | api(project(":readium:readium-shared")) 21 | api(project(":readium:readium-navigator")) 22 | api(project(":readium:adapters:pspdfkit:readium-adapter-pspdfkit-document")) 23 | 24 | implementation(libs.androidx.fragment.ktx) 25 | implementation(libs.timber) 26 | implementation(libs.pspdfkit) 27 | implementation(libs.kotlinx.coroutines.android) 28 | implementation(libs.kotlinx.serialization.json) 29 | } 30 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-adapter-pspdfkit-navigator 2 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/java/org/readium/adapter/pspdfkit/navigator/PsPdfKitDefaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pspdfkit.navigator 8 | 9 | import org.readium.r2.navigator.preferences.ReadingProgression 10 | import org.readium.r2.navigator.preferences.Spread 11 | 12 | /** 13 | * Default values for the PDF navigator with the PSPDFKit adapter. 14 | * 15 | * These values will be used when no publication metadata or user preference takes precedence. 16 | * 17 | * @see PsPdfKitPreferences 18 | */ 19 | public data class PsPdfKitDefaults( 20 | val offsetFirstPage: Boolean? = null, 21 | val pageSpacing: Double? = null, 22 | val readingProgression: ReadingProgression? = null, 23 | val scroll: Boolean? = null, 24 | val spread: Spread? = null, 25 | ) 26 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/java/org/readium/adapter/pspdfkit/navigator/PsPdfKitNavigator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pspdfkit.navigator 8 | 9 | import org.readium.r2.navigator.pdf.PdfNavigatorFactory 10 | import org.readium.r2.navigator.pdf.PdfNavigatorFragment 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | 13 | @ExperimentalReadiumApi 14 | public typealias PsPdfKitNavigatorFragment = PdfNavigatorFragment 15 | 16 | @ExperimentalReadiumApi 17 | public typealias PsPdfKitNavigatorFactory = PdfNavigatorFactory 18 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/java/org/readium/adapter/pspdfkit/navigator/PsPdfKitPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pspdfkit.navigator 8 | 9 | import kotlinx.serialization.json.Json 10 | import org.readium.r2.navigator.preferences.PreferencesSerializer 11 | 12 | /** 13 | * JSON serializer of [PsPdfKitPreferences]. 14 | */ 15 | public class PsPdfKitPreferencesSerializer : PreferencesSerializer { 16 | 17 | override fun serialize(preferences: PsPdfKitPreferences): String = 18 | Json.encodeToString(PsPdfKitPreferences.serializer(), preferences) 19 | 20 | override fun deserialize(preferences: String): PsPdfKitPreferences = 21 | Json.decodeFromString(PsPdfKitPreferences.serializer(), preferences) 22 | } 23 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/java/org/readium/adapter/pspdfkit/navigator/PsPdfKitSettings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.adapter.pspdfkit.navigator 8 | 9 | import org.readium.r2.navigator.preferences.* 10 | 11 | /** 12 | * Settings values of the PDF navigator with the PSPDFKit adapter. 13 | * 14 | * @see PsPdfKitPreferences 15 | */ 16 | public data class PsPdfKitSettings( 17 | val fit: Fit, 18 | val offsetFirstPage: Boolean, 19 | val pageSpacing: Double, 20 | val readingProgression: ReadingProgression, 21 | val scroll: Boolean, 22 | val scrollAxis: Axis, 23 | val spread: Spread, 24 | ) : Configurable.Settings 25 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/navigator/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/adapters/pspdfkit/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/lcp/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-lcp 2 | -------------------------------------------------------------------------------- /readium/lcp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /readium/lcp/src/main/java/org/readium/r2/lcp/license/container/BytesLicenseContainer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-lcp-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.lcp.license.container 11 | 12 | import org.readium.r2.lcp.license.model.LicenseDocument 13 | 14 | /** 15 | * Access a License Document from its raw bytes. 16 | */ 17 | internal class BytesLicenseContainer(private var bytes: ByteArray) : WritableLicenseContainer { 18 | 19 | override fun read(): ByteArray = bytes 20 | 21 | override fun write(license: LicenseDocument) { 22 | bytes = license.toByteArray() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /readium/lcp/src/main/java/org/readium/r2/lcp/license/container/FileUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.lcp.license.container 8 | 9 | import java.io.File 10 | internal fun File.moveTo(target: File) { 11 | if (!this.renameTo(target)) { 12 | this.copyTo(target, overwrite = true) 13 | this.delete() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /readium/lcp/src/main/java/org/readium/r2/lcp/license/model/components/lsd/PotentialRights.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-lcp-kotlin 3 | * Developers: Aferdita Muriqi 4 | * 5 | * Copyright (c) 2019. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | @file:OptIn(InternalReadiumApi::class) 11 | 12 | package org.readium.r2.lcp.license.model.components.lsd 13 | 14 | import org.json.JSONObject 15 | import org.readium.r2.shared.InternalReadiumApi 16 | import org.readium.r2.shared.extensions.optNullableString 17 | import org.readium.r2.shared.util.Instant 18 | 19 | public data class PotentialRights(val json: JSONObject) { 20 | val end: Instant? = json.optNullableString("end")?.let { Instant.parse(it) } 21 | } 22 | -------------------------------------------------------------------------------- /readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/a-fc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/a-fc.jpg -------------------------------------------------------------------------------- /readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/futuristic_tales.cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/lcp/src/test/resources/org/readium/r2/lcp/license/container/futuristic_tales.cbz -------------------------------------------------------------------------------- /readium/lcp/src/test/resources/org/readium/r2/lcp/util/a-fc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/lcp/src/test/resources/org/readium/r2/lcp/util/a-fc.jpg -------------------------------------------------------------------------------- /readium/navigator/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator 2 | -------------------------------------------------------------------------------- /readium/navigator/libs/PhotoView-2.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigator/libs/PhotoView-2.3.0.jar -------------------------------------------------------------------------------- /readium/navigator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "globals": { 7 | "Android": "readonly", 8 | "global": "writable", 9 | "readium": "writable" 10 | }, 11 | "extends": "eslint:recommended", 12 | "parserOptions": { 13 | "ecmaVersion": 12, 14 | "sourceType": "module" 15 | }, 16 | "ignorePatterns": ["src/vendor"], 17 | "rules": { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/.prettierignore: -------------------------------------------------------------------------------- 1 | src/vendor 2 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/.prettierrc.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigator/src/main/assets/_scripts/.prettierrc.json -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/README.md: -------------------------------------------------------------------------------- 1 | # Readium JS (Kotlin) 2 | 3 | A set of JavaScript files used by the Kotlin EPUB navigator. 4 | 5 | This folder starts with an underscore to prevent Gradle from embedding it as an asset. 6 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/src/index-fixed.js: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2021 Readium Foundation. All rights reserved. 3 | // Use of this source code is governed by the BSD-style license 4 | // available in the top-level LICENSE file of the project. 5 | // 6 | 7 | // Script used for fixed layouts resources. 8 | 9 | import "./index"; 10 | 11 | window.readium.isFixedLayout = true; 12 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/src/index-reflowable.js: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2021 Readium Foundation. All rights reserved. 3 | // Use of this source code is governed by the BSD-style license 4 | // available in the top-level LICENSE file of the project. 5 | // 6 | 7 | // Script used for reflowable resources. 8 | 9 | import "./index"; 10 | 11 | window.readium.isReflowable = true; 12 | 13 | document.addEventListener("DOMContentLoaded", function () { 14 | // Setups the `viewport` meta tag to disable zooming. 15 | let meta = document.createElement("meta"); 16 | meta.setAttribute("name", "viewport"); 17 | meta.setAttribute( 18 | "content", 19 | "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no" 20 | ); 21 | document.head.appendChild(meta); 22 | }); 23 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/src/vendor/hypothesis/README.md: -------------------------------------------------------------------------------- 1 | The code in this module has been directly copied from https://github.com/hypothesis/client, released under the 2-Clause BSD license. 2 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/src/vendor/hypothesis/anchoring/test/html-baselines/minimal.html: -------------------------------------------------------------------------------- 1 |
One Two Three
2 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/src/vendor/hypothesis/anchoring/test/html-baselines/minimal.json: -------------------------------------------------------------------------------- 1 | { 2 | "total": 1, 3 | "rows": [{ 4 | "id": "test", 5 | "target": [{ 6 | "selector": [{ 7 | "type": "RangeSelector", 8 | "startContainer": "/div[1]", 9 | "endContainer": "/div[1]", 10 | "startOffset": 4, 11 | "endOffset": 7 12 | },{ 13 | "type": "TextPositionSelector", 14 | "start": 4, 15 | "end": 7 16 | },{ 17 | "type": "TextQuoteSelector", 18 | "prefix": "One ", 19 | "suffix": " Three\n", 20 | "exact": "Two" 21 | }] 22 | }] 23 | }] 24 | } 25 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/_scripts/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | mode: "production", 5 | devtool: "source-map", 6 | entry: { 7 | reflowable: "./src/index-reflowable.js", 8 | fixed: "./src/index-fixed.js", 9 | }, 10 | output: { 11 | filename: "readium-[name].js", 12 | path: path.resolve(__dirname, "../readium/scripts"), 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.m?js$/, 18 | exclude: /node_modules/, 19 | use: { 20 | loader: "babel-loader", 21 | options: { 22 | presets: ["@babel/preset-env"], 23 | }, 24 | }, 25 | }, 26 | ], 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/divina/divinaPlayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DiViNa Player 6 | 15 | 16 | 17 | 18 | 19 | 26 | 27 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/error.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/fonts/OpenDyslexic-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigator/src/main/assets/readium/fonts/OpenDyslexic-Regular.otf -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/readium-css/fonts/AccessibleDfA.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigator/src/main/assets/readium/readium-css/fonts/AccessibleDfA.otf -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/readium-css/fonts/iAWriterDuospace-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigator/src/main/assets/readium/readium-css/fonts/iAWriterDuospace-Regular.ttf -------------------------------------------------------------------------------- /readium/navigator/src/main/assets/readium/scripts/.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/DummyPublication.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.navigator 2 | 3 | import org.readium.r2.shared.publication.LocalizedString 4 | import org.readium.r2.shared.publication.Manifest 5 | import org.readium.r2.shared.publication.Metadata 6 | import org.readium.r2.shared.publication.Publication 7 | 8 | public object RestorationNotSupportedException : Exception( 9 | "Restoration of the navigator fragment after process death is not supported. You must pop it from the back stack or finish the host Activity before `onResume`." 10 | ) 11 | 12 | internal val dummyPublication = Publication( 13 | Manifest( 14 | metadata = Metadata( 15 | identifier = "readium:dummy", 16 | localizedTitle = LocalizedString("") 17 | ) 18 | ) 19 | ) 20 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/NavigatorFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator 8 | 9 | import android.os.Bundle 10 | import androidx.fragment.app.Fragment 11 | import org.readium.r2.shared.publication.Publication 12 | import org.readium.r2.shared.publication.services.isRestricted 13 | 14 | public abstract class NavigatorFragment internal constructor( 15 | protected val publication: Publication, 16 | ) : Fragment(), Navigator { 17 | 18 | override fun onCreate(savedInstanceState: Bundle?) { 19 | require(!publication.isRestricted) { "The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection." } 20 | 21 | super.onCreate(savedInstanceState) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/SimpleOverflow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator 8 | 9 | import org.readium.r2.navigator.preferences.Axis 10 | import org.readium.r2.navigator.preferences.ReadingProgression 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | import org.readium.r2.shared.InternalReadiumApi 13 | 14 | @InternalReadiumApi 15 | @OptIn(ExperimentalReadiumApi::class) 16 | public data class SimpleOverflow( 17 | override val readingProgression: ReadingProgression, 18 | override val scroll: Boolean, 19 | override val axis: Axis, 20 | ) : OverflowableNavigator.Overflow 21 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.epub 8 | 9 | import kotlinx.serialization.json.Json 10 | import org.readium.r2.navigator.preferences.PreferencesSerializer 11 | 12 | /** 13 | * JSON serializer of [EpubPreferences]. 14 | */ 15 | public class EpubPreferencesSerializer : PreferencesSerializer { 16 | 17 | override fun serialize(preferences: EpubPreferences): String = 18 | Json.encodeToString(EpubPreferences.serializer(), preferences) 19 | 20 | override fun deserialize(preferences: String): EpubPreferences = 21 | Json.decodeFromString(EpubPreferences.serializer(), preferences) 22 | } 23 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/epub/extensions/Language.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.epub.extensions 8 | 9 | import org.readium.r2.shared.util.Language 10 | 11 | internal val Language.isRtl: Boolean get() { 12 | val c = code.lowercase() 13 | return c == "ar" || 14 | c == "fa" || 15 | c == "he" || 16 | c == "zh-hant" || 17 | c == "zh-tw" 18 | } 19 | 20 | internal val Language.isCjk: Boolean get() { 21 | val c = code.lowercase() 22 | return c == "ja" || 23 | c == "ko" || 24 | removeRegion().code.lowercase() == "zh" 25 | } 26 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/extensions/ControlFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.extensions 8 | 9 | /** 10 | * Unwraps the two given arguments and pass them to the [closure] if they are not null. 11 | */ 12 | internal inline fun let(a: A?, b: B?, closure: (A, B) -> R?): R? = 13 | if (a == null || b == null) { 14 | null 15 | } else { 16 | closure(a, b) 17 | } 18 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Extensions.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.navigator.extensions 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.view.View 6 | import androidx.annotation.ColorInt 7 | import androidx.annotation.ColorRes 8 | import androidx.core.content.ContextCompat 9 | 10 | /** 11 | * Extensions 12 | */ 13 | 14 | /** returns true if the resolved layout direction of the content view in this 15 | * activity is ViewCompat.LAYOUT_DIRECTION_RTL. Otherwise false. */ 16 | internal fun Activity.layoutDirectionIsRTL(): Boolean { 17 | return findViewById(android.R.id.content).layoutDirection == View.LAYOUT_DIRECTION_RTL 18 | } 19 | 20 | @ColorInt 21 | internal fun Context.color(@ColorRes id: Int): Int { 22 | return ContextCompat.getColor(this, id) 23 | } 24 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/extensions/JSON.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.extensions 8 | 9 | import android.graphics.RectF 10 | import org.json.JSONObject 11 | 12 | /** 13 | * Parses a [RectF] from its JSON representation. 14 | */ 15 | internal fun JSONObject.optRectF(name: String): RectF? = 16 | optJSONObject(name)?.let { json -> 17 | val left = json.optDouble("left").toFloat() 18 | val top = json.optDouble("top").toFloat() 19 | val right = json.optDouble("right").toFloat() 20 | val bottom = json.optDouble("bottom").toFloat() 21 | RectF(left, top, right, bottom) 22 | } 23 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Number.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.extensions 8 | 9 | import java.text.NumberFormat 10 | import org.readium.r2.shared.InternalReadiumApi 11 | 12 | @InternalReadiumApi 13 | public fun Number.format(maximumFractionDigits: Int, percent: Boolean = false): String { 14 | val format = if (percent) NumberFormat.getPercentInstance() else NumberFormat.getNumberInstance() 15 | format.maximumFractionDigits = maximumFractionDigits 16 | return format.format(this) 17 | } 18 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/extensions/String.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.extensions 8 | 9 | /** 10 | * Splits a [String] in two components, at the given delimiter. 11 | */ 12 | // FIXME: Move to an internal module when the monorepo will be setup 13 | internal fun String.splitAt(delimiter: String): Pair { 14 | val components = split(delimiter, limit = 2) 15 | return Pair(components[0], components.getOrNull(1)) 16 | } 17 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/input/DragEvent.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.navigator.input 2 | 3 | import android.graphics.PointF 4 | 5 | /** 6 | * Represents a drag event emitted by a navigator from a [start] point moved by an [offset]. 7 | * 8 | * All the points are relative to the navigator view. 9 | */ 10 | public data class DragEvent( 11 | val type: Type, 12 | val start: PointF, 13 | val offset: PointF, 14 | ) { 15 | public enum class Type { Start, Move, End } 16 | } 17 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/input/InputModifier.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.navigator.input 2 | 3 | /** 4 | * Represents a key modifier for an input event. 5 | */ 6 | public enum class InputModifier { 7 | Alt, 8 | Control, 9 | Meta, 10 | Shift, 11 | } 12 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/input/TapEvent.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.navigator.input 2 | 3 | import android.graphics.PointF 4 | 5 | /** 6 | * Represents a tap event emitted by a navigator at the given [point]. 7 | * 8 | * All the points are relative to the navigator view. 9 | */ 10 | public data class TapEvent( 11 | val point: PointF, 12 | ) 13 | -------------------------------------------------------------------------------- /readium/navigator/src/main/java/org/readium/r2/navigator/util/BaseActionModeCallback.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.util 8 | 9 | import android.view.ActionMode 10 | import android.view.Menu 11 | import android.view.MenuItem 12 | 13 | /** 14 | * A convenient base implementation of [ActionMode.Callback], when you don't need to override all 15 | * methods. 16 | */ 17 | public abstract class BaseActionModeCallback : ActionMode.Callback { 18 | override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = false 19 | override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean = false 20 | override fun onDestroyActionMode(mode: ActionMode) {} 21 | } 22 | -------------------------------------------------------------------------------- /readium/navigator/src/main/res/layout/readium_navigator_viewpager_fragment_epub.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /readium/navigator/src/main/res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20dp 4 | -------------------------------------------------------------------------------- /readium/navigator/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 40dp 4 | -------------------------------------------------------------------------------- /readium/navigator/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigator/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | Audiobook 10 | Audiobook currently being played 11 | 12 | 13 | -------------------------------------------------------------------------------- /readium/navigator/src/test/java/org/readium/r2/navigator/epub/css/LayoutTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.navigator.epub.css 8 | 9 | import kotlin.test.assertEquals 10 | import org.junit.Test 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | 13 | @OptIn(ExperimentalReadiumApi::class) 14 | class LayoutTest { 15 | 16 | @Test 17 | fun `Compute the HTML dir from the stylesheets`() { 18 | assertEquals(Layout.HtmlDir.Ltr, Layout.Stylesheets.Default.htmlDir) 19 | assertEquals(Layout.HtmlDir.Rtl, Layout.Stylesheets.Rtl.htmlDir) 20 | assertEquals(Layout.HtmlDir.Unspecified, Layout.Stylesheets.CjkVertical.htmlDir) 21 | assertEquals(Layout.HtmlDir.Ltr, Layout.Stylesheets.CjkHorizontal.htmlDir) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /readium/navigator/src/test/resources/robolectric.properties: -------------------------------------------------------------------------------- 1 | sdk=30 2 | -------------------------------------------------------------------------------- /readium/navigators/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | alias(libs.plugins.kotlin.serialization) 10 | alias(libs.plugins.compose.compiler) 11 | } 12 | 13 | android { 14 | namespace = "org.readium.navigators.common" 15 | 16 | buildFeatures { 17 | compose = true 18 | } 19 | } 20 | 21 | dependencies { 22 | api(project(":readium:readium-shared")) 23 | api(project(":readium:readium-navigator")) 24 | 25 | implementation(libs.kotlinx.serialization.json) 26 | implementation(libs.bundles.compose) 27 | implementation(libs.timber) 28 | implementation(libs.kotlinx.coroutines.android) 29 | } 30 | -------------------------------------------------------------------------------- /readium/navigators/common/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-common 2 | -------------------------------------------------------------------------------- /readium/navigators/common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /readium/navigators/common/src/main/java/org/readium/navigator/common/LocatorAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.common 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | import org.readium.r2.shared.publication.Locator 11 | 12 | @ExperimentalReadiumApi 13 | public interface LocatorAdapter { 14 | 15 | public fun Locator.toGoLocation(): G 16 | 17 | public fun L.toLocator(): Locator 18 | } 19 | -------------------------------------------------------------------------------- /readium/navigators/common/src/main/java/org/readium/navigator/common/RenditionState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.common 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | 11 | /** 12 | * The state of the rendition, giving access to a [NavigationController] after the first composition. 13 | */ 14 | @ExperimentalReadiumApi 15 | public interface RenditionState> { 16 | 17 | public val controller: N? 18 | } 19 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/java/org/readium/navigator/demo/persistence/LocatorRepository.kt: -------------------------------------------------------------------------------- 1 | package org.readium.navigator.demo.persistence 2 | 3 | import org.readium.r2.shared.publication.Locator 4 | import org.readium.r2.shared.util.AbsoluteUrl 5 | 6 | object LocatorRepository { 7 | 8 | private val savedLocators: MutableMap = 9 | mutableMapOf() 10 | 11 | fun saveLocator(url: AbsoluteUrl, locator: Locator) { 12 | savedLocators[url] = locator 13 | } 14 | 15 | fun getLocator(url: AbsoluteUrl): Locator? { 16 | return savedLocators[url] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/java/org/readium/navigator/demo/preferences/PreferencesManager.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.demo.preferences 8 | 9 | import kotlinx.coroutines.flow.MutableStateFlow 10 | import org.readium.r2.navigator.preferences.Configurable 11 | 12 | /** 13 | * Trivial user preferences manager. You can add persistence. 14 | */ 15 | class PreferencesManager

>( 16 | initialPreferences: P 17 | ) { 18 | private val preferencesMutable: MutableStateFlow

= 19 | MutableStateFlow(initialPreferences) 20 | 21 | fun setPreferences(preferences: P) { 22 | preferencesMutable.value = preferences 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/navigators/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Readium Navigator Demo 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/demo/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | developer.android.com 5 | google.github.io 6 | android-developers.googleblog.com 7 | io.google 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /readium/navigators/media/audio/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.navigators.media.audio" 13 | 14 | buildFeatures { 15 | viewBinding = true 16 | } 17 | } 18 | 19 | dependencies { 20 | api(project(":readium:navigators:media:readium-navigator-media-common")) 21 | 22 | implementation(libs.androidx.media3.common) 23 | implementation(libs.androidx.media3.session) 24 | 25 | implementation(libs.timber) 26 | implementation(libs.kotlinx.coroutines.android) 27 | } 28 | -------------------------------------------------------------------------------- /readium/navigators/media/audio/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-media-audio 2 | -------------------------------------------------------------------------------- /readium/navigators/media/audio/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/media/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.navigator.media" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:navigators:media:readium-navigator-media-common")) 17 | api(project(":readium:navigators:media:readium-navigator-media-audio")) 18 | api(project(":readium:navigators:media:readium-navigator-media-tts")) 19 | } 20 | -------------------------------------------------------------------------------- /readium/navigators/media/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.navigators.media.common" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:readium-shared")) 17 | api(project(":readium:readium-navigator")) 18 | 19 | implementation(libs.androidx.media3.common) 20 | implementation(libs.timber) 21 | implementation(libs.kotlinx.coroutines.android) 22 | } 23 | -------------------------------------------------------------------------------- /readium/navigators/media/common/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-media-common 2 | -------------------------------------------------------------------------------- /readium/navigators/media/common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/media/common/src/main/java/org/readium/navigator/media/common/DefaultMediaMetadataProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.common 8 | 9 | import android.net.Uri 10 | import org.readium.r2.shared.publication.Publication 11 | 12 | /** 13 | * Builds a [MediaMetadataFactory] which will use the given title, author and cover, 14 | * and fall back on what is in the publication. 15 | */ 16 | public class DefaultMediaMetadataProvider( 17 | private val title: String? = null, 18 | private val author: String? = null, 19 | private val cover: Uri? = null, 20 | ) : MediaMetadataProvider { 21 | 22 | override fun createMetadataFactory(publication: Publication): MediaMetadataFactory { 23 | return DefaultMediaMetadataFactory(publication, title, author, cover) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /readium/navigators/media/common/src/main/java/org/readium/navigator/media/common/Media3Adapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.common 8 | 9 | import androidx.media3.common.Player 10 | import org.readium.r2.shared.ExperimentalReadiumApi 11 | 12 | /** 13 | * An object able to pass as a Jetpack media3 [Player]. 14 | */ 15 | @ExperimentalReadiumApi 16 | public interface Media3Adapter { 17 | public fun asMedia3Player(): Player 18 | } 19 | -------------------------------------------------------------------------------- /readium/navigators/media/common/src/main/java/org/readium/navigator/media/common/MediaMetadataFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.common 8 | 9 | import androidx.media3.common.MediaMetadata 10 | 11 | /** 12 | * Factory for the [MediaMetadata] associated with the publication and its resources. 13 | * 14 | * The metadata are used for example in the media-style Android notification. 15 | */ 16 | public interface MediaMetadataFactory { 17 | 18 | /** 19 | * Creates the [MediaMetadata] for the whole publication. 20 | */ 21 | public suspend fun publicationMetadata(): MediaMetadata 22 | 23 | /** 24 | * Creates the [MediaMetadata] for the reading order resource at the given [index]. 25 | */ 26 | public suspend fun resourceMetadata(index: Int): MediaMetadata 27 | } 28 | -------------------------------------------------------------------------------- /readium/navigators/media/common/src/main/java/org/readium/navigator/media/common/MediaMetadataProvider.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.common 8 | 9 | import org.readium.r2.shared.publication.Publication 10 | 11 | /** 12 | * To be implemented to use a custom [MediaMetadataFactory]. 13 | */ 14 | public fun interface MediaMetadataProvider { 15 | 16 | public fun createMetadataFactory(publication: Publication): MediaMetadataFactory 17 | } 18 | -------------------------------------------------------------------------------- /readium/navigators/media/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-media 2 | -------------------------------------------------------------------------------- /readium/navigators/media/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | alias(libs.plugins.kotlin.serialization) 10 | } 11 | 12 | android { 13 | namespace = "org.readium.navigators.media.tts" 14 | } 15 | 16 | dependencies { 17 | api(project(":readium:navigators:media:readium-navigator-media-common")) 18 | 19 | implementation(libs.androidx.media3.common) 20 | implementation(libs.androidx.media3.session) 21 | 22 | implementation(libs.timber) 23 | implementation(libs.kotlinx.coroutines.android) 24 | implementation(libs.kotlinx.serialization.json) 25 | } 26 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-media-tts 2 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/android/AndroidTtsDefaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.tts.android 8 | 9 | import org.readium.r2.shared.util.Language 10 | 11 | /** 12 | * Default values for the Android TTS engine. 13 | * 14 | * These values will be used as a last resort by [AndroidTtsSettingsResolver] 15 | * when no user preference takes precedence. 16 | * 17 | * @see AndroidTtsPreferences 18 | */ 19 | public data class AndroidTtsDefaults( 20 | val language: Language? = null, 21 | val pitch: Double? = null, 22 | val speed: Double? = null, 23 | ) { 24 | init { 25 | require(pitch == null || pitch > 0) 26 | require(speed == null || speed > 0) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/android/AndroidTtsPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.tts.android 8 | 9 | import kotlinx.serialization.json.Json 10 | import org.readium.r2.navigator.preferences.PreferencesSerializer 11 | 12 | /** 13 | * JSON serializer of [AndroidTtsPreferences]. 14 | */ 15 | public class AndroidTtsPreferencesSerializer : PreferencesSerializer { 16 | 17 | override fun serialize(preferences: AndroidTtsPreferences): String = 18 | Json.encodeToString(AndroidTtsPreferences.serializer(), preferences) 19 | 20 | override fun deserialize(preferences: String): AndroidTtsPreferences = 21 | Json.decodeFromString(AndroidTtsPreferences.serializer(), preferences) 22 | } 23 | -------------------------------------------------------------------------------- /readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/android/AndroidTtsSettings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.media.tts.android 8 | 9 | import org.readium.navigator.media.tts.TtsEngine 10 | import org.readium.r2.shared.ExperimentalReadiumApi 11 | import org.readium.r2.shared.util.Language 12 | 13 | /** 14 | * Settings values of the Android built-in TTS engine. 15 | * 16 | * @see AndroidTtsPreferences 17 | */ 18 | @OptIn(ExperimentalReadiumApi::class) 19 | public data class AndroidTtsSettings( 20 | override val language: Language, 21 | override val overrideContentLanguage: Boolean, 22 | val pitch: Double, 23 | val speed: Double, 24 | val voices: Map, 25 | ) : TtsEngine.Settings 26 | -------------------------------------------------------------------------------- /readium/navigators/web/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | alias(libs.plugins.kotlin.serialization) 10 | alias(libs.plugins.compose.compiler) 11 | } 12 | 13 | android { 14 | namespace = "org.readium.navigators.web" 15 | 16 | buildFeatures { 17 | compose = true 18 | } 19 | } 20 | 21 | dependencies { 22 | api(project(":readium:readium-shared")) 23 | api(project(":readium:readium-navigator")) 24 | api(project(":readium:navigators:readium-navigator-common")) 25 | 26 | implementation(libs.kotlinx.serialization.json) 27 | implementation(libs.bundles.compose) 28 | implementation(libs.timber) 29 | implementation(libs.kotlinx.coroutines.android) 30 | implementation(libs.androidx.webkit) 31 | implementation(libs.jsoup) 32 | } 33 | -------------------------------------------------------------------------------- /readium/navigators/web/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-navigator-web 2 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "rules": { 13 | "@typescript-eslint/no-explicit-any": "off", 14 | "@typescript-eslint/no-namespace": "off" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/.prettierignore: -------------------------------------------------------------------------------- 1 | src/vendor 2 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false 3 | } 4 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/README.md: -------------------------------------------------------------------------------- 1 | # Readium JS (Kotlin) 2 | 3 | A set of JavaScript files used by the Kotlin EPUB navigator. 4 | 5 | This folder starts with an underscore to prevent Gradle from embedding it as an asset. 6 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/public/fixed-single-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 |
33 | 34 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/bridge/fixed-gestures-bridge.ts: -------------------------------------------------------------------------------- 1 | import { AreaManager } from "../fixed/area-manager" 2 | 3 | export interface GesturesBridge { 4 | onTap(event: string): void 5 | onLinkActivated(href: string, outerHtml: string): void 6 | } 7 | 8 | export interface TapEvent { 9 | x: number 10 | y: number 11 | } 12 | 13 | export class BridgeGesturesAdapter implements AreaManager.Listener { 14 | readonly nativeApi: GesturesBridge 15 | 16 | constructor(gesturesApi: GesturesBridge) { 17 | this.nativeApi = gesturesApi 18 | } 19 | 20 | onTap(event: TapEvent): void { 21 | this.nativeApi.onTap(JSON.stringify(event)) 22 | } 23 | 24 | onLinkActivated(href: string, outerHtml: string): void { 25 | this.nativeApi.onLinkActivated(href, outerHtml) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/bridge/fixed-initialization-bridge.ts: -------------------------------------------------------------------------------- 1 | export interface InitializationBridge { 2 | onScriptsLoaded: () => void 3 | } 4 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/common/events.ts: -------------------------------------------------------------------------------- 1 | export interface TapEvent { 2 | x: number 3 | y: number 4 | } 5 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/common/types.ts: -------------------------------------------------------------------------------- 1 | export interface Size { 2 | width: number 3 | height: number 4 | } 5 | 6 | export interface Margins { 7 | top: number 8 | left: number 9 | bottom: number 10 | right: number 11 | } 12 | 13 | export interface Insets { 14 | top: number 15 | left: number 16 | bottom: number 17 | right: number 18 | } 19 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/fixed/area-manager.ts: -------------------------------------------------------------------------------- 1 | import { TapEvent } from "../common/events" 2 | 3 | export namespace AreaManager { 4 | export interface Listener { 5 | onTap(event: TapEvent): void 6 | onLinkActivated(href: string, outerHtml: string): void 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/fixed/iframe-message.ts: -------------------------------------------------------------------------------- 1 | import { Size } from "../common/types" 2 | 3 | export interface ContentSizeMessage { 4 | kind: "contentSize" 5 | size?: Size 6 | } 7 | 8 | export interface TapMessage { 9 | kind: "tap" 10 | x: number 11 | y: number 12 | } 13 | 14 | export interface LinkActivatedMessage { 15 | kind: "linkActivated" 16 | href: string 17 | outerHtml: string 18 | } 19 | 20 | export type IframeMessage = 21 | | ContentSizeMessage 22 | | TapMessage 23 | | LinkActivatedMessage 24 | 25 | export class IframeMessageSender { 26 | private messagePort: MessagePort 27 | 28 | constructor(messagePort: MessagePort) { 29 | this.messagePort = messagePort 30 | } 31 | 32 | send(message: IframeMessage) { 33 | this.messagePort.postMessage(message) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/src/util/fit.ts: -------------------------------------------------------------------------------- 1 | import { Size } from "../common/types" 2 | 3 | export const enum Fit { 4 | Contain = "contain", 5 | Width = "width", 6 | Height = "height", 7 | } 8 | 9 | export function computeScale(fit: Fit, content: Size, container: Size): number { 10 | switch (fit) { 11 | case Fit.Contain: 12 | return fitContain(content, container) 13 | case Fit.Width: 14 | return fitWidth(content, container) 15 | case Fit.Height: 16 | return fitHeight(content, container) 17 | } 18 | } 19 | 20 | function fitContain(content: Size, container: Size): number { 21 | const widthRatio = container.width / content.width 22 | const heightRatio = container.height / content.height 23 | return Math.min(widthRatio, heightRatio) 24 | } 25 | 26 | function fitWidth(content: Size, container: Size): number { 27 | return container.width / content.width 28 | } 29 | 30 | function fitHeight(content: Size, container: Size): number { 31 | return container.height / content.height 32 | } 33 | -------------------------------------------------------------------------------- /readium/navigators/web/scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "noImplicitAny": true, 5 | "module": "es6", 6 | "target": "es6", 7 | "jsx": "react", 8 | "allowJs": true, 9 | "moduleResolution": "node", 10 | "strict": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/assets/readium/navigators/web/error.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/assets/readium/navigators/web/fixed-single-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 |
33 | 34 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/assets/readium/navigators/web/prepaginated-single-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 |
33 | 34 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/layout/ReadingOrder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.layout 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | import org.readium.r2.shared.publication.presentation.Presentation 11 | import org.readium.r2.shared.util.Url 12 | 13 | @ExperimentalReadiumApi 14 | internal data class ReadingOrder( 15 | val items: List, 16 | ) { 17 | 18 | fun indexOfHref(href: Url): Int? = items 19 | .indexOfFirst { it.href == href } 20 | .takeUnless { it == -1 } 21 | } 22 | 23 | @ExperimentalReadiumApi 24 | internal data class ReadingOrderItem( 25 | val href: Url, 26 | val page: Presentation.Page?, 27 | ) 28 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/pager/LoggingTargetedFlingBehavior.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.pager 8 | 9 | import androidx.compose.foundation.gestures.ScrollScope 10 | import androidx.compose.foundation.gestures.TargetedFlingBehavior 11 | import timber.log.Timber 12 | 13 | internal class LoggingTargetedFlingBehavior( 14 | private val delegate: TargetedFlingBehavior, 15 | ) : TargetedFlingBehavior { 16 | 17 | override suspend fun ScrollScope.performFling( 18 | initialVelocity: Float, 19 | onRemainingDistanceUpdated: (Float) -> Unit, 20 | ): Float { 21 | Timber.d("performFling $initialVelocity") 22 | return with(delegate) { 23 | performFling(initialVelocity, onRemainingDistanceUpdated) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/preferences/FixedWebDefaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.preferences 8 | 9 | import org.readium.r2.navigator.preferences.Fit 10 | import org.readium.r2.navigator.preferences.ReadingProgression 11 | import org.readium.r2.shared.ExperimentalReadiumApi 12 | 13 | @ExperimentalReadiumApi 14 | public data class FixedWebDefaults( 15 | val fit: Fit? = null, 16 | val readingProgression: ReadingProgression? = null, 17 | val spreads: Boolean? = null, 18 | ) 19 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/preferences/FixedWebSettings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.preferences 8 | 9 | import org.readium.r2.navigator.preferences.Configurable 10 | import org.readium.r2.navigator.preferences.Fit 11 | import org.readium.r2.navigator.preferences.ReadingProgression 12 | import org.readium.r2.shared.ExperimentalReadiumApi 13 | 14 | @ExperimentalReadiumApi 15 | public data class FixedWebSettings( 16 | val fit: Fit, 17 | val readingProgression: ReadingProgression, 18 | val spreads: Boolean, 19 | ) : Configurable.Settings 20 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/util/DisplayArea.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.util 8 | 9 | import androidx.compose.ui.unit.Dp 10 | import androidx.compose.ui.unit.DpSize 11 | 12 | internal data class DisplayArea( 13 | val viewportSize: DpSize, 14 | val safeDrawingPadding: AbsolutePaddingValues, 15 | ) 16 | 17 | internal data class AbsolutePaddingValues( 18 | val top: Dp, 19 | val right: Dp, 20 | val bottom: Dp, 21 | val left: Dp, 22 | ) 23 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/util/WebViewClient.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.util 8 | 9 | import android.webkit.WebResourceRequest 10 | import android.webkit.WebResourceResponse 11 | import android.webkit.WebView 12 | 13 | internal class WebViewClient( 14 | private val webViewServer: WebViewServer, 15 | ) : android.webkit.WebViewClient() { 16 | 17 | override fun shouldInterceptRequest( 18 | view: WebView, 19 | request: WebResourceRequest, 20 | ): WebResourceResponse? { 21 | return webViewServer.shouldInterceptRequest(request) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /readium/navigators/web/src/main/java/org/readium/navigator/web/webapi/InitializationApi.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.navigator.web.webapi 8 | 9 | import android.webkit.JavascriptInterface 10 | import android.webkit.WebView 11 | 12 | internal class InitializationApi( 13 | private val onScriptsLoadedDelegate: () -> Unit, 14 | ) { 15 | 16 | fun registerOnWebView(webView: WebView) { 17 | webView.addJavascriptInterface(this, "initialization") 18 | } 19 | 20 | @JavascriptInterface 21 | fun onScriptsLoaded() { 22 | onScriptsLoadedDelegate.invoke() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /readium/opds/README.md: -------------------------------------------------------------------------------- 1 | # Readium OPDS 2 | 3 | A parser for OPDS 1.x and 2.0 written in Kotlin using the [Readium Web Publication Manifest](https://github.com/readium/webpub-manifest). 4 | 5 | ## Features 6 | 7 | - [x] Abstract model 8 | - [x] OPDS 1.x support 9 | - [x] OPDS 2.0 support 10 | - [ ] Search 11 | - [x] Full entries 12 | - [x] Facets 13 | - [x] Groups 14 | - [x] Indirect acquisition 15 | - [ ] Library specific extensions 16 | -------------------------------------------------------------------------------- /readium/opds/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.r2.opds" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:readium-shared")) 17 | 18 | implementation(libs.timber) 19 | implementation(libs.kotlinx.coroutines.android) 20 | 21 | // Tests 22 | testImplementation(libs.junit) 23 | testImplementation(libs.robolectric) 24 | } 25 | -------------------------------------------------------------------------------- /readium/opds/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-opds 2 | -------------------------------------------------------------------------------- /readium/opds/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /readium/opds/src/test/resources/robolectric.properties: -------------------------------------------------------------------------------- 1 | sdk=30 2 | -------------------------------------------------------------------------------- /readium/shared/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-shared 2 | -------------------------------------------------------------------------------- /readium/shared/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/JSONable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Aferdita Muriqi, Clément Baumann, Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.shared 11 | 12 | import org.json.JSONArray 13 | import org.json.JSONObject 14 | 15 | public interface JSONable { 16 | 17 | /** 18 | * Serializes the object to its JSON representation. 19 | */ 20 | public fun toJSON(): JSONObject 21 | } 22 | 23 | /** 24 | * Serializes a list of [JSONable] into a [JSONArray]. 25 | */ 26 | public fun List.toJSON(): JSONArray = 27 | JSONArray(map(JSONable::toJSON)) 28 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/extensions/ContentResolver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | @file:OptIn(InternalReadiumApi::class) 11 | 12 | package org.readium.r2.shared.extensions 13 | 14 | import android.content.ContentResolver 15 | import android.net.Uri 16 | import org.readium.r2.shared.InternalReadiumApi 17 | 18 | internal fun ContentResolver.queryProjection(uri: Uri, projection: String): String? = 19 | tryOrLog { 20 | query(uri, arrayOf(projection), null, null, null)?.use { cursor -> 21 | if (cursor.moveToFirst()) { 22 | return cursor.getString(0) 23 | } 24 | return null 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/extensions/Float.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.extensions 8 | 9 | import kotlin.math.abs 10 | import org.readium.r2.shared.InternalReadiumApi 11 | 12 | @InternalReadiumApi 13 | public fun Float.equalsDelta(other: Float, delta: Float = 0.001f): Boolean = 14 | this == other || abs(this - other) < delta 15 | 16 | @InternalReadiumApi 17 | public fun Double.equalsDelta(other: Double, delta: Double = 0.001): Boolean = 18 | this == other || abs(this - other) < delta 19 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/extensions/Iterable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.extensions 8 | 9 | import kotlin.collections.Iterable 10 | 11 | internal fun Iterable.contains(predicate: (T) -> Boolean): Boolean = 12 | firstOrNull(predicate) != null 13 | 14 | internal fun Iterable.containsAny(vararg elements: T): Boolean { 15 | for (element in elements) { 16 | if (contains(element)) { 17 | return true 18 | } 19 | } 20 | return false 21 | } 22 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/publication/Collection.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.shared.publication 11 | 12 | /** 13 | * Collection type used for collection/series metadata. 14 | * For convenience, the JSON schema reuse the Contributor's definition. 15 | */ 16 | public typealias Collection = Contributor 17 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/publication/encryption/Properties.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Aferdita Muriqi, Clément Baumann, Mickaël Menu 4 | * 5 | * Copyright (c) 2018. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.shared.publication.encryption 11 | 12 | import org.json.JSONObject 13 | import org.readium.r2.shared.publication.Properties 14 | 15 | // Encryption extensions for link [Properties]. 16 | 17 | /** 18 | * Indicates that a resource is encrypted/obfuscated and provides relevant information for 19 | * decryption. 20 | */ 21 | public val Properties.encryption: Encryption? 22 | get() = (this["encrypted"] as? Map<*, *>) 23 | ?.let { Encryption.fromJSON(JSONObject(it)) } 24 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/publication/epub/Presentation.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.shared.publication.epub 11 | 12 | import org.readium.r2.shared.publication.Link 13 | import org.readium.r2.shared.publication.presentation.Presentation 14 | 15 | /** 16 | * Get the layout of the given resource in this publication. 17 | * Falls back on REFLOWABLE. 18 | */ 19 | public fun Presentation.layoutOf(link: Link): EpubLayout { 20 | return link.properties.layout 21 | ?: layout 22 | ?: EpubLayout.REFLOWABLE 23 | } 24 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/publication/opds/Publication.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.shared.publication.opds 11 | 12 | import org.readium.r2.shared.publication.Link 13 | import org.readium.r2.shared.publication.Publication 14 | 15 | // OPDS extensions for [Publication] 16 | 17 | public val Publication.images: List get() = linksWithRole("images") 18 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/publication/presentation/Metadata.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-shared-kotlin 3 | * Developers: Mickaël Menu 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | package org.readium.r2.shared.publication.presentation 10 | 11 | import org.json.JSONObject 12 | import org.readium.r2.shared.publication.Metadata 13 | 14 | // Presentation extensions for [Metadata] 15 | 16 | public val Metadata.presentation: Presentation 17 | get() = Presentation.fromJSON( 18 | (this["presentation"] as? Map<*, *>) 19 | ?.let { JSONObject(it) } 20 | ) 21 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/Benchmarking.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.util 8 | 9 | import kotlin.time.measureTime 10 | import timber.log.Timber 11 | 12 | internal inline fun benchmark(title: String, enabled: Boolean = true, closure: () -> T): T { 13 | if (!enabled) { 14 | return closure() 15 | } 16 | 17 | var result: T 18 | val duration = measureTime { 19 | result = closure() 20 | } 21 | Timber.d("""Benchmark "$title" took %.4f seconds """.format(duration.inWholeSeconds)) 22 | return result 23 | } 24 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/resource/SingleResourceContainer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.util.resource 8 | 9 | import org.readium.r2.shared.util.Url 10 | import org.readium.r2.shared.util.data.Container 11 | 12 | /** A [Container] for a single [Resource]. */ 13 | public class SingleResourceContainer( 14 | private val entryUrl: Url, 15 | private val resource: Resource, 16 | ) : Container { 17 | 18 | override val entries: Set = setOf(entryUrl) 19 | 20 | override fun get(url: Url): Resource? { 21 | if (!url.removeFragment().removeQuery().isEquivalent(entryUrl)) { 22 | return null 23 | } 24 | 25 | return resource.borrow() 26 | } 27 | 28 | override fun close() { 29 | resource.close() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/tokenizer/Tokenizer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.util.tokenizer 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | 11 | /** A tokenizer splits a piece of data [D] into a list of [T] tokens. */ 12 | @ExperimentalReadiumApi 13 | public fun interface Tokenizer { 14 | public fun tokenize(data: D): List 15 | } 16 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/units/Hertz.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.util.units 8 | 9 | @JvmInline 10 | public value class Hz(public val value: Double) 11 | 12 | public val Double.hz: Hz get() = Hz(this) 13 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/AsynchronousCloseException.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | 3 | /** 4 | * An {@code AsynchronousCloseException} is thrown when the underlying channel 5 | * for an I/O operation is closed by another thread. 6 | */ 7 | public class AsynchronousCloseException extends ClosedChannelException { 8 | private static final long serialVersionUID = 6891178312432313966L; 9 | /** 10 | * Constructs an {@code AsynchronousCloseException}. 11 | */ 12 | public AsynchronousCloseException() { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/ByteChannel.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | /** 3 | * A ByteChannel is both readable and writable. 4 | *

5 | * The methods for the byte channel are precisely those defined by readable and 6 | * writable byte channels. 7 | * 8 | * @see ReadableByteChannel 9 | * @see WritableByteChannel 10 | */ 11 | public interface ByteChannel extends ReadableByteChannel, WritableByteChannel { 12 | // No methods defined. 13 | } 14 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/ClosedByInterruptException.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | 3 | /** 4 | * A {@code ClosedByInterruptException} is thrown when a thread is interrupted 5 | * in a blocking I/O operation. 6 | *

7 | * When the thread is interrupted by a call to {@code interrupt()}, it closes 8 | * the channel, sets the interrupt status of the thread to {@code true} and 9 | * throws a {@code ClosedByInterruptException}. 10 | */ 11 | public class ClosedByInterruptException extends AsynchronousCloseException { 12 | private static final long serialVersionUID = -4488191543534286750L; 13 | /** 14 | * Constructs a {@code ClosedByInterruptException}. 15 | */ 16 | public ClosedByInterruptException() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/ClosedChannelException.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | 3 | import java.io.IOException; 4 | /** 5 | * A {@code ClosedChannelException} is thrown when a channel is closed for the 6 | * type of operation attempted. 7 | */ 8 | public class ClosedChannelException extends IOException { 9 | private static final long serialVersionUID = 882777185433553857L; 10 | /** 11 | * Constructs a {@code ClosedChannelException}. 12 | */ 13 | public ClosedChannelException() { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/NonReadableChannelException.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | 3 | /** 4 | * A {@code NonReadableChannelException} is thrown when attempting to read from 5 | * a channel that is not open for reading. 6 | */ 7 | public class NonReadableChannelException extends IllegalStateException { 8 | private static final long serialVersionUID = -3200915679294993514L; 9 | /** 10 | * Constructs a {@code NonReadableChannelException}. 11 | */ 12 | public NonReadableChannelException() { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /readium/shared/src/main/java/org/readium/r2/shared/util/zip/jvm/NonWritableChannelException.java: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.util.zip.jvm; 2 | 3 | /** 4 | * A {@code NonWritableChannelException} is thrown when attempting to write to a 5 | * channel that is not open for writing. 6 | */ 7 | public class NonWritableChannelException extends IllegalStateException { 8 | private static final long serialVersionUID = -7071230488279011621L; 9 | /** 10 | * Constructs a {@code NonWritableChannelException}. 11 | */ 12 | public NonWritableChannelException() { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /readium/shared/src/test/java/org/readium/r2/shared/extensions/LongRangeTest.kt: -------------------------------------------------------------------------------- 1 | @file:OptIn(InternalReadiumApi::class) 2 | 3 | package org.readium.r2.shared.extensions 4 | 5 | import kotlin.test.assertEquals 6 | import org.junit.Test 7 | import org.readium.r2.shared.InternalReadiumApi 8 | 9 | class LongRangeTest { 10 | 11 | @Test 12 | fun `coerceIn is correct`() { 13 | assertEquals((25L..30), (25L..30).coerceIn(22L..32)) 14 | assertEquals((27L..28), (25L..30).coerceIn(27L..28)) 15 | assertEquals((27L..30), (25L..30).coerceIn(27L..32)) 16 | assertEquals((25L..28), (25L..30).coerceIn(22L..28)) 17 | assertEquals(0L until 0, (25L..30).coerceIn(0L until 0)) 18 | assertEquals(0L until 0, (25L..30).coerceIn(32L until 34)) 19 | assertEquals(0L until 0, (25L..30).coerceIn(0L until 25)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /readium/shared/src/test/java/org/readium/r2/shared/extensions/StringTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.shared.extensions 8 | 9 | import kotlin.test.assertFalse 10 | import kotlin.test.assertTrue 11 | import org.junit.Test 12 | 13 | class StringTest { 14 | 15 | @Test 16 | fun `checks if a string is made of printable ASCII characters`() { 17 | assertTrue("".isPrintableAscii()) 18 | assertTrue(" foo/@bar".isPrintableAscii()) 19 | assertFalse("école".isPrintableAscii()) 20 | assertFalse("\u0001 non printable".isPrintableAscii()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /readium/shared/src/test/java/org/readium/r2/shared/publication/ReadingProgressionTest.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.shared.publication 2 | 3 | import org.junit.Assert.* 4 | import org.junit.Test 5 | 6 | class ReadingProgressionTest { 7 | 8 | @Test 9 | fun `parse reading progression`() { 10 | assertEquals(ReadingProgression.LTR, ReadingProgression("LTR")) 11 | assertEquals(ReadingProgression.LTR, ReadingProgression("ltr")) 12 | assertEquals(ReadingProgression.RTL, ReadingProgression("rtl")) 13 | assertEquals(null, ReadingProgression("auto")) 14 | assertEquals(null, ReadingProgression("foobar")) 15 | assertEquals(null, ReadingProgression(null)) 16 | } 17 | 18 | @Test fun `get reading progression value`() { 19 | assertEquals("ltr", ReadingProgression.LTR.value) 20 | assertEquals("rtl", ReadingProgression.RTL.value) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/extensions/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/extensions/image.jpg -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/publication/services/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/publication/services/cover.jpg -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/any.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "value" 3 | } 4 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/audiobook-lcp.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/audiobook-lcp.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/audiobook-package.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/audiobook-package.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/cbz.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/cbz.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/divina-package.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/divina-package.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/epub.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/epub.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/html-doctype-case.unknown: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sample HTML document 5 | 6 | 7 | 8 |

Sample HTML document.

9 | 10 | 11 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/html.unknown: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sample HTML document 5 | 6 | 7 | 8 |

Sample HTML document.

9 | 10 | 11 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/lpf-index-html.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/lpf-index-html.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/lpf.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/lpf.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/pdf-lcp.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/pdf-lcp.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/pdf.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/pdf.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/png.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/png.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/unknown: -------------------------------------------------------------------------------- 1 | unknown format 2 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/unknown.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/unknown.zip -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/w3c-wpub.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context" : ["https://schema.org","https://www.w3.org/ns/wp-context"], 3 | "type" : "Book", 4 | "url" : "https://publisher.example.org/mobydick", 5 | "name" : "Moby Dick", 6 | "readingOrder" : [ 7 | "html/title.html", 8 | "html/copyright.html", 9 | "html/introduction.html", 10 | "html/epigraph.html", 11 | "html/c001.html", 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/webpub-lcp.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/webpub-lcp.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/webpub-package.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/webpub-package.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/xhtml.unknown: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | Sample XHTML Document 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/asset/zab.unknown: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/asset/zab.unknown -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/directory/subdirectory/hello.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/resource/directory/subdirectory/hello.mp3 -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/directory/subdirectory/text2.txt: -------------------------------------------------------------------------------- 1 | text2 -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/directory/text1.txt: -------------------------------------------------------------------------------- 1 | text1 -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub.epub -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/EPUB/cover.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Children's Literature 6 | 7 | 8 | 9 | Cover Image 10 | 11 | 12 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/EPUB/css/nav.css: -------------------------------------------------------------------------------- 1 | 2 | @namespace epub "http://www.idpf.org/2007/ops"; 3 | 4 | h2 { 5 | text-align: left; 6 | } 7 | 8 | a { 9 | text-decoration: none; 10 | } 11 | 12 | nav[epub\:type~='landmarks'], nav[epub\:type~='page-list'] { 13 | display: none; 14 | visibility: hidden; 15 | } 16 | 17 | ol { 18 | list-style-type: none; 19 | } 20 | 21 | ol > li:first-child { 22 | margin-top: 0.3em; 23 | } 24 | 25 | nav[epub|type~='toc'] > ol > li > ol > li { 26 | margin-top: 0.3em; 27 | } 28 | 29 | li.front { 30 | font-style: italic; 31 | font-size: 85%; 32 | } 33 | 34 | li.front + li.body { 35 | margin-top: 1.5em; 36 | } 37 | 38 | span.author { 39 | font-family: arial, helvetica, sans-serif; 40 | font-weight: bold; 41 | } 42 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/EPUB/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/EPUB/images/cover.png -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/META-INF/container.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /readium/shared/src/test/resources/org/readium/r2/shared/util/resource/epub/mimetype: -------------------------------------------------------------------------------- 1 | application/epub+zip -------------------------------------------------------------------------------- /readium/shared/src/test/resources/robolectric.properties: -------------------------------------------------------------------------------- 1 | sdk=30 2 | -------------------------------------------------------------------------------- /readium/streamer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | plugins { 8 | id("readium.library-conventions") 9 | } 10 | 11 | android { 12 | namespace = "org.readium.r2.streamer" 13 | } 14 | 15 | dependencies { 16 | api(project(":readium:readium-shared")) 17 | 18 | @Suppress("GradleDependency") 19 | implementation(libs.timber) 20 | // AM NOTE: conflicting support libraries, excluding these 21 | implementation("com.mcxiaoke.koi:core:0.5.5") { 22 | exclude(module = "support-v4") 23 | } 24 | implementation(libs.kotlinx.coroutines.android) 25 | 26 | // Tests 27 | testImplementation(libs.junit) 28 | testImplementation(libs.kotlin.junit) 29 | testImplementation(libs.assertj) 30 | testImplementation(libs.robolectric) 31 | } 32 | -------------------------------------------------------------------------------- /readium/streamer/gradle.properties: -------------------------------------------------------------------------------- 1 | pom.artifactId=readium-streamer 2 | -------------------------------------------------------------------------------- /readium/streamer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /readium/streamer/src/main/java/org/readium/r2/streamer/extensions/File.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-streamer-kotlin 3 | * Developers: Quentin Gliosca 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.streamer.extensions 11 | 12 | import java.io.File 13 | 14 | /** 15 | * Returns a [File] to the first component of the [File]'s path, 16 | * regardless of whether it is a directory or a file. 17 | */ 18 | internal val File.firstComponent: File 19 | get() = parent.takeUnless { it == "/" } 20 | ?.let { File(it).firstComponent } 21 | ?: this 22 | -------------------------------------------------------------------------------- /readium/streamer/src/main/java/org/readium/r2/streamer/extensions/Url.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.streamer.extensions 8 | 9 | import org.readium.r2.shared.util.Url 10 | 11 | internal val Url.isHiddenOrThumbs: Boolean 12 | get() = filename?.let { it.startsWith(".") || it == "Thumbs.db" } ?: false 13 | -------------------------------------------------------------------------------- /readium/streamer/src/test/java/org/readium/r2/streamer/TestUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Module: r2-streamer-kotlin 3 | * Developers: Quentin Gliosca 4 | * 5 | * Copyright (c) 2020. Readium Foundation. All rights reserved. 6 | * Use of this source code is governed by a BSD-style license which is detailed in the 7 | * LICENSE file present in the project repository where this source code is maintained. 8 | */ 9 | 10 | package org.readium.r2.streamer 11 | 12 | import kotlinx.coroutines.runBlocking 13 | import org.readium.r2.shared.publication.Publication 14 | import org.readium.r2.shared.util.asset.Asset 15 | import org.readium.r2.shared.util.resource.Resource 16 | import org.readium.r2.streamer.parser.PublicationParser 17 | 18 | internal fun Resource.readBlocking(range: LongRange? = null) = runBlocking { read(range) } 19 | 20 | internal fun PublicationParser.parseBlocking(asset: Asset): Publication.Builder? = 21 | runBlocking { parse(asset).getOrNull() } 22 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.testinstance.lifecycle.default = per_class -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.adb.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.adb.woff -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.obf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.obf.woff -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/deobfuscation/cut-cut.woff -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/navigation/nav-children.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/navigation/nav-empty.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

Section Title

10 |

Some text

11 |

Table of Contents

12 |

Some text

13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/navigation/nav-section.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

Section Title

10 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/ncx/ncx-empty.ncx: -------------------------------------------------------------------------------- 1 | 2 | 3 | Document Title 4 | 5 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/collections-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/cover-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/cover-epub3.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/cover-mix.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/dates-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 2012-04-02T12:47:00Z 6 | 1865-07-04 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/dates-epub3.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 1865-07-04 6 | 2012-04-02T12:47:00Z 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/fallbacks-termination.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/fallbacks.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/identifier-unique.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | BEQ 7 | urn:uuid:2 8 | 978-3-16-148410-0 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/languages-order-nomatch.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | en 9 | fr 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/languages-order.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | en 9 | ar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/meta-termination.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | Media Overlays Narrator 6 | nrt 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/presentation-metadata.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | pre-paginated 7 | landscape 8 | scrolled-doc 9 | both 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/progression-default.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/progression-ltr.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/progression-none.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/progression-rtl.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | Alice's Adventures in Wonderland 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/subjects-complex.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | FICTION / Occult & Supernatural 6 | FICTION / Occulte & Surnaturel 7 | occult 8 | BISAC 9 | FIC024000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/subjects-multiple.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | fiction 6 | 7 | apple; banana, pear 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/subjects-single.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | apple; banana, pear 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/tdm-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/tdm-epub3.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 1 7 | https://provider.com/policies/policy.json 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/title-main-precedence.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | Main title takes precedence 6 | main 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/title-multiple-subtitles.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | Subtitle 1 6 | subtitle 7 | 2 8 | Subtitle 2 9 | subtitle 10 | 1 11 | en 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/titles-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | en 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/version-default.opf: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | Alice's Adventures in Wonderland 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/version-epub2.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/epub/package/version-epub3.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alice's Adventures in Wonderland 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/image/futuristic_tales.cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/streamer/src/test/resources/org/readium/r2/streamer/parser/image/futuristic_tales.cbz -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/org/readium/r2/streamer/parser/image/futuristic_tales.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/readium/streamer/src/test/resources/org/readium/r2/streamer/parser/image/futuristic_tales.jpg -------------------------------------------------------------------------------- /readium/streamer/src/test/resources/robolectric.properties: -------------------------------------------------------------------------------- 1 | sdk=30 2 | -------------------------------------------------------------------------------- /test-app/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | *.aab 11 | r2-testapp/release 12 | -------------------------------------------------------------------------------- /test-app/src/main/assets/annotation-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-app/src/main/assets/configs/config.properties: -------------------------------------------------------------------------------- 1 | useExternalFileDir=false -------------------------------------------------------------------------------- /test-app/src/main/assets/fonts/Literata-Italic-VariableFont_opsz,wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/assets/fonts/Literata-Italic-VariableFont_opsz,wght.ttf -------------------------------------------------------------------------------- /test-app/src/main/assets/fonts/Literata-VariableFont_opsz,wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/assets/fonts/Literata-VariableFont_opsz,wght.ttf -------------------------------------------------------------------------------- /test-app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/about/AboutFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.about 8 | 9 | import android.os.Bundle 10 | import android.view.LayoutInflater 11 | import android.view.View 12 | import android.view.ViewGroup 13 | import androidx.fragment.app.Fragment 14 | import org.readium.r2.testapp.R 15 | 16 | class AboutFragment : Fragment() { 17 | 18 | override fun onCreateView( 19 | inflater: LayoutInflater, 20 | container: ViewGroup?, 21 | savedInstanceState: Bundle?, 22 | ): View? { 23 | return inflater.inflate(R.layout.fragment_about, container, false) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/data/CatalogRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.data 8 | 9 | import kotlinx.coroutines.flow.Flow 10 | import org.readium.r2.testapp.data.db.CatalogDao 11 | import org.readium.r2.testapp.data.model.Catalog 12 | 13 | class CatalogRepository(private val catalogDao: CatalogDao) { 14 | 15 | suspend fun insertCatalog(catalog: Catalog): Long { 16 | return catalogDao.insertCatalog(catalog) 17 | } 18 | 19 | fun getCatalogsFromDatabase(): Flow> = catalogDao.getCatalogModels() 20 | 21 | suspend fun deleteCatalog(id: Long) = catalogDao.deleteCatalog(id) 22 | } 23 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/drm/DrmManagementContract.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.drm 8 | 9 | import android.os.Bundle 10 | 11 | object DrmManagementContract { 12 | 13 | private const val HAS_RETURNED_KEY = "hasReturned" 14 | 15 | val REQUEST_KEY: String = DrmManagementContract::class.java.name 16 | 17 | data class Result(val hasReturned: Boolean) 18 | 19 | fun createResult(hasReturned: Boolean): Bundle { 20 | return Bundle().apply { 21 | putBoolean(HAS_RETURNED_KEY, hasReturned) 22 | } 23 | } 24 | 25 | fun parseResult(result: Bundle): Result { 26 | val hasReturned = requireNotNull(result.getBoolean(HAS_RETURNED_KEY)) 27 | return Result(hasReturned) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/search/SearchUserError.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.search 8 | 9 | import org.readium.r2.shared.ExperimentalReadiumApi 10 | import org.readium.r2.shared.publication.services.search.SearchError 11 | import org.readium.r2.testapp.R 12 | import org.readium.r2.testapp.utils.UserError 13 | 14 | @OptIn(ExperimentalReadiumApi::class) 15 | fun SearchError.toUserError(): UserError = when (this) { 16 | is SearchError.Engine -> UserError(R.string.search_error_other, cause = this) 17 | is SearchError.Reading -> UserError(R.string.search_error_other, cause = this) 18 | } 19 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/shared/views/Group.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.shared.views 8 | 9 | import androidx.compose.runtime.Composable 10 | import org.readium.r2.testapp.utils.compose.Emphasis 11 | import org.readium.r2.testapp.utils.compose.EmphasisProvider 12 | import org.readium.r2.testapp.utils.compose.LocalContentEmphasis 13 | 14 | /** 15 | * Sets the emphasis (alpha) of a group of [Composable] views. 16 | */ 17 | @Composable 18 | fun Group(enabled: Boolean = true, content: @Composable () -> Unit) { 19 | val emphasis = when { 20 | !enabled -> Emphasis.Disabled 21 | else -> Emphasis.Medium 22 | } 23 | EmphasisProvider(LocalContentEmphasis provides emphasis) { 24 | content() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/Exception.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.testapp.utils 2 | 3 | import timber.log.Timber 4 | 5 | /** 6 | * Returns the result of the given [closure], or null if an [Exception] was raised. 7 | */ 8 | inline fun tryOrNull(closure: () -> T): T? = 9 | tryOr(null, closure) 10 | 11 | /** 12 | * Returns the result of the given [closure], or [default] if an [Exception] was raised. 13 | */ 14 | inline fun tryOr(default: T, closure: () -> T): T = 15 | try { 16 | closure() 17 | } catch (e: Exception) { 18 | default 19 | } 20 | 21 | /** 22 | * Returns the result of the given [closure], or null if an [Exception] was raised. 23 | * The [Exception] will be logged. 24 | */ 25 | inline fun tryOrLog(closure: () -> T): T? = 26 | try { 27 | closure() 28 | } catch (e: Exception) { 29 | Timber.e(e) 30 | null 31 | } 32 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Intent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.utils.extensions 8 | 9 | import android.content.Context 10 | import android.content.Intent 11 | import androidx.core.app.ShareCompat 12 | 13 | /** 14 | * Start a new activity to share the given plain [text] to other applications. 15 | */ 16 | fun createShareIntent( 17 | launchingContext: Context, 18 | text: String, 19 | title: String? = null, 20 | ): Intent { 21 | val intent = 22 | ShareCompat.IntentBuilder(launchingContext) 23 | .setType("text/plain") 24 | .setText(text) 25 | .intent 26 | .setAction(Intent.ACTION_SEND) 27 | .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 28 | return Intent.createChooser(intent, title) 29 | } 30 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Number.kt: -------------------------------------------------------------------------------- 1 | package org.readium.r2.testapp.utils.extensions 2 | 3 | import java.text.NumberFormat 4 | 5 | fun Number.formatPercentage(maximumFractionDigits: Int = 0): String { 6 | val format = NumberFormat.getPercentInstance() 7 | format.maximumFractionDigits = maximumFractionDigits 8 | return format.format(this) 9 | } 10 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/extensions/String.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.utils.extensions 8 | 9 | import android.os.Build 10 | import android.text.Html 11 | import android.text.Spanned 12 | 13 | fun String.toHtml(): Spanned = 14 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 15 | Html.fromHtml(this, Html.FROM_HTML_MODE_COMPACT) 16 | } else { 17 | @Suppress("DEPRECATION") 18 | Html.fromHtml(this) 19 | } 20 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/extensions/readium/LinkExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.utils.extensions.readium 8 | 9 | import org.readium.r2.shared.publication.Link 10 | 11 | val Link.outlineTitle: String 12 | get() = title ?: href.toString() 13 | -------------------------------------------------------------------------------- /test-app/src/main/java/org/readium/r2/testapp/utils/extensions/readium/MetadataExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Readium Foundation. All rights reserved. 3 | * Use of this source code is governed by the BSD-style license 4 | * available in the top-level LICENSE file of the project. 5 | */ 6 | 7 | package org.readium.r2.testapp.utils.extensions.readium 8 | 9 | import org.readium.r2.shared.publication.Metadata 10 | 11 | val Metadata.authorName: String get() = 12 | authors.firstOrNull()?.name ?: "" 13 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/background_action_mode.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/baseline_dashboard_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/baseline_info_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/baseline_local_library_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/res/drawable/cover.png -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_add_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_bookmark_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_delete_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_edit_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_enhanced_encryption_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_headphones_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_info_24.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_pause_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_play_arrow_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_baseline_search_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_notch.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_outline_format_size_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/ic_outline_menu_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/icon_overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/res/drawable/icon_overflow.png -------------------------------------------------------------------------------- /test-app/src/main/res/drawable/repfr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/readium/kotlin-toolkit/38b1a810235409967b9c9bacea1516aabc344699/test-app/src/main/res/drawable/repfr.png -------------------------------------------------------------------------------- /test-app/src/main/res/layout/activity_reader.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /test-app/src/main/res/layout/add_catalog_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 17 | 18 | 25 | -------------------------------------------------------------------------------- /test-app/src/main/res/layout/fragment_listview.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-app/src/main/res/layout/fragment_reader.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /test-app/src/main/res/layout/item_recycle_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 |