BBC BASIC
Programming >> Graphics and Games >> Bug - or unrecognised feature?
http://bbcbasic.conforums.com/index.cgi?board=graphics&action=display&num=1513847020

Bug - or unrecognised feature?
Post by KenDown on Dec 21st, 2017, 08:03am

I want to find the length of a string which contains colour codes and, as the string will be printed under VDU5, that means adding the string equivalent of VDU18,0,colour

I would have thought that those three characters should *not* be included in the string length, but to my annoyance they are. Am I missing something? The following short program illustrates the problem.


DIMU%300:U%=(U%+1)AND-2
DIMfsize{fontx%,fonty%}
OSCLI("FONT Arial,32,B")
a$="Kendall Down"
b$="Kendall "+CHR$18+CHR$0+CHR$9+"Down"
PROClen(a$)
PROClen(b$)
END
:
DEFPROClen(t$):LOCALL%
OSCLI("FONT Arial,32,B")
SYS"MultiByteToWideChar",&FDE9,0,t$,LENt$,0,0TOL%
SYS"MultiByteToWideChar",&FDE9,0,t$,LENt$,U%,L%
SYS"GetTextExtentPoint32W",@memhdc%,U%,L%,fsize{}
PRINTfsize.fontx%
ENDPROC
Re: Bug - or unrecognised feature?
Post by Richard Russell on Dec 21st, 2017, 2:00pm

on Dec 21st, 2017, 08:03am, KenDown wrote:
I would have thought that those three characters should *not* be included in the string length, but to my annoyance they are. Am I missing something?

Using the more straightforward WIDTH() function - which returns the width in graphics units - I don't see any problem:

Code:
      OSCLI "FONT Arial,32,B"      a$ = "Kendall Down"      b$ = "Kendall "+CHR$18+CHR$0+CHR$9+"Down"      PRINT WIDTH(a$)      PRINT WIDTH(b$)      END 

Richard.

Re: Bug - or unrecognised feature?
Post by KenDown on Dec 21st, 2017, 3:42pm

Thanks, but will WIDTH() deal with UTF-8 characters, such as Bulgarian or even Welsh? That, I am pretty sure, is why the slightly long-winded MultiBytetpWide method was adopted.
Re: Bug - or unrecognised feature?
Post by KenDown on Dec 21st, 2017, 3:44pm

Ah, I've just looked up the WIDTH command and see that since 6.10a it *will* handle UTF-8. I can sense a major rewrite coming up!
Re: Bug - or unrecognised feature?
Post by KenDown on Dec 22nd, 2017, 05:47am

Thanks. I've incorportated the WIDTH command and the program runs noticeably faster in consequence. However I still have to use the MultiBytetoWide method every time I change font to find out the height of the font. We need a HEIGHT() command as well!

While I'm at it, there is a major annoyance for me in that under VDU5 text is wrapped - I'm sure that in the BBC Micro VDU5 was not wrapped and simply vanished off the right-hand edge of the screen. It would be good if there could be a flag to set so that either behaviour could be selected.
Re: Bug - or unrecognised feature?
Post by Richard Russell on Dec 22nd, 2017, 09:18am

on Dec 22nd, 2017, 05:47am, KenDown wrote:
We need a HEIGHT() command as well!

I disagree. There's no such thing as 'proportional height' text (!) so the complication that different characters have different widths has no equivalent. Whether it's a monospaced font or a proportional font, the value at @vdu%!220 is an accurate measure of the character (row) height in pixels. This is a documented system variable, and has been for a very long time.

Note that, as with most system variables, in BBCSDL you must perform a 'thread synchronisation' before you can read the value reliably. It's harmless to do the same thing in BB4W so it's as well to get into the habit, for example:

Code:
      sync% = POS      height% = @vdu%!220 

Quote:
While I'm at it, there is a major annoyance for me in that under VDU5 text is wrapped - I'm sure that in the BBC Micro VDU5 was not wrapped and simply vanished off the right-hand edge of the screen.

You say that you are "sure that in the BBC Micro VDU5 was not wrapped" so how come that when I turn on my BBC Master, enter MODE 1 and then VDU 5,30, text that I type wraps from one line to the next?

Your recollection is faulty, and I would have hoped that you would expect BB4W and BBCSDL to emulate the BBC Micro accurately in this respect, as they do in most others.

Quote:
It would be good if there could be a flag to set so that either behaviour could be selected.

Er, so that would be VDU 23,16... then, which has been implemented (and documented) since the Acorn Archimedes, that's at least thirty years!!

Richard.

Re: Bug - or unrecognised feature?
Post by KenDown on Dec 22nd, 2017, 1:16pm

Hmmmm. I repent in dust and ashes!

However, although on its own @vdu%!220 (with or without the POS) returns the right answer for the height of a font, it must conflict with something else in my program because it mucks up the values returned by WIDTH() (or mucks up how I deal with them, or something). I'll have to look into it more.

VDU23,16,64;0;0;0; causes the behavour I'm looking for (scrolling text starting off the screen to the right and ending off the screen to the left). Thanks for that and apologies for not realising that it was there.

Is VDU23,16,0;0;0;0; the default? ie. If I do that after my scrolling routine has finished, will I be back to square one, so to speak?
Re: Bug - or unrecognised feature?
Post by Richard Russell on Dec 22nd, 2017, 2:02pm

on Dec 22nd, 2017, 1:16pm, KenDown wrote:
Is VDU23,16,0;0;0;0; the default?

Yes.

Richard.

Re: Bug - or unrecognised feature?
Post by KenDown on Dec 22nd, 2017, 8:42pm

Thanks. I really appreciate your replies. A very big help.
Re: Bug - or unrecognised feature?
Post by KenDown on Dec 23rd, 2017, 02:21am

Curioser and curioser. A friend with whom I have been corresponding over this matter sent me the following program.

f$= "FONT Arial,32,B"
a$="Kendall Down"
b$="Kendall "+CHR$18+CHR$0+CHR$9+"Down"
OSCLI(f$)
VDU5
MOVE100,400:PRINTa$, WIDTH(a$)/2, @vdu%!220
MOVE100,300:PRINTb$, WIDTH(b$)/2, @vdu%!220

MOVE100,200:PRINTb$, WIDTH(b$)/2, @vdu%!220
MOVE100,100:PRINTa$, WIDTH(a$)/2, @vdu%!220
VDU4
END

When you run it the numbers in the top and bottom lines are further to the right than the numbers in the middle two lines. Now reverse the order of the lines, so that the two lines with b$ are at top and bottom and the two lines with a$ are in the middle. Run it again and it is *still* the top and bottom lines which have the numbers offset to the right!

I blame the litte green men on Mars, myself.
Re: Bug - or unrecognised feature?
Post by Richard Russell on Dec 23rd, 2017, 10:09am

on Dec 23rd, 2017, 02:21am, KenDown wrote:
When you run it the numbers in the top and bottom lines are further to the right than the numbers in the middle two lines.

There's nothing strange going on here. What you are forgetting is that there are features of the PRINT statement which work properly only when all the characters output have the same width; specifically they are right-justified printing of numbers (which is the default) and tabulation using the TAB(n) function or the comma delimiter. The program you listed uses both right-justified numbers and the comma delimiter, so it is not surprising that it misbehaves.

PRINT simply counts the characters (bytes) you output - you can get the current value from the COUNT function - and assumes they all occupy the same width on the screen. When it tries to align the text to a specific column it outputs a number of spaces based on the current value of COUNT. If you select a proportional-spaced font, or use UTF-8 encoding, or incorporate 'non-printing' characters in strings, this doesn't work.

In that case you must take responsibility for formatting yourself, so if you want to have numbers printed right-justified, or tabulate output in columns, you cannot rely on the built-in features of the PRINT statement. Instead you will need to convert the numbers to strings (STR$), measure their width (WIDTH) and MOVE the graphics pointer to the appropriate place to achieve the required alignment.

Richard.