PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
"""A small PDF with the cases the PDF reader has to get right (e2e and by hand).
|
|
|
|
|
|
|
|
|
|
python e2e/fixtures/make_test_pdf.py e2e/fixtures/test.pdf
|
|
|
|
|
|
|
|
|
|
12 pages: A4 portrait text pages, one A5 page and one A4 landscape page (mixed
|
|
|
|
|
sizes), page 7 nearly empty (only a page number: the smart crop must not zoom
|
|
|
|
|
it to infinity), an outline (table of contents) with three entries, internal
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
links from page 1 to pages 5 and 9 and one external link, a coloured picture on
|
|
|
|
|
page 2 (it must stay as it is in the reader's colours) and page labels like a
|
|
|
|
|
book's: i, ii for the first two pages, then 1, 2, 3 … Plain PDF 1.4, Helvetica,
|
|
|
|
|
no dependencies.
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
"""
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
A4 = (595, 842)
|
|
|
|
|
A5 = (420, 595)
|
|
|
|
|
A4L = (842, 595)
|
|
|
|
|
|
|
|
|
|
WORDS = ('Die Seite trägt Text, damit Auswahl, Suche und Vorlesen etwas finden. '
|
|
|
|
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. ').split()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def esc(t):
|
|
|
|
|
return t.replace('\\', '\\\\').replace('(', '\\(').replace(')', '\\)')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def text_lines(n, words_per_line=11):
|
|
|
|
|
out, i = [], 0
|
|
|
|
|
for _ in range(n):
|
|
|
|
|
out.append(' '.join(WORDS[(i + k) % len(WORDS)] for k in range(words_per_line)))
|
|
|
|
|
i += words_per_line
|
|
|
|
|
return out
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def page_content(no, size):
|
|
|
|
|
w, h = size
|
|
|
|
|
ops = ['BT', '/F1 22 Tf', f'50 {h - 70} Td', f'(Kapitel {no} - Seite {no}) Tj', 'ET']
|
|
|
|
|
if no == 7:
|
|
|
|
|
# Nearly empty: just the number at the bottom.
|
|
|
|
|
return '\n'.join(['BT', '/F1 10 Tf', f'{w / 2 - 10:.0f} 30 Td', f'({no}) Tj', 'ET'])
|
|
|
|
|
y = h - 110
|
|
|
|
|
lines = text_lines(28 if h > 700 else 18, 11 if w > 500 else 8)
|
|
|
|
|
ops += ['BT', '/F1 11 Tf', f'50 {y} Td', '14 TL']
|
|
|
|
|
for ln in lines:
|
|
|
|
|
ops.append(f'({esc(ln)}) Tj T*')
|
|
|
|
|
ops.append('ET')
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
if no == 2:
|
|
|
|
|
ops += ['q', f'200 0 0 120 {w - 260} 60 cm', '/Im1 Do', 'Q']
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
if no == 1:
|
|
|
|
|
ops += ['BT', '/F1 12 Tf', f'50 {y - 30 - 14 * len(lines)} Td',
|
|
|
|
|
'(Link zu Seite 5) Tj', '0 -20 Td', '(Link zu Seite 9) Tj', '0 -20 Td', '(Externer Link: example.org) Tj', 'ET']
|
|
|
|
|
ops += ['BT', '/F1 10 Tf', f'{w / 2 - 10:.0f} 30 Td', f'({no}) Tj', 'ET']
|
|
|
|
|
return '\n'.join(ops)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build(path):
|
|
|
|
|
sizes = [A4] * 12
|
|
|
|
|
sizes[3] = A5 # page 4
|
|
|
|
|
sizes[8] = A4L # page 9
|
|
|
|
|
objs = [] # index = object number - 1
|
|
|
|
|
|
|
|
|
|
def add(body):
|
|
|
|
|
objs.append(body)
|
|
|
|
|
return len(objs)
|
|
|
|
|
|
|
|
|
|
catalog = add(None)
|
|
|
|
|
pages_obj = add(None)
|
|
|
|
|
font = add('<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>')
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
# A picture of four colours (2 x 2 pixels, drawn large).
|
|
|
|
|
pixels = b'FF0000 00A000 0000FF FFD700>'
|
|
|
|
|
image = add(b'<< /Type /XObject /Subtype /Image /Width 2 /Height 2 /ColorSpace /DeviceRGB '
|
|
|
|
|
b'/BitsPerComponent 8 /Filter /ASCIIHexDecode /Length %d >>\nstream\n' % len(pixels)
|
|
|
|
|
+ pixels + b'\nendstream')
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
page_ids = []
|
|
|
|
|
for i, size in enumerate(sizes):
|
|
|
|
|
content = page_content(i + 1, size).encode('cp1252')
|
|
|
|
|
cid = add(b'<< /Length %d >>\nstream\n' % len(content) + content + b'\nendstream')
|
|
|
|
|
pid = add(None)
|
|
|
|
|
page_ids.append((pid, cid, size))
|
|
|
|
|
# links on page 1 (placed where the text is: bottom part of the text block)
|
|
|
|
|
p1_h = sizes[0][1]
|
|
|
|
|
base_y = p1_h - 110 - 30 - 14 * 28
|
|
|
|
|
|
|
|
|
|
def link_to(page_no, y):
|
|
|
|
|
return add(f'<< /Type /Annot /Subtype /Link /Rect [48 {y - 4} 220 {y + 14}] /Border [0 0 0] '
|
|
|
|
|
f'/Dest [{page_ids[page_no - 1][0]} 0 R /XYZ 0 {sizes[page_no - 1][1]} null] >>')
|
|
|
|
|
annots = [link_to(5, base_y), link_to(9, base_y - 20),
|
|
|
|
|
add(f'<< /Type /Annot /Subtype /Link /Rect [48 {base_y - 44} 300 {base_y - 26}] /Border [0 0 0] '
|
|
|
|
|
f'/A << /S /URI /URI (https://example.org/) >> >>')]
|
|
|
|
|
for n, (pid, cid, (w, h)) in enumerate(page_ids):
|
|
|
|
|
extra = f' /Annots [{" ".join(f"{a} 0 R" for a in annots)}]' if n == 0 else ''
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
xobj = f' /XObject << /Im1 {image} 0 R >>' if n == 1 else ''
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
objs[pid - 1] = (f'<< /Type /Page /Parent {pages_obj} 0 R /MediaBox [0 0 {w} {h}] '
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
f'/Resources << /Font << /F1 {font} 0 R >>{xobj} >> /Contents {cid} 0 R{extra} >>')
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
objs[pages_obj - 1] = f'<< /Type /Pages /Kids [{" ".join(f"{p} 0 R" for p, _, _ in page_ids)}] /Count {len(page_ids)} >>'
|
|
|
|
|
# outline: three entries
|
|
|
|
|
outline = add(None)
|
|
|
|
|
entries = [('Anfang', 1), ('Querformat', 9), ('Fast leer', 7)]
|
|
|
|
|
ids = [add(None) for _ in entries]
|
|
|
|
|
for k, ((title, page), oid) in enumerate(zip(entries, ids)):
|
|
|
|
|
nav = ''
|
|
|
|
|
if k > 0:
|
|
|
|
|
nav += f' /Prev {ids[k - 1]} 0 R'
|
|
|
|
|
if k < len(ids) - 1:
|
|
|
|
|
nav += f' /Next {ids[k + 1]} 0 R'
|
|
|
|
|
objs[oid - 1] = (f'<< /Title ({esc(title)}) /Parent {outline} 0 R{nav} '
|
|
|
|
|
f'/Dest [{page_ids[page - 1][0]} 0 R /XYZ 0 {sizes[page - 1][1]} null] >>')
|
|
|
|
|
objs[outline - 1] = f'<< /Type /Outlines /First {ids[0]} 0 R /Last {ids[-1]} 0 R /Count {len(ids)} >>'
|
PDF: öffnet an der gespeicherten Seite, Leserfarben, Seitenzahlen wie im Buch (sw CACHE v166)
Der Lesestand wird gleich beim Öffnen erfragt (parallel zur Datei), ein PDF zeichnet zuerst
die Seite, an der es weitergeht, statt Seite 1; Titel, Inhaltsverzeichnis und Seitenzahlen
kommen nebenher und halten das Öffnen nicht mehr auf. Eine Zeichnung, die schon läuft, wird
abgewartet statt neu begonnen.
„Leserfarben“ (neben Originalfarben und Invertieren): die Seite in den Farben des Lesers
(Dunkel, Sepia) per SVG-Filter, Bilder darüber wie gedruckt (ihre Lage aus den
Zeichenbefehlen); ein Bild, das die halbe Seite füllt, ist ein Scan und wird mit umgefärbt.
pdf.js' eigene pageColors färben die Bilder mit um. Ein anderes Design ändert nur die Farben
des Filters.
Seitenzahlen des Buchs (PageLabels: „iv“, „A-3“) im Kopf mit der Seite der Datei daneben,
eingeben lässt sich beides; Lesezeichen und der Zurück-Knopf nennen sie. Das Test-PDF hat
dafür Seitenzahlen und ein farbiges Bild bekommen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:42:26 +01:00
|
|
|
objs[catalog - 1] = (f'<< /Type /Catalog /Pages {pages_obj} 0 R /Outlines {outline} 0 R /PageMode /UseOutlines '
|
|
|
|
|
f'/PageLabels << /Nums [0 << /S /r >> 2 << /S /D >>] >> >>')
|
PDF-Reader: ein Zeichenweg, Seitenmodus neu, Seitensprung für beide Modi (WIP, ungetestet)
- 58-pdf.js: _pdfDraw – eine Zeichnung je Canvas (die vorige wird
abgebrochen und abgewartet), Pixeldichte, höchstens 16,7 MP; Seiten, die
gehen, geben auch pdf.js' Seitendaten frei; ein gemeinsamer pdf.js-Worker
(_pdfLoad) auch für Uploads, Seitenzahl, Hefte und Cover; Inhalts-
verzeichnis parallel aufgelöst, auch mit Seitenindex als Ziel;
ResizeObserver: Drehen, Breite, Leisten – neu an derselben Seite.
- 66-pdf-paginated.js: Seitenmodus auf _pdfDraw, Zuschnitt in
Bildschirmkoordinaten (gedrehte Seiten) und höchstens 2,5× der ganzen
Seite (eine fast leere Seite wird nicht unendlich groß); nächste und
vorige Seite vorgezeichnet; Tippen zum Blättern blendet die Leisten
nicht mehr ein; Wischen nur deutlich seitwärts; Mausrad; Pinch setzt die
Vorschau zurück; nach dem Blättern wird gespeichert und 'diora-pdf-turn'
gemeldet (E-Ink-Refresh).
- pdfGoToPage für beide Modi: Inhaltsverzeichnis, Seitenzahl im Kopf,
Lesezeichen, Tasten (Seitenmodus jetzt auch Leertaste, Bild auf/ab).
- Beim Scrollen wird die aktuelle Seite mitgeführt (Lesezeichen sagten
immer „Seite 1“).
- Schalter Scrollen | Seiten im PDF-Panel; Zoom-Regler zeichnet erst neu,
wenn er ruht.
- openBook hängt seine Listener über _readerListen an; closeReader nimmt
sie ab (vorher sammelten sie sich bei jedem Öffnen an). Abbrechen und
ein zweites Buch geben das alte Dokument frei; der entschlüsselte
PDF-Puffer wird nicht mehr gehalten.
- Invertieren dreht die Farbtöne zurück (Fotos keine Negative).
- e2e/fixtures/make_test_pdf.py: Test-PDF mit gemischten Formaten,
Outline, Links und einer fast leeren Seite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 17:52:28 +01:00
|
|
|
info = add('<< /Title (Testdokument PDF) /Author (diora Test) >>')
|
|
|
|
|
|
|
|
|
|
out = bytearray(b'%PDF-1.4\n%\xe2\xe3\xcf\xd3\n')
|
|
|
|
|
offsets = []
|
|
|
|
|
for i, body in enumerate(objs):
|
|
|
|
|
offsets.append(len(out))
|
|
|
|
|
data = body if isinstance(body, bytes) else body.encode('cp1252')
|
|
|
|
|
out += b'%d 0 obj\n' % (i + 1) + data + b'\nendobj\n'
|
|
|
|
|
xref = len(out)
|
|
|
|
|
out += b'xref\n0 %d\n0000000000 65535 f \n' % (len(objs) + 1)
|
|
|
|
|
for off in offsets:
|
|
|
|
|
out += b'%010d 00000 n \n' % off
|
|
|
|
|
out += (b'trailer\n<< /Size %d /Root %d 0 R /Info %d 0 R >>\nstartxref\n%d\n%%%%EOF\n'
|
|
|
|
|
% (len(objs) + 1, catalog, info, xref))
|
|
|
|
|
open(path, 'wb').write(out)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
build(sys.argv[1] if len(sys.argv) > 1 else 'test.pdf')
|