⛏️ index : haiku.git

author Máximo Castañeda <antiswen@yahoo.es> 2024-07-06 18:15:14.0 +02:00:00
committer Adrien Destugues <pulkomandy@pulkomandy.tk> 2024-07-30 9:28:56.0 +00:00:00
commit
770c98e56f27f2681b7cc3072d2b22c0f37a0cf4 [patch]
tree
fe384167ede95b1769ca5b9ea938283977aa7286
parent
94777a3d5b65daf46c1d59cf0f62c63d567158fb
download
r1beta4.tar.gz

MediaPlayer: fix subtitles

- Setting word wrapping and resizing the BTextView to the video size
  before adding the text moves the subtitles to where they are supposed
  to be, and breaks long lines that would be cut off.
- Show last subtitle entry: _IndexFor returns the index at which to
  insert a new subtitle for some start time, so when getting an existing
  one, we always need the previous index. Before the change we would do
  that after checking the time of the subtitle at the returned index,
  which for the times of the last one would be outside the list.
- Improve charset detection by using the whole file. Just the first line
  of subtitle text may be too short to be useful, and to get there we
  should have decoded the file first. The refactor also fixes not getting
  the last entry from the file.
- While not subtitle related, fix typo in aspect ratio menu shortcuts.

Fixes #18151

Change-Id: I83fae735d31bce4616da9128a46be15763c30591
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7833
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Haiku-Format: Haiku-format Bot <no-reply+haikuformatbot@haiku-os.org>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
(cherry picked from commit a5df3d52215e734171db52859a2f921e394d0657)
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7856
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>

Diff

 src/apps/mediaplayer/MainWin.cpp                  |  6 ++----
 src/apps/mediaplayer/interface/SubtitleBitmap.cpp |  6 ++----
 src/apps/mediaplayer/supplier/SubTitles.h         |  3 ---
 src/apps/mediaplayer/supplier/SubTitlesSRT.cpp    | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
 4 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp
index d177d07..7a8a893 100644
--- a/src/apps/mediaplayer/MainWin.cpp
+++ b/src/apps/mediaplayer/MainWin.cpp
@@ -1869,11 +1869,9 @@

	menu->AddSeparatorItem();

	menu->AddItem(item = new BMenuItem("4 : 3",
		new BMessage(M_ASPECT_4_3), 2, B_SHIFT_KEY));
	menu->AddItem(item = new BMenuItem("4 : 3", new BMessage(M_ASPECT_4_3), '2', B_SHIFT_KEY));
	item->SetMarked(fWidthAspect == 4 && fHeightAspect == 3);
	menu->AddItem(item = new BMenuItem("16 : 9",
		new BMessage(M_ASPECT_16_9), 3, B_SHIFT_KEY));
	menu->AddItem(item = new BMenuItem("16 : 9", new BMessage(M_ASPECT_16_9), '3', B_SHIFT_KEY));
	item->SetMarked(fWidthAspect == 16 && fHeightAspect == 9);

	menu->AddSeparatorItem();
diff --git a/src/apps/mediaplayer/interface/SubtitleBitmap.cpp b/src/apps/mediaplayer/interface/SubtitleBitmap.cpp
index 839af68..1e0e4b0 100644
--- a/src/apps/mediaplayer/interface/SubtitleBitmap.cpp
+++ b/src/apps/mediaplayer/interface/SubtitleBitmap.cpp
@@ -25,12 +25,10 @@
{
	fTextView->SetStylable(true);
	fTextView->MakeEditable(false);
	fTextView->SetWordWrap(false);
	fTextView->SetAlignment(B_ALIGN_CENTER);

	fShadowTextView->SetStylable(true);
	fShadowTextView->MakeEditable(false);
	fShadowTextView->SetWordWrap(false);
	fShadowTextView->SetAlignment(B_ALIGN_CENTER);
}

@@ -275,8 +273,6 @@
			face |= B_BOLD_FACE;
		if (state->italic)
			face |= B_ITALIC_FACE;
		// NOTE: This is probably not supported by the app_server (perhaps
		// it is if the font contains a specific underline face).
		if (state->underlined)
			face |= B_UNDERSCORE_FACE;
	} else
@@ -349,6 +345,7 @@

	fTextView->SetText(NULL);
	fTextView->SetFontAndColor(&font, B_FONT_ALL, &color);
	fTextView->ResizeTo(fVideoBounds.Width(), fVideoBounds.Height());

	fTextView->Insert(" ");
	parse_text(fText, fTextView, font, color, true);
@@ -357,6 +354,7 @@
	fShadowTextView->ForceFontAliasing(overlayMode);
	fShadowTextView->SetText(NULL);
	fShadowTextView->SetFontAndColor(&font, B_FONT_ALL, &shadow);
	fShadowTextView->ResizeTo(fVideoBounds.Width(), fVideoBounds.Height());

	fShadowTextView->Insert(" ");
	parse_text(fText, fShadowTextView, font, shadow, false);
diff --git a/src/apps/mediaplayer/supplier/SubTitles.h b/src/apps/mediaplayer/supplier/SubTitles.h
index dd6acc0..22a0a85 100644
--- a/src/apps/mediaplayer/supplier/SubTitles.h
+++ b/src/apps/mediaplayer/supplier/SubTitles.h
@@ -10,9 +10,6 @@
#include <String.h>


class BFile;


struct SubTitle {
	BString		text;
	BPoint		placement;
diff --git a/src/apps/mediaplayer/supplier/SubTitlesSRT.cpp b/src/apps/mediaplayer/supplier/SubTitlesSRT.cpp
index bce8f70..649674c 100644
--- a/src/apps/mediaplayer/supplier/SubTitlesSRT.cpp
+++ b/src/apps/mediaplayer/supplier/SubTitlesSRT.cpp
@@ -8,27 +8,57 @@

#include <new>

#include <stdio.h>
#include <stdlib.h>

#include <AutoDeleter.h>
#include <File.h>
#include <StringList.h>
#include <TextEncoding.h>

#include "FileReadWrite.h"

static void
ReadLines(BFile* file, BStringList& lines)
{
	if (file == NULL)
		return;
	if (file->InitCheck() != B_OK)
		return;

	off_t size;
	if (file->GetSize(&size) != B_OK || size == 0)
		return;

	ArrayDeleter<char> buffer(new(std::nothrow) char[size + 1]);
	if (!buffer.IsSet())
		return;

	if (file->Read(buffer.Get(), size) < size)
		return;
	buffer[size] = '\0';

	BPrivate::BTextEncoding decoder(buffer.Get(), size);
	size_t decodedLength = size * 4;
	BString content;
	char* decoded = content.LockBuffer(decodedLength);
	size_t consumed = size;
	decoder.Decode(buffer.Get(), consumed, decoded, decodedLength);
	content.UnlockBuffer(decodedLength);

	content.Split("\n", false, lines);
}


SubTitlesSRT::SubTitlesSRT(BFile* file, const char* name)
	:
	SubTitles(),
	fName(name),
	fSubTitles(64)
{
	if (file == NULL)
		return;
	if (file->InitCheck() != B_OK)
		return;
	BStringList lines;
	ReadLines(file, lines);
	int32 totalLines = lines.CountStrings();

	FileReadWrite lineProvider(file);
	BString line;
	enum {
		EXPECT_SEQUENCE_NUMBER = 0,
		EXPECT_TIME_CODE,
@@ -37,13 +67,10 @@

	SubTitle subTitle;
	int32 lastSequenceNumber = 0;
	int32 currentLine = 0;

	BPrivate::BTextEncoding* decoder = NULL;

	int32 state = EXPECT_SEQUENCE_NUMBER;
	while (lineProvider.Next(line)) {
		line.RemoveAll("\n");
	for (int32 currentLine = 0; currentLine < totalLines; currentLine++) {
		BString line(lines.StringAt(currentLine));
		line.RemoveAll("\r");
		switch (state) {
			case EXPECT_SEQUENCE_NUMBER:
@@ -127,26 +154,11 @@

					state = EXPECT_SEQUENCE_NUMBER;
				} else {
					if (decoder == NULL) {
						// We try to guess the encoding from the first line of
						// text in the subtitle file.
						decoder = new BPrivate::BTextEncoding(line.String(),
							line.Length());
					}
					char buffer[line.Length() * 4];
					size_t inLength = line.Length();
					size_t outLength = line.Length() * 4;
					decoder->Decode(line.String(), inLength, buffer, outLength);
					buffer[outLength] = 0;
					subTitle.text << buffer << '\n';
					subTitle.text << line << '\n';
				}
				break;
		}
		line.SetTo("");
		currentLine++;
	}

	delete decoder;
}


@@ -167,15 +179,10 @@
const SubTitle*
SubTitlesSRT::SubTitleAt(bigtime_t time) const
{
	int32 index = _IndexFor(time);
	SubTitle* subTitle
		= reinterpret_cast<SubTitle*>(fSubTitles.ItemAt(index));
	if (subTitle != NULL && subTitle->startTime > time)
		subTitle = reinterpret_cast<SubTitle*>(fSubTitles.ItemAt(index - 1));
	if (subTitle != NULL && subTitle->startTime <= time
		&& subTitle->startTime + subTitle->duration > time) {
	int32 index = _IndexFor(time) - 1;
	SubTitle* subTitle = reinterpret_cast<SubTitle*>(fSubTitles.ItemAt(index));
	if (subTitle != NULL && subTitle->startTime + subTitle->duration > time)
		return subTitle;
	}
	return NULL;
}

@@ -197,6 +204,3 @@
	}
	return lower;
}