-
Notifications
You must be signed in to change notification settings - Fork 596
/
Copy pathpage.rst
2365 lines (1567 loc) · 133 KB
/
page.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
.. include:: header.rst
.. _Page:
================
Page
================
Class representing a document page. A page object is created by :meth:`Document.load_page` or, equivalently, via indexing the document like `doc[n]` - it has no independent constructor.
There is a parent-child relationship between a document and its pages. If the document is closed or deleted, all page objects (and their respective children, too) in existence will become unusable ("orphaned"): If a page property or method is being used, an exception is raised.
Several page methods have a :ref:`Document` counterpart for convenience. At the end of this chapter you will find a synopsis.
.. note:: Many times in this chapter we are using the term **coordinate**. It is of high importance to have at least a basic understanding of what that is and that you feel comfortable with the section :ref:`Coordinates`.
Modifying Pages
---------------
Changing page properties and adding or changing page content is available for PDF documents only.
In a nutshell, this is what you can do with PyMuPDF:
* Modify page rotation and the visible part ("cropbox") of the page.
* Insert images, other PDF pages, text and simple geometrical objects.
* Add annotations and form fields.
.. note::
Methods require coordinates (points, rectangles) to put content in desired places. Please be aware that these coordinates **must always** be provided relative to the **unrotated** page (since v1.17.0). The reverse is also true: except :attr:`Page.rect`, resp. :meth:`Page.bound` (both *reflect* when the page is rotated), all coordinates returned by methods and attributes pertain to the unrotated page.
So the returned value of e.g. :meth:`Page.get_image_bbox` will not change if you do a :meth:`Page.set_rotation`. The same is true for coordinates returned by :meth:`Page.get_text`, annotation rectangles, and so on. If you want to find out, where an object is located in **rotated coordinates**, multiply the coordinates with :attr:`Page.rotation_matrix`. There also is its inverse, :attr:`Page.derotation_matrix`, which you can use when interfacing with other readers, which may behave differently in this respect.
.. note::
If you add or update annotations, links or form fields on the page and immediately afterwards need to work with them (i.e. **without leaving the page**), you should reload the page using :meth:`Document.reload_page` before referring to these new or updated items.
Reloading the page is generally recommended -- although not strictly required in all cases. However, some annotation and widget types have extended features in PyMuPDF compared to MuPDF. More of these extensions may also be added in the future.
Releoading the page ensures all your changes have been fully applied to PDF structures, so you can safely create Pixmaps or successfully iterate over annotations, links and form fields.
================================== =======================================================
**Method / Attribute** **Short Description**
================================== =======================================================
:meth:`Page.add_caret_annot` PDF only: add a caret annotation
:meth:`Page.add_circle_annot` PDF only: add a circle annotation
:meth:`Page.add_file_annot` PDF only: add a file attachment annotation
:meth:`Page.add_freetext_annot` PDF only: add a text annotation
:meth:`Page.add_highlight_annot` PDF only: add a "highlight" annotation
:meth:`Page.add_ink_annot` PDF only: add an ink annotation
:meth:`Page.add_line_annot` PDF only: add a line annotation
:meth:`Page.add_polygon_annot` PDF only: add a polygon annotation
:meth:`Page.add_polyline_annot` PDF only: add a multi-line annotation
:meth:`Page.add_rect_annot` PDF only: add a rectangle annotation
:meth:`Page.add_redact_annot` PDF only: add a redaction annotation
:meth:`Page.add_squiggly_annot` PDF only: add a "squiggly" annotation
:meth:`Page.add_stamp_annot` PDF only: add a "rubber stamp" annotation
:meth:`Page.add_strikeout_annot` PDF only: add a "strike-out" annotation
:meth:`Page.add_text_annot` PDF only: add a comment
:meth:`Page.add_underline_annot` PDF only: add an "underline" annotation
:meth:`Page.add_widget` PDF only: add a PDF Form field
:meth:`Page.annot_names` PDF only: a list of annotation (and widget) names
:meth:`Page.annot_xrefs` PDF only: a list of annotation (and widget) xrefs
:meth:`Page.annots` return a generator over the annots on the page
:meth:`Page.apply_redactions` PDF only: process the redactions of the page
:meth:`Page.bound` rectangle of the page
:meth:`Page.cluster_drawings` PDF only: bounding boxes of vector graphics
:meth:`Page.delete_annot` PDF only: delete an annotation
:meth:`Page.delete_image` PDF only: delete an image
:meth:`Page.delete_link` PDF only: delete a link
:meth:`Page.delete_widget` PDF only: delete a widget / field
:meth:`Page.draw_bezier` PDF only: draw a cubic Bezier curve
:meth:`Page.draw_circle` PDF only: draw a circle
:meth:`Page.draw_curve` PDF only: draw a special Bezier curve
:meth:`Page.draw_line` PDF only: draw a line
:meth:`Page.draw_oval` PDF only: draw an oval / ellipse
:meth:`Page.draw_polyline` PDF only: connect a point sequence
:meth:`Page.draw_quad` PDF only: draw a quad
:meth:`Page.draw_rect` PDF only: draw a rectangle
:meth:`Page.draw_sector` PDF only: draw a circular sector
:meth:`Page.draw_squiggle` PDF only: draw a squiggly line
:meth:`Page.draw_zigzag` PDF only: draw a zig-zagged line
:meth:`Page.find_tables` locate tables on the page
:meth:`Page.get_drawings` get vector graphics on page
:meth:`Page.get_fonts` PDF only: get list of referenced fonts
:meth:`Page.get_image_bbox` PDF only: get bbox and matrix of embedded image
:meth:`Page.get_image_info` get list of meta information for all used images
:meth:`Page.get_image_rects` PDF only: improved version of :meth:`Page.get_image_bbox`
:meth:`Page.get_images` PDF only: get list of referenced images
:meth:`Page.get_label` PDF only: return the label of the page
:meth:`Page.get_links` get all links
:meth:`Page.get_pixmap` create a page image in raster format
:meth:`Page.get_svg_image` create a page image in SVG format
:meth:`Page.get_text` extract the page's text
:meth:`Page.get_textbox` extract text contained in a rectangle
:meth:`Page.get_textpage_ocr` create a TextPage with OCR for the page
:meth:`Page.get_textpage` create a TextPage for the page
:meth:`Page.get_xobjects` PDF only: get list of referenced xobjects
:meth:`Page.insert_font` PDF only: insert a font for use by the page
:meth:`Page.insert_image` PDF only: insert an image
:meth:`Page.insert_link` PDF only: insert a link
:meth:`Page.insert_text` PDF only: insert text
:meth:`Page.insert_htmlbox` PDF only: insert html text in a rectangle
:meth:`Page.insert_textbox` PDF only: insert a text box
:meth:`Page.links` return a generator of the links on the page
:meth:`Page.load_annot` PDF only: load a specific annotation
:meth:`Page.load_widget` PDF only: load a specific field
:meth:`Page.load_links` return the first link on a page
:meth:`Page.new_shape` PDF only: create a new :ref:`Shape`
:meth:`Page.recolor` PDF only: change the colorspace of objects
:meth:`Page.remove_rotation` PDF only: set page rotation to 0
:meth:`Page.replace_image` PDF only: replace an image
:meth:`Page.search_for` search for a string
:meth:`Page.set_artbox` PDF only: modify `/ArtBox`
:meth:`Page.set_bleedbox` PDF only: modify `/BleedBox`
:meth:`Page.set_cropbox` PDF only: modify the :data:`cropbox` (visible page)
:meth:`Page.set_mediabox` PDF only: modify `/MediaBox`
:meth:`Page.set_rotation` PDF only: set page rotation
:meth:`Page.set_trimbox` PDF only: modify `/TrimBox`
:meth:`Page.show_pdf_page` PDF only: display PDF page image
:meth:`Page.update_link` PDF only: modify a link
:meth:`Page.widgets` return a generator over the fields on the page
:meth:`Page.write_text` write one or more :ref:`Textwriter` objects
:attr:`Page.cropbox_position` displacement of the :data:`cropbox`
:attr:`Page.cropbox` the page's :data:`cropbox`
:attr:`Page.artbox` the page's `/ArtBox`
:attr:`Page.bleedbox` the page's `/BleedBox`
:attr:`Page.trimbox` the page's `/TrimBox`
:attr:`Page.derotation_matrix` PDF only: get coordinates in unrotated page space
:attr:`Page.first_annot` first :ref:`Annot` on the page
:attr:`Page.first_link` first :ref:`Link` on the page
:attr:`Page.first_widget` first widget (form field) on the page
:attr:`Page.mediabox_size` bottom-right point of :data:`mediabox`
:attr:`Page.mediabox` the page's :data:`mediabox`
:attr:`Page.number` page number
:attr:`Page.parent` owning document object
:attr:`Page.rect` rectangle of the page
:attr:`Page.rotation_matrix` PDF only: get coordinates in rotated page space
:attr:`Page.rotation` PDF only: page rotation
:attr:`Page.transformation_matrix` PDF only: translate between PDF and MuPDF space
:attr:`Page.xref` PDF only: page :data:`xref`
================================== =======================================================
**Class API**
.. class:: Page
.. method:: bound()
Determine the rectangle of the page. Same as property :attr:`Page.rect`. For PDF documents this **usually** also coincides with :data:`mediabox` and :data:`cropbox`, but not always. For example, if the page is rotated, then this is reflected by this method -- the :attr:`Page.cropbox` however will not change.
:rtype: :ref:`Rect`
.. method:: add_caret_annot(point)
PDF only: Add a caret icon. A caret annotation is a visual symbol normally used to indicate the presence of text edits on the page.
:arg point_like point: the top left point of a 20 x 20 rectangle containing the MuPDF-provided icon.
:rtype: :ref:`Annot`
:returns: the created annotation. Stroke color blue = (0, 0, 1), no fill color support.
.. image:: images/img-caret-annot.*
:scale: 70
|history_begin|
* New in v1.16.0
|history_end|
.. method:: add_text_annot(point, text, icon="Note")
PDF only: Add a comment icon ("sticky note") with accompanying text. Only the icon is visible, the accompanying text is hidden and can be visualized by many PDF viewers by hovering the mouse over the symbol.
:arg point_like point: the top left point of a 20 x 20 rectangle containing the MuPDF-provided "note" icon.
:arg str text: the commentary text. This will be shown on double clicking or hovering over the icon. May contain any Latin characters.
:arg str icon: choose one of "Note" (default), "Comment", "Help", "Insert", "Key", "NewParagraph", "Paragraph" as the visual symbol for the embodied text [#f4]_. (New in v1.16.0)
:rtype: :ref:`Annot`
:returns: the created annotation. Stroke color yellow = (1, 1, 0), no fill color support.
.. index::
pair: rect; add_freetext_annot
pair: fontsize; add_freetext_annot
pair: fontname; add_freetext_annot
pair: text_color; add_freetext_annot
pair: fill_color; add_freetext_annot
pair: border_width; add_freetext_annot
pair: dashes; add_freetext_annot
pair: callout; add_freetext_annot
pair: line_end; add_freetext_annot
pair: opacity; add_freetext_annot
pair: align; add_freetext_annot
pair: rotate; add_freetext_annot
pair: richtext; add_freetext_annot
pair: style; add_freetext_annot
.. method:: add_freetext_annot(rect, text, *, fontsize=11, fontname="helv", text_color=0, fill_color=None, border_width=0, dashes=None, callout=None, line_end=PDF_ANNOT_LE_OPEN_ARROW, opacity=1, align=TEXT_ALIGN_LEFT, rotate=0, richtext=False, style=None)
PDF only: Add text in a given rectangle. Optionally, the appearance of a "callout" shape can be requested by specifying two or three point-like objects -- see below.
:arg rect_like rect: the rectangle into which the text should be inserted. Text is automatically wrapped to a new line at box width. Text portions not fitting into the rectangle will be invisible without warning.
:arg str text: the text. May contain any mixture of Latin, Greek, Cyrillic, Chinese, Japanese and Korean characters. If `richtext=True` (see below), the string is interpreted as HTML syntax. This adds a plethora of ways for attractive effects.
:arg float fontsize: the :data:`fontsize`. Default is 11. Ignored if `richtext=True`.
:arg str fontname: The font name. Default is "Helv". Ignored if `richtext=True`, otherwise the following **restritions apply:**
* Accepted alternatives are "Helv" (Helvetica), "Cour" (Courier), "TiRo" (Timnes-Roman), "ZaDb" (ZapfDingBats) and "Symb" (Symbol). The name may be abbreviated to the first two characters, like "Co" for "Cour", lower case accepted.
* Bold or italic variants of the fonts are **not supported.**
:arg list,tuple,float text_color: the text color. Default is black. Ignored if `richtext=True`.
:arg list,tuple,float fill_color: the fill color. This is used for ``rect`` and the end point of the callout lines when applicable. Default is ``None``.
:arg list,tuple,float border_color: This parameter **only has an effect** if `richtext=True`. Otherwise, ``text_color`` is used.
:arg float border_width: the width of border and ``callout`` lines. Default is 0 (no border), in which case callout lines may still appear with some hairline width, depending on the PDF viewer used. In any case, this value must be positive to see a border line.
:arg list,tuple dashes: a list of floats specifying how border and callout lines should be dashed. Default is ``None``.
:arg list,tuple callout: a list / tuple of two or three :data:`point_like` objects, which will be interpreted as end point [, knee point] and start point (in this sequence) of up to two line segments, converting this annotation into a call-out shape.
:arg int line_end: the line end symbol of the call-out line. It is drawn at the first point specified in the `callout` list. Default is an open arrow. For possible values see :ref:`AnnotationLineEnds`.
:arg float opacity: a float `0 <= opacity < 1` turning the annotation transparent. Default is no transparency.
:arg int align: text alignment, one of TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT - justify is **not supported**. Ignored if `richtext=True`.
:arg int rotate: the text orientation. Accepted values are integer multiples of 90°. Invalid entries receive a rotation of 0.
:arg bool richtext: treat ``text`` as HTML syntax. This allows to achieve **bold**, *italic*, arbitrary text colors, font sizes, text alignment including justify and more - as far as the PDF subset of HTML and styling instructions supports this. This is similar to what happens in :meth:`Page.insert_htmlbox`. The base library will for example pull in required fonts if it encounters characters not contained in the standard ones. Some parameters are ignored if this option is set, as mentioned above. Default is ``False``.
:arg str style: supply optional HTML styling information in CSS syntax. Ignored if `richtext=False`.
:rtype: :ref:`Annot`
:returns: the created annotation.
|history_begin|
* Changed in v1.19.6: add border color parameter
|history_end|
.. method:: add_file_annot(pos, buffer, filename, ufilename=None, desc=None, icon="PushPin")
PDF only: Add a file attachment annotation with a "PushPin" icon at the specified location.
:arg point_like pos: the top-left point of a 18x18 rectangle containing the MuPDF-provided "PushPin" icon.
:arg bytes,bytearray,BytesIO buffer: the data to be stored (actual file content, any data, etc.).
Changed in v1.14.13: *io.BytesIO* is now also supported.
:arg str filename: the filename to associate with the data.
:arg str ufilename: the optional PDF unicode version of filename. Defaults to filename.
:arg str desc: an optional description of the file. Defaults to filename.
:arg str icon: choose one of "PushPin" (default), "Graph", "Paperclip", "Tag" as the visual symbol for the attached data [#f4]_. (New in v1.16.0)
:rtype: :ref:`Annot`
:returns: the created annotation. Stroke color yellow = (1, 1, 0), no fill color support.
.. method:: add_ink_annot(list)
PDF only: Add a "freehand" scribble annotation.
:arg sequence list: a list of one or more lists, each containing :data:`point_like` items. Each item in these sublists is interpreted as a :ref:`Point` through which a connecting line is drawn. Separate sublists thus represent separate drawing lines.
:rtype: :ref:`Annot`
:returns: the created annotation in default appearance black =(0, 0, 0),line width 1. No fill color support.
.. method:: add_line_annot(p1, p2)
PDF only: Add a line annotation.
:arg point_like p1: the starting point of the line.
:arg point_like p2: the end point of the line.
:rtype: :ref:`Annot`
:returns: the created annotation. It is drawn with line (stroke) color red = (1, 0, 0) and line width 1. No fill color support. The **annot rectangle** is automatically created to contain both points, each one surrounded by a circle of radius 3 * line width to make room for any line end symbols.
.. method:: add_rect_annot(rect)
.. method:: add_circle_annot(rect)
PDF only: Add a rectangle, resp. circle annotation.
:arg rect_like rect: the rectangle in which the circle or rectangle is drawn, must be finite and not empty. If the rectangle is not equal-sided, an ellipse is drawn.
:rtype: :ref:`Annot`
:returns: the created annotation. It is drawn with line (stroke) color red = (1, 0, 0), line width 1, fill color is supported.
---------
Redactions
~~~~~~~~~~~
.. method:: add_redact_annot(quad, text=None, fontname=None, fontsize=11, align=TEXT_ALIGN_LEFT, fill=(1, 1, 1), text_color=(0, 0, 0), cross_out=True)
**PDF only**: Add a redaction annotation. A redaction annotation identifies an area whose content should be removed from the document. Adding such an annotation is the first of two steps. It makes visible what will be removed in the subsequent step, :meth:`Page.apply_redactions`.
:arg quad_like,rect_like quad: specifies the (rectangular) area to be removed which is always equal to the annotation rectangle. This may be a :data:`rect_like` or :data:`quad_like` object. If a quad is specified, then the enveloping rectangle is taken.
:arg str text: text to be placed in the rectangle after applying the redaction (and thus removing old content). (New in v1.16.12)
:arg str fontname: the font to use when ``text`` is given, otherwise ignored. Only CJK and the :ref:`Base-14-Fonts` are supported. Apart from this, the same rules apply as for :meth:`Page.insert_textbox` -- which is what the method :meth:`Page.apply_redactions` internally invokes.
:arg float fontsize: the :data:`fontsize` to use for the replacing text. If the text is too large to fit, several insertion attempts will be made, gradually reducing the :data:`fontsize` to no less than 4. If then the text will still not fit, no text insertion will take place at all. (New in v1.16.12)
:arg int align: the horizontal alignment for the replacing text. See :meth:`insert_textbox` for available values. The vertical alignment is (approximately) centered.
:arg sequence fill: the fill color of the rectangle **after applying** the redaction. The default is *white = (1, 1, 1)*, which is also taken if ``None`` is specified. To suppress a fill color altogether, specify ``False``. In this cases the rectangle remains transparent. (New in v1.16.12)
:arg sequence text_color: the color of the replacing text. Default is *black = (0, 0, 0)*. (New in v1.16.12)
:arg bool cross_out: add two diagonal lines to the annotation rectangle. (New in v1.17.2)
:rtype: :ref:`Annot`
:returns: the created annotation. Its standard appearance looks like a red rectangle (no fill color), optionally showing two diagonal lines. Colors, line width, dashing, opacity and blend mode can now be set and applied via :meth:`Annot.update` like with other annotations. (Changed in v1.17.2)
.. image:: images/img-redact.*
|history_begin|
* New in v1.16.11
|history_end|
.. method:: apply_redactions(images=PDF_REDACT_IMAGE_PIXELS|2, graphics=PDF_REDACT_LINE_ART_REMOVE_IF_TOUCHED|2, text=PDF_REDACT_TEXT_REMOVE|0)
**PDF only**: Remove all **content** contained in any redaction rectangle on the page.
**This method applies and then deletes all redactions from the page.**
:arg int images: How to redact overlapping images. The default (2) blanks out overlapping pixels. `PDF_REDACT_IMAGE_NONE | 0` ignores, and `PDF_REDACT_IMAGE_REMOVE | 1` completely removes images overlapping any redaction annotation. Option `PDF_REDACT_IMAGE_REMOVE_UNLESS_INVISIBLE | 3` only removes images that are actually visible.
:arg int graphics: How to redact overlapping vector graphics (also called "line-art" or "drawings"). The default (2) removes any overlapping vector graphics. `PDF_REDACT_LINE_ART_NONE | 0` ignores, and `PDF_REDACT_LINE_ART_REMOVE_IF_COVERED | 1` removes graphics fully contained in a redaction annotation. When removing line-art, please be aware that **stroked** vector graphics (i.e. type "s" or "sf") have a **larger wrapping rectangle** than one might expect: first of all, at least 50% of the path's line width have to be added in each direction to truly include all of the drawing. If a so-called "miter limit" is provided (see page 121 of the PDF specification), the enlarging value is `miter * width / 2`. So, when letting everything default (width = 1, miter = 10), the redaction rectangle should be at least 5 points larger in every direction.
:arg int text: Whether to redact overlapping text. The default `PDF_REDACT_TEXT_REMOVE | 0` removes all characters whose boundary box overlaps any redaction rectangle. This complies with the original legal / data protection intentions of redaction annotations. Other use cases however may require to **keep text** while redacting vector graphics or images. This can be achieved by setting `text=True|PDF_REDACT_TEXT_NONE | 1`. This does **not comply** with the data protection intentions of redaction annotations. **Do so at your own risk.**
:returns: `True` if at least one redaction annotation has been processed, `False` otherwise.
.. note::
* Text contained in a redaction rectangle will be **physically** removed from the page (assuming :meth:`Document.save` with a suitable garbage option) and will no longer appear in e.g. text extractions or anywhere else. All redaction annotations will also be removed. Other annotations are unaffected.
* All overlapping links will be removed. If the rectangle of the link was covering text, then only the overlapping part of the text is being removed. Similar applies to images covered by link rectangles.
* The overlapping parts of **images** will be blanked-out for default option `PDF_REDACT_IMAGE_PIXELS` (changed in v1.18.0). Option 0 does not touch any images and 1 will remove any image with an overlap.
* For option `images=PDF_REDACT_IMAGE_REMOVE` only this page's **references to the images** are removed - not necessarily the images themselves. Images are completely removed from the file only, if no longer referenced at all (assuming suitable garbage collection options).
* For option `images=PDF_REDACT_IMAGE_PIXELS` a new image of format PNG is created, which the page will use in place of the original one. The original image is not deleted or replaced as part of this process, so other pages may still show the original. In addition, the new, modified PNG image currently is **stored uncompressed**. Do keep these aspects in mind when choosing the right garbage collection method and compression options during save.
* **Text removal** is done by character: A character is removed if its bbox has a **non-empty overlap** with a redaction rectangle (changed in MuPDF v1.17). Depending on the font properties and / or the chosen line height, deletion may occur for undesired text parts. Using :meth:`Tools.set_small_glyph_heights` with a ``True`` argument before text search may help to prevent this.
* Redactions are a simple way to replace single words in a PDF, or to just physically remove them. Locate the word "secret" using some text extraction or search method and insert a redaction using "xxxxxx" as replacement text for each occurrence.
- Be wary if the replacement is longer than the original -- this may lead to an awkward appearance, line breaks or no new text at all.
- For a number of reasons, the new text may not exactly be positioned on the same line like the old one -- especially true if the replacement font was not one of CJK or :ref:`Base-14-Fonts`.
|history_begin|
* New in v1.16.11
* Changed in v1.16.12: The previous *mark* parameter is gone. Instead, the respective rectangles are filled with the individual *fill* color of each redaction annotation. If a *text* was given in the annotation, then :meth:`insert_textbox` is invoked to insert it, using parameters provided with the redaction.
* Changed in v1.18.0: added option for handling images that overlap redaction areas.
* Changed in v1.23.27: added option for removing graphics as well.
* Changed in v1.24.2: added option `keep_text` to leave text untouched.
|history_end|
---------
.. method:: add_polyline_annot(points)
.. method:: add_polygon_annot(points)
PDF only: Add an annotation consisting of lines which connect the given points. A **Polygon's** first and last points are automatically connected, which does not happen for a **PolyLine**. The **rectangle** is automatically created as the smallest rectangle containing the points, each one surrounded by a circle of radius 3 (= 3 * line width). The following shows a 'PolyLine' that has been modified with colors and line ends.
:arg list points: a list of :data:`point_like` objects.
:rtype: :ref:`Annot`
:returns: the created annotation. It is drawn with line color black, line width 1 no fill color but fill color support. Use methods of :ref:`Annot` to make any changes to achieve something like this:
.. image:: images/img-polyline.*
:scale: 70
.. method:: add_underline_annot(quads=None, start=None, stop=None, clip=None)
.. method:: add_strikeout_annot(quads=None, start=None, stop=None, clip=None)
.. method:: add_squiggly_annot(quads=None, start=None, stop=None, clip=None)
.. method:: add_highlight_annot(quads=None, start=None, stop=None, clip=None)
PDF only: These annotations are normally used for **marking text** which has previously been somehow located (for example via :meth:`Page.search_for`). But this is not required: you are free to "mark" just anything.
Standard (stroke only -- no fill color support) colors are chosen per annotation type: **yellow** for highlighting, **red** for striking out, **green** for underlining, and **magenta** for wavy underlining.
All these four methods convert the arguments into a list of :ref:`Quad` objects. The **annotation** rectangle is then calculated to envelop all these quadrilaterals.
.. note::
:meth:`search_for` delivers a list of either :ref:`Rect` or :ref:`Quad` objects. Such a list can be directly used as an argument for these annotation types and will deliver **one common annotation** for all occurrences of the search string::
>>> # prefer quads=True in text searching for annotations!
>>> quads = page.search_for("pymupdf", quads=True)
>>> page.add_highlight_annot(quads)
.. note::
Obviously, text marker annotations need to know what is the top, the bottom, the left, and the right side of the area(s) to be marked. If the arguments are quads, this information is given by the sequence of the quad points. In contrast, a rectangle delivers much less information -- this is illustrated by the fact, that 4! = 24 different quads can be constructed with the four corners of a rectangle.
Therefore, we **strongly recommend** to use the `quads` option for text searches, to ensure correct annotations. A similar consideration applies to marking **text spans** extracted with the "dict" / "rawdict" options of :meth:`Page.get_text`. For more details on how to compute quadrilaterals in this case, see section "How to Mark Non-horizontal Text" of :ref:`FAQ`.
:arg rect_like,quad_like,list,tuple quads:
the location(s) -- rectangle(s) or quad(s) -- to be marked. (Changed in v1.14.20)
A list or tuple must consist of :data:`rect_like` or :data:`quad_like` items (or even a mixture of either).
Every item must be finite, convex and not empty (as applicable).
**Set this parameter to** ``None`` if you want to use the following arguments (Changed in v1.16.14).
And vice versa: if not ``None``, the remaining parameters must be ``None``.
:arg point_like start: start text marking at this point. Defaults to the top-left point of *clip*. Must be provided if `quads` is ``None``. (New in v1.16.14)
:arg point_like stop: stop text marking at this point. Defaults to the bottom-right point of *clip*. Must be used if `quads` is ``None``. (New in v1.16.14)
:arg rect_like clip: only consider text lines intersecting this area. Defaults to the page rectangle. Only use if `start` and `stop` are provided. (New in v1.16.14)
:rtype: :ref:`Annot` or ``None`` (changed in v1.16.14).
:returns: the created annotation. If *quads* is an empty list, **no annotation** is created (changed in v1.16.14).
.. note::
You can use parameters *start*, *stop* and *clip* to highlight consecutive lines between the points *start* and *stop* (starting with v1.16.14).
Make use of *clip* to further reduce the selected line bboxes and thus deal with e.g. multi-column pages.
The following multi-line highlight on a page with three text columns was created by specifying the two red points and setting clip accordingly.
.. image:: images/img-markers.*
:scale: 100
.. method:: cluster_drawings(clip=None, drawings=None, x_tolerance=3, y_tolerance=3, final_filter=True)
Cluster vector graphics (synonyms are line-art or drawings) based on their geometrical vicinity. The method walks through the output of :meth:`Page.get_drawings` and joins paths whose `path["rect"]` are closer to each other than some tolerance values (given in the arguments). The result is a list of rectangles that each wrap things like tables (with gridlines), pie charts, bar charts, etc.
:arg rect_like clip: only consider paths inside this area. The default is the full page.
:arg list drawings: (optional) provide a previously generated output of :meth:`Page.get_drawings`. If `None` the method will execute the method.
:arg float x_tolerance / y_tolerance: Assume vector graphics to be close enough neighbors for belonging to the same rectangle. Default is 3 points.
:arg bool final_filter: If `True` (default), the method will to remove rectangles having width or height smaller than the respective tolerance value. If `False` no such filtering is done.
.. method:: find_tables(clip=None, strategy=None, vertical_strategy=None, horizontal_strategy=None, vertical_lines=None, horizontal_lines=None, snap_tolerance=None, snap_x_tolerance=None, snap_y_tolerance=None, join_tolerance=None, join_x_tolerance=None, join_y_tolerance=None, edge_min_length=3, min_words_vertical=3, min_words_horizontal=1, intersection_tolerance=None, intersection_x_tolerance=None, intersection_y_tolerance=None, text_tolerance=None, text_x_tolerance=None, text_y_tolerance=None, add_lines=None)
Find tables on the page and return an object with related information. Typically, the default values of the many parameters will be sufficient. Adjustments should ever only be needed in corner case situations.
:arg rect_like clip: specify a region to consider within the page rectangle and ignore the rest. Default is the full page.
:arg str strategy: Request a **table detection** strategy. Valid values are "lines", "lines_strict" and "text".
Default is **"lines"** which uses all vector graphics on the page to detect grid lines.
Strategy **"lines_strict"** ignores borderless rectangle vector graphics. Sometimes single text pieces have background colors which may lead to false columns or lines. This strategy ignores them and can thus increase detection precision.
If **"text"** is specified, text positions are used to generate "virtual" column and / or row boundaries. Use `min_words_*` to request the number of words for considering their coordinates.
Use parameters `vertical_strategy` and `horizontal_strategy` **instead** for a more fine-grained treatment of the dimensions.
:arg sequence[floats] horizontal_lines: y-coordinates of rows. If provided, there will be no attempt to identify additional table rows. This influences table detection.
:arg sequence[floats] vertical_lines: x-coordinates of columns. If provided, there will be no attempt to identify additional table columns. This influences table detection.
:arg int min_words_vertical: relevant for vertical strategy option "text": at least this many words must coincide to establish a **virtual column** boundary.
:arg int min_words_horizontal: relevant for horizontal strategy option "text": at least this many words must coincide to establish a **virtual row** boundary.
:arg float snap_tolerance: Any two horizontal lines whose y-values differ by no more than this value will be **snapped** into one. Accordingly for vertical lines. Default is 3. Separate values can be specified instead for the dimensions, using `snap_x_tolerance` and `snap_y_tolerance`.
:arg float join_tolerance: Any two lines will be **joined** to one if the end and the start points differ by no more than this value (in points). Default is 3. Instead of this value, separate values can be specified for the dimensions using `join_x_tolerance` and `join_y_tolerance`.
:arg float edge_min_length: Ignore a line if its length does not exceed this value (points). Default is 3.
:arg float intersection_tolerance: When combining lines into cell borders, orthogonal lines must be within this value (points) to be considered intersecting. Default is 3. Instead of this value, separate values can be specified for the dimensions using `intersection_x_tolerance` and `intersection_y_tolerance`.
:arg float text_tolerance: Characters will be combined into words only if their distance is no larger than this value (points). Default is 3. Instead of this value, separate values can be specified for the dimensions using `text_x_tolerance` and `text_y_tolerance`.
:arg tuple,list add_lines: Specify a list of "lines" (i.e. pairs of :data:`point_like` objects) as **additional**, "virtual" vector graphics. These lines may help with table and / or cell detection and will not otherwise influence the detection strategy. Especially, in contrast to parameters `horizontal_lines` and `vertical_lines`, they will not prevent detecting rows or columns in other ways. These lines will be treated exactly like "real" vector graphics in terms of joining, snapping, intersectiing, minimum length and containment in the `clip` rectangle. Similarly, lines not parallel to any of the coordinate axes will be ignored.
.. image:: images/img-findtables.*
:returns: a `TableFinder` object that has the following significant attributes:
* `cells`: a list of **all bboxes** on the page, that have been identified as table cells (across all tables). Each cell is a :data:`rect_like` tuple `(x0, y0, x1, y1)` of coordinates or `None`.
* `tables`: a list of `Table` objects. This is `[]` if the page has no tables. Single tables can be found as items of this list. But the `TableFinder` object itself is also a sequence of its tables. This means that if `tabs` is a `TableFinder` object, then table "n" is delivered by `tabs.tables[n]` as well as by the shorter `tabs[n]`.
* The `Table` object has the following attributes:
* ``bbox``: the bounding box of the table as a tuple `(x0, y0, x1, y1)`.
* ``cells``: bounding boxes of the table's cells (list of tuples). A cell may also be `None`.
* ``extract()``: this method returns the text content of each table cell as a list of list of strings.
* ``to_markdown()``: this method returns the table as a **string in markdown format** (compatible to Github). Supporting viewers can render the string as a table. This output is optimized for **small token** sizes, which is especially beneficial for LLM/RAG feeds. Pandas DataFrames (see method `to_pandas()` below) offer an equivalent markdown table output which however is better readable for the human eye.
* `to_pandas()`: this method returns the table as a `pandas <https://pypi.org/project/pandas/>`_ `DataFrame <https://pandas.pydata.org/docs/reference/frame.html>`_. DataFrames are very versatile objects allowing a plethora of table manipulation methods and outputs to almost 20 well-known formats, among them Excel files, CSV, JSON, markdown-formatted tables and more. `DataFrame.to_markdown()` generates a Github-compatible markdown format optimized for human readability. This method however requires the package `tabulate <https://pypi.org/project/tabulate/>`_ to be installed in addition to pandas itself.
* ``header``: a `TableHeader` object containing header information of the table.
* ``col_count``: an integer containing the number of table columns.
* ``row_count``: an integer containing the number of table rows.
* ``rows``: a list of `TableRow` objects containing two attributes, ``bbox`` is the boundary box of the row, and `cells` is a list of table cells contained in this row.
* The `TableHeader` object has the following attributes:
* ``bbox``: the bounding box of the header.
* `cells`: a list of bounding boxes containing the name of the respective column.
* `names`: a list of strings containing the text of each of the cell bboxes. They represent the column names -- which are used when exporting the table to pandas DataFrames, markdown, etc.
* `external`: a bool indicating whether the header bbox is outside the table body (`True`) or not. Table headers are never identified by the `TableFinder` logic. Therefore, if `external` is true, then the header cells are not part of any cell identified by `TableFinder`. If `external == False`, then the first table row is the header.
Please have a look at these `Jupyter notebooks <https://github.com/pymupdf/PyMuPDF-Utilities/tree/master/table-analysis>`_, which cover standard situations like multiple tables on one page or joining table fragments across multiple pages.
.. caution:: The lifetime of the `TableFinder` object, as well as that of all its tables **equals the lifetime of the page**. If the page object is deleted or reassigned, all tables are no longer valid.
The only way to keep table content beyond the page's availability is to **extract it** via methods `Table.to_markdown()`, `Table.to_pandas()` or a copy of `Table.extract()` (e.g. `Table.extract()[:]`).
.. note::
Once a table has been extracted to a **Pandas DataFrame** with `to_pandas()` it is easy to convert to other file types with the **Pandas API**:
- table to Markdown, use `to_markdown <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_markdown.html#pandas.DataFrame.to_markdown>`_
- table to JSON, use: `to_json <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html>`_
- table to Excel, use: `to_excel <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_excel.html>`_
- table to CSV, use: `to_csv <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html>`_
- table to HTML, use: `to_html <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_html.html>`_
- table to SQL, use: `to_sql <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_sql.html>`_
|history_begin|
* New in version 1.23.0
* Changed in version 1.23.19: new argument `add_lines`.
|history_end|
.. important::
There is also the `pdf2docx extract tables method`_ which is capable of table extraction if you prefer.
.. method:: add_stamp_annot(rect, stamp=0)
PDF only: Add a "rubber stamp" annotation to e.g. indicate the document's intended use ("DRAFT", "CONFIDENTIAL", etc.). The parameter may be either an integer to select text from a predefined array of standard texts or an image.
:arg rect_like rect: rectangle where to place the annotation.
:arg multiple stamp: The following options are available:
* The id number (int) of the stamp text. For available stamps see :ref:`StampIcons`.
* A string specifying an image file path.
* A ``bytes``, ``bytearray`` or ``io.BytesIO`` object for an image in memory.
* A :ref:`Pixmap`.
1. **Text-based stamps**
* :attr:`Annot.rect` is automatically calculated as the largest rectangle with an aspect ratio of ``width:height = 3.8`` that fits in the provided ``rect``. Its position is vertically and horizontally centered.
* The font chosen is "Times Bold" and the text will be upper case.
* The appearance can be modified using :meth:`Annot.set_opacity` and by setting the "stroke" color. By PDF specification, stamp annotations have no "fill" color.
.. image:: images/img-stampannot.*
2. **Image-based stamps**
* The image is scaled to fit into the rectangle `rect` such that the image's center and the center of `rect` coincide. The aspect ratio of the image is preserved, so the image may not fill the entire rectangle. However, at least one of the given rectangle's width or height are fully covered.
* The annotation can be modified via :meth:`Annot.set_opacity`. This method therefore is a way to display images transparently even if no alpha channel is present.
* Setting colors has no effect on image stamps.
* Rotating image-based stamps **is not supported**. Setting the rotation may lead to unexpected results.
.. method:: add_widget(widget)
PDF only: Add a PDF Form field ("widget") to a page. This also **turns the PDF into a Form PDF**. Because of the large amount of different options available for widgets, we have developed a new class :ref:`Widget`, which contains the possible PDF field attributes. It must be used for both, form field creation and updates.
:arg widget: a :ref:`Widget` object which must have been created upfront.
:type widget: :ref:`Widget`
:returns: a widget annotation.
.. method:: delete_annot(annot)
* The removal will now include any bound 'Popup' or response annotations and related objects (changed in v1.16.6).
PDF only: Delete annotation from the page and return the next one.
:arg annot: the annotation to be deleted.
:type annot: :ref:`Annot`
:rtype: :ref:`Annot`
:returns: the annotation following the deleted one. Please remember that physical removal requires saving to a new file with garbage > 0.
.. method:: delete_widget(widget)
PDF only: Delete field from the page and return the next one.
:arg widget: the widget to be deleted.
:type widget: :ref:`Widget`
:rtype: :ref:`Widget`
:returns: the widget following the deleted one. Please remember that physical removal requires saving to a new file with garbage > 0.
|history_begin|
(New in v1.18.4)
|history_end|
.. method:: delete_link(linkdict)
PDF only: Delete the specified link from the page. The parameter must be an **original item** of :meth:`get_links()`, see :ref:`link_dict_description`. The reason for this is the dictionary's *"xref"* key, which identifies the PDF object to be deleted.
:arg dict linkdict: the link to be deleted.
.. method:: insert_link(linkdict)
PDF only: Insert a new link on this page. The parameter must be a dictionary of format as provided by :meth:`get_links()`, see :ref:`link_dict_description`.
:arg dict linkdict: the link to be inserted.
.. method:: update_link(linkdict)
PDF only: Modify the specified link. The parameter must be a (modified) **original item** of :meth:`get_links()`, see :ref:`link_dict_description`. The reason for this is the dictionary's *"xref"* key, which identifies the PDF object to be changed.
:arg dict linkdict: the link to be modified.
.. warning:: If updating / inserting a URI link (`"kind": LINK_URI`), please make sure to start the value for the `"uri"` key with a disambiguating string like `"http://"`, `"https://"`, `"file://"`, `"ftp://"`, `"mailto:"`, etc. Otherwise -- depending on your browser or other "consumer" software -- unexpected default assumptions may lead to unwanted behaviours.
.. method:: get_label()
PDF only: Return the label for the page.
:rtype: str
:returns: the label string like "vii" for Roman numbering or "" if not defined.
|history_begin|
* New in v1.18.6
|history_end|
.. method:: get_links()
Retrieves **all** links of a page.
:rtype: list
:returns: A list of dictionaries. For a description of the dictionary entries, see :ref:`link_dict_description`. Always use this or the :meth:`Page.links` method if you intend to make changes to the links of a page.
.. method:: links(kinds=None)
Return a generator over the page's links. The results equal the entries of :meth:`Page.get_links`.
:arg sequence kinds: a sequence of integers to down-select to one or more link kinds. Default is all links. Example: *kinds=(pymupdf.LINK_GOTO,)* will only return internal links.
:rtype: generator
:returns: an entry of :meth:`Page.get_links()` for each iteration.
|history_begin|
* New in v1.16.4
|history_end|
.. method:: annots(types=None)
Return a generator over the page's annotations.
:arg sequence types: a sequence of integers to down-select to one or more annotation types. Default is all annotations. Example: `types=(pymupdf.PDF_ANNOT_FREETEXT, pymupdf.PDF_ANNOT_TEXT)` will only return 'FreeText' and 'Text' annotations.
:rtype: generator
:returns: an :ref:`Annot` for each iteration.
.. caution::
You **cannot safely update annotations** from within this generator. This is because most annotation updates require reloading the page via `page = doc.reload_page(page)`. To circumvent this restriction, make a list of annotations xref numbers first and then iterate over these numbers::
In [4]: xrefs = [annot.xref for annot in page.annots(types=[...])]
In [5]: for xref in xrefs:
...: annot = page.load_annot(xref)
...: annot.update()
...: page = doc.reload_page(page)
In [6]:
|history_begin|
* New in v1.16.4
|history_end|
.. method:: widgets(types=None)
Return a generator over the page's form fields.
:arg sequence types: a sequence of integers to down-select to one or more widget types. Default is all form fields. Example: `types=(pymupdf.PDF_WIDGET_TYPE_TEXT,)` will only return 'Text' fields.
:rtype: generator
:returns: a :ref:`Widget` for each iteration.
|history_begin|
* New in v1.16.4
|history_end|
.. method:: write_text(rect=None, writers=None, overlay=True, color=None, opacity=None, keep_proportion=True, rotate=0, oc=0)
PDF only: Write the text of one or more :ref:`Textwriter` objects to the page.
:arg rect_like rect: where to place the text. If omitted, the rectangle union of the text writers is used.
:arg sequence writers: a non-empty tuple / list of :ref:`TextWriter` objects or a single :ref:`TextWriter`.
:arg float opacity: set transparency, overwrites resp. value in the text writers.
:arg sequ color: set the text color, overwrites resp. value in the text writers.
:arg bool overlay: put the text in foreground or background.
:arg bool keep_proportion: maintain the aspect ratio.
:arg float rotate: rotate the text by an arbitrary angle.
:arg int oc: the :data:`xref` of an :data:`OCG` or :data:`OCMD`. (New in v1.18.4)
.. note:: Parameters *overlay, keep_proportion, rotate* and *oc* have the same meaning as in :meth:`Page.show_pdf_page`.
|history_begin|
* New in v1.16.18
|history_end|
.. index::
pair: border_width; insert_text
pair: color; insert_text
pair: encoding; insert_text
pair: fill; insert_text
pair: fontfile; insert_text
pair: fontname; insert_text
pair: fontsize; insert_text
pair: morph; insert_text
pair: overlay; insert_text
pair: render_mode; insert_text
pair: miter_limit; insert_text
pair: rotate; insert_text
pair: stroke_opacity; insert_text
pair: fill_opacity; insert_text
pair: oc; insert_text
.. method:: insert_text(point, text, *, fontsize=11, fontname="helv", fontfile=None, idx=0, color=None, fill=None, render_mode=0, miter_limit=1, border_width=0.05, encoding=TEXT_ENCODING_LATIN, rotate=0, morph=None, stroke_opacity=1, fill_opacity=1, overlay=True, oc=0)
PDF only: Insert text lines starting at :data:`point_like` ``point``. See :meth:`Shape.insert_text`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: align; insert_textbox
pair: border_width; insert_textbox
pair: color; insert_textbox
pair: encoding; insert_textbox
pair: expandtabs; insert_textbox
pair: fill; insert_textbox
pair: fontfile; insert_textbox
pair: fontname; insert_textbox
pair: fontsize; insert_textbox
pair: morph; insert_textbox
pair: overlay; insert_textbox
pair: render_mode; insert_textbox
pair: miter_limit; insert_textbox
pair: rotate; insert_textbox
pair: stroke_opacity; insert_textbox
pair: fill_opacity; insert_textbox
pair: oc; insert_textbox
.. method:: insert_textbox(rect, buffer, *, fontsize=11, fontname="helv", fontfile=None, idx=0, color=None, fill=None, render_mode=0, miter_limit=1, border_width=1, encoding=TEXT_ENCODING_LATIN, expandtabs=8, align=TEXT_ALIGN_LEFT, charwidths=None, rotate=0, morph=None, stroke_opacity=1, fill_opacity=1, oc=0, overlay=True)
PDF only: Insert text into the specified :data:`rect_like` *rect*. See :meth:`Shape.insert_textbox`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: rect; insert_htmlbox
pair: text; insert_htmlbox
pair: css; insert_htmlbox
pair: adjust; insert_htmlbox
pair: archive; insert_htmlbox
pair: overlay; insert_htmlbox
pair: rotate; insert_htmlbox
pair: oc; insert_htmlbox
pair: opacity; insert_htmlbox
pair: morph; insert_htmlbox
.. method:: insert_htmlbox(rect, text, *, css=None, scale_low=0, archive=None, rotate=0, oc=0, opacity=1, overlay=True)
**PDF only:** Insert text into the specified rectangle. The method has similarities with methods :meth:`Page.insert_textbox` and :meth:`TextWriter.fill_textbox`, but is **much more powerful**. This is achieved by letting a :ref:`Story` object do all the required processing.
* Parameter ``text`` may be a string as in the other methods. But it will be **interpreted as HTML source** and may therefore also contain HTML language elements -- including styling. The `css` parameter may be used to pass in additional styling instructions.
* Automatic line breaks are generated at word boundaries. The "soft hyphen" character `"­"` (or `­`) can be used to cause hyphenation and thus may also cause line breaks. **Forced** line breaks however are only achievable via the HTML tag ``<br>`` - ``\n`` is ignored and will be treated like a space.
* With this method the following can be achieved:
- Styling effects like bold, italic, text color, text alignment, font size or font switching.
- The text may include arbitrary languages -- **including right-to-left** languages.
- Scripts like `Devanagari <https://en.wikipedia.org/wiki/Devanagari>`_ and several others in Asia have a highly complex system of ligatures, where two or more unicodes together yield one glyph. The Story uses the software package `HarfBuzz <https://harfbuzz.github.io/>`_ , to deal with these things and produce correct output.
- One can also **include images** via HTML tag `<img>` -- the Story will take care of the appropriate layout. This is an alternative option to insert images, compared to :meth:`Page.insert_image`.
- HTML tables (tag `<table>`) may be included in the text and will be handled appropriately.
- Links are automatically generated when present.
* If content does not fit in the rectangle, the developer has two choices:
- **either** only be informed about this (and accept a no-op, just like with the other textbox insertion methods),
- **or** (`scale_low=0` - the default) scale down the content until it fits.
:arg rect_like rect: rectangle on page to receive the text.
:arg str,Story text: the text to be written. Can contain a mixture of plain text and HTML tags with styling instructions. Alternatively, a :ref:`Story` object may be specified (in which case the internal Story generation step will be omitted). A Story must have been generated with all required styling and Archive information.
:arg str css: optional string containing additional CSS instructions. This parameter is ignored if ``text`` is a Story.
:arg float scale_low: if necessary, scale down the content until it fits in the target rectangle. This sets the down scaling limit. Default is 0, no limit. A value of 1 means no down-scaling permitted. A value of e.g. 0.2 means maximum down-scaling by 80%.
:arg Archive archive: an Archive object that points to locations where to find images or non-standard fonts. If ``text`` refers to images or non-standard fonts, this parameter is required. This parameter is ignored if ``text`` is a Story.
:arg int rotate: one of the values 0, 90, 180, 270. Depending on this, text will be filled:
- 0: top-left to bottom-right.
- 90: bottom-left to top-right.
- 180: bottom-right to top-left.
- 270: top-right to bottom-left.
.. image:: images/img-rotate.*
:arg int oc: the xref of an :data:`OCG` / :data:`OCMD` or 0. Please refer to :meth:`Page.show_pdf_page` for details.
:arg float opacity: set the fill and stroke opacity of the content. Only values `0 <= opacity < 1` are considered.
:arg bool overlay: put the text in front of other content. Please refer to :meth:`Page.show_pdf_page` for details.
:returns: A tuple of floats `(spare_height, scale)`.
- `spare_height`: -1 if content did not fit, else >= 0. It is the height of the unused (still available) rectangle stripe. Positive only if scale = 1 (no down-scaling happened).
- `scale`: down-scaling factor, 0 < scale <= 1.
Please refer to examples in this section of the recipes: :ref:`RecipesText_I_c`.
|history_begin|
* New in v1.23.8; rebased-only.
* New in v1.23.9: `opacity` parameter.
|history_end|
**Drawing Methods**
.. index::
pair: closePath; draw_line
pair: color; draw_line
pair: dashes; draw_line
pair: fill; draw_line
pair: lineCap; draw_line
pair: lineJoin; draw_line
pair: lineJoin; draw_line
pair: morph; draw_line
pair: overlay; draw_line
pair: width; draw_line
pair: stroke_opacity; draw_line
pair: fill_opacity; draw_line
pair: oc; draw_line
.. method:: draw_line(p1, p2, color=(0,), width=1, dashes=None, lineCap=0, lineJoin=0, overlay=True, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw a line from *p1* to *p2* (:data:`point_like` \s). See :meth:`Shape.draw_line`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: breadth; draw_zigzag
pair: closePath; draw_zigzag
pair: color; draw_zigzag
pair: dashes; draw_zigzag
pair: fill; draw_zigzag
pair: lineCap; draw_zigzag
pair: lineJoin; draw_zigzag
pair: morph; draw_zigzag
pair: overlay; draw_zigzag
pair: width; draw_zigzag
pair: stroke_opacity; draw_zigzag
pair: fill_opacity; draw_zigzag
pair: oc; draw_zigzag
.. method:: draw_zigzag(p1, p2, breadth=2, color=(0,), width=1, dashes=None, lineCap=0, lineJoin=0, overlay=True, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw a zigzag line from *p1* to *p2* (:data:`point_like` \s). See :meth:`Shape.draw_zigzag`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: breadth; draw_squiggle
pair: closePath; draw_squiggle
pair: color; draw_squiggle
pair: dashes; draw_squiggle
pair: fill; draw_squiggle
pair: lineCap; draw_squiggle
pair: lineJoin; draw_squiggle
pair: morph; draw_squiggle
pair: overlay; draw_squiggle
pair: width; draw_squiggle
pair: stroke_opacity; draw_squiggle
pair: fill_opacity; draw_squiggle
pair: oc; draw_squiggle
.. method:: draw_squiggle(p1, p2, breadth=2, color=(0,), width=1, dashes=None, lineCap=0, lineJoin=0, overlay=True, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw a squiggly (wavy, undulated) line from *p1* to *p2* (:data:`point_like` \s). See :meth:`Shape.draw_squiggle`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: closePath; draw_circle
pair: color; draw_circle
pair: dashes; draw_circle
pair: fill; draw_circle
pair: lineCap; draw_circle
pair: lineJoin; draw_circle
pair: morph; draw_circle
pair: overlay; draw_circle
pair: width; draw_circle
pair: stroke_opacity; draw_circle
pair: fill_opacity; draw_circle
pair: oc; draw_circle
.. method:: draw_circle(center, radius, color=(0,), fill=None, width=1, dashes=None, lineCap=0, lineJoin=0, overlay=True, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw a circle around *center* (:data:`point_like`) with a radius of *radius*. See :meth:`Shape.draw_circle`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: closePath; draw_oval
pair: color; draw_oval
pair: dashes; draw_oval
pair: fill; draw_oval
pair: lineCap; draw_oval
pair: lineJoin; draw_oval
pair: morph; draw_oval
pair: overlay; draw_oval
pair: width; draw_oval
pair: stroke_opacity; draw_oval
pair: fill_opacity; draw_oval
pair: oc; draw_oval
.. method:: draw_oval(quad, color=(0,), fill=None, width=1, dashes=None, lineCap=0, lineJoin=0, overlay=True, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw an oval (ellipse) within the given :data:`rect_like` or :data:`quad_like`. See :meth:`Shape.draw_oval`.
|history_begin|
* Changed in v1.18.4
|history_end|
.. index::
pair: closePath; draw_sector
pair: color; draw_sector
pair: dashes; draw_sector
pair: fill; draw_sector
pair: fullSector; draw_sector
pair: lineCap; draw_sector
pair: lineJoin; draw_sector
pair: morph; draw_sector
pair: overlay; draw_sector
pair: width; draw_sector
pair: stroke_opacity; draw_sector
pair: fill_opacity; draw_sector
pair: oc; draw_sector
.. method:: draw_sector(center, point, angle, color=(0,), fill=None, width=1, dashes=None, lineCap=0, lineJoin=0, fullSector=True, overlay=True, closePath=False, morph=None, stroke_opacity=1, fill_opacity=1, oc=0)
PDF only: Draw a circular sector, optionally connecting the arc to the circle's center (like a piece of pie). See :meth:`Shape.draw_sector`.