From 83ed3402263008a337c5e6a36904871cd3237876 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 08:17:09 +0000 Subject: [PATCH 1/3] Initial plan From 452abf332816e81949a27d9d696753159f171783 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 08:26:28 +0000 Subject: [PATCH 2/3] Add include_positioning parameter to BaseWriter to control positioning output Co-authored-by: lorandvarga <7048551+lorandvarga@users.noreply.github.com> --- docs/introduction.rst | 5 +++- pycaption/base.py | 9 ++++++- pycaption/webvtt.py | 2 +- tests/test_base.py | 56 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/introduction.rst b/docs/introduction.rst index 408ea1f7..e8299298 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -147,7 +147,7 @@ Positioning Some caption formats support positioning information and PyCaption tries to preserve it when possible. In the process, some adjustments are made. Some of these adjustments can be customized by properly initializing the Writer class. -.. py:class:: BaseWriter(relativize=True, video_width=None, video_height=None, fit_to_screen=True) +.. py:class:: BaseWriter(relativize=True, video_width=None, video_height=None, fit_to_screen=True, include_positioning=True) :param relativize: If True (default), converts absolute positioning values (e.g. px) to percentage. ATTENTION: WebVTT does not support @@ -163,6 +163,9 @@ Some caption formats support positioning information and PyCaption tries to pres (re)calculate it based on origin. It is a pycaption fix for caption files that are technically valid but contains inconsistent settings that may cause long captions to be cut out of the screen. + :param include_positioning: If True (default), positioning information + is processed and included in the output. If False, all positioning + information is ignored and default positioning is used. Examples ~~~~~~~~ diff --git a/pycaption/base.py b/pycaption/base.py index 1fa77895..3978a155 100644 --- a/pycaption/base.py +++ b/pycaption/base.py @@ -52,7 +52,8 @@ def read(self, content): class BaseWriter: def __init__( - self, relativize=True, video_width=None, video_height=None, fit_to_screen=True + self, relativize=True, video_width=None, video_height=None, fit_to_screen=True, + include_positioning=True ): """ Initialize writer with the given parameters. @@ -72,13 +73,19 @@ def __init__( It is a pycaption fix for caption files that are technically valid but contains inconsistent settings that may cause long captions to be cut out of the screen. + :param include_positioning: If True (default), positioning information + is processed and included in the output. If False, all positioning + information is ignored and default positioning is used. """ self.relativize = relativize self.video_width = video_width self.video_height = video_height self.fit_to_screen = fit_to_screen + self.include_positioning = include_positioning def _relativize_and_fit_to_screen(self, layout_info): + if not self.include_positioning: + return None if layout_info: if self.relativize: # Transform absolute values (e.g. px) into percentages diff --git a/pycaption/webvtt.py b/pycaption/webvtt.py index c3573b29..8c54516c 100644 --- a/pycaption/webvtt.py +++ b/pycaption/webvtt.py @@ -301,7 +301,7 @@ def _convert_positioning(self, layout): :type layout: Layout :rtype: str """ - if not layout: + if not self.include_positioning or not layout: return "" # If it's converting from WebVTT to WebVTT, keep positioning info diff --git a/tests/test_base.py b/tests/test_base.py index 5d7cba23..1b77f7fb 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1,6 +1,7 @@ import pytest -from pycaption.base import CaptionList, Caption +from pycaption.base import CaptionList, Caption, BaseWriter +from pycaption.geometry import Layout, Point, Size, UnitEnum class TestCaption: @@ -56,3 +57,56 @@ def test_add_two_caption_lists(self): with pytest.raises(ValueError): newcaps = self.caps + CaptionList([4], layout_info="Other Layout") + + +class TestBaseWriter: + def setup_method(self): + # Create a mock layout_info for testing + self.layout_info = Layout( + origin=Point(Size(10, UnitEnum.PERCENT), Size(20, UnitEnum.PERCENT)) + ) + + def test_include_positioning_default_true(self): + """Test that include_positioning defaults to True""" + writer = BaseWriter() + assert writer.include_positioning is True + + def test_include_positioning_false(self): + """Test that include_positioning can be set to False""" + writer = BaseWriter(include_positioning=False) + assert writer.include_positioning is False + + def test_relativize_and_fit_to_screen_with_include_positioning_true(self): + """Test that layout_info is processed when include_positioning=True""" + writer = BaseWriter(include_positioning=True, video_width=640, video_height=360) + result = writer._relativize_and_fit_to_screen(self.layout_info) + # Should return processed layout_info, not None + assert result is not None + + def test_relativize_and_fit_to_screen_with_include_positioning_false(self): + """Test that layout_info is ignored when include_positioning=False""" + writer = BaseWriter(include_positioning=False, video_width=640, video_height=360) + result = writer._relativize_and_fit_to_screen(self.layout_info) + # Should return None when positioning is disabled + assert result is None + + def test_relativize_and_fit_to_screen_with_none_layout_info(self): + """Test that None layout_info is handled correctly""" + writer = BaseWriter(include_positioning=True) + result = writer._relativize_and_fit_to_screen(None) + assert result is None + + def test_relativize_and_fit_to_screen_with_none_layout_info_and_positioning_false(self): + """Test that None layout_info returns None even when include_positioning=False""" + writer = BaseWriter(include_positioning=False) + result = writer._relativize_and_fit_to_screen(None) + assert result is None + + def test_backward_compatibility_default_parameters(self): + """Test that all BaseWriter parameters have appropriate defaults for backward compatibility""" + writer = BaseWriter() + assert writer.relativize is True + assert writer.video_width is None + assert writer.video_height is None + assert writer.fit_to_screen is True + assert writer.include_positioning is True From 5edfa6a08d996585d2ca9d7c4942254d2d7db6be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 08:28:56 +0000 Subject: [PATCH 3/3] Fix DFXP writer to properly ignore global and language-level positioning when include_positioning=False Co-authored-by: lorandvarga <7048551+lorandvarga@users.noreply.github.com> --- pycaption/dfxp/base.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pycaption/dfxp/base.py b/pycaption/dfxp/base.py index bef05864..1f2e7691 100644 --- a/pycaption/dfxp/base.py +++ b/pycaption/dfxp/base.py @@ -340,7 +340,16 @@ def write(self, caption_set, force=''): # Loop through all captions/nodes and apply transformations to layout # in function of the provided or default settings + caption_set.layout_info = self._relativize_and_fit_to_screen( + caption_set.layout_info) + for lang in langs: + # Also process the language-specific layout info + lang_layout_info = caption_set.get_layout_info(lang) + if hasattr(caption_set._captions[lang], 'layout_info'): + caption_set._captions[lang].layout_info = self._relativize_and_fit_to_screen( + lang_layout_info) + for caption in caption_set.get_captions(lang): caption.layout_info = self._relativize_and_fit_to_screen( caption.layout_info)