diff --git a/pympress/document.py b/pympress/document.py index c2b0da06..4cb8cd26 100644 --- a/pympress/document.py +++ b/pympress/document.py @@ -167,8 +167,8 @@ def to_screen(val, x, y, x2 = None, y2 = None): Args: x (`float`): x coordinate on the page, on a scale 0..1 y (`float`): y coordinate on the page, on a scale 0..1 - x2 (`float`): second x coordinate on the page, from the other side, on a scale 0..1 - y2 (`float`): second y coordinate on the page, from the other side, on a scale 0..1 + x2 (`float`): optional second x coordinate on the page, on a scale 0..1 + y2 (`float`): optional second y coordinate on the page, on a scale 0..1 """ if val == PdfPage.RIGHT: screen = (x * 2 - 1, y) @@ -184,7 +184,7 @@ def to_screen(val, x, y, x2 = None, y2 = None): if x2 is None or y2 is None: return screen else: - return screen + val.complement().to_screen(x2, y2) + return screen + val.to_screen(x2, y2) class Link(object): @@ -242,7 +242,7 @@ def build_closure(fun, *args, **kwargs): #: A class that holds all the properties for media files -Media = collections.namedtuple('Media', ['relative_margins', 'filename', 'autoplay', 'repeat', 'poster', +Media = collections.namedtuple('Media', ['x1', 'y1', 'x2', 'y2', 'filename', 'autoplay', 'repeat', 'poster', 'show_controls', 'type', 'start_pos', 'duration'], defaults=[False, False, False, False, '', 0., 0.]) @@ -315,11 +315,12 @@ def __init__(self, page, number, parent): logger.error(_("Pympress can not find file ") + movie.get_filename()) continue - relative_margins = Poppler.Rectangle() - relative_margins.x1 = annotation.area.x1 / self.pw # left - relative_margins.x2 = 1.0 - annotation.area.x2 / self.pw # right - relative_margins.y1 = annotation.area.y1 / self.ph # bottom - relative_margins.y2 = 1.0 - annotation.area.y2 / self.ph # top + media_rect = ( + annotation.area.x1 / self.pw, # left + 1 - annotation.area.y2 / self.ph, # top + annotation.area.x2 / self.pw, # right + 1 - annotation.area.y1 / self.ph, # bottom + ) movie_options = {'show_controls': movie.show_controls(), 'poster': movie.need_poster()} try: @@ -330,7 +331,7 @@ def __init__(self, page, number, parent): except AttributeError: pass # Missing functions in pre-21.04 Poppler versions - media = Media(relative_margins, filepath, **movie_options) + media = Media(*media_rect, filepath, **movie_options) self.medias.append(media) action = Link.build_closure(self.parent.play_media, hash(media)) @@ -497,11 +498,12 @@ def get_annot_action(self, link_type, action, rect): logger.error(_("Pympress can not find file ") + media.get_filename()) return None - relative_margins = Poppler.Rectangle() - relative_margins.x1 = rect.x1 / self.pw # left - relative_margins.x2 = 1.0 - rect.x2 / self.pw # right - relative_margins.y1 = rect.y1 / self.ph # bottom - relative_margins.y2 = 1.0 - rect.y2 / self.ph # top + media_rect = ( + rect.x1 / self.pw, # left + 1 - rect.y2 / self.ph, # top + rect.x2 / self.pw, # right + 1 - rect.y1 / self.ph, # bottom + ) media_options = {'type': media.get_mime_type()} try: @@ -511,7 +513,7 @@ def get_annot_action(self, link_type, action, rect): # NB: no poster in Poppler’s MediaParameters except AttributeError: pass - media = Media(relative_margins, filename, **media_options) + media = Media(*media_rect, filename, **media_options) self.medias.append(media) return Link.build_closure(self.parent.play_media, hash(media)) diff --git a/pympress/media_overlays/base.py b/pympress/media_overlays/base.py index 7aabf6c3..214f001d 100644 --- a/pympress/media_overlays/base.py +++ b/pympress/media_overlays/base.py @@ -34,7 +34,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import GLib, Gio -from pympress import builder +from pympress import document, builder class VideoOverlay(builder.Builder): @@ -59,10 +59,10 @@ class VideoOverlay(builder.Builder): progress = None #: :class:`~Gtk.DrawingArea` where the media is rendered. movie_zone = None - #: `tuple` containing the left/top/right/bottom space around the drawing area in the PDF page - relative_page_margins = None - #: `tuple` containing the left/top/right/bottom space around the drawing area in the visible slide - relative_margins = None + #: `tuple` containing the left/top/right/bottom coordinates of the drawing area in the PDF page + relative_rect = None + #: `tuple` containing the left/top/right/bottom coordinates of the drawing area in the visible slide + rect = None #: `bool` that tracks whether we should play automatically autoplay = False #: `bool` that tracks whether we should play after we finished playing @@ -92,7 +92,7 @@ def __init__(self, container, page_type, action_map, media): super(VideoOverlay, self).__init__() self.parent = container - self.relative_page_margins = tuple(getattr(media.relative_margins, v) for v in ('x1', 'y2', 'x2', 'y1')) + self.relative_rect = (media.x1, media.y1, media.x2, media.y2) self.update_margins_for_page(page_type) self.load_ui('media_overlay') @@ -187,7 +187,21 @@ def update_margins_for_page(self, page_type): Arguments: page_type (:class:`~pympress.document.PdfPage`): the part of the page to display """ - self.relative_margins = page_type.to_screen(*self.relative_page_margins) + left, top, right, bot = page_type.to_screen(*self.relative_rect) + + # Some configurations generate incorrect media positions. Assume no one intentionally puts media on notes pages. + if page_type == document.PdfPage.RIGHT and -1 <= left < right <= 0: + left, right = left + 1, right + 1 + logger.warning('Shifting media from LEFT notes page to RIGHT content page') + + if page_type == document.PdfPage.TOP and 1 <= top < bot <= 2: + top, bot = top - 1, bot - 1 + logger.warning('Shifting media from BOTTOM notes page to TOP content page') + + self.rect = left, top, right, bot + if min(self.rect) < 0 or max(self.rect) > 1: + logger.warning('Negative margin(s) clipped to 0 (might alter the aspect ratio?): ' + + 'LTRB = {}'.format(self.rect)) def resize(self): @@ -197,10 +211,11 @@ def resize(self): return pw, ph = self.parent.get_allocated_width(), self.parent.get_allocated_height() - self.media_overlay.props.margin_left = pw * max(self.relative_margins[0], 0) - self.media_overlay.props.margin_right = pw * max(self.relative_margins[2], 0) - self.media_overlay.props.margin_bottom = ph * max(self.relative_margins[3], 0) - self.media_overlay.props.margin_top = ph * max(self.relative_margins[1], 0) + left, top, right, bot = self.rect + self.media_overlay.props.margin_left = pw * max(left, 0) + self.media_overlay.props.margin_right = pw * min(1 - right, 1) + self.media_overlay.props.margin_bottom = ph * min(1 - bot, 1) + self.media_overlay.props.margin_top = ph * max(top, 0) def is_shown(self): @@ -239,9 +254,9 @@ def _set_file(self, filepath): def show(self): """ Bring the widget to the top of the overlays if necessary. """ - if min(self.relative_margins) < 0: + if min(self.rect) < 0 or max(self.rect) > 1: logger.warning('Negative margin(s) clipped to 0 (might alter the aspect ratio?): ' + - 'LTRB = {}'.format(self.relative_margins)) + 'LTRB = {}'.format(self.rect)) if not self.media_overlay.get_parent(): self.parent.add_overlay(self.media_overlay)