Appearance
Release notes Android Framework 4 stable
4.8.0 2026-10-02
WARNING
Some fixes in this release change behavior that your code may depend on:
- Cancelled
suspendcalls now throwCancellationExceptioninstead of returningColibrioResult.Error. ColibrioAudioPlayerExceptionhas a newPreparationFailedcase, andColibrioAudioPlayer.reload()can now throw.ReadingSystemEngine.createSyncMediaPlayer(ColibrioAudioPlayer)fails withColibrioPlayerAlreadySyncedExceptionfor an audio player that is already synced.- You now own the
TtsSynthesizerwhenReaderPublication.createTtsSyncMediaTimeline()fails or is cancelled. ColibrioTtsSynthesizerno longer extendsUtteranceProgressListeneror implementsCoroutineScope.
See the improvements and bugfixes below for details.
New features
- Added the new option
SyncMediaTtsTimelineContentTransformationOptions.contentBlockAttributeExclusions. It lists the attribute names, and optionally attribute values, that exclude a content block and its descendants from a TTS Sync Media timeline. By default, content blocks withrole="presentation",role="none"oraria-hidden="true"are excluded, which matches the previous hard-coded behavior. Setting the option replaces the default list rather than adding to it, and an empty list excludes nothing. Attribute names are matched on the qualified name, so a namespace-prefixed attribute must be listed with its prefix. - Added the constants
ErrorType.WEBVIEW_VERSION_OUTDATEDandExceptionMessage.WEBVIEW_VERSION_UNSUPPORTED. They match theerrorTypeandmessageof theColibrioExceptionthat is reported when a publication is loaded in a WebView that is too old to run the framework.
Improvements
<audio>,<video>,<canvas>and<iframe>elements are now always kept indivisible during reflow, whateverEpubReaderPublicationOptions.reflowOptions.plugins.fragmentableElements.blacklistSelectorsis set to, so a page break can no longer be placed inside one.<audio>and<video>have therefore been removed from that option's default value, which is nowtr,pictureandmath.ReaderViewnow applies all state updates before it calls any listener, so listeners always read a consistent state. As a result,OnCanPerformNavigationChangedListeneris now called last instead of first, andOnReadingPositionChangedListeneris called afterOnVisibleContentChangedListener.onVisibleRangeChanged()andonVisiblePagesChanged().- Android Studio should now be able to render KDoc for the Colibrio Framework APIs.
ColibrioTtsSynthesizerno longer extendsUtteranceProgressListeneror implementsCoroutineScope, which were implementation details. Code that used it as either no longer compiles. Its public API is now theTtsSynthesizerinterface, theColibrioTtsSynthesizer(textToSpeech)constructor andsetColibrioTtsSynthesizerConfigurationListener().- We have documented that the whole reading system API —
ReadingSystemEngine, itsReaderView, the publications it loads, and their timelines andSyncMediaPlayers — must be used from the main thread, including thesuspendoverloads. See the API documentation for details. - We have documented that the whole audio API —
AudioReadingSystemEngine, theColibrioAudioPlayerit creates, that player's media session, andWpAudioPublication.createAudioTimeline— must be used from the main thread, including itssuspendfunctions, and that the playback service must run in the same process as the code creating the player. See the API documentation for details. - We have documented that a
ColibrioAudioPlayercannot recover a lost connection to the playback service. Whenreload()throwsPlaybackServiceConnectionFailedException, create a new player withcreateAudioPlayer()instead. See the API documentation for details. - We have documented how to recover from a WebView renderer process crash on
ColibrioReadingSystemView.setOnRendererProcessCrash(). This includes how to handle aColibrioAudioPlayerconnected throughReadingSystemEngine.createSyncMediaPlayer(), whose audio keeps playing after the crash. See the API documentation for details. - The audio API now logs an error when one of its state-changing members or
suspendentry points is called from a thread other than the main thread, so an unsupported call is visible in Logcat instead of failing silently later.
Bugfixes
- Fixed an issue where page navigation swipe gestures failed to trigger when initiated over a scrollable container that had reached its scroll limits.
- Fixed a rendering bug where inline MathML was forced onto its own line in paginated renderers instead of remaining inline as in scroll renderers.
- Fixed an issue where an element that set
overflow-xthrough an inlinestyleattribute was measured with a scrollable vertical overflow, which could change layout and pagination. - Fixed an issue where an embedded
<iframe>(such as a YouTube embed) in a reflowable document could overflow horizontally when the viewport was narrower than the iframe's authored width; the iframe is now scaled down to fit the available width while preserving its aspect ratio. - Fixed an issue where
<audio>,<video>,<canvas>and<iframe>elements in reflowable publications were left-aligned in paginated renderers instead of being centered by their container'stext-align(e.g.figure { text-align: center }). - Fixed an issue where an
<audio controls>element in a reflowable publication collapsed to zero size, hiding its controls, when the page was narrower than the control's default width. - Fixed an issue where a
<video>element that set only awidthor only aheightattribute could be rendered with the other dimension as 0. Missing video dimensions are now derived from the video's intrinsic aspect ratio, and videos with no available metadata no longer render at an excessive size in scroll renderers. - Fixed an issue where an image in a reflowable publication was resized when the publication's CSS combined
box-sizing: border-boxwith a border or padding on the image. - Fixed an issue where reflowable images without explicit
width/heightattributes could stay locked to the narrower pre-margin width and fail to expand to the full content width afterremovePublicationDefinedHorizontalPageMarginsremoved the page margins. - Fixed an issue where enabling
removePublicationDefinedHorizontalPageMarginscould leave content left-aligned and narrower than the available width when a publication used a constrained width with auto margins (e.g.max-widthwithmargin: 0 auto) to center its content. - Fixed an issue where scripts in sandboxed EPUB content could not resolve relative URLs because
Node.baseURIdid not reflect the content document's URL. - Fixed an issue where audio created with the
new Audio()constructor in sandboxed EPUB content failed to load and play. - Fixed an issue where attaching a
SyncMediaPlayerto aReaderViewwith theSYNC_MEDIA_SEEKmethod could navigate the view to the player's position instead of seeking the player to the current reading position. - Fixed an issue where an EPUB content document containing an XML processing instruction, for example
<?target data?>, sometimes failed to render on an Android WebView running Chromium 150 or later, leaving the page blank. - Fixed an issue where
ColibrioAudioPlayerdid not restore its state after callingreload(). - Fixed several issues where
AudioReadingSystemEngine.createAudioPlayer()could crash the application, never return, or leave the audio API unusable so that no later player could be created. Such calls now fail instead. IfColibrioMediaBrowserServiceis declared in a differentandroid:processthan the code using the audio API, the error names both processes. - Fixed an issue where a failed audio playback preparation, such as an invalid audio URI or a missing timeline, could leave
ColibrioAudioPlayerpermanently unresponsive or crash the application.AudioReadingSystemEngine.createAudioPlayer()now returns the newColibrioAudioPlayerException.PreparationFailedin aColibrioResult.Error, andColibrioAudioPlayer.reload()throws aColibrioException. Exhaustivewhenexpressions overColibrioAudioPlayerExceptionmust handle the new case, and calls toreload()should handle the exception. - Fixed an issue where calling
AudioReadingSystemEngine.createAudioPlayer(),ColibrioAudioPlayer.reload()orWpAudioPublication.createAudioTimeline()from a background thread could throw, or could make the player deliver its callbacks on that thread from then on. These calls now switch to the main thread. Calling them from another thread is still unsupported and logs an error. - Fixed issues where the media session of a destroyed
ColibrioAudioPlayerstill received notification controls and media buttons, and reported the values of the player created after it. - Fixed issues in the
ColibrioAudioPlayerlifecycle: destroying a player could leave playback and its position updates running until the playback service itself was destroyed, and listeners added to or removed from a player or its media session whilereload()was in progress were silently ignored. - Fixed an issue where, when using
MediaSessionTimelineMode.Sections,ColibrioAudioPlayer.mediaSession.activeTimelineSectionreportednulluntil playback first crossed into a new section, and could report an outdated section, or the first section, duringreload(). It now always reports the section at the current playback position. - Fixed an issue where
OnMediaPlayerEventListenerbriefly received a position at the start of the timeline duringColibrioAudioPlayer.reload(), andapproximateElapsedTimeMsreturned 0 until playback was back at the saved position. - Fixed issues with the media session notification when using
MediaSessionTimelineMode.Sections. The section skip controls and the seek bar could seek to the start of the publication instead of the current section. This happened before playback had reported a position, afterreload(), and after changing the sections withColibrioAudioPlayer.mediaSession.setMediaSessionTimelineMode(). The seek bar also showed a position and a duration of zero once playback reached the exact end of the timeline. - Fixed an issue where
ReadingSystemEngine.createSyncMediaPlayer(ColibrioAudioPlayer)accepted a destroyed or reloading audio player and returned aSyncMediaPlayerwhose commands silently did nothing. Such calls now fail. - Fixed an issue where
ReadingSystemEngine.createSyncMediaPlayer(ColibrioAudioPlayer)silently replaced the existingSyncMediaPlayerwhen the audio player was already driven by aSyncMediaPlayercreated by the same engine. It now fails with the newColibrioPlayerAlreadySyncedException. CalldestroySyncMediaPlayer()on the existing player first. - Fixed issues where a failed
SyncMediaPlayercommand could freeze the reported playback position or leave a playback range that could never be cleared, and wheresetPlaybackRange()threw on failure instead of returning the documentedColibrioResult.Error. - Fixed issues where
WpAudioPublication.createAudioTimeline()could stall the UI while an audiobook loaded, and where cancelling the call from another thread could throw an uncatchable exception. - Fixed an issue where retrying
ReaderPublication.createTtsSyncMediaTimeline()with the sameTtsSynthesizerinstance always failed once a previous attempt had failed. Ownership ofTtsSyncMediaTimelineConfiguration.ttsSynthesizernow returns to you when the call fails or is cancelled: either pass the synthesizer to anothercreateTtsSyncMediaTimeline()call or callTtsSynthesizer.destroy()yourself, as the reading system no longer destroys it. - Fixed issues where pausing TTS playback with
ColibrioTtsSynthesizerand resuming could continue at the wrong position, either at the start of the next segment or ahead of what had already been spoken, and where the word boundary positions reported for synchronized highlighting could drift ahead of the spoken text, especially in long segments. - Fixed an issue where
ColibrioTtsSynthesizercould crash the application on the nextplay()call, or silently skip the rest of the segment, when the device's speech engine reported a word boundary outside the text it was given. - Fixed issues where TTS playback with
ColibrioTtsSynthesizercould stall permanently, never reporting the segment as finished. This included segments at least as long as the speech engine's maximum input length on Android 7, 8 and 9. - Fixed an issue where an error from the device's speech engine left
ColibrioTtsSynthesizerre-speaking the failed text forever. Playback now reports the error once and can be resumed from the next segment. - Fixed an issue where adding or removing a listener from inside a listener callback could throw a
ConcurrentModificationExceptionor skip other listeners. This is now supported; see the API documentation for the ordering. - Fixed an issue where cancelling a coroutine while it awaited one of the framework's
suspendmethods, including the overloads returningColibrioResult, returned the cancellation as aColibrioResult.Errorinstead of propagating theCancellationExceptionto your caller. If you relied on the error result to detect a cancelled call, catch the exception instead. - Fixed an issue where cancelling
ReadingSystemEngine.createSyncMediaPlayer(ColibrioAudioPlayer)while the call was in progress could leak theSyncMediaPlayerthe engine had already created. It is now destroyed before the cancellation propagates. - Fixed an issue where framework calls that were still in progress when
ColibrioReadingSystemView.destroy()was called, or when the WebView renderer process crashed, never completed. They now fail withBridgeDestroyedException. - Fixed an issue where
ColibrioException.stackcould hold a placeholder instead of the stack trace. - Fixed an issue where the
compareTooperator forSyncMediaTimelinePositionData(com.colibrio.readingsystem.utils.compareTo) was missing from the release build of the framework, so code that compared two positions with<,>orcompareTo()did not compile.
4.7.1 2026-04-10
New features
- Introduced explicit focus targeting for
ReaderView.focusOnReadingPosition. You can now select the nearest element, character, word, or sentence, significantly improving precision for accessibility and reading-position workflows.
Bugfixes
- Fixed an issue that could cause
SearchResultItemIterator.takeRemaining()to fail on a large set of search results. - Fixed an issue that could cause publication content with
position: absoluteto overflow in paginated renderers without being able to scroll the content. - Resolved an issue where
:nth-pseudo-class selectors using An+B syntax like:nth-child(2n+1)sometimes were not preserved correctly. - Fixed several issues where selecting text in PDF documents would fail or behave unexpectedly.
4.7.0 2026-04-10
In this version we accidentally bumped the AGP (Android Gradle Plugin) version.
Please use version 4.7.1 instead.
4.6.3 2026-01-23
Bugfixes
- Fixed an issue where calling
ReaderView.goTotwice in quick succession (causing the first call to be aborted) could leave pages stuck in a "Loading" state or cause rendering glitches. - Fixed an issue where nested CSS
@importdeclarations used the wrong base URL. Relative URLs inside imported CSS files located in a different directory than the parent CSS file now resolve correctly. - Fixed an issue causing EPUBs with MathML to sometimes fail rendering on Chrome 108 and earlier.
Improvements
- Removed global flags from consumer ProGuard rules that caused gradle warnings.
4.6.2 2025-11-25
Bugfixes
- Fixed an issue where native audio player sometimes did not respond correctly to "Next" and "Previous" controls on headphones and other external devices.
- Fixed an issue with parsing W3C Audiobooks Publication Manifest.
- Fixed an issue with pinch-zooming in PDFs containing many links. Previously, if one finger was on a link, pinch-zooming failed.
Improvements
- Added safeguards when adding listeners to avoid adding the same listener more than once.
4.6.0 2025-10-07
New features
- Added
ReaderView.addOnRendererScrollHeightChangedEventListener(listener: OnRendererScrollHeightChangedEventListener)andReaderView.removeOnRendererScrollHeightChangedEventListener(listener: OnRendererScrollHeightChangedEventListener)to manage listeners notified when a scrolling renderer's scrollable height changes. - Added the option
EpubContentProcessingOptions.addTabIndexToMediaElements. When set to true,tabindex="0"is added to non-interactive media elements (e.g., video, audio, img). This improves accessibility for screen reader and keyboard users by enabling focus and interaction with media elements.
Bugfixes
- Fixed a memory leak that could occur when using
ColibrioTtsSynthesizerto play a TTSSyncMediaTimeline. - Fixed an issue where certain elements were given
tabindex="-1"when callingReaderView.focusOnReadingPosition, preventing focus via standard keyboard navigation (e.g., Tab). - Fixed an issue where publication content that changed overflow-x styling could break reflow due to browsers implicitly setting overflow-y to auto.
- Fixed an issue where pointer events on a
ReaderViewAnnotationrendered inRenderer.SingleDocumentScrollreported an incorrectevent.target.frameworkComponent. - Fixed an issue where
TtsUtteranceData.nodeDatareferenced the parent element for elements with alt/alttext (e.g.,<math>with alttext), instead of the element itself.
4.5.0 2025-08-29
New features
Added two new options,
injectionPointStartUnprocessedandinjectionPointEndUnprocessed, toEpubReaderPublicationCustomCssOptions.CSS injected using these options is not affected by
publicationStyleOptions. This is useful for cases such as customizing the::selectionpseudo-element without being overridden by the palette option, for example.
Bugfixes
- Fixed an issue where
ReaderViewdid not stay synchronized withSyncMediaPlayerwhen seeking to the end of the timeline. - Fixed an issue where a loader briefly disappeared during navigation.
- Fixed an issue where
SyncMediaPlayer.readerViewSynchronizationWaitBehaviorset toWAIT_OUTSIDE_ADJACENTdid not always allow playback when the timeline position was within the previous or next spread. - Fixed an issue where
OnSelectionChangedListener.onSelectionChanged()was not invoked when selecting content in the first reader document. - Fixed an issue where
ReaderView.focusOnReadingPosition()sometimes focused on the oldreadingPositionwhen called right afterReaderView.goTo(). - Fixed an issue where reflowing EPUB content into pages could result in an error when elements with
position: absolutewere nested inside inline elements withposition: relative.
4.4.2 2025-07-25
Bugfixes
- Fixed an issue that prevented EPUB files larger than 4.2 GB from loading correctly.
- Fixed an issue where audio playback might stop before reaching the end of the timeline when using
ColibrioAudioPlayer. - Playback is now properly paused when temporarily interrupted by the system (e.g., when audio focus is temporarily lost with "can duck").
4.4.1 2025-07-04
Bugfixes
- Fixed a bug where performing a
goTo()while using theRenderer.SingleDocumentScrollcould result in areadingPositionthat differed from the one passed togoTo(). - Fixed an issue where iframes pointing to
httporhttpsURLs would cause the entire content document to become sandboxed, even whenEpubReaderPublicationOptions.remoteResourcesNonScriptedDocumentsOptions.policyTypewas set toALLOW_ALLorWHITELIST. This prevented embedded YouTube iframes from functioning correctly, for example.
4.4.0 2025-06-12
New features
- Added new options under
ReaderViewOptions.pageContainerOptions.titleOptionsthat can be used to configure thetitleattribute on page container<iframe>elements.
Bugfixes
- Fixed an issue where the CSS at-rules
@container,@layer, and@scopewere not processed correctly. - Fixed an issue where
ContentBlockTarget.getCharLength()could return the wrong length. - Fixed an issue where element vertical padding sometimes caused vertical overflow scroll in reflowable EPUBs.
- Fixed an issue where pages ending with
<br>elements sometimes caused vertical overflow scroll in reflowable EPUBs. - Fixed issue when using the native
ColibrioAudioPlayertogether with theSyncMediaPlayerfor EPUB Media Overlays: in some cases, audio did not pause precisely at the end of the visible range whenSyncMediaPlayer.readerViewSynchronizationWaitBehaviorwas set toWAIT_OUTSIDE_VISIBLE. - Fixed an issue where
SyncMediaPlayer.waitingForMediaObjectRenderersandSyncMediaPlayer.waitingForViewSynchronizationsometimes had wrong values.
4.3.0 2025-05-08
New features
- Added support for dividing
AudioTimelines into sections when using the nativeColibrioAudioPlayerfor playback. This allows you to customize how Audio playback progress is shown in your app and in the media session notification. You can for example show progress per chapter instead of the whole publication. SeeMediaSessionTimelineModefor more information. - Added the new option
activeElementStylesOverridetoEpubReaderPublicationOptions.mediaOverlayOptions. It allows you to override the CSS for the active element when playing EPUB MediaOverlays, without being affected bypublicationStyleOptionssuch aspaletteOptions. - Added a new option
PdfReaderPublicationOptions.addColibrioSpecificFragmentSelectorData. Setting it to true will add a new Colibrio specific parameter,colibrio-pagerects, to theLocator's selector. This allows the selector to represent multiple rectangles. This is useful when adding text selection highlights for example.
Deprecations
The following methods have been deprecated. They will be removed in the next major version of the framework.
- Deprecated
ColibrioAudioPlayer.setMediaSessionMetadata. UseColibrioAudioPlayer.mediaSession.metadatainstead. - Deprecated
ColibrioAudioPlayer.setMediaCommands. UseColibrioAudioPlayer.mediaSession.mediaCommandsinstead.
Bugfixes
- Fixed an issue where
PublicationStyleOptions.fontSizeScaleFactorhad no effect in some reflowable EPUBs. - Fixed an issue where
EpubReflowPluginOptions.customForcedPageBreakonly worked if all its options was specified. - Fixed an issue where the playback cache was not cleaned up when using the native
ColibrioAudioPlayer.
Improvements
- Setting the option
PublicationStyleOptions.removePublicationDefinedHorizontalPageMarginsto true, will now apply margin removal on more publications where it previously bailed out. - Adds
tabindex="0"to overflow scroll elements so that they can be scrolled with the keyboard as required by WCAG. - Added
tabindex="0"to<iframe>elements to allow keyboard navigation to focusable elements inside the iframe in Safari. - Added the new property
mediaSession: ColibrioMediaSessionto theColibrioAudioPlayer. It allows you to configure which playback controls are available and how metadata information is presented in the media session notification.
4.2.1 2025-04-07
Bugfixes
- Fixed an issue introduced in version 4.2.0 where
PublicationStyleOptions.fontSizeScaleFactorhad no effect in some EPUBs.
4.2.0 2025-03-26
New features
- Added a new method
setContentSelectiontoVisiblePage. - Added new options,
typographyResetOptions.removePublicationDefinedFontSizesandtypographyResetOptions.removePublicationDefinedLineHeightstoPublicationStyleOptions.
Bugfixes
- Fixed an issue where paragraph text indentation was sometimes applied on fragmented paragraphs.
- Fixed an issue where page content with negative margins could appear outside of the page if
PublicationStyleOptions.removePublicationDefinedHorizontalPageMarginswas true.
Improvements
- Fixed the event order when navigating in the
Renderer.SingleDocumentScrollto make it more consistent with how the other renderers work. The listener methodOnReadingPositionChangedListener.onReadingPositionChangedwill be called beforeOnNavigationStateChangedListener.onNavigationEndedis called.
4.1.0 2025-02-28
New features
- Added a new option
publicationStyleOptions.removePublicationDefinedHorizontalPageMargins. When enabled, it does a best effort try to remove page margins defined in the publication CSS. - Added a new method,
ReaderPublicationNavigation.getNavigationItemById.
Bugfixes
- Fixed a bug where
OnSelectionChangedListener.onSelectionChangedwasn't called ifReaderView.scriptedContentDocumentEventHandlersEnabledhad been set to false. - Fixed a bug where CSS background images did not load if the selector for the style rule contained
:beforeor:afterpseudo selectors. - Fixed a bug where
VisiblePage.boundingClientRectdid not update whenactiveTransformchanged, such as while zooming and panning. - Fixed a rare crash that could occur when assigning an empty list to
ReaderView.readerDocuments.
Improvements
- Improved building TTS
SyncMediaTimelineperformance.
4.0.0 2025-02-04
NOTE
These release notes describe the changes since version 3.12.0
Overview
We are excited to announce native audiobook support.
This version of the framework enables you to load EPUBs with Media Overlays in audio-only mode, with the flexibility to synchronize with the ReaderView at any time. It also supports playback of W3C Audiobooks, whether zipped as an LPF package or "un-packaged" for streaming over HTTP. Additional format support will be added in future releases.
Check out the AudioReadingSystemEngine API documentation for how to configure your app to use the new audio playback capability. Sample applications will be available soon.
Major new features
- New
AudioReadingSystemEngineandColibrioAudioPlayerclass that handles playback of audio using the ExoPlayer library. - Support for audio playback of W3C Audiobooks and EPUB with Media Overlays.
- Audio playback is managed in a service, allowing it to continue in the background.
- Full integration with Android's MediaSession features. Provides playback control from any connected device that supports MediaSession controls, such as Android Auto, Wear OS and more.
- The Content Block API is now available. This new API provides programmatic access to a simplified representation of a publication's structure, such as the HTML elements in an EPUB.
- Document Sectioning for reflowable EPUB content-documents. When enabled, reflowable documents can be split into sections prior to reflowing. This can greatly increase performance for publications with long content documents. You can control where and how often these breaks occur using options of course. We recommend that you enable Document Sectioning as a default.
- New mitigation options for horizontally overflowing table and math elements let you wrap these elements in scroll containers. Previously these would have been shrunken to fit the page width, affecting legibility and accessibility. Note that we have changed the default behaviour to scroll instead of shrink. Read more in the Breaking Changes section below.
New features
- Added the new option
EpubContentProcessingOptions.horizontalOverflowMitigationMinFontSize. When a word is too wide to fit on the page, it can either be broken into multiple lines or scaled down. This option sets the minimum font size to scale down to. If scaling is not enough to fit the word, the styleoverflow-wrap: break-word;will also be applied, allowing the word to be broken up over more than one line. - Added the new option
EpubContentProcessingOptions.horizontalOverflowMathMLStrategycontrolling if<math>elements too wide to fit in the page should be scaled down to fit, or horizontally scrollable. - Added the new option
EpubContentProcessingOptions.horizontalOverflowTableStrategycontrolling if table elements too wide to fit in the page should be scaled down to fit, or horizontally scrollable. - Added the new option
EpubContentProcessingOptions.verticalOverflowMitigationStrategycontrolling if a reflowed page should be allowed to vertically scroll if all content does not fit. - Added the new option
EpubReflowOptions.removeBottomMarginsOnFragmentedElementscontrolling if the bottom margin on fragmented elements should be removed or kept. - Added support for iframes added by scripts in content documents.
- Added a new option
TextSearchQueryOptions.ignoreDiacritics, allowing searches to match text with or without diacritics. - Added
PdfReaderPublicationOptions.textLayerOptions.customCss, which allows injecting custom CSS into the text layer of PDF pages. - Added two new options:
EpubReaderPublicationOptions.allowAudioElementAutoplayandEpubReaderPublicationOptions.allowVideoElementAutoplay. - Added
ReaderViewAnnotationLayer.refreshAnnotations(), allowing annotations to be refreshed programmatically. - Introduced
OnClipboardEventListener, with theonCopyevent firing when a user copies content from a publication to their clipboard. UseReaderView.addOnClipboardEventListenerto receive this event. - Added
ReaderDocument.fetchLocatorForEntireDocument(). - The following options in
ReaderViewAnnotationOptionsnow support space-separated class names:containerClassNamepositionClassNamerangeClassName
- Added the new option
PublicationStyleOptions.wordSpacing, allowing modification of word spacing in reflowable EPUB documents. - Added the new option
PublicationStyleOptions.letterSpacing, allowing modification of letter spacing in reflowable EPUB documents. Renderer.SpreadSwipenow supports switching from two-page spreads to a single centered page when the EPUB author has configured the document withrendition:page-spread-centerorspread-none.- Added the new option
ReaderViewOptions.contentDisplayAreaOptions, controlling how the available display area is utilized by publication content. - Added
ContentPositionTimeline.fetchTimelinePositionsandContentPositionTimeline.fetchTimelinePositionsForNavigationItemswhich can be used to fetch multiple positions in one call. - You can now manage
ReaderPublication's storage state, such aslocalStorageandsessionStoragefor scripted EPUB content documents. UseEpubReaderPublication.readerPublicationStorage.getStorageArea()to get aReaderPublicationStorageAreathat can be used for adding, updating and removing items from storages.
Known issues
The ColibrioNotificationManager posts media notifications. These notifications are exempt from the requirement (introduced in Android 13) to get the user's permission. If you do not declare the android.permission.POST_NOTIFICATIONS permission in your app and get this lint error:
Error: When targeting Android 13 or higher,
posting a permission requires holding the POST_NOTIFICATIONS permission
(usage from com.colibrio.readingsystem.audio.service.ColibrioNotificationManager)
[NotificationPermission]then add this rule to your lint configuration file:
xml
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="NotificationPermission">
<ignore regexp="com.colibrio.readingsystem.audio.service.ColibrioNotificationManager" />
</issue>
</lint>Breaking changes
- Minimum supported Android WebView version is now Chrome 62.
- Minimum supported Android version is now 7 (Android SDK 24).
- Upgraded Android Gradle Plugin to 8.3.2, and Kotlin Gradle Plugin to 1.9.25.
ResourceProviderinterface changes:- Introduced new
baseUrlproperty. fetchandfetchMetadatanow takes aURLinstead of a path.- Error handling updated to distinguish between recoverable and non-recoverable errors.
- Introduced new
ReaderView.visiblePagesnow returnsList<VisiblePage>instead ofList<VisiblePageData>.SyncMediaPlayer.approximateElapsedTimehas been renamed toSyncMediaPlayer.approximateElapsedTimeMs.ContentLocation.fetchNavigationItemReferencesonSuccesscallback is now called withFetchNavigationItemReferencesResultinstead ofFetchNavigationItemReferencesResultData. Properties inFetchNavigationItemReferencesResultreturnList<ReaderPublicationNavigationItemReference>instead ofList<ReaderPublicationNavigationItemReferenceData>.- The following suspend functions now return a
ColibrioResultobject:ContentLocationContentResolver.fetchTextContentContentLocationContentResolver.fetchTextContentAfterContentLocationContentResolver.fetchTextContentBefore
- Removed deprecated property
ColibrioTtsSynthesizer.onBeforeSpeak. - The new options
EpubReflowOptions.removeBottomMarginsOnFragmentedElementsandEpubReflowOptions.removeTopMarginsOnFragmentedElementsdefault to true. This may cause content to appear closer to the top and bottom edge of the page compared to previous Colibrio Reader Framework versions. Set these options to false to keep the old behavior. - The new options
EpubContentProcessingOptions.horizontalOverflowMathMLStrategyandEpubContentProcessingOptions.horizontalOverflowTableStrategydefault toEpubContentOverflowStrategy.SCROLLin order to improve legibility and accessibility. This will introduce horizontal scrolling within the page when the table or math elements do not fit horizontally. Set this option toEpubContentOverflowStrategy.SCALEto keep the old behavior. - The new option
EpubContentProcessingOptions.horizontalOverflowMitigationMinFontSizedefaults to 16 pixels in order to improve accessibility. This may cause long words be broken up over more than one line. Set this option to 0 to keep the old behavior. - The new option
EpubContentProcessingOptions.verticalOverflowMitigationStrategydefaults toEpubContentOverflowStrategy.SCROLLin order to improve accessibility. This will introduce vertical scrolling within a page if not all content fits. Set this option toEpubContentOverflowStrategy.SCALEto keep the old behavior. - In
ReaderViewOptions,forcePageAspectRatioanddefaultPageAspectRatiohave been removed. UseReaderViewOptions.contentDisplayAreaOptionsinstead. - Subtypes of the sealed classes
EpubPageCountEstimationAlgorithmandEpubDocumentSectioningAlgorithmare now declared asdata class, ordata objectinstead ofclass.
Deprecations
The following methods and properties have been deprecated. They will continue to work in all 4.x.x versions of the framework, but will be removed in the next major version update.
ReaderPublicationNavigationDatais deprecated. Replaced byReaderPublicationNavigation.ReaderPublicationNavigationCollectionDatais deprecated. Replaced byReaderPublicationNavigationCollection.ReaderPublicationNavigationItemDatais deprecated. Replaced byReaderPublicationNavigationItem.locatorinReaderPublicationNavigationItemis deprecated. Instead, use theReaderPublicationNavigationItemdirectly with methods that support locator.VisiblePageDatais deprecated. Replaced byVisiblePage.ReaderView.fetchRectsForVisibleContentis deprecated. Replaced byVisiblePage.fetchRectsForVisibleContent.- Setter for
ReaderView.syncMediaPlayeris deprecated. UsesetSyncMediaPlayer(SyncMediaPlayer, SyncMediaReaderViewSynchronizationMethod)instead. SyncMediaPlayer.playingis deprecated. Use!paused && readyinstead.SyncMediaPlayer.approximateElapsedTimeis deprecated. Replaced bySyncMediaPlayer.approximateElapsedTimeMs.FetchNavigationItemReferencesResultDatais deprecated. Replaced byFetchNavigationItemReferencesResult.ReaderPublicationNavigationItemReferenceDatais deprecated. Replaced byReaderPublicationNavigationItemReference.- The renderer option
ignoreAspectRatiohas been deprecated. It will continue to work until its removal in version 5.0.0 of the framework. Please useReaderViewOptions.contentDisplayAreaOptionswith type set toFILLinstead. ReadingSystemEngine.createZipResourceProvideris now deprecated. UseZipResourceProvider.create(dataSource: RandomAccessDataSource, zipResourceProviderOptions: ZipResourceProviderOptions)instead.ZipResourceProvider.create(dataSource: RandomAccessDataSource, serializedZipArchiveInformation: ByteArray, chunkCacheSize: Int)is now deprecated. UseZipResourceProvider.create(dataSource: RandomAccessDataSource, zipResourceProviderOptions: ZipResourceProviderOptions)instead.
Bugfixes
- Fixed an issue that sometimes caused
OnVisibleContentChangedListener.onVisiblePagesChangedto not be called. - Fixed an issue where
publicationHashSignaturewas calculated differently compared to the Web framework. - Improvements and bugfixes when applying page-breaks inside tables.
- Fixed an issue where the reflow engine would fail to properly measure elements that had a transform applied to them, causing inaccurate page-breaks.
- Fixed an issue where page-breaks were not applied correctly for pre-formatted text, like code examples.
- Fixed an issue where reflow engine did not calculate margin-collapse rules correctly.
- Fixed Reflow Engine issues that in some cases caused page breaks to be applied at wrong positions.
- Annotation's rendered positions now updates correctly inside scrolling containers.
- Fixed issues that could cause images to get incorrect aspect ratios.
- Fixed a bug where reading position might not be accurate when navigating to an annotation spanning two pages.
- Fixed a bug where the "keydown" engine event's
modifiers.shiftwas false, even if shift was pressed. - Fixed an issue where calling
ReaderView.focusOnReadingPosition()sometimes had no effect. - Fixed an issue where TTS playback could not be resumed after being paused due to an interruption from the system.
ContentLocation.contentResolvermethods now works correctly for ranges spanning multiple EPUB documents.ContentLocation.fetchNavigationItemReferencesnow functions correctly for locator ranges spanning multiple EPUB documents.- Fixed an issue where EPUBs missing the
unique-identifierin the OPF file could not be loaded. - Fixed an issue where
ReaderView.visiblePagessometimes did not update correctly.
Improvements
Renderer.SpreadSwipeandRenderer.SinglePageSwipeare now able to use all available display area when displaying publications containing fixed-layout documents with varying dimensions, such as mixed portrait and landscape documents.ContentPositionTimelinemethods are now many times faster.- Updated PDF.js to version 4.8.73.
4.0.0 (Changes since 4.0.0-rc.5) 2025-02-04
New features
- Added
ContentPositionTimeline.fetchTimelinePositionsandContentPositionTimeline.fetchTimelinePositionsForNavigationItems. - You can now manage
ReaderPublication's storage state, such aslocalStorageandsessionStoragefor scripted EPUB content documents. UseEpubReaderPublication.readerPublicationStorage.getStorageArea()to get aReaderPublicationStorageAreathat can be used for adding, updating and removing items from storages. - Loading audiobooks with a
ZipResourceProviderdoes not require theReadingSystemEngineanymore. You can now create aZipResourceProviderusingZipResourceProvider.create(dataSource: RandomAccessDataSource, zipResourceProviderOptions: ZipResourceProviderOptions).
Breaking changes
Minimum supported Android WebView version is now Chrome 62.
Minimum supported Android version is now 7 (Android SDK 24).
Changed the file you need to reference in your
lint.xmlfile to ignore the missing notification lint error. You need to replaceColibrioMediaBrowserServicewithColibrioNotificationManager. The new rule looks like this:xml<?xml version="1.0" encoding="UTF-8"?> <lint> <issue id="NotificationPermission"> <ignore regexp="com.colibrio.readingsystem.audio.service.ColibrioNotificationManager" /> </issue> </lint>
Deprecations
ReadingSystemEngine.createZipResourceProvideris now deprecated. UseZipResourceProvider.create(dataSource: RandomAccessDataSource, zipResourceProviderOptions: ZipResourceProviderOptions)instead.ZipResourceProvider.create(dataSource: RandomAccessDataSource, serializedZipArchiveInformation: ByteArray, chunkCacheSize: Int)is now deprecated. UseZipResourceProvider.create(dataSource: RandomAccessDataSource, zipResourceProviderOptions: ZipResourceProviderOptions)instead.
Bugfixes
- Fixed issues where synchronization didn't work in some books.
- Fixed issue with maintaining audio focus properly.
- Fixed an issue where EPUBs missing the
unique-identifierin the OPF file could not be loaded. - Fixed issue with updating media session metadata and commands.
- Fixed an issue where
ReaderView.visiblePagessometimes did not update correctly.
Improvements
ContentPositionTimelinemethods are now many times faster.- Updated PDF.js to version 4.8.73.
4.0.0-rc.5 2024-11-19
Breaking changes
- In
ReaderViewOptions,forcePageAspectRatioanddefaultPageAspectRatiohave been removed. UseReaderViewOptions.contentDisplayAreaOptionsinstead. ContentLocation.fetchContentBlockTargetsreturns a list ofContentBlockTargetnow instead of a list ofContentBlockTargetData.ContentBlockTargetallows you direct access to the targetContentBlock.- Subtypes of the sealed classes
EpubPageCountEstimationAlgorithmandEpubDocumentSectioningAlgorithmare now declared asdata class, ordata objectinstead ofclass.
Deprecations
- The renderer option
ignoreAspectRatiohas been deprecated. It will continue to work until its removal in version 5.0.0 of the framework. Please useReaderViewOptions.contentDisplayAreaOptionswith type set toFILLinstead.
New features
- Added the new option
PublicationStyleOptions.wordSpacing, allowing modification of word spacing in reflowable EPUB documents. - Added the new option
PublicationStyleOptions.letterSpacing, allowing modification of letter spacing in reflowable EPUB documents. Renderer.SpreadSwipenow supports switching from two-page spreads to a single centered page when the EPUB author has configured the document withrendition:page-spread-centerorspread-none.- Added the new option
ReaderViewOptions.contentDisplayAreaOptions, controlling how the available display area is utilized by publication content.
Improvements
Renderer.SpreadSwipeandRenderer.SinglePageSwipeare now able to use all available display area when displaying publications containing fixed-layout documents with varying dimensions, such as mixed portrait and landscape documents.
Bugfixes
ContentLocation.fetchNavigationItemReferencesnow functions correctly for locator ranges spanning multiple EPUB documents.- Fixed a memory leak issue in the Web framework running inside the WebView.
4.0.0-rc.4 2024-10-17
New features
- Added
ReaderDocument.fetchLocatorForEntireDocument(). - The following options in
ReaderViewAnnotationOptionsnow support space-separated class names:containerClassNamepositionClassNamerangeClassName
Bugfixes
- Fixed an issue introduced in
4.0.0-rc.2where severalContentLocationmethods returned incorrect results. - Fixed an issue where TTS playback could not be resumed after being paused due to an interruption from the system.
ContentLocation.contentResolvermethods now works correctly for ranges spanning multiple EPUB documents.
4.0.0-rc.3 2024-10-11
Major new features
- The Content Block API is now available. This new API provides programmatic access to a simplified representation of a publication's structure, such as the HTML elements in an EPUB. This flexible API is used internally for features like
ReaderDocumentSearchandTtsSyncMediaTimeline.
Breaking changes
- Upgraded Android Gradle Plugin to 8.3.2, and Kotlin Gradle Plugin to 1.9.25.
New features
- Added a new option
TextSearchQueryOptions.ignoreDiacritics, allowing searches to match text with or without diacritics. - Added
PdfReaderPublicationOptions.textLayerOptions.customCss, which allows injecting custom CSS into the text layer of PDF pages. - Added two new options:
EpubReaderPublicationOptions.allowAudioElementAutoplayandEpubReaderPublicationOptions.allowVideoElementAutoplay. - Added
ReaderViewAnnotationLayer.refreshAnnotations(), allowing annotations to be refreshed programmatically. - Added the new option
ColibrioMediaCommands.seekBarEnabledto enable or disable seeking in the media notification. - Introduced
OnClipboardEventListener, with theonCopyevent firing when a user copies content from a publication to their clipboard. UseReaderView.addOnClipboardEventListenerto receive this event.
Bugfixes
- Fixed a bug where the "keydown" engine event's
modifiers.shiftwas false, even if shift was pressed. - Fixed an issue where calling
ReaderView.focusOnReadingPosition()sometimes had no effect.
4.0.0-rc.2 2024-08-29
NOTE
These release notes describe the changes since version 3.11.0
Overview
We are excited to announce native audiobook support.
This version of the framework enables you to load EPUBs with Media Overlays in audio-only mode, with the flexibility to synchronize with the ReaderView at any time. It also supports playback of W3C Audiobooks, whether zipped as an LPF package or "un-packaged" for streaming over HTTP. Additional format support will be added in future releases.
Check out the AudioReadingSystemEngine API documentation for how to configure your app to use the new audio playback capability. Sample applications will be available soon.
Major new features
- New
AudioReadingSystemEngineandColibrioAudioPlayerclass that handles playback of audio using the ExoPlayer library. - Support for audio playback of W3C Audiobooks and EPUB with Media Overlays.
- Audio playback is managed in a service, allowing it to continue in the background.
- Full integration with Android's MediaSession features. Provides playback control from any connected device that supports MediaSession controls, such as Android Auto, Wear OS and more.
- Document Sectioning for reflowable EPUB content-documents. When enabled, reflowable documents can be split into sections prior to reflowing. This can greatly increase performance for publications with long content documents. You can control where and how often these breaks occur using options of course. We recommend that you enable Document Sectioning as a default.
- New mitigation options for horizontally overflowing table and math elements let you wrap these elements in scroll containers. Previously these would have been shrunken to fit the page width, affecting legibility and accessibility. Note that we have changed the default behaviour to scroll instead of shrink. Read more in the Breaking Changes section below.
New features
- Added the new option
EpubContentProcessingOptions.horizontalOverflowMitigationMinFontSize. When a word is too wide to fit on the page, it can either be broken into multiple lines or scaled down. This option sets the minimum font size to scale down to. If scaling is not enough to fit the word, the styleoverflow-wrap: break-word;will also be applied, allowing the word to be broken up over more than one line. - Added the new option
EpubContentProcessingOptions.horizontalOverflowMathMLStrategycontrolling if<math>elements too wide to fit in the page should be scaled down to fit, or horizontally scrollable. - Added the new option
EpubContentProcessingOptions.horizontalOverflowTableStrategycontrolling if table elements too wide to fit in the page should be scaled down to fit, or horizontally scrollable. - Added the new option
EpubContentProcessingOptions.verticalOverflowMitigationStrategycontrolling if a reflowed page should be allowed to vertically scroll if all content does not fit. - Added the new option
EpubReflowOptions.removeBottomMarginsOnFragmentedElementscontrolling if the bottom margin on fragmented elements should be removed or kept. - Added support for iframes added by scripts in content documents.
Known issues
The ColibrioMediaBrowserService posts media notifications. These notifications are exempt from the requirement (introduced in Android 13) to get the user's permission. If you do not declare the android.permission.POST_NOTIFICATIONS permission in your app and get this lint error:
Error: When targeting Android 13 or higher,
posting a permission requires holding the POST_NOTIFICATIONS permission
(usage from com.colibrio.readingsystem.audio.service.ColibrioMediaBrowserService)
[NotificationPermission]then add this rule to your lint configuration file:
xml
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="NotificationPermission">
<ignore regexp="com.colibrio.readingsystem.audio.service.ColibrioMediaBrowserService" />
</issue>
</lint>Breaking changes
- Changed minimum Android version to 6.
- Updated Kotlin Gradle Plugin to 1.7.22 and Android Gradle Plugin to 7.4.2.
ResourceProviderinterface changes:- Introduced new
baseUrlproperty. fetchandfetchMetadatanow takes aURLinstead of a path.- Error handling updated to distinguish between recoverable and non-recoverable errors.
- Introduced new
ReaderView.visiblePagesnow returnsList<VisiblePage>instead ofList<VisiblePageData>.SyncMediaPlayer.approximateElapsedTimehas been renamed toSyncMediaPlayer.approximateElapsedTimeMs.ContentLocation.fetchNavigationItemReferencesonSuccesscallback is now called withFetchNavigationItemReferencesResultinstead ofFetchNavigationItemReferencesResultData. Properties inFetchNavigationItemReferencesResultreturnList<ReaderPublicationNavigationItemReference>instead ofList<ReaderPublicationNavigationItemReferenceData>.- The following suspend functions now return a
ColibrioResultobject:ContentLocationContentResolver.fetchTextContentContentLocationContentResolver.fetchTextContentAfterContentLocationContentResolver.fetchTextContentBefore
- Removed deprecated property
ColibrioTtsSynthesizer.onBeforeSpeak. - The new options
EpubReflowOptions.removeBottomMarginsOnFragmentedElementsandEpubReflowOptions.removeTopMarginsOnFragmentedElementsdefault to true. This may cause content to appear closer to the top and bottom edge of the page compared to previous Colibrio Reader Framework versions. Set these options to false to keep the old behavior. - The new options
EpubContentProcessingOptions.horizontalOverflowMathMLStrategyandEpubContentProcessingOptions.horizontalOverflowTableStrategydefault toEpubContentOverflowStrategy.SCROLLin order to improve legibility and accessibility. This will introduce horizontal scrolling within the page when the table or math elements do not fit horizontally. Set this option toEpubContentOverflowStrategy.SCALEto keep the old behavior. - The new option
EpubContentProcessingOptions.horizontalOverflowMitigationMinFontSizedefaults to 16 pixels in order to improve accessibility. This may cause long words be broken up over more than one line. Set this option to 0 to keep the old behavior. - The new option
EpubContentProcessingOptions.verticalOverflowMitigationStrategydefaults toEpubContentOverflowStrategy.SCROLLin order to improve accessibility. This will introduce vertical scrolling within a page if not all content fits. Set this option toEpubContentOverflowStrategy.SCALEto keep the old behavior.
Deprecations
The following methods and properties have been deprecated. They will continue to work in all 4.x.x versions of the framework, but will be removed in the next major version update.
ReaderPublicationNavigationDatais deprecated. Replaced byReaderPublicationNavigation.ReaderPublicationNavigationCollectionDatais deprecated. Replaced byReaderPublicationNavigationCollection.ReaderPublicationNavigationItemDatais deprecated. Replaced byReaderPublicationNavigationItem.locatorinReaderPublicationNavigationItemis deprecated. Instead, use theReaderPublicationNavigationItemdirectly with methods that support locator.VisiblePageDatais deprecated. Replaced byVisiblePage.ReaderView.fetchRectsForVisibleContentis deprecated. Replaced byVisiblePage.fetchRectsForVisibleContent.- Setter for
ReaderView.syncMediaPlayeris deprecated. UsesetSyncMediaPlayer(SyncMediaPlayer, SyncMediaReaderViewSynchronizationMethod)instead. SyncMediaPlayer.playingis deprecated. Use!paused && readyinstead.SyncMediaPlayer.approximateElapsedTimeis deprecated. Replaced bySyncMediaPlayer.approximateElapsedTimeMs.FetchNavigationItemReferencesResultDatais deprecated. Replaced byFetchNavigationItemReferencesResult.ReaderPublicationNavigationItemReferenceDatais deprecated. Replaced byReaderPublicationNavigationItemReference.
Bugfixes
- Fixed an issue that sometimes caused
OnVisibleContentChangedListener.onVisiblePagesChangedto not be called. - Fixed an issue where
publicationHashSignaturewas calculated differently compared to the Web framework. - Improvements and bugfixes when applying page-breaks inside tables.
- Fixed an issue where the reflow engine would fail to properly measure elements that had a transform applied to them, causing inaccurate page-breaks.
- Fixed an issue where page-breaks were not applied correctly for pre-formatted text, like code examples.
- Fixed an issue where reflow engine did not calculate margin-collapse rules correctly.
- Fixed Reflow Engine issues that in some cases caused page breaks to be applied at wrong positions.
- Annotation's rendered positions now updates correctly inside scrolling containers.
- Fixed issues that could cause images to get incorrect aspect ratios.
- Fixed a bug where reading position might not be accurate when navigating to an annotation spanning two pages.
Changes from 4.0.0-experimental.2
ColibrioMediaServiceis nowAudioReadingSystemEngine.ColibrioMediaSessionMetadata.smallIconResIdis now mandatory. It cannot be set to null.- LPF and EPUB Media Overlay "audio-only" publications are now loaded from the
AudioReadingSystemEngine. - A
SyncMediaPlayerusing theColibrioAudioPlayerfor audio playback can now only be created usingReadingSystemEngine.createSyncMediaPlayer(audioPlayer). - Added
ColibrioAudioPlayer.reloadfunction which allows you to recover from an error state and retry without losing playback position. - Fixed several issues where the playback state was not synced correctly when creating a
SyncMediaPlayerfrom aColibrioAudioPlayerfor synchronization with aReaderView. - Fixed several issues where the playback state was not synced correctly when destroying a
SyncMediaPlayerthat was synchronized with aReaderView. - Fixed an issue where
ColibrioAudioPlayer.approximateElapsedTimeMsdid not update immediately when seeking. - Fixed an issue where
ColibrioAudioPlayer.totalDurationMsreturned 0 for a short amount of time when theColibrioAudioPlayerwas created.