@@ -2781,7 +2781,6 @@ def cell(
2781
2781
max_width = w ,
2782
2782
trailing_nl = False ,
2783
2783
),
2784
- w ,
2785
2784
h ,
2786
2785
border ,
2787
2786
new_x = new_x ,
@@ -2794,7 +2793,6 @@ def cell(
2794
2793
def _render_styled_text_line (
2795
2794
self ,
2796
2795
text_line : TextLine ,
2797
- w : float = None ,
2798
2796
h : float = None ,
2799
2797
border : Union [str , int ] = 0 ,
2800
2798
new_x : XPos = XPos .RIGHT ,
@@ -2817,8 +2815,6 @@ def _render_styled_text_line(
2817
2815
Args:
2818
2816
text_line (TextLine instance): Contains the (possibly empty) tuple of
2819
2817
fragments to render.
2820
- w (float): Cell width. Default value: None, meaning to fit text width.
2821
- If 0, the cell extends up to the right margin.
2822
2818
h (float): Cell height. Default value: None, meaning an height equal
2823
2819
to the current font size.
2824
2820
border: Indicates if borders must be drawn around the cell.
@@ -2847,25 +2843,30 @@ def _render_styled_text_line(
2847
2843
2848
2844
if padding is None :
2849
2845
padding = Padding (0 , 0 , 0 , 0 )
2850
-
2851
- if padding .left == 0 and padding . right == 0 :
2852
- horizontal_margin = self .c_margin
2853
- else :
2854
- horizontal_margin = 0
2846
+ l_c_margin = r_c_margin = 0
2847
+ if padding .left == 0 :
2848
+ l_c_margin = self .c_margin
2849
+ if padding . right == 0 :
2850
+ r_c_margin = self . c_margin
2855
2851
2856
2852
styled_txt_width = text_line .text_width
2857
2853
if not styled_txt_width :
2858
2854
for i , frag in enumerate (text_line .fragments ):
2859
2855
unscaled_width = frag .get_width (initial_cs = i != 0 )
2860
2856
styled_txt_width += unscaled_width
2861
2857
2862
-
2863
2858
w = text_line .max_width
2859
+ if w is None :
2860
+ if not text_line .fragments :
2861
+ raise ValueError (
2862
+ "'text_line' must have fragments if 'text_line.text_width' is None"
2863
+ )
2864
+ w = styled_txt_width + l_c_margin + r_c_margin
2865
+ elif w == 0 :
2866
+ w = self .w - self .r_margin - self .x
2864
2867
if center :
2865
- self .x = (
2866
- self .w / 2 if align == Align .X else self .l_margin + (self .epw - w ) / 2
2867
- )
2868
- if align == Align .X :
2868
+ self .x = self .l_margin + (self .epw - w ) / 2
2869
+ elif text_line .align == Align .X :
2869
2870
self .x -= w / 2
2870
2871
2871
2872
max_font_size = 0 # how much height we need to accomodate.
@@ -2922,16 +2923,16 @@ def _render_styled_text_line(
2922
2923
last_used_color = self .fill_color
2923
2924
if text_line .fragments :
2924
2925
if text_line .align == Align .R :
2925
- dx = w - horizontal_margin - styled_txt_width
2926
+ dx = w - l_c_margin - styled_txt_width
2926
2927
elif text_line .align in [Align .C , Align .X ]:
2927
2928
dx = (w - styled_txt_width ) / 2
2928
2929
else :
2929
- dx = horizontal_margin
2930
+ dx = l_c_margin
2930
2931
s_start += dx
2931
2932
word_spacing = 0
2932
2933
if text_line .align == Align .J and text_line .number_of_spaces :
2933
2934
word_spacing = (
2934
- w - horizontal_margin - horizontal_margin - styled_txt_width
2935
+ w - l_c_margin - r_c_margin - styled_txt_width
2935
2936
) / text_line .number_of_spaces
2936
2937
sl .append (
2937
2938
f"BT { (self .x + dx ) * k :.2f} "
@@ -3065,7 +3066,7 @@ def _render_styled_text_line(
3065
3066
self .x = s_start + s_width
3066
3067
elif new_x == XPos .WCONT :
3067
3068
if s_width :
3068
- self .x = s_start + s_width - horizontal_margin
3069
+ self .x = s_start + s_width - r_c_margin
3069
3070
else :
3070
3071
self .x = s_start
3071
3072
elif new_x == XPos .CENTER :
@@ -3392,10 +3393,11 @@ def multi_cell(
3392
3393
center (bool): center the cell horizontally on the page.
3393
3394
padding (float or Sequence): padding to apply around the text. Default value: 0.
3394
3395
When one value is specified, it applies the same padding to all four sides.
3395
- When two values are specified, the first padding applies to the top and bottom, the second to the left and right.
3396
- When three values are specified, the first padding applies to the top, the second to the right and left, the third to the bottom.
3397
- When four values are specified, the paddings apply to the top, right, bottom, and left in that order (clockwise)
3398
- If padding for left and right ends up being non-zero then c_margin is ignored.
3396
+ When two values are specified, the first padding applies to the top and bottom, the second to
3397
+ the left and right. When three values are specified, the first padding applies to the top,
3398
+ the second to the right and left, the third to the bottom. When four values are specified,
3399
+ the paddings apply to the top, right, bottom, and left in that order (clockwise)
3400
+ If padding for left or right ends up being non-zero then respective c_margin is ignored.
3399
3401
3400
3402
Center overrides values for horizontal padding
3401
3403
@@ -3493,8 +3495,13 @@ def multi_cell(
3493
3495
# Apply padding to contents
3494
3496
# decrease maximum allowed width by padding
3495
3497
# shift the starting point by padding
3496
- w = w - padding .right - padding .left
3497
- maximum_allowed_width = w - 2 * self .c_margin
3498
+ maximum_allowed_width = w = w - padding .right - padding .left
3499
+ clearance_margins = []
3500
+ # If we don't have padding on either side, we need a clearance margin.
3501
+ if not padding .left :
3502
+ clearance_margins .append (self .c_margin )
3503
+ if not padding .right :
3504
+ clearance_margins .append (self .c_margin )
3498
3505
self .x += padding .left
3499
3506
self .y += padding .top
3500
3507
@@ -3522,6 +3529,7 @@ def multi_cell(
3522
3529
multi_line_break = MultiLineBreak (
3523
3530
styled_text_fragments ,
3524
3531
maximum_allowed_width ,
3532
+ clearance_margins ,
3525
3533
align = align ,
3526
3534
print_sh = print_sh ,
3527
3535
wrapmode = wrapmode ,
@@ -3561,7 +3569,6 @@ def multi_cell(
3561
3569
has_line_after = not is_last_line or should_render_bottom_blank_cell
3562
3570
new_page = self ._render_styled_text_line (
3563
3571
text_line ,
3564
- w ,
3565
3572
h = current_cell_height ,
3566
3573
border = "" .join (
3567
3574
(
@@ -3593,7 +3600,6 @@ def multi_cell(
3593
3600
max_width = w ,
3594
3601
trailing_nl = False ,
3595
3602
),
3596
- w ,
3597
3603
h = h ,
3598
3604
border = "" .join (
3599
3605
(
@@ -3696,31 +3702,28 @@ def write(
3696
3702
multi_line_break = MultiLineBreak (
3697
3703
styled_text_fragments ,
3698
3704
lambda h : max_width ,
3705
+ (self .c_margin , self .c_margin ),
3699
3706
print_sh = print_sh ,
3700
3707
wrapmode = wrapmode ,
3701
3708
)
3702
3709
# first line from current x position to right margin
3703
3710
first_width = self .w - self .x - self .r_margin
3704
- max_width = first_width - 2 * self . c_margin
3711
+ max_width = first_width
3705
3712
text_line = multi_line_break .get_line ()
3706
3713
# remaining lines fill between margins
3707
3714
full_width = self .w - self .l_margin - self .r_margin
3708
- max_width = full_width - 2 * self . c_margin
3715
+ max_width = full_width
3709
3716
while (text_line ) is not None :
3710
3717
text_lines .append (text_line )
3711
3718
text_line = multi_line_break .get_line ()
3712
3719
if not text_lines :
3713
3720
return False
3714
3721
3715
3722
for text_line_index , text_line in enumerate (text_lines ):
3716
- if text_line_index == 0 :
3717
- line_width = first_width
3718
- else :
3719
- line_width = full_width
3723
+ if text_line_index > 0 :
3720
3724
self .ln ()
3721
3725
new_page = self ._render_styled_text_line (
3722
3726
text_line ,
3723
- line_width ,
3724
3727
h = h ,
3725
3728
border = 0 ,
3726
3729
new_x = XPos .WCONT ,
@@ -4196,11 +4199,18 @@ def ln(self, h=None):
4196
4199
the amount passed as parameter.
4197
4200
4198
4201
Args:
4199
- h (float): The height of the break.
4200
- By default, the value equals the height of the last printed cell.
4202
+ h (float, optional): The height of the break.
4203
+ By default, the value equals the height of the last printed cell, or absent that
4204
+ the height of the current font.
4205
+ If no 'h' is given, nothing has been written yet, and no font size is set, nothing happens.
4201
4206
"""
4202
4207
self .x = self .l_margin
4203
- self .y += self ._lasth if h is None else h
4208
+ if h :
4209
+ self .y += h
4210
+ elif self ._lasth :
4211
+ self .y += self ._lasth
4212
+ # elif self.font_size:
4213
+ # self.y += self.font_size
4204
4214
4205
4215
def get_x (self ):
4206
4216
"""Returns the abscissa of the current position."""
@@ -4846,31 +4856,33 @@ def table(self, *args, **kwargs):
4846
4856
Detailed usage documentation: https://py-pdf.github.io/fpdf2/Tables.html
4847
4857
4848
4858
Args:
4849
- rows: optional. Sequence of rows (iterable) of str to initiate the table cells with text content
4850
- align (str, fpdf.enums.Align): optional, default to CENTER. Sets the table horizontal position relative to the page,
4851
- when it's not using the full page width
4852
- borders_layout (str, fpdf.enums.TableBordersLayout): optional, default to ALL. Control what cell borders are drawn
4859
+ rows: optional. Sequence of rows (iterable) of str to initiate the table cells with text content.
4860
+ align (str, fpdf.enums.Align): optional, default to CENTER. Sets the table horizontal position
4861
+ relative to the page, when it's not using the full page width.
4862
+ borders_layout (str, fpdf.enums.TableBordersLayout): optional, default to ALL. Control what cell
4863
+ borders are drawn.
4853
4864
cell_fill_color (int, tuple, fpdf.drawing.DeviceGray, fpdf.drawing.DeviceRGB): optional.
4854
- Defines the cells background color
4855
- cell_fill_mode (str, fpdf.enums.TableCellFillMode): optional. Defines which cells are filled with color in the background
4856
- col_widths (int, tuple): optional. Sets column width. Can be a single number or a sequence of numbers
4865
+ Defines the cells background color.
4866
+ cell_fill_mode (str, fpdf.enums.TableCellFillMode): optional. Defines which cells are filled
4867
+ with color in the background.
4868
+ col_widths (int, tuple): optional. Sets column width. Can be a single number or a sequence of numbers.
4857
4869
first_row_as_headings (bool): optional, default to True. If False, the first row of the table
4858
- is not styled differently from the others
4859
- gutter_height (float): optional vertical space between rows
4860
- gutter_width (float): optional horizontal space between columns
4870
+ is not styled differently from the others.
4871
+ gutter_height (float): optional vertical space between rows.
4872
+ gutter_width (float): optional horizontal space between columns.
4861
4873
headings_style (fpdf.fonts.FontFace): optional, default to bold.
4862
4874
Defines the visual style of the top headings row: size, color, emphasis...
4863
- line_height (number): optional. Defines how much vertical space a line of text will occupy
4864
- markdown (bool): optional, default to False. Enable markdown interpretation of cells textual content
4875
+ line_height (number): optional. Defines how much vertical space a line of text will occupy.
4876
+ markdown (bool): optional, default to False. Enable markdown interpretation of cells textual content.
4865
4877
text_align (str, fpdf.enums.Align): optional, default to JUSTIFY. Control text alignment inside cells.
4866
- width (number): optional. Sets the table width
4878
+ width (number): optional. Sets the table width.
4867
4879
wrapmode (fpdf.enums.WrapMode): "WORD" for word based line wrapping (default),
4868
4880
"CHAR" for character based line wrapping.
4869
4881
padding (number, tuple, Padding): optional. Sets the cell padding. Can be a single number or a sequence
4870
4882
of numbers, default:0
4871
- If padding for left and right ends up being non-zero then c_margin is ignored.
4872
- outer_border_width (number): optional. The outer_border_width will trigger rendering of the outer border of
4873
- the table with the given width regardless of any other defined border styles.
4883
+ If padding for left or right ends up being non-zero then the respective c_margin is ignored.
4884
+ outer_border_width (number): optional. The outer_border_width will trigger rendering of the outer
4885
+ border of the table with the given width regardless of any other defined border styles.
4874
4886
"""
4875
4887
table = Table (self , * args , ** kwargs )
4876
4888
yield table
0 commit comments