PDA

View Full Version : Text positioning in ShowFrameNumber, etc


Gavino
28th October 2009, 11:46
In ShowFrameNumber, when using the arguments x and y to set the text position explicitly, the text is not positioned correctly. Instead of having (left, baseline) at (x, y), it appears at (x-2, y-8).
Also, when scroll=true, the text for some frames can be off the screen, depending on the relationship between frame height and font size. For example,
BlankClip(100, 400, 292).ShowFrameNumber(scroll=true)
has no visible text for frame 12.
A minor cosmetic improvement can also be made by using an alignment of TA_RIGHT when writing on the right hand side of the frame, rather than using left alignment and calculating (inaccurately) the start position.

I suggest the following code changes in ShowFrameNumber::GetFrame to address these issues.
Original code:
SetTextAlign(hdc, TA_BASELINE|TA_LEFT);
RECT r = { 0, 0, 32767, 32767 };
FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
char text[16];
wsprintf(text, "%05d", n);
if (x!=-1 && y!=-1) {
TextOut(hdc, x*8, y*8-48, text, strlen(text));
} else if (scroll) {
int n1 = vi.IsFieldBased() ? (n/2) : n;
int y2 = size + (size*n1)%(vi.height*8);
TextOut(hdc, child->GetParity(n) ? 32 : vi.width*8-int(3*size), y2, text, strlen(text));
} else {
for (int y2=size; y2<vi.height*8; y2 += size)
//TextOut(hdc, x*8, y*8-48, text, strlen(text));
TextOut(hdc, child->GetParity(n) ? 32 : vi.width*8-int(3*size), y2, text, strlen(text));
}
New code:
RECT r = { 0, 0, 32767, 32767 };
FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
char text[16];
wsprintf(text, "%05d", n);
if (x!=-1 && y!=-1) {
SetTextAlign(hdc, TA_BASELINE|TA_LEFT);
TextOut(hdc, x*8+16, y*8+16, text, strlen(text));
} else if (scroll) {
int n1 = vi.IsFieldBased() ? (n/2) : n;
int y2 = size + size*(n1%(vi.height*8/size));
SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));
TextOut(hdc, child->GetParity(n) ? 32 : vi.width*8, y2, text, strlen(text));
} else {
SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));
for (int y2=size; y2<vi.height*8; y2 += size)
//TextOut(hdc, x*8, y*8-48, text, strlen(text));
TextOut(hdc, child->GetParity(n) ? 32 : vi.width*8, y2, text, strlen(text));
}
Similarly, ShowSMPTE and ShowTime both display text with (center, baseline) at (x-2, y-8) instead of (x, y).
The code in ShowSMPTE::GetFrame should be changed from
TextOut(hdc, x*8, y*8-48, text, strlen(text));
to
TextOut(hdc, x*8+16, y*8+16, text, strlen(text));
To allow for this, the setting of default y in ShowSMPTE::CreateSMTPE must be changed from
const int y = args[5].AsInt(yreal);
to
const int y = args[5].AsInt(yreal-8);
with a similar change (with args[3]) in ShowSMPTE::CreateTime.

Finally, there is a possible deficiency in ApplyMessage - if the intention is to center the text, it doesn't do it accurately.
RECT r = { 4*8, 4*8, (vi.width-4)*8, (vi.height-4)*8 };
should be
RECT r = { 4*8, 4*8, vi.width*8, vi.height*8 };

Wilbert
29th May 2011, 20:50
@Gavino, is above addressed or is it still an issue?

Gavino
29th May 2011, 22:10
I believe this is covered by the change list item "SubTitle, improve pixel registration".

I'll have a detailed look at the new code and get back later to confirm that everything has been addressed.

Gavino
30th May 2011, 01:13
I can confirm the changes were incorporated into revision 1.33 of text-overlay.cpp.