Set page rotation to 0 while maintaining visual appearance.
(self)
| 11857 | return pix |
| 11858 | |
| 11859 | def remove_rotation(self): |
| 11860 | """Set page rotation to 0 while maintaining visual appearance.""" |
| 11861 | rot = self.rotation # normalized rotation value |
| 11862 | if rot == 0: |
| 11863 | return Identity # nothing to do |
| 11864 | |
| 11865 | # need to derotate the page's content |
| 11866 | mb = self.mediabox # current mediabox |
| 11867 | |
| 11868 | if rot == 90: |
| 11869 | # before derotation, shift content horizontally |
| 11870 | mat0 = Matrix(1, 0, 0, 1, mb.y1 - mb.x1 - mb.x0 - mb.y0, 0) |
| 11871 | elif rot == 270: |
| 11872 | # before derotation, shift content vertically |
| 11873 | mat0 = Matrix(1, 0, 0, 1, 0, mb.x1 - mb.y1 - mb.y0 - mb.x0) |
| 11874 | else: # rot = 180 |
| 11875 | mat0 = Matrix(1, 0, 0, 1, -2 * mb.x0, -2 * mb.y0) |
| 11876 | |
| 11877 | # prefix with derotation matrix |
| 11878 | mat = mat0 * self.derotation_matrix |
| 11879 | cmd = _format_g(tuple(mat)) + ' cm ' |
| 11880 | cmd = cmd.encode('utf8') |
| 11881 | _ = TOOLS._insert_contents(self, cmd, False) # prepend to page contents |
| 11882 | |
| 11883 | # swap x- and y-coordinates |
| 11884 | if rot in (90, 270): |
| 11885 | x0, y0, x1, y1 = mb |
| 11886 | mb.x0 = y0 |
| 11887 | mb.y0 = x0 |
| 11888 | mb.x1 = y1 |
| 11889 | mb.y1 = x1 |
| 11890 | self.set_mediabox(mb) |
| 11891 | |
| 11892 | self.set_rotation(0) |
| 11893 | rot = ~mat # inverse of the derotation matrix |
| 11894 | |
| 11895 | for annot in self.annots(): # modify rectangles of annotations |
| 11896 | r = annot.rect * rot |
| 11897 | # TODO: only try to set rectangle for applicable annot types |
| 11898 | annot.set_rect(r) |
| 11899 | for link in self.get_links(): # modify 'from' rectangles of links |
| 11900 | r = link["from"] * rot |
| 11901 | self.delete_link(link) |
| 11902 | link["from"] = r |
| 11903 | try: # invalid links remain deleted |
| 11904 | self.insert_link(link) |
| 11905 | except Exception: |
| 11906 | pass |
| 11907 | for widget in self.widgets(): # modify field rectangles |
| 11908 | r = widget.rect * rot |
| 11909 | widget.rect = r |
| 11910 | widget.update() |
| 11911 | return rot # the inverse of the generated derotation matrix |
| 11912 | |
| 11913 | def cluster_drawings( |
| 11914 | self, clip=None, drawings=None, x_tolerance: float = 3, y_tolerance: float = 3, |