mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
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>
This commit is contained in:
parent
2813fd13ca
commit
a5df3d5221
@ -1872,11 +1872,9 @@ MainWin::_SetupVideoAspectItems(BMenu* menu)
|
||||
|
||||
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();
|
||||
|
@ -25,12 +25,10 @@ SubtitleBitmap::SubtitleBitmap()
|
||||
{
|
||||
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 @@ apply_state(BTextView* textView, const ParseState* state, BFont font,
|
||||
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 @@ SubtitleBitmap::_InsertText(BRect& textRect, float& outlineRadius,
|
||||
|
||||
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 @@ SubtitleBitmap::_InsertText(BRect& textRect, float& outlineRadius,
|
||||
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);
|
||||
|
@ -10,9 +10,6 @@
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BFile;
|
||||
|
||||
|
||||
struct SubTitle {
|
||||
BString text;
|
||||
BPoint placement;
|
||||
|
@ -8,12 +8,45 @@
|
||||
|
||||
#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)
|
||||
@ -22,13 +55,10 @@ SubTitlesSRT::SubTitlesSRT(BFile* file, const char* name)
|
||||
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 @@ SubTitlesSRT::SubTitlesSRT(BFile* file, const char* name)
|
||||
|
||||
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 @@ SubTitlesSRT::SubTitlesSRT(BFile* file, const char* name)
|
||||
|
||||
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 @@ SubTitlesSRT::Name() const
|
||||
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 @@ SubTitlesSRT::_IndexFor(bigtime_t startTime) const
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user