Exemple #1
0
    def test_paragraph_content_alignment_detection_right(self):
        caption_paragraph = SccCaptionParagraph()

        caption_paragraph.set_cursor_at(10, 0)
        caption_paragraph.append_text("0123456789")

        caption_paragraph.set_cursor_at(11, 0)
        caption_paragraph.append_text("    012345")

        caption_paragraph.set_cursor_at(12, 0)
        caption_paragraph.append_text("      0123")

        self.assertEqual(TextAlignType.end,
                         caption_paragraph.guess_text_alignment())

        caption_paragraph = SccCaptionParagraph()

        caption_paragraph.set_cursor_at(10, 0)
        caption_paragraph.append_text("0123456789")

        caption_paragraph.set_cursor_at(11, 0)
        caption_paragraph.append_text("    012345")

        caption_paragraph.set_cursor_at(12, 4)
        caption_paragraph.append_text("  0123")

        self.assertEqual(TextAlignType.end,
                         caption_paragraph.guess_text_alignment())
Exemple #2
0
    def test_paragraph_content_alignment_detection_center(self):
        caption_paragraph = SccCaptionParagraph()

        caption_paragraph.set_cursor_at(0, 2)
        caption_paragraph.append_text("0123456789")

        caption_paragraph.set_cursor_at(1, 2)
        caption_paragraph.append_text("  012345")

        caption_paragraph.set_cursor_at(2, 2)
        caption_paragraph.append_text("   0123")

        self.assertEqual(TextAlignType.center,
                         caption_paragraph.guess_text_alignment())

        caption_paragraph = SccCaptionParagraph()

        caption_paragraph.set_cursor_at(0, 0)
        caption_paragraph.append_text("  0123456789")

        caption_paragraph.set_cursor_at(1, 2)
        caption_paragraph.append_text("  012345")

        caption_paragraph.set_cursor_at(2, 5)
        caption_paragraph.append_text("0123")

        self.assertEqual(TextAlignType.center,
                         caption_paragraph.guess_text_alignment())
Exemple #3
0
    def paint_on_active_caption(self, time_code: SmpteTimeCode):
        """Initialize active caption for paint-on style"""
        active_style = SccCaptionStyle.PaintOn
        copied_lines = []
        cursor = self.active_cursor

        if self.has_active_caption():
            active_style = self.active_caption.get_caption_style()
            cursor = self.active_caption.get_cursor()

            # Copy buffered lines
            copied_lines = self.active_caption.copy_lines()

            # Push active to model if there is one
            self.push_active_caption_to_model(time_code)

        # Initialize new buffered caption
        self.active_caption = SccCaptionParagraph(self.safe_area_x_offset,
                                                  self.safe_area_y_offset,
                                                  active_style)
        self.initialize_active_caption(time_code)

        if len(copied_lines) > 0:
            # Set remaining lines to the new buffered caption
            self.active_caption.set_lines(copied_lines)

        self.active_caption.set_cursor_at(cursor[0], cursor[1])
Exemple #4
0
    def test_to_paragraph(self):
        caption_paragraph = SccCaptionParagraph()
        doc = ContentDocument()

        self.assertRaisesRegex(TypeError,
                               "Element id must be a valid xml:id string",
                               caption_paragraph.to_paragraph, doc)

        caption_paragraph.set_id("test-id")

        origin = caption_paragraph.get_origin()
        self.assertEqual(0, origin.x.value)
        self.assertEqual(0, origin.y.value)

        extent = caption_paragraph.get_extent()
        self.assertEqual(0, extent.width.value)
        self.assertEqual(0, extent.height.value)

        paragraph = caption_paragraph.to_paragraph(doc)

        self.assertEqual("test-id", paragraph.get_id())
        self.assertEqual(doc, paragraph.get_doc())
        self.assertIsNone(paragraph.get_begin())
        self.assertIsNone(paragraph.get_end())

        children = list(paragraph)
        self.assertEqual(0, len(children))

        caption_paragraph.set_begin(SmpteTimeCode.parse("00:01:02:03", FPS_30))
        caption_paragraph.set_end(SmpteTimeCode.parse("00:02:03:04", FPS_30))

        caption_paragraph.set_cursor_at(0)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("Hello")
        caption_paragraph.set_cursor_at(1)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("World")

        paragraph = caption_paragraph.to_paragraph(doc)

        self.assertEqual("test-id", paragraph.get_id())
        self.assertEqual(doc, paragraph.get_doc())
        self.assertEqual(Fraction(1863, 30), paragraph.get_begin())
        self.assertEqual(Fraction(3694, 30), paragraph.get_end())

        children = list(paragraph)
        self.assertEqual(3, len(children))

        self.assertIsInstance(children[0], Span)
        self.assertEqual("Hello", list(children[0])[0].get_text())

        self.assertIsInstance(children[1], Br)

        self.assertIsInstance(children[2], Span)
        self.assertEqual("World", list(children[2])[0].get_text())
Exemple #5
0
    def test_region_prefix(self):
        doc = ContentDocument()

        caption_paragraph = SccCaptionParagraph()
        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)
        self.assertEqual("region", paragraph_region._get_region_prefix())

        caption_paragraph = SccCaptionParagraph(
            caption_style=SccCaptionStyle.PaintOn)
        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)
        self.assertEqual("paint", paragraph_region._get_region_prefix())

        caption_paragraph = SccCaptionParagraph(
            caption_style=SccCaptionStyle.PopOn)
        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)
        self.assertEqual("pop", paragraph_region._get_region_prefix())

        caption_paragraph = SccCaptionParagraph(
            caption_style=SccCaptionStyle.RollUp)
        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)
        self.assertEqual("rollup", paragraph_region._get_region_prefix())
Exemple #6
0
    def test_paragraph_alignment_detection_left(self):
        caption_paragraph = SccCaptionParagraph()

        caption_paragraph.set_cursor_at(0, 0)
        caption_paragraph.append_text("0123456789")

        caption_paragraph.set_cursor_at(1, 0)
        caption_paragraph.append_text("012345")

        caption_paragraph.set_cursor_at(2, 0)
        caption_paragraph.append_text("0123")

        self.assertEqual(TextAlignType.start,
                         caption_paragraph.guess_text_alignment())
Exemple #7
0
  def process_preamble_address_code(self, pac: SccPreambleAddressCode, time_code: SccTimeCode):
    """Processes SCC Preamble Address Code it to the map to model"""
    if self.current_caption is None:
      raise ValueError("No current SCC caption initialized")

    pac_row = pac.get_row()
    pac_indent = pac.get_indent()

    if self.current_caption.get_caption_style() is SccCaptionStyle.PaintOn:
      if self.current_caption.get_current_text() is not None \
          and self.safe_area_y_offset + pac_row == self.current_caption.get_row_offset() + 1:
        # Creates a new Paragraph if the new caption is contiguous (Paint-On)
        self.set_current_to_previous()

        self.current_caption = SccCaptionParagraph(self.safe_area_x_offset, self.safe_area_y_offset, SccCaptionStyle.PaintOn)
        self.init_current_caption(time_code)

      elif len(self.previous_captions) > 0 and self.previous_captions[0].get_current_text() is not None \
          and self.safe_area_y_offset + pac_row == self.previous_captions[0].get_row_offset():
        # Pushes and erases displayed row so that it can be replaced by current row (Paint-On)
        self.push_previous_caption(self.current_caption.get_begin())

    self.current_caption.new_caption_text()

    if self.current_caption.get_caption_style() is SccCaptionStyle.RollUp:
      # Ignore PACs for rows 5-11, but get indent from PACs for rows 1-4 and 12-15. (Roll-Up)
      if pac_row in range(5, 12):
        self.current_caption.apply_current_text_offsets()
        return

      self.current_caption.set_column_offset(pac_indent)
    else:
      self.current_caption.set_row_offset(pac_row)
      self.current_caption.set_column_offset(pac_indent)

    self.current_caption.get_current_text().add_style_property(StyleProperties.Color, pac.get_color())
    self.current_caption.get_current_text().add_style_property(StyleProperties.FontStyle, pac.get_font_style())
    self.current_caption.get_current_text().add_style_property(StyleProperties.TextDecoration, pac.get_text_decoration())

    self.current_caption.apply_current_text_offsets()
Exemple #8
0
    def process_control_code(self, control_code: SccControlCode,
                             time_code: SmpteTimeCode):
        """Processes SCC Control Code to map it to the model"""

        processed_caption = self.buffered_caption

        if control_code is SccControlCode.RCL:
            # Start a new Pop-On caption
            self.current_style = SccCaptionStyle.PopOn

        elif control_code is SccControlCode.RDC:
            # Start a new Paint-On caption
            self.current_style = SccCaptionStyle.PaintOn

        elif control_code in (SccControlCode.RU2, SccControlCode.RU3,
                              SccControlCode.RU4):
            # Start a new Roll-Up caption
            self.current_style = SccCaptionStyle.RollUp

            if control_code is SccControlCode.RU2:
                self.roll_up_depth = 2

            elif control_code is SccControlCode.RU3:
                self.roll_up_depth = 3

            elif control_code is SccControlCode.RU4:
                self.roll_up_depth = 4

        else:
            # If the Paint-On or Roll-Up style is activated, write directly on active caption
            if self.current_style in (SccCaptionStyle.PaintOn,
                                      SccCaptionStyle.RollUp):
                processed_caption = self.active_caption

        if control_code is SccControlCode.EOC:
            # Display caption (Pop-On)
            self.set_buffered_caption_begin_time(time_code)
            self.flip_buffered_to_active_captions(time_code)

            if self.has_active_caption():
                # Set text alignment
                if self.text_alignment == TextAlignment.AUTO:
                    text_alignment = self.active_caption.guess_text_alignment()
                else:
                    text_alignment = self.text_alignment.text_align

                # Apply text alignment
                self.active_caption.add_style_property(
                    StyleProperties.TextAlign, text_alignment)

        elif control_code is SccControlCode.EDM:
            # Erase displayed captions
            if self.has_active_caption():
                if time_code is not None:
                    # End time is exclusive in the model, set it to the next frame
                    end_time_code = copy.copy(time_code)
                    end_time_code.add_frames()
                else:
                    end_time_code = time_code

                self.push_active_caption_to_model(end_time_code)

        elif control_code is SccControlCode.ENM:
            # Erase buffered caption
            self.buffered_caption = None

        elif control_code is SccControlCode.TO1:
            processed_caption.indent_cursor(1)

        elif control_code is SccControlCode.TO2:
            processed_caption.indent_cursor(2)

        elif control_code is SccControlCode.TO3:
            processed_caption.indent_cursor(3)

        elif control_code is SccControlCode.CR:
            # Roll the displayed caption up one row (Roll-Up)

            if self.has_active_caption():
                # Push active caption to model (but don't erase it)
                self.push_active_caption_to_model(time_code, False)
                # Roll the active caption up
                self.active_caption.roll_up()
                # Get the remaining lines to initialize the following caption with the expected depth
                previous_lines = self.active_caption.get_last_caption_lines(
                    self.roll_up_depth - 1)

                # Initialize the new caption with the previous lines
                self.active_caption = SccCaptionParagraph(
                    self.safe_area_x_offset, self.safe_area_y_offset,
                    SccCaptionStyle.RollUp)
                self.initialize_active_caption(time_code)
                self.active_caption.set_lines(previous_lines)

                self.active_caption.set_cursor_at(self.active_cursor[0],
                                                  self.active_cursor[1])

        elif control_code is SccControlCode.DER:
            # Delete to End of Row (Paint-On)
            # The DER may be issued from any point on a row to delete all displayable characters, transparent
            # spaces, and mid-row codes from (and including) the current cell to the end of the row.
            # Not used in this implementation since this SCC reader does not map the text overlapping into
            # the model (i.e. a row is erased when a PAC is received, so before a new caption is written onto it).
            pass

        elif control_code is SccControlCode.BS:
            # Backspace
            # When a Backspace is received, the cursor moves to the left one column position erasing
            # the character or Mid-Row Code occupying that location, unless the cursor is in Column 1
            processed_caption.get_current_text().backspace()
Exemple #9
0
    def process_preamble_address_code(self, pac: SccPreambleAddressCode,
                                      time_code: SmpteTimeCode):
        """Processes SCC Preamble Address Code it to the map to model"""

        pac_row = pac.get_row()
        pac_indent = pac.get_indent()

        if self.current_style is SccCaptionStyle.PaintOn:

            self.paint_on_active_caption(time_code)

            if self.active_caption.get_caption_style(
            ) is SccCaptionStyle.PaintOn:
                # Clear target row on Paint-On style
                target_row = self.active_caption.get_lines().get(pac_row)
                if target_row is not None:
                    target_row.clear()

            self.active_caption.set_cursor_at(pac_row, pac_indent)

            if self.active_caption.get_current_text() is None:
                self.active_caption.new_caption_text()

        elif self.current_style is SccCaptionStyle.RollUp:

            if not self.has_active_caption():
                # If there is no current active caption, initialize an empty new paragraph
                self.active_caption = SccCaptionParagraph(
                    self.safe_area_x_offset, self.safe_area_y_offset,
                    SccCaptionStyle.RollUp)
                self.initialize_active_caption(time_code)

            # Ignore PACs for rows 5-11, but get indent from PACs for rows 1-4 and 12-15. (Roll-Up)
            if pac_row in range(5, 12):
                self.active_caption.set_cursor_at(ROLL_UP_BASE_ROW)
                self.active_caption.new_caption_text()
                return

            # Force roll-up paragraph to belong to the same region
            self.active_caption.set_cursor_at(ROLL_UP_BASE_ROW, pac_indent)

            self.active_caption.new_caption_text()

        else:  # Pop-On Style

            if self.buffered_caption is None:
                self.buffered_caption = SccCaptionParagraph(
                    self.safe_area_x_offset, self.safe_area_y_offset,
                    SccCaptionStyle.PopOn)

            # set cursor in paragraph and create line or text if necessary
            self.buffered_caption.set_cursor_at(pac_row, pac_indent)

            self.buffered_caption.new_caption_text()

        self.current_color = pac.get_color()
        self.current_font_style = pac.get_font_style()
        self.current_text_decoration = pac.get_text_decoration()

        if self.has_active_caption():
            self.active_cursor = self.active_caption.get_cursor()
Exemple #10
0
  def process_control_code(self, control_code: SccControlCode, time_code: SccTimeCode):
    """Processes SCC Control Code to map it to the model"""

    if control_code is SccControlCode.RCL:
      # Start a new Pop-On caption
      if self.current_caption is not None and self.current_caption.get_current_text() is not None:
        self.set_current_to_previous()

      self.current_caption = SccCaptionParagraph(self.safe_area_x_offset, self.safe_area_y_offset, SccCaptionStyle.PopOn)

    elif control_code is SccControlCode.RDC:
      # Start a new Paint-On caption
      self.set_current_to_previous()

      self.current_caption = SccCaptionParagraph(self.safe_area_x_offset, self.safe_area_y_offset, SccCaptionStyle.PaintOn)
      self.init_current_caption(time_code)

    elif control_code in (SccControlCode.RU2, SccControlCode.RU3, SccControlCode.RU4):
      # Start a new Roll-Up caption
      self.set_current_to_previous()

      previous_last_lines: List[SccCaptionContent] = []
      if len(self.previous_captions) > 0:

        if control_code is SccControlCode.RU2:
          previous_last_lines = self.previous_captions[0].get_last_caption_lines(1)

        elif control_code is SccControlCode.RU3:
          previous_last_lines = self.previous_captions[0].get_last_caption_lines(2)

        elif control_code is SccControlCode.RU4:
          previous_last_lines = self.previous_captions[0].get_last_caption_lines(3)

        previous_last_lines.append(SccCaptionLineBreak())

      self.push_previous_caption(time_code)

      self.current_caption = SccCaptionParagraph(self.safe_area_x_offset, self.safe_area_y_offset, SccCaptionStyle.RollUp)
      self.current_caption.set_contents(previous_last_lines)
      self.init_current_caption(time_code)
      self.current_caption.apply_roll_up_row_offsets()

    elif control_code is SccControlCode.EOC:
      # Display caption (Pop-On)
      self.init_current_caption(time_code)
      self.set_current_to_previous()

    elif control_code in (SccControlCode.EDM, SccControlCode.ENM):
      # Erase displayed caption (Pop-On)
      if len(self.previous_captions) > 0:
        # Set line breaks depending on the position of the content

        contents = []
        initial_length = len(self.previous_captions[0].get_contents())

        for index in range(0, initial_length):
          content = self.previous_captions[0].get_contents()[index - 1]
          if not isinstance(content, SccCaptionText):
            continue

          next_content = self.previous_captions[0].get_contents()[index]
          if not isinstance(next_content, SccCaptionText):
            continue

          if next_content.is_contiguous(content):
            contents.append(SccCaptionLineBreak())

          contents.append(next_content)

        self.previous_captions[0].set_contents(contents)

      self.push_previous_caption(time_code)

    elif control_code is SccControlCode.TO1:
      self.current_caption.indent(1)

    elif control_code is SccControlCode.TO2:
      self.current_caption.indent(2)

    elif control_code is SccControlCode.TO3:
      self.current_caption.indent(3)

    elif control_code is SccControlCode.CR:
      # Roll the display up one row (Roll-Up)
      # Not used in this implementation since this SCC reader does not really map the roll-up effect,
      # but it erases the displayed paragraph and resets a new paragraph with the resulting rows.
      pass

    elif control_code is SccControlCode.DER:
      # Delete to End of Row (Paint-On)
      # The DER may be issued from any point on a row to delete all displayable characters, transparent
      # spaces, and mid-row codes from (and including) the current cell to the end of the row.
      # Not used in this implementation since this SCC reader does not map the text overlapping into
      # the model (i.e. a row is erased when a PAC is received, so before a new caption is written onto it).
      pass
Exemple #11
0
    def test_matching_region(self):
        doc = ContentDocument()
        doc_columns = 40
        doc_rows = 19
        doc.set_cell_resolution(
            CellResolutionType(rows=doc_rows, columns=doc_columns))

        safe_area_x_offset = 4
        safe_area_y_offset = 2

        caption_paragraph = SccCaptionParagraph(safe_area_x_offset,
                                                safe_area_y_offset)
        caption_paragraph.set_cursor_at(4, 7)
        caption_paragraph.new_caption_text()

        caption_paragraph.get_current_text().append("A 20-char long line.")

        origin = caption_paragraph.get_origin()
        self.assertEqual(11, origin.x.value)
        self.assertEqual(5, origin.y.value)

        extent = caption_paragraph.get_extent()
        self.assertEqual(20, extent.width.value)
        self.assertEqual(1, extent.height.value)

        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)

        self.assertIsNone(paragraph_region._find_matching_region())
        region = paragraph_region._create_matching_region()

        self.assertEqual("region1", region.get_id())
        self.assertTrue(paragraph_region._has_same_origin_as_region(region))
        self.assertEqual(region, paragraph_region._find_matching_region())

        self.assertEqual(ShowBackgroundType.whenActive,
                         region.get_style(StyleProperties.ShowBackground))

        region_extent = region.get_style(StyleProperties.Extent)

        self.assertEqual(50, region_extent.width.value)
        self.assertEqual(63, region_extent.height.value)

        caption_paragraph.set_cursor_at(5, 7)
        caption_paragraph.new_caption_text()
        caption_paragraph.get_current_text().append(
            "This is another 34-char long line.")

        origin = caption_paragraph.get_origin()
        self.assertEqual(11, origin.x.value)
        self.assertEqual(5, origin.y.value)

        extent = caption_paragraph.get_extent()
        self.assertEqual(34, extent.width.value)
        self.assertEqual(2, extent.height.value)

        paragraph_region = _SccParagraphRegion(caption_paragraph, doc)

        self.assertEqual(region, paragraph_region._find_matching_region())
        paragraph_region._extend_region_to_paragraph(region)
        self.assertTrue(paragraph_region._has_same_origin_as_region(region))

        region_extent = region.get_style(StyleProperties.Extent)

        self.assertEqual(62, region_extent.width.value)
        self.assertEqual(63, region_extent.height.value)
Exemple #12
0
    def test_content(self):
        caption_paragraph = SccCaptionParagraph()
        self.assertEqual(0, caption_paragraph._safe_area_x_offset)
        self.assertEqual(0, caption_paragraph._safe_area_y_offset)

        caption_paragraph = SccCaptionParagraph(4, 2)
        self.assertEqual(4, caption_paragraph._safe_area_x_offset)
        self.assertEqual(2, caption_paragraph._safe_area_y_offset)

        self.assertIsNone(caption_paragraph.get_current_text())
        self.assertEqual(0, len(caption_paragraph._caption_lines))

        caption_paragraph.new_caption_text()
        self.assertEqual(caption_paragraph.get_current_line(),
                         caption_paragraph.get_lines()[0])
        self.assertIsNotNone(caption_paragraph.get_current_text())
        self.assertEqual(1, len(caption_paragraph._caption_lines))

        caption_paragraph.set_cursor_at(4, 4)
        caption_paragraph.new_caption_text()
        self.assertEqual((4, 4), caption_paragraph.get_cursor())
        self.assertEqual(caption_paragraph.get_current_line(),
                         caption_paragraph.get_lines()[4])
        self.assertEqual(4, caption_paragraph.get_current_line().get_row())
        self.assertEqual(4, caption_paragraph.get_current_line().get_indent())
        self.assertEqual(0, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(0, caption_paragraph.get_current_text().get_cursor())

        caption_paragraph.indent_cursor(3)
        self.assertEqual((4, 7), caption_paragraph.get_cursor())
        self.assertEqual(4, caption_paragraph.get_current_line().get_row())
        self.assertEqual(7, caption_paragraph.get_current_line().get_indent())
        self.assertEqual(0, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(0, caption_paragraph.get_current_text().get_cursor())

        caption_paragraph.append_text("Hello")
        self.assertEqual(5, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(5, caption_paragraph.get_current_text().get_cursor())

        caption_paragraph.set_cursor_at(4, 10)
        self.assertEqual((4, 10), caption_paragraph.get_cursor())
        self.assertEqual(4, caption_paragraph.get_current_line().get_row())
        self.assertEqual(7, caption_paragraph.get_current_line().get_indent())

        self.assertEqual(3, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(3, caption_paragraph.get_current_text().get_cursor())

        caption_paragraph.indent_cursor(2)
        self.assertEqual((4, 12), caption_paragraph.get_cursor())
        self.assertEqual(4, caption_paragraph.get_current_line().get_row())
        self.assertEqual(7, caption_paragraph.get_current_line().get_indent())

        self.assertEqual(5, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(5, caption_paragraph.get_current_text().get_cursor())

        self.assertListEqual([], caption_paragraph.get_last_caption_lines(0))
        self.assertListEqual([caption_paragraph.get_current_line()],
                             caption_paragraph.get_last_caption_lines(1))

        caption_paragraph.set_cursor_at(2, 4)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("World")
        self.assertEqual(5, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(5, caption_paragraph.get_current_text().get_cursor())

        self.assertRaisesRegex(RuntimeError,
                               "Cannot roll-Up Unknown-styled caption.",
                               caption_paragraph.roll_up)

        caption_paragraph._caption_style = SccCaptionStyle.PopOn
        self.assertRaisesRegex(RuntimeError,
                               "Cannot roll-Up PopOn-styled caption.",
                               caption_paragraph.roll_up)

        caption_paragraph._caption_style = SccCaptionStyle.RollUp
        caption_paragraph.roll_up()
        self.assertEqual(2, len(caption_paragraph.get_lines()))
        self.assertEqual(caption_paragraph.get_current_line(),
                         caption_paragraph.get_lines().get(1))
        self.assertEqual(1, caption_paragraph.get_lines().get(1).get_row())
        self.assertEqual(
            "World",
            caption_paragraph.get_lines().get(1).get_current_text().get_text())

        self.assertTrue(
            isinstance(caption_paragraph.get_lines().get(3), SccCaptionLine))
        self.assertEqual(3, caption_paragraph.get_lines().get(3).get_row())
        self.assertEqual(
            "Hello",
            caption_paragraph.get_lines().get(3).get_current_text().get_text())

        self.assertListEqual([], caption_paragraph.get_last_caption_lines(0))
        self.assertListEqual([caption_paragraph.get_lines().get(3)],
                             caption_paragraph.get_last_caption_lines(1))
        self.assertListEqual([
            caption_paragraph.get_lines().get(1),
            caption_paragraph.get_lines().get(3)
        ], caption_paragraph.get_last_caption_lines(2))

        caption_paragraph.set_cursor_at(15, 0)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("!!!")
        self.assertEqual(3, caption_paragraph.get_current_line().get_cursor())
        self.assertEqual(3, caption_paragraph.get_current_text().get_cursor())

        caption_paragraph.roll_up()
        self.assertEqual(3, len(caption_paragraph.get_lines()))
        self.assertTrue(
            isinstance(caption_paragraph.get_lines().get(0), SccCaptionLine))
        self.assertEqual(0, caption_paragraph.get_lines().get(0).get_row())
        self.assertEqual(
            "World",
            caption_paragraph.get_lines().get(0).get_current_text().get_text())

        self.assertTrue(
            isinstance(caption_paragraph.get_lines().get(2), SccCaptionLine))
        self.assertEqual(2, caption_paragraph.get_lines().get(2).get_row())
        self.assertEqual(
            "Hello",
            caption_paragraph.get_lines().get(2).get_current_text().get_text())

        self.assertEqual(caption_paragraph.get_current_line(),
                         caption_paragraph.get_lines().get(14))
        self.assertEqual(14, caption_paragraph.get_lines().get(14).get_row())
        self.assertEqual(
            "!!!",
            caption_paragraph.get_lines().get(
                14).get_current_text().get_text())

        self.assertListEqual([], caption_paragraph.get_last_caption_lines(0))
        self.assertListEqual([caption_paragraph.get_lines().get(14)],
                             caption_paragraph.get_last_caption_lines(1))
        self.assertListEqual([
            caption_paragraph.get_lines().get(2),
            caption_paragraph.get_lines().get(14)
        ], caption_paragraph.get_last_caption_lines(2))
        self.assertListEqual([
            caption_paragraph.get_lines().get(0),
            caption_paragraph.get_lines().get(2),
            caption_paragraph.get_lines().get(14)
        ], caption_paragraph.get_last_caption_lines(3))
Exemple #13
0
    def process_control_code(self, control_code: SccControlCode,
                             time_code: SmpteTimeCode):
        """Processes SCC Control Code to map it to the model"""

        if control_code is SccControlCode.RCL:
            # Start a new Pop-On caption
            self.current_style = SccCaptionStyle.PopOn

        elif control_code is SccControlCode.RDC:
            # Start a new Paint-On caption
            self.current_style = SccCaptionStyle.PaintOn

        elif control_code in (SccControlCode.RU2, SccControlCode.RU3,
                              SccControlCode.RU4):
            # Start a new Roll-Up caption
            self.current_style = SccCaptionStyle.RollUp

            previous_last_lines: List[SccCaptionLine] = []
            if self.has_active_caption():

                if control_code is SccControlCode.RU2:
                    previous_last_lines = self.active_caption.get_last_caption_lines(
                        1)

                elif control_code is SccControlCode.RU3:
                    previous_last_lines = self.active_caption.get_last_caption_lines(
                        2)

                elif control_code is SccControlCode.RU4:
                    previous_last_lines = self.active_caption.get_last_caption_lines(
                        3)

            self.push_active_caption_to_model(time_code)

            self.active_caption = SccCaptionParagraph(self.safe_area_x_offset,
                                                      self.safe_area_y_offset,
                                                      SccCaptionStyle.RollUp)
            self.initialize_active_caption(time_code)

            self.active_caption.set_lines(previous_last_lines)

        elif control_code is SccControlCode.EOC:
            # Display caption (Pop-On)
            self.set_buffered_caption_begin_time(time_code)
            self.flip_buffered_to_active_captions(time_code)

            if self.has_active_caption():
                # Set text alignment
                if self.text_alignment == TextAlignment.AUTO:
                    text_alignment = self.active_caption.guess_text_alignment()
                else:
                    text_alignment = self.text_alignment.text_align

                # Apply text alignment
                self.active_caption.add_style_property(
                    StyleProperties.TextAlign, text_alignment)

        elif control_code is SccControlCode.EDM:
            # Erase displayed captions
            if self.has_active_caption():
                self.push_active_caption_to_model(time_code)

        elif control_code is SccControlCode.ENM:
            # Erase buffered caption
            self.buffered_caption = None

        elif control_code is SccControlCode.TO1:
            self.buffered_caption.indent_cursor(1)

        elif control_code is SccControlCode.TO2:
            self.buffered_caption.indent_cursor(2)

        elif control_code is SccControlCode.TO3:
            self.buffered_caption.indent_cursor(3)

        elif control_code is SccControlCode.CR:
            # Roll the display up one row (Roll-Up)
            self.active_caption.roll_up()

        elif control_code is SccControlCode.DER:
            # Delete to End of Row (Paint-On)
            # The DER may be issued from any point on a row to delete all displayable characters, transparent
            # spaces, and mid-row codes from (and including) the current cell to the end of the row.
            # Not used in this implementation since this SCC reader does not map the text overlapping into
            # the model (i.e. a row is erased when a PAC is received, so before a new caption is written onto it).
            pass

        elif control_code is SccControlCode.BS:
            # Backspace
            # When a Backspace is received, the cursor moves to the left one column position erasing
            # the character or Mid-Row Code occupying that location, unless the cursor is in Column 1
            self.buffered_caption.get_current_text().backspace()