From my experiments with Windows Glulx, it supports font size changes in the TextBuffer windows, but not TextGrid windows.
If the writer of a game wishes to only change font sizes at the beginning of lines, then they can do so very easily with my proposal. Why remove the option of more control? The complexity of this system falls on the game code, not the interpreter. The only changes since DavidK pointed out the problem are a new word in the header extension, and a new property for z6 windows, both of which the interpreter is allowed to ignore. Saying that game writers should not be allowed the option to do something because it would be difficult for them (not the interpreter writer) seems pointless.
But it is complicated for the interpreter writer! Getting ascender and descender information could be hard or impossible. What units should be used? And even if the interpreter provided those details how is the game author to make use of them?
I realise that getting that information may be impossible, which is why the interpreter has the option of not providing it if it cannot. It’d probably be worth making a gestalt for this, so the game writer knows ahead of time what is possible. Units would be units (probably pixels) just as for font height. Obviously, if you use character size for unit size, you cannot give useful information for the ascent and descent. So they would be set to 0. But if you’re using character size for unit size, you’re probably using z5, in an interpreter which does not allow for font size changes in the upper window, so all the characters involved in any complex text-placement operations are the same exact size and the baseline no longer matters.
And, as for how the game author is to make use of them, that code I printed earlier in response to DavidK can be easily modified to work properly if the extra font information is available.
[ main small_fasc large_fasc x y; @get_wind_prop 0 18 → x; @log_shift x 8 → small_fasc;
font_size(1); @get_wind_prop 0 13 → x; @log_shift x 8 → large_fasc;
y = large_fasc - small_fasc;
x = 1;
font_size(0); @set_cursor x y;
print "This is a bunch of text. ";
font_size(1); @get_cursor cpos;
x = cpos → 1;
y = 1; @set_cursor x y;
print “This is some larger text.^”
];[/code]
The interpreter can supply the baseline position, which would help some, but I still think that this feature needs more thought. As I see it, there basically three window types to consider V5 (lower), V5 (upper) and V6 windows.
V5 (lower) is the easy case. Text is just written to it as a stream, and if the game asks for different font sizes and the interpreter wishes to honor them, then it’s up to the interpreter to handle buffering up text, aligning text baselines etc. That is well understood, and how Windows Glk handles text buffer windows.
V5 (upper) seems trickier, since changing the font height will also change the font width, too. Are columns in the upper window supposed to line up after printing in a different font size?
V6 is where it gets even harder, since what you’re proposing essentially means that the game and the interpreter have to co-operate somehow to print text nicely formatted. Suppose the game is printing a string to a V6 window and wants to put in a word at a different font size. How does the game know which line will need the font height / baseline adjustment logic? As soon as you put the game in charge of handling that, it also has to know about word wrapping.
I believe I have the font-size changes for z6 required by my proposal working correctly in my interpreter now, so I will play around with it for a while and see if I can make it work nicely.
Basically every modern interpreter sets units to be character sizes in z5, and there are probably several games which (technically incorrectly) assume this to always be true. What I’m assuming will happen, if an interpreter actually allows font size changes in the upper window, is that units will be set to pixels. The ‘font size’ information in the header will always be updated to be accurate for the current font and font size, and games that wish to use fonts of different sizes in the upper window will have to cope with the fact that it is no longer a grid of characters, and cursor placement will have to be made on a pixel level.
In order that the interpreter can set unit size to pixels instead of characters, Flags 3 will have a new bit that must be set if the game wants to change font sizes.
I’m also assuming that for most interpreters, they will actually just leave unit sizes as character sizes, and font size changes will not affect the text in the upper window. Having units as character sizes while font size changes work in the lower window will not matter, because the game is unable to move the cursor about in the lower window anyway, so that the size of units affects nothing.
So, I spent quite a while working on making Inform code that would allow a z6 game writer to easily print text of different font sizes with the same baseline, and I think I’d nearly got there, but the code was getting ridiculously complex for an operation that would likely be one of the main uses of font size changes.
So I went back and took another look at the z6 model, and came up with a new idea. Essentially each window is given a new attribute, which controls whether the interpreter adjusts the text to look nice.
This suffers from the same fundamental issue as the previous approach. Allowing the game to print text with different font sizes is most straightforward when the screen model is essentially that of an output stream, but the V6 screen model is that of a rectangular grid of pixels. The conflict between these two ideas is present in your suggestion, notably in that you’ve had to disallow variable font sizes with transparent background printing. From a user’s point of view, why shouldn’t different font sizes work with transparency?
To my mind the only approach that will solve this properly is to have some way to reconcile the two screen models. I could imagine a workable scheme where we have some concept of a way of defining a point in the sequence of text output for a window from where the interpreter buffers up text output and font sizes until the next such point (e.g. some new opcode, or something like changing a window flag, or moving the cursor) at which point all the currently buffered text is written to the display, with appropriate positioning for font sizes. If you don’t do this then you end up with a model where the interpreter has to try to patch up the differences between the screen models as it goes along (as in your current suggestion) which to me seems like it will always be brittle.
Buffering up the text like that doesn’t always work, though. The game could wait for a key to be pressed between two bits of text of different sizes on the same line, or have the text appear at regular intervals using timed input. Buffering might be turned off for that window. If we want to buffer font size changes, we’d have to buffer all other changes that might happen at the same time, like colours changes, or it breaks.
Scrolling a window with a transparent background is already illegal, for much the same reason.