package com.peachpasswords.codex /** * A4 Codex page geometry — the exact port of the browser's * `popup/codex/pdf-layout.ts`, which is the canonical Codex page format. * * A Codex is a *cross-platform paper backup*: a PDF printed from the browser * extension has to restore on Android and vice versa. That only holds if both * sides agree on where every Aztec sits on the page, to the point. * * They didn't. Android's generator used its own geometry (36pt margin, 54pt * header, a computed square cell) and its importer blind-cropped that same * private grid, so it could only ever read PDFs it had produced itself. Handed * a real browser-generated Codex it cropped the wrong regions and decoded * roughly a quarter of the codes — enough to look like a flaky scan rather * than a format mismatch. * * Units are PDF points (1pt = 1/72 inch). Keep these values identical to * pdf-layout.ts; drift here silently breaks paper restore across platforms. */ object CodexPageLayout { const val PAGE_WIDTH = 595.28f const val PAGE_HEIGHT = 841.89f const val MARGIN = 28f const val HEADER_HEIGHT = 44f /** Vertical gap between the header hairline and the top of row 0. */ const val HEADER_GAP = 16f const val CODE_SIZE = 80f /** Horizontal gap between adjacent codes in a row. */ const val COL_GAP = (PAGE_WIDTH - 2 * MARGIN - CODES_PER_ROW * CODE_SIZE) / (CODES_PER_ROW - 1) /** Space reserved for the per-code numeric label drawn under each Aztec. */ const val LABEL_HEIGHT = 14f /** Printed white space between a label and the next row's code. */ const val ROW_GAP = 18f /** Top-of-code-N to top-of-code-N+1 distance — what the importer steps by. */ const val ROW_STEP = CODE_SIZE + ROW_GAP + LABEL_HEIGHT /** Top of row 0, measured from the top of the page. */ const val GRID_TOP = MARGIN + HEADER_HEIGHT + HEADER_GAP /** Quiet zone the importer includes around each code, as a fraction of it. */ const val QUIET_FRACTION = 0.12f fun codeLeft(col: Int): Float = MARGIN + col * (CODE_SIZE + COL_GAP) fun codeTop(row: Int): Float = GRID_TOP + row * ROW_STEP }