Example #1
0
    def test_copy_to(self):
        src = model.ContentDocument()

        src.set_display_aspect_ratio(Fraction(16, 9))
        src.set_active_area(model.ActiveAreaType(0.1, 0.15, 0.8, 0.7))
        src.set_px_resolution(model.PixelResolutionType(height=480, width=640))
        src.set_lang("fr")
        src.set_cell_resolution(model.CellResolutionType(rows=10, columns=20))

        src.put_initial_value(styles.StyleProperties.Color,
                              styles.ColorType((12, 23, 43, 56)))

        dest = model.ContentDocument()

        src.copy_to(dest)

        self.assertEqual(dest.get_display_aspect_ratio(),
                         src.get_display_aspect_ratio())
        self.assertEqual(dest.get_active_area(), src.get_active_area())
        self.assertEqual(dest.get_px_resolution(), src.get_px_resolution())
        self.assertEqual(dest.get_lang(), src.get_lang())
        self.assertEqual(dest.get_cell_resolution(), src.get_cell_resolution())

        self.assertSequenceEqual(list(dest.iter_initial_values()),
                                 list(src.iter_initial_values()))
Example #2
0
    def extract(ttml_element) -> model.ActiveAreaType:

        aa = ttml_element.attrib.get(ActiveAreaAttribute.qn)

        if aa is not None:

            s = aa.split(" ")

            if len(s) != 4:
                LOGGER.error("Syntax error in ittp:activeArea on <tt>")
                return None

            (left_offset, left_offset_units) = utils.parse_length(s[0])

            (top_offset, top_offset_units) = utils.parse_length(s[1])

            (w, w_units) = utils.parse_length(s[2])

            (h, h_units) = utils.parse_length(s[3])

            if w_units != "%" or h_units != "%" or left_offset_units != "%" or top_offset_units != "%":
                LOGGER.error("ittp:activeArea on <tt> must use % units")
                return None

            return model.ActiveAreaType(left_offset / 100, top_offset / 100,
                                        w / 100, h / 100)

        return None
Example #3
0
    def test_active_area(self):

        aa = model.ActiveAreaType(0.1, 0.15, 0.8, 0.7)

        self.assertEqual(aa.left_offset, 0.1)

        self.assertEqual(aa.top_offset, 0.15)

        self.assertEqual(aa.width, 0.8)

        self.assertEqual(aa.height, 0.7)

        with self.assertRaises(ValueError):
            model.ActiveAreaType(-0.1, 0.15, 0.8, 0.7)

        with self.assertRaises(ValueError):
            model.ActiveAreaType(0.1, 0.15, -0.8, 0.7)
Example #4
0
    def test_active_area_default(self):

        aa = model.ActiveAreaType()

        self.assertEqual(aa.left_offset, 0)

        self.assertEqual(aa.top_offset, 0)

        self.assertEqual(aa.height, 1)

        self.assertEqual(aa.width, 1)
Example #5
0
    def test_document_active_area(self):

        d = model.ContentDocument()

        aa = model.ActiveAreaType(0.1, 0.15, 0.8, 0.7)

        d.set_active_area(aa)

        self.assertEqual(d.get_active_area(), aa)

        d.set_active_area(None)

        self.assertIsNone(d.get_active_area())
Example #6
0
    def __init__(self,
                 gsi_block: bytes,
                 disable_fill_line_gap: bool = False,
                 disable_line_padding: bool = False,
                 start_tc: typing.Optional[str] = None,
                 font_stack: typing.Tuple[typing.Union[
                     str, styles.GenericFontFamilyType]] = None,
                 max_row_count: typing.Optional[typing.Union[int,
                                                             str]] = None):

        self.gsi = _GSIBlock._make(
            struct.unpack(
                '3s8sc2s2s32s32s32s32s32s32s16s6s6s2s5s5s3s2s2s1s8s8s1s1s3s32s32s32s75x576s',
                gsi_block))

        self.doc = model.ContentDocument()

        self.doc.set_cell_resolution(
            model.CellResolutionType(
                columns=round(100 * DEFAULT_TELETEXT_COLS /
                              (100 - 2 * DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT)),
                rows=round(100 * DEFAULT_TELETEXT_ROWS /
                           (100 - 2 * DEFAULT_VERTICAL_SAFE_MARGIN_PCT))))

        self.doc.set_active_area(
            model.ActiveAreaType(
                left_offset=DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT / 100,
                top_offset=DEFAULT_VERTICAL_SAFE_MARGIN_PCT / 100,
                width=1 - 2 * DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT / 100,
                height=1 - 2 * DEFAULT_VERTICAL_SAFE_MARGIN_PCT / 100))

        self.body = model.Body(self.doc)

        if not disable_fill_line_gap:
            self.body.set_style(styles.StyleProperties.FillLineGap, True)

        if not disable_line_padding:
            self.body.set_style(
                styles.StyleProperties.LinePadding,
                styles.LengthType(LINE_PADDING_LENGTH_C,
                                  styles.LengthType.Units.c))

        if font_stack is not None:
            self.body.set_style(styles.StyleProperties.FontFamily, font_stack)
        else:
            self.body.set_style(styles.StyleProperties.FontFamily,
                                DEFAULT_FONT_STACK)

        self.doc.set_body(self.body)

        self.sgn_to_div_map = {}

        self.last_sn = None

        self.is_in_extension = False

        self.tti_tf = None

        self.fps = _DFC_FRACTION_MAP.get(self.gsi.DFC)
        if self.fps is None:
            LOGGER.error("Unknown GSI DFC value %s, defaulting to 25 fps",
                         self.gsi.DFC)
            self.fps = Fraction(25)
        else:
            LOGGER.debug("GSI DFC: %s", self.gsi.DFC)

        self.cct = self.gsi.CCT
        LOGGER.debug("GSI CCT: %s", self.gsi.CCT)

        try:
            self.tti_count = int(self.gsi.TNB)
            LOGGER.debug("GSI TNB: %s", self.gsi.TNB)
        except ValueError:
            LOGGER.error("Invalid TNB field value: %s", self.gsi.TNB)
            self.tti_count = sys.maxsize

        self.language = _LC_BCP47_MAP.get(self.gsi.LC)
        if self.language is None:
            LOGGER.warning(
                "Unknown LC value: %s, defaulting to 'unspecified''",
                self.gsi.LC)
            self.language = ""
        else:
            LOGGER.debug("GSI LC: %s", self.gsi.LC)

        self.doc.set_lang(self.language)

        if start_tc is None:
            self.start_offset = 0
        elif start_tc == "TCP":
            try:
                self.start_offset = SmpteTimeCode(
                    int(self.gsi.TCP[0:2]), int(self.gsi.TCP[2:4]),
                    int(self.gsi.TCP[4:6]), int(self.gsi.TCP[6:8]),
                    self.get_fps()).to_temporal_offset()
                LOGGER.debug("GSI TCP: %s", self.gsi.TCP)
            except ValueError:
                LOGGER.error("Invalid TCP value: %s", self.gsi.tcp)
                self.start_offset = 0
        else:
            try:
                self.start_offset = SmpteTimeCode.parse(
                    start_tc, self.get_fps()).to_temporal_offset()
            except ValueError:
                LOGGER.error("Invalid start_tc value")
                raise

        if max_row_count is None or self.is_teletext():
            self.max_row_count = DEFAULT_TELETEXT_ROWS
        elif isinstance(max_row_count, str) and max_row_count == "MNR":
            try:
                self.max_row_count = int(self.gsi.MNR)
                LOGGER.debug("GSI MNR: %s", self.gsi.MNR)
            except ValueError:
                LOGGER.error("Invalid MNR value: %s", self.gsi.MNR)
                self.start_offset = DEFAULT_TELETEXT_ROWS
        else:
            self.max_row_count = max_row_count

        # p_element for use across cumulative subtitles
        self.cur_p_element = None