/** * Book Page Format Module * Defines the canonical page geometry used by the WebGL book renderer. */ import { BaseModule } from './base-module.js'; class BookPageFormatModule extends BaseModule { constructor() { super('book-page-format', 'Book Page Format'); this.dependencies = []; this.format = Object.freeze({ id: 'us-mass-market-paperback', trim: Object.freeze({ widthIn: 4.25, heightIn: 6.87 }), margins: Object.freeze({ topIn: 0.46, bottomIn: 0.58, innerIn: 0.56, outerIn: 0.44 }), typography: Object.freeze({ fontFamily: '"EB Garamond", "EB Garamond 12", serif', linesPerPage: 25, bodyLineRatio: 1.5, headingScale: 1, dropCapLines: 2 }) }); this.bindMethods([ 'getFormat', 'getAspectRatio', 'getTextureMetrics', 'inchesToTexture' ]); } async initialize() { this.reportProgress(100, 'Book page format ready'); return true; } getFormat() { return this.format; } getAspectRatio() { return this.format.trim.widthIn / this.format.trim.heightIn; } inchesToTexture(valueIn, textureHeight) { return (Number(valueIn) / this.format.trim.heightIn) * textureHeight; } getTextureMetrics(textureWidth = 1280) { const width = Math.max(1, Math.round(Number(textureWidth) || 1280)); const height = Math.round(width / this.getAspectRatio()); const margins = { top: this.inchesToTexture(this.format.margins.topIn, height), bottom: this.inchesToTexture(this.format.margins.bottomIn, height), inner: this.inchesToTexture(this.format.margins.innerIn, height), outer: this.inchesToTexture(this.format.margins.outerIn, height) }; const content = { x: margins.outer, y: margins.top, width: Math.max(1, width - margins.outer - margins.inner), height: Math.max(1, height - margins.top - margins.bottom) }; const contentBySide = { left: { ...content, x: margins.outer }, right: { ...content, x: margins.inner } }; const linesPerPage = Math.max(1, Number(this.format.typography.linesPerPage || 25)); const typographyLineHeightPx = content.height / linesPerPage; const bodyFontSizePx = typographyLineHeightPx / Math.max(1, Number(this.format.typography.bodyLineRatio || 1.5)); return { width, height, aspectRatio: this.getAspectRatio(), margins, content, contentBySide, linesPerPage, bodyFontSizePx, typographyLineHeightPx, typography: this.format.typography }; } } const bookPageFormat = new BookPageFormatModule(); export { bookPageFormat as BookPageFormat }; if (window.moduleRegistry) { window.moduleRegistry.register(bookPageFormat); } window.BookPageFormat = bookPageFormat;