Fix: Text-Highlights (GlyphRange) in annotierten PDFs sichtbar machen

- merge-annotations.py: rmscene GlyphRange-Blöcke auslesen und als SVG-Rects rendern
- Koordinaten: rmscene screen-px × 72/226 → SVG-Punkte (identisch mit rmc-Skalierung)
- Farben: fill='rgb(...)' + fill-opacity statt rgba() (Inkscape-Kompatibilität)
- Highlights werden VOR Stift-Annotationen eingefügt (korrekte Z-Order)
- Dockerfile: rmscene==0.6.1 (rmrl+rmscene>=0.7.0 waren inkompatibel mit rmc)
This commit is contained in:
Borgal
2026-03-25 01:33:11 +01:00
parent b63131c0c5
commit 88d947e2ac
2 changed files with 41 additions and 1 deletions

View File

@@ -94,6 +94,46 @@ for i in range(n_pages):
inner_m = re.search(r'<svg[^>]*>(.*)</svg>', svg, re.DOTALL)
inner = inner_m.group(1) if inner_m else ''
# GlyphRange-Highlights (Textmarkierungen) aus .rm lesen
highlight_svg = ''
try:
import rmscene
RM_SCALE = 72.0 / 226 # rmscene screen-px → SVG-Punkte (wie rmc)
HIGHLIGHT_COLORS = {
9: ('rgb(255,235,0)', 0.4), # HIGHLIGHT (gelb)
3: ('rgb(251,247,25)', 0.4), # YELLOW
4: ('rgb(0,255,0)', 0.4), # GREEN
5: ('rgb(255,192,203)', 0.4), # PINK
6: ('rgb(78,105,201)', 0.4), # BLUE
7: ('rgb(179,62,57)', 0.4), # RED
}
with open(page_rm[i], 'rb') as rmf:
blocks = list(rmscene.read_blocks(rmf))
for block in blocks:
if not (hasattr(block, 'item') and hasattr(block.item, 'value')):
continue
glyph = block.item.value
if not hasattr(glyph, 'rectangles'):
continue
try:
color_id = int(glyph.color)
except Exception:
color_id = 9
fill, opacity = HIGHLIGHT_COLORS.get(color_id, ('rgb(255,235,0)', 0.4))
for rect in glyph.rectangles:
highlight_svg += (
f'<rect x="{rect.x * RM_SCALE:.3f}" y="{rect.y * RM_SCALE:.3f}" '
f'width="{rect.w * RM_SCALE:.3f}" height="{rect.h * RM_SCALE:.3f}" '
f'fill="{fill}" fill-opacity="{opacity}" stroke="none"/>\n'
)
except Exception as e:
print(f' GlyphRange Fehler: {e}', flush=True)
# Highlights VOR den Stift-Annotationen einblenden
if highlight_svg:
print(f' {highlight_svg.count("<rect")} GlyphRect(s) für Seite {i+1}', flush=True)
inner = highlight_svg + inner
# Annotation-Koordinaten sind in PDF-Punkten
# Skalierung: PDF-Punkte -> PNG-Pixel
pts_to_px = png_w / pdf_w_pt