Skip to content

Commit 0359285

Browse files
committed
Fix line wrapping with justified content and unicode fonts - close #118
1 parent 95873b5 commit 0359285

File tree

4 files changed

+31
-14
lines changed

4 files changed

+31
-14
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and [PEP 440](https://www.python.org/dev/peps/pep-0440/).
1010
## [2.3.2] - not released yet
1111
### Added
1212
- `FPDF.set_xmp_metadata`
13+
### Fixed
14+
- line wrapping with justified content and unicode fonts, _cf._ [#118](https://github.com/PyFPDF/fpdf2/issues/118)
1315

1416
## [2.3.1] - 2021-02-28
1517
### Added

fpdf/fpdf.py

+15-14
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ def add_font(self, family, style="", fname=None, uni=False):
760760

761761
# Check if font already added or one of the core fonts
762762
if fontkey in self.fonts or fontkey in self.core_fonts:
763-
warnings.warn("Core font or font already added: doing nothing")
763+
warnings.warn(f"Core font or font already added '{fontkey}': doing nothing")
764764
return
765765
if uni:
766766
for parent in (".", FPDF_FONT_DIR, SYSTEM_TTFONTS):
@@ -1082,6 +1082,11 @@ def rotation(self, angle, x=None, y=None):
10821082
The rotation affects all elements which are printed inside the indented context
10831083
(with the exception of clickable areas).
10841084
1085+
Args:
1086+
angle (float): angle in degrees
1087+
x (float): abscissa of the center of the rotation
1088+
y (float): ordinate of the center of the rotation
1089+
10851090
Notes
10861091
-----
10871092
@@ -1214,18 +1219,15 @@ def cell(self, w, h=0, txt="", border=0, ln=0, align="", fill=False, link=""):
12141219
s += (
12151220
f"BT 0 Tw {(self.x + dx) * k:.2F} "
12161221
f"{(self.h - self.y - 0.5 * h - 0.3 * self.font_size) * k:.2F} "
1217-
f"Td ["
1222+
"Td ["
12181223
)
12191224

1220-
t = txt.split(" ")
1221-
numt = len(t)
1222-
for i in range(numt):
1223-
tx = t[i]
1224-
tx = enclose_in_parens(
1225-
escape_parens(tx.encode("UTF-16BE").decode("latin-1"))
1226-
)
1227-
s += f"{tx} "
1228-
if (i + 1) < numt:
1225+
words = txt.split(" ")
1226+
for i, word in enumerate(words):
1227+
word = escape_parens(word.encode("UTF-16BE").decode("latin-1"))
1228+
s += f"({word}) "
1229+
is_last_word = (i + 1) == len(words)
1230+
if not is_last_word:
12291231
adj = -(self.ws * self.k) * 1000 / self.font_size_pt
12301232
s += f"{adj}({space}) "
12311233
s += "] TJ"
@@ -1237,7 +1239,6 @@ def cell(self, w, h=0, txt="", border=0, ln=0, align="", fill=False, link=""):
12371239
self.current_font["subset"].append(ord(char))
12381240
else:
12391241
txt2 = escape_parens(txt)
1240-
12411242
s += (
12421243
f"BT {(self.x + dx) * k:.2f} "
12431244
f"{(self.h - self.y - 0.5 * h - 0.3 * self.font_size) * k:.2f} "
@@ -1326,8 +1327,8 @@ def multi_cell(
13261327
(in any order):
13271328
`L`: left ; `T`: top ; `R`: right ; `B`: bottom. Default value: 0.
13281329
align (str): Allows to center or align the text. Possible values are:
1329-
`L` or empty string: left align (default value) ; `C`: center ;
1330-
`R`: right align
1330+
`J`: justify (default value); `L` or empty string: left align ;
1331+
`C`: center ; `R`: right align
13311332
fill (bool): Indicates if the cell background must be painted (`True`)
13321333
or transparent (`False`). Default value: False.
13331334
split_only (bool): if `True`, does not output anything, only perform

test/cells/test_multi_cell.py

+14
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,20 @@ def test_multi_cell_table_unbreakable(tmp_path): # issue 111
137137
assert_pdf_equal(pdf, HERE / "multi_cell_table_unbreakable.pdf", tmp_path)
138138

139139

140+
def test_multi_cell_justified_with_unicode_font(tmp_path): # issue 118
141+
pdf = fpdf.FPDF()
142+
pdf.add_page()
143+
pdf.add_font(
144+
"DejaVu", "", HERE / "../end_to_end_legacy/charmap/DejaVuSans.ttf", uni=True
145+
)
146+
pdf.set_font("DejaVu", "", 14)
147+
text = 'Justified line containing "()" that is long enough to trigger wrapping and a line jump'
148+
pdf.multi_cell(w=0, h=8, txt=text, ln=1)
149+
assert_pdf_equal(
150+
pdf, HERE / "test_multi_cell_justified_with_unicode_font.pdf", tmp_path
151+
)
152+
153+
140154
## Code used to create test
141155
# doc = fpdf.FPDF(format = 'letter', unit = 'pt')
142156
# set_doc_date_0(doc)
Binary file not shown.

0 commit comments

Comments
 (0)