Skip to content

Commit

Permalink
Improve media coordinates
Browse files Browse the repository at this point in the history
- use a tuple istead of a Poppler.Rectangle
- only transform to margins at last stage, keep coordinates as long as possible
  - in particular simplify PdfPage.to_screen() semantics
- shift medias that are on bottom or right page when they are notes pages
  • Loading branch information
Cimbali committed May 18, 2024
1 parent 18563db commit 9df1e17
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 29 deletions.
34 changes: 18 additions & 16 deletions pympress/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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):
Expand Down Expand Up @@ -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.])

Expand Down Expand Up @@ -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:
Expand All @@ -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))

Expand Down Expand Up @@ -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:
Expand All @@ -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))

Expand Down
41 changes: 28 additions & 13 deletions pympress/media_overlays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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):
Expand All @@ -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):
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 9df1e17

Please sign in to comment.