feat(rtl): rendu droite-a-gauche complet pour Word, PowerPoint, Excel et PDF
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m37s

- source unique RTL_LANGUAGES/is_rtl dans core/languages.py (fin des 3 copies)
- Word: bidi partout (corps, tableaux bidiVisual, notes/fin/commentaires,
  zones de texte, 6 zones d'en-tetes/pieds), insertion OOXML ordonnee,
  polices cs elargies aux 11 langues
- PowerPoint: alignements explicites preserves, notes du presentateur,
  indice de police <a:cs> insert a sa place
- Excel: feuilles affichees de droite a gauche, feuilles graphiques ignorees
- PDF: faconnage bidi (arabic-reshaper + python-bidi), polices par ecriture
  (arabe/hebreu), TTF enregistree pour le PDF recompose
- 46 tests nouveaux (tests/test_translators/test_rtl_layout.py), 253 au total
This commit is contained in:
2026-09-01 20:22:46 +02:00
parent fddd7b7428
commit f22f645fab
12 changed files with 1727 additions and 80 deletions

View File

@@ -99,7 +99,7 @@ class TestSmartFitTiers:
translator = pdf_mod.PDFTranslator()
result = translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
# Should have succeeded
assert result is True
@@ -122,7 +122,7 @@ class TestSmartFitTiers:
block = self._make_block(font_size=12, x0=100, y0=100, x1=400, y1=120)
translator = pdf_mod.PDFTranslator()
result = translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
assert result is True
# Should have tried multiple times
@@ -137,7 +137,7 @@ class TestSmartFitTiers:
block = self._make_block(font_size=20, x0=100, y0=100, x1=400, y1=120)
translator = pdf_mod.PDFTranslator()
result = translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
# Should have failed (returned False) because persistent overflow
assert result is False
@@ -159,7 +159,7 @@ class TestSmartFitTiers:
block = self._make_block(font_size=22, text="X" * 1000)
translator = pdf_mod.PDFTranslator()
translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
# All attempted sizes should be >= 22 * 0.90 = 19.8
for s in call_sizes:
@@ -180,7 +180,7 @@ class TestSmartFitTiers:
block = self._make_block(font_size=12, text="Y" * 1000)
translator = pdf_mod.PDFTranslator()
translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
for s in call_sizes:
if s is not None:
@@ -201,7 +201,7 @@ class TestSmartFitTiers:
with patch.object(pdf_mod, "_record_format_loss_metric", fake_record):
block = self._make_block(font_size=12, text="Z" * 1000)
result = translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
assert result is False
# A format_loss metric should have been emitted
@@ -221,7 +221,7 @@ class TestSmartFitTiers:
with patch.object(pdf_mod, "_record_format_loss_metric", fake_record):
block = self._make_block(font_size=12, text="Short")
result = translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
assert result is True
# No format_loss should have been emitted
@@ -242,7 +242,7 @@ class TestSmartFitTiers:
block = self._make_block(font_size=3, text="Q" * 1000)
translator = pdf_mod.PDFTranslator()
translator._write_translated_block(
page, block, font_path=None, is_rtl=False
page, block, font_path=None, rtl_target=False
)
# Exclude the placeholder font (used in graceful failure)
real_sizes = [s for s in call_sizes if s is not None and s >= 4.5]

File diff suppressed because it is too large Load Diff