Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPUB appearance: Add 'Use original font' and 'Page width' options, increase zoom limit #132

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/common/components/reader-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const ReaderUI = React.forwardRef((props, ref) => {
// We always read the primaryViewState, but we write both view states
<EPUBAppearancePopup
params={state.primaryViewState.appearance}
enablePageWidth={state.primaryViewState.flowMode !== 'paginated' || state.primaryViewState.spreadMode === 0 }
onChange={props.onChangeEPUBAppearance}
onClose={() => props.onToggleEPUBAppearance({ open: false })}
/>
Expand Down
42 changes: 40 additions & 2 deletions src/common/components/view-popup/epub-appearance-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import IconRevert from '../../../../res/icons/16/revert.svg';
import { FormattedMessage, useIntl } from 'react-intl';
import { DEFAULT_EPUB_APPEARANCE as DEFAULTS } from '../../../dom/epub/defines';

function EPUBAppearancePopup({ params, onChange, onClose }) {
function EPUBAppearancePopup({ params, enablePageWidth, onChange, onClose }) {
const intl = useIntl();

if (!params) {
Expand All @@ -14,7 +14,12 @@ function EPUBAppearancePopup({ params, onChange, onClose }) {
}

function handleChange(event) {
params[event.target.name] = parseFloat(event.target.value);
if (event.target.type === 'checkbox') {
params[event.target.name] = event.target.checked;
}
else {
params[event.target.name] = parseFloat(event.target.value);
}
onChange(params);
}

Expand Down Expand Up @@ -91,6 +96,39 @@ function EPUBAppearancePopup({ params, onChange, onClose }) {
onClick={() => handleRevert('letterSpacing')}
><IconRevert/></button>
</div>

<div className="row">
<label htmlFor="page-width"><FormattedMessage id="pdfReader.epubAppearance.pageWidth"/></label>
<input
type="range"
id="page-width"
name="pageWidth"
value={params.pageWidth}
min="-1"
max="1"
step="1"
onChange={handleChange}
disabled={!enablePageWidth}
/>
<span className="value">{(params.pageWidth + 3) / 4 * 100}%</span>
<button
className={cx('toolbar-button', { hidden: params.pageWidth === DEFAULTS.pageWidth })}
aria-label={intl.formatMessage({ id: 'pdfReader.epubAppearance.pageWidth.revert' })}
onClick={() => handleRevert('pageWidth')}
disabled={!enablePageWidth}
><IconRevert/></button>
</div>

<div className="checkbox-row">
<input
type="checkbox"
id="use-original-font"
name="useOriginalFont"
checked={params.useOriginalFont}
onChange={handleChange}
/>
<label htmlFor="use-original-font"><FormattedMessage id="pdfReader.epubAppearance.useOriginalFont"/></label>
</div>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/common/stylesheets/base/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ input[type="range"] {
0 0.25px 0.25px 0 rgba(0, 0, 0, 0.15);
}

&:active {
&:active:not(:disabled) {
&::-moz-range-thumb {
background: rgba(240, 240, 240, 1);
}
Expand Down
7 changes: 7 additions & 0 deletions src/common/stylesheets/components/_view-popup.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@
}
}

.checkbox-row {
display: flex;
align-items: center;
gap: 4px 8px;
padding-block: 8px;
}

.hidden {
visibility: hidden;
}
Expand Down
2 changes: 1 addition & 1 deletion src/dom/common/dom-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { History } from "../../common/lib/history";
abstract class DOMView<State extends DOMViewState, Data> {
readonly MIN_SCALE = 0.6;

readonly MAX_SCALE = 1.5;
readonly MAX_SCALE = 1.8;

initializedPromise: Promise<void>;

Expand Down
4 changes: 3 additions & 1 deletion src/dom/epub/defines.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EPUBAppearance } from "./epub-view";
import { EPUBAppearance, PageWidth } from "./epub-view";

export const EPUB_LOCATION_BREAK_INTERVAL = 1800;

Expand All @@ -25,4 +25,6 @@ export const DEFAULT_EPUB_APPEARANCE: EPUBAppearance = Object.freeze({
lineHeight: 1.2,
wordSpacing: 0,
letterSpacing: 0,
pageWidth: PageWidth.Normal,
useOriginalFont: false,
});
39 changes: 36 additions & 3 deletions src/dom/epub/epub-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -854,11 +854,36 @@ class EPUBView extends DOMView<EPUBViewState, EPUBViewData> {
this._handleViewUpdate();
}

setAppearance(appearance: EPUBAppearance) {
this._appearance = { ...appearance };
setAppearance(partialAppearance: Partial<EPUBAppearance>) {
let cfiBefore = this.flow?.startCFI;

let appearance = {
...DEFAULT_EPUB_APPEARANCE,
...partialAppearance
};
this._appearance = appearance;
this._iframeDocument.documentElement.style.setProperty('--content-line-height-adjust', String(appearance.lineHeight));
this._iframeDocument.documentElement.style.setProperty('--content-word-spacing-adjust', String(appearance.wordSpacing));
this._iframeDocument.documentElement.style.setProperty('--content-letter-spacing-adjust', String(appearance.letterSpacing));
this._iframeDocument.documentElement.classList.toggle('use-original-font', appearance.useOriginalFont);

let pageWidth;
switch (appearance.pageWidth) {
case PageWidth.Narrow:
pageWidth = 'narrow';
break;
case PageWidth.Normal:
pageWidth = 'normal';
break;
case PageWidth.Full:
pageWidth = 'full';
break;
}
this._iframeDocument.documentElement.dataset.pageWidth = pageWidth;

if (cfiBefore) {
this.navigate({ pageNumber: cfiBefore.toString() }, { skipHistory: true, behavior: 'auto' });
}
this._handleViewUpdate();
}

Expand Down Expand Up @@ -1105,13 +1130,21 @@ export interface EPUBViewState extends DOMViewState {
savedPageMapping?: string;
flowMode?: FlowMode;
spreadMode?: SpreadMode;
appearance?: EPUBAppearance;
appearance?: Partial<EPUBAppearance>;
}

export interface EPUBAppearance {
lineHeight: number;
wordSpacing: number;
letterSpacing: number;
pageWidth: PageWidth;
useOriginalFont: boolean;
}

export const enum PageWidth {
Narrow = -1,
Normal = 0,
Full = 1
}

export interface EPUBViewData {
Expand Down
10 changes: 7 additions & 3 deletions src/dom/epub/stylesheets/_content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ replaced-body {
background: transparent !important;
color: inherit !important;

font-family: var(--content-font-family, "Georgia"), serif;
:root:not(.use-original-font) & {
font-family: var(--content-font-family, "Georgia", serif);
}
font-size: inherit !important;
line-height: var(--content-line-height) !important;
word-spacing: var(--content-word-spacing) !important;
Expand Down Expand Up @@ -143,9 +145,11 @@ replaced-body {
--content-line-height-compensation: 1.167;
}

p {
p, [role="paragraph"] {
// Really enforce some of our formatting choices on body paragraphs
font-family: var(--content-font-family, "Georgia"), serif !important;
:root:not(.use-original-font) & {
font-family: var(--content-font-family, "Georgia", serif);
}
line-height: var(--content-line-height) !important;
word-spacing: var(--content-word-spacing) !important;
letter-spacing: var(--content-letter-spacing) !important;
Expand Down
22 changes: 14 additions & 8 deletions src/dom/epub/stylesheets/layout/_paginated.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,29 @@
overflow: hidden;
overscroll-behavior: none;

&.spread-mode-odd {
column-width: calc(50vw - 80px);
--media-max-width: calc(50vw - 80px);
}

&.spread-mode-none {
max-width: 800px;
column-width: 800px;
column-gap: 100vw;
--media-max-width: calc(100vw - 80px);
}

&.spread-mode-odd {
column-width: calc(50vw - 80px);
--media-max-width: calc(50vw - 80px);
:root[data-page-width="narrow"] &.spread-mode-none {
max-width: 650px;
column-width: 650px;
}

@media (max-width: 800px) {
:root[data-page-width="normal"] &.spread-mode-none {
max-width: 800px;
column-width: 800px;
column-gap: 100vw;
--media-max-width: calc(100vw - 80px);
}

:root[data-page-width="full"] &.spread-mode-none {
max-width: calc(100vw - 80px);
column-width: calc(100vw - 80px);
}

> .section-container {
Expand Down
14 changes: 13 additions & 1 deletion src/dom/epub/stylesheets/layout/_scrolled.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@
> .section-container {
margin-inline: auto;
margin-bottom: 100px;
max-width: 800px;

:root[data-page-width="narrow"] & {
max-width: 650px;
}

:root[data-page-width="normal"] & {
max-width: 800px;
}

:root[data-page-width="full"] & {
max-width: 100%;
}

// Try some different permutations of the 'contain' values that we want,
// because Firefox, at least, seems to throw away the whole property
// when it sees an unknown value.
Expand Down
3 changes: 3 additions & 0 deletions src/en-us.strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,12 @@ export default {
'pdfReader.epubAppearance.lineHeight': 'Line height',
'pdfReader.epubAppearance.wordSpacing': 'Word spacing',
'pdfReader.epubAppearance.letterSpacing': 'Letter spacing',
'pdfReader.epubAppearance.pageWidth': 'Page width',
'pdfReader.epubAppearance.useOriginalFont': 'Use original font',
'pdfReader.epubAppearance.lineHeight.revert': 'Use default line height',
'pdfReader.epubAppearance.wordSpacing.revert': 'Use default word spacing',
'pdfReader.epubAppearance.letterSpacing.revert': 'Use default letter spacing',
'pdfReader.epubAppearance.pageWidth.revert': 'Use default page width',
'pdfReader.deleteAnnotation.singular': 'Are you sure you want to delete the selected annotation?',
'pdfReader.deleteAnnotation.plural': 'Are you sure you want to delete the selected annotations?',
'pdfReader.enterPassword': 'Enter the password to open this PDF file.',
Expand Down
Loading