Log in

View Full Version : Subtitle position 1,2,3 position & multiple line text.?


Rob105
30th October 2023, 20:45
When running following code positions align=1,2 and 3 is hiding second and third line of text outside video window, is this normal mode of operation or a bug?

function rotateSubtitle(clip vid, string text, int pos) {
return vid.Subtitle(text, align=pos, lsp=0)
}


text = "THE QUICK BROWN FOX \nJUMPS OVER \nTHE LAZY DOG."

Animate(BlankClip(length=10), 0, 8, "rotateSubtitle", text, 1, text, 9)

Could you suggest a workaround to show entire multi line text when using align=1,2 and 3 regardless of how many lines of text or the font size.

pinterf
31st October 2023, 10:00
And a question from me, because I've just encountered the same issue, while looking into issue #368 ( https://github.com/AviSynth/AviSynthPlus/issues/368 )

A vertically bottom or center aligned multiline text only calculates and aligns the Y position of the first line.
So, as Rob105 experienced, a bottom aligned e.g. three-line text will show only the first line, the next lines will be off-screen.
Similarly, a vertically center-aligned text will start the first line at the center, but the bounding text box containing the three lines won't be in the center.

Is it a planned behaviour or was just not thought of and was not implemented when multiline option was introduced in SubTitle.

StainlessS
31st October 2023, 12:43
Is it a planned behaviour or was just not thought of and was not implemented when multiline option was introduced in SubTitle.
Think maybe "just not thought of and was not implemented when multiline option was introduced"


Also, Thread: Subtitle - Align Middle? :- https://forum.doom9.org/showthread.php?p=1628691

I just made this small mod to post #13 in that thread [EDIT: added in BLUE].

#Avisource("D:\avs\test.avi")
ColorBars()

Function SubV(clip c, string text, float "x", float "y", int "first_frame", int "last_frame", string "font", float "size", \
int "text_color", int "halo_color", int "align", int "spc", int "lsp", float "font_width", float "font_angle", bool "interlaced", \
bool "vcenter") { # http://forum.doom9.org/showthread.php?p=1628899#post1628899
c
# GScript("""
size=Default(size,18)
vcenter=Default(vcenter,false)
if(Defined(align) && Defined(lsp)) {
if((align>=4 && align<=6) && vcenter) { # vertical central justification.
s=RT_StrReplace(text,"\n",Chr(10),Sig=false)
Lines = RT_TxtQueryLines(s) # Line count with/without final newline
y=(Height/2) - ((Lines-1) * (size + lsp/8.0) / 2.0)
} else if(align>=1 && align<=3) { # vertical bottom justification.
s=RT_StrReplace(text,"\n",Chr(10),Sig=false)
Lines = RT_TxtQueryLines(s) # Line count with/without final newline
y=Height - ((Lines-1) * (size + lsp/8.0))
}
}
# """)
Subtitle(text,x,y,first_frame,last_frame,font,size,text_color,halo_color,align,spc,lsp,font_width,font_angle,interlaced)
}

VC=True
#VC=False

S="The\nQuick\nBrown\nfox\njumped\nover\nthe\nlazy\ndog.\nThe\nQuick\nBrown\nfox\njumped\nover\nthe\nlazy\ndog.\n"

TEST_BOT = True
#TEST_BOT = False

if(!TEST_BOT) { # vcenter relative
SubV(S,lsp=0,align=4,vcenter=VC)
SubV(S,lsp=0,align=5,vcenter=VC)
SubV(S,lsp=0,align=6,vcenter=VC)
} Else { # bottom relative
SubV(S,lsp=0,align=1)
SubV(S,lsp=0,align=2)
SubV(S,lsp=0,align=3)
}


EDIT: I think there are maybe also more dragons in Subtitle(), when using 'font_angle'.

pinterf
31st October 2023, 13:54
Thanks. I was curious enough to make a test build and make vertical (and bottom) alignment work properly for multiline text as well. (Both in SubTitle and Text)

One note: vertical center alignment does not exist in Windows GDI. Avisynth is using the 4,5,6 align values to calculate the y center of the screen, but it's the baseline of the string which will be positioned to this y coordinate. For a single line text "Baseline alignment" in SubTitle almost matches with the vertical center.
But it's not the perfect vertical middle of the character box. To understand what baseline is: letters below the baseline are g, j, q or y for example.

As for deciding with/without final newline:

When final newline is not counted, then
"Line1" is 1 line
"Line1\n" has 2 lines (Line1 and an empty line)
"Line1\n\n" has 3 lines

When final newline is counted, then
"Line1" is 1 line
"Line1\n" is still 1 line
"Line1\n\n" has 2 lines (Line1 and an empty line)

My present test implementation counts the final new line as well. Opinions?

Rob105
31st October 2023, 14:43
Thanks. I was curious enough to make a test build and make vertical (and bottom) alignment work properly for multiline text as well. (Both in SubTitle and Text)

Could you share the test build somewhere i'd love to test it.

One note: vertical center alignment does not exist in Windows GDI. Avisynth is using the 4,5,6 align values to calculate the y center of the screen, but it's the baseline of the string which will be positioned to this y coordinate. For a single line text "Baseline alignment" in SubTitle almost matches with the vertical center.
But it's not the perfect vertical middle of the character box. To understand what baseline is: letters below the baseline are g, j, q or y for example.
Sometimes picture worth a 100 words, English is not my native language and took me like 30 minutes to figure out what you talking about :)

Vertical alignment when using align=4,5,6 aligns based on the bottom line of the text, not vertical middle point of text, not very usable for large fonts.

reference = BlankClip(length=1, width=800, height=200, pixel_type="RGB32", fps=24, color=$004499)

Overlay(reference, BlankClip(reference, height=reference.height/2, color=$000000))

Subtitle("Hello World gjqy", size=100, align=5, lsp=0)

Gives this result
https://forum.doom9.org/attachment.php?attachmentid=18501&stc=1&d=1698761922

As for deciding with/without final newline:

When final newline is not counted, then
"Line1" is 1 line
"Line1\n" has 2 lines (Line1 and an empty line)
"Line1\n\n" has 3 lines

When final newline is counted, then
"Line1" is 1 line
"Line1\n" is still 1 line
"Line1\n\n" has 2 lines (Line1 and an empty line)


What is "final new line"?

pinterf
31st October 2023, 15:29
Could you share the test build somewhere i'd love to test it.

Unfortunately (I'm usually providing XP builds as well) the build process is 20-30 minutes per .exe when target is XP compatible. So for me it takes ~2 hours to have a properly made and administered build. I post to Avisynth+ topic when it's ready.


What is "final new line"?

A string ending with "\n" intentionally.

pinterf
31st October 2023, 15:31
Vertical alignment when using align=4,5,6 aligns based on the bottom line of the text, not vertical middle point of text, not very usable for large fonts.

I agree. But Windows does not support such a "perfect vertical center" alignment so we cannot do that (unlike in "Text", where we have known fixed character box sizes)

Rob105
31st October 2023, 16:02
A string ending with "\n" intentionally.

Why would someone need that? I see no use case scenario.

I agree. But Windows does not support such a "perfect vertical center" alignment so we cannot do that (unlike in "Text", where we have known fixed character box sizes)

Can you adopt it from "Text" function whatever way they use to center text vertically and put it into "Subtitle" function?


I was also thinking about a workaround inside the AviSynth script, e.g.
1. create temporary clip with multi-line or single line text aligned on top right corner (align=7)
2. trim the box keeping only the text like in Photoshop

https://forum.doom9.org/attachment.php?attachmentid=18502&stc=1&d=1698765196

turns into this
https://forum.doom9.org/attachment.php?attachmentid=18503&stc=1&d=1698765196


3. overlay() cropped text box with target clip using the box height which can be queried to position it vertically on the main video clip.

Problem is for step 2 i have no solution how to crop a clip leaving only the text using AviSynth+

Emulgator
31st October 2023, 19:17
About the (maybe historical) derivation of Subtitle() alignment:

https://forum.doom9.org/showthread.php?p=1993169#post1993169

StainlessS
1st November 2023, 00:12
When final newline is counted, then
"Line1" is 1 line [EDIT: Newlines Count is 0 {ie count of '\n' sequences}, Does NOT end in NewLine, must add 1 to the count of NewLines, 0 + 1 = 1]
"Line1\n" is still 1 line [EDIT: Newlines Count is 1, DOES end in NewLine so OK, all done return NewLine count(1)]
"Line1\n\n" has 2 lines (Line1 and an empty line) [EDIT: Newlines Count is 2, DOES end in NewLine so OK, all done return NewLine count(2)]

My present test implementation counts the final new line as well. Opinions?
That one is correct.

Counting Lines in Multi-line string:
For vertical justification we need to count the number of lines printed in a multi-line string.
So, firstly if the multi-line text string is "" then number of lines is 0, Otherwise below,
To count the text lines, you need to count the '\n' newlines, but, if newline '\n' does not occur at very end of the multi-line string, then counting
newlines alone gives wrong answer (you need add 1 to line count in such a case).
[EDIT: This Line in SubV script function,
# Line count with/without final newline
means that we want only the text lines count, and it has to be the same whether or not the multiline string ends with a newline or not.
END EDIT]


Also, I was aware that vertical centering was done at BaseLine, but no easy way of figuring out what that offset is
when not default font size. I did actually (in some subtitle 'mangling' script function) do some measurements to get
Baseline offset, but is a real pain having to do dummy rendering to some temp frame to figure it out (so we just ignored it {pixel difference between center and Baseline}).


Can you adopt it from "Text" function whatever way they use to center text vertically and put it into "Subtitle" function?

There is no way to enquire where the BaseLine is in system GDI subtitle fonts, it depends upon the Font and font_size.
The Text() function has a fixed size font and box size, it never changes so has fixed offset to Baseline.

I've just noticed that there is no mention of Text() on Wiki.

EDIT: @ Rob105,
Postimage instructions:- https://forum.doom9.org/showthread.php?p=1959414&highlight=postimage#post1959414
Can directly insert image (or small thumbnail as below) into your post [waiting for moderator approval can take quite some time].
[ClickMe]
https://i.postimg.cc/FYw7b7XS/post.jpg (https://postimg.cc/FYw7b7XS)

videoFred
1st November 2023, 13:47
Why not use SubtitleEx? Works great for me :)

Fred.

StainlessS
1st November 2023, 17:01
Why not use SubtitleEx? Works great for me :)
SSSssshhhhuuush !!!,
ReelDeel wanted some mod to SubtitleEx, you might remind him.

Reel.Deel
1st November 2023, 18:25
SSSssshhhhuuush !!!,
ReelDeel wanted some mod to SubtitleEx, you might remind him.

Thanks for reminding me StainlessS! I forgot to remind you for the 2 year anniversary (https://forum.doom9.org/showthread.php?p=1950327#post1950327). ... BTW, I read videoFred's message earlier but I didn't think of that, until you said something (also reminds me of ClipBlend) :p

StainlessS
1st November 2023, 19:29
Patience is a virtue {as well as a really boring card game}.