[SDL] "Text has zero width" isn't an error.

Stefan Monov logixoul at gmail.com
Wed Apr 8 11:10:12 PDT 2009


On Wed, Apr 8, 2009 at 10:23 AM, Donny Viszneki
<donny.viszneki at gmail.com> wrote:
> On Wed, Apr 8, 2009 at 1:01 PM, Stefan Monov <logixoul at gmail.com> wrote:
>>> How is the error reported from RenderUTF8? It isn't something foolish
>>> like only a string description of the error, is it?
>> A null pointer is returned.
> Oh, is "string has zero width" the *only* error message RenderUTF8 can return?
I see what you mean.

First, to answer your question. Currently RenderUTF8 can produce the
following errors:
- "string has zero width"
- "failed to allocate text surface"
- "failed to find glyph"

Of those, only the first one sets the error-string (queried with
TTF_GetError). The second and third don't (which is a bug).
There is no real(*) way to know which one of those happened.
(*) The only way is to call TTF_SetError("dummy"), then call
RenderUTF8, then check whether the error-string has changed to "string
has zero width". This is clearly unacceptable, and does not let you
detect the other two errors. But that's another discussion.

> I'm a little confused as to why returning no surface when there is no
> data to be on that surface is being interpreted by some as a problem.
Here's where we diverge: I say there _is_ data to be on the surface,
and the data happens to be an empty string.
For example, the following should be correct usage of SDL_ttf:
SDL_Surface* surface = TTF_RenderUTF8_Blended(font, myTextVar, myColorVar);
myButton.resize(surface->w, surface->h);
SDL_BlitSurface(surface, NULL, screen, NULL);
SDL_FreeSurface(surface);

Here I am ignoring the possibility for errors other than "string has
zero width". If those were reported properly, the code would become:
TTF_ErrorCode err;
SDL_Surface* surface = TTF_RenderUTF8_Blended(font, myTextVar,
myColorVar, &err);
if(err == TTF_SurfaceAllocationError) /* handle error */;
if(err == TTF_GlyphNotFound) /* handle error */;
/* note lack of check for "err == TTF_ZeroWidthError" */
myButton.resize(surface->w, surface->h);
SDL_BlitSurface(surface, NULL, screen, NULL);
SDL_FreeSurface(surface);

> You should be checking if it's null anyway, otherwise you segfault
> when you dereference the pointer to get the width and height. This is
> a small part of the reason I'm perplexed by the desire for no-pixel
> surfaces as the return value.
This desire is merely the application of the Principle of Least
Surprise. I consider it to make SDL more difficult to use.
I think this is pretty self-explanatory.
I will try to make available a patch shortly as I've no desire of
arguing further. From there I leave the decision to you.

> What would width==0 and height!=0 mean? (or vice versa.)
> This is the reason I disagree with Stefan [..]
It would mean that blitting the surface is a no-op and querying
"surface->w" and "surface->h" is a legal operation yielding 0 and a
nonzero value.

Torsen says:
> I think the basic reason why SDL_ttf is doing it in this way, is just because it is also
> used in SDL all over the place. If there an error occurs, the function returns a NULL pointer.
As Donny said, I don't consider it an error, so NULL must not be returned.

> The second thing i can imagine is the speed reason.
> It is a little bit faster to check if the pointer is null
> then to check if width == 0 && height == 0 in your routines.
No, that's wrong: I won't do any checking at all. I'll simply use the
surface as usual. See code example above.

Jonathan says:
> It is a lot less computation to return NULL rather than
> a fully-initialised 0x0 surface with all its fields...
True. However, is this not a pointless thing to optimize? The cost of
constructing a 0x0 surface is dwarfed even by that of say, blitting a
32x32 sprite of which there are thousands in an application...

> Actually, now that I think of it, if you're using SDL_BlitSurface(),
> it doesn't care if you pass a NULL surface.  What is the use case
> here?
Mainly, to be able to query width and height without needless checks.
See code sample above.
Also, not all functions in real-world code are documented to be no-ops
when passed a NULL surface.
For example, SDL_gfx's rotozoomSurface just might crash if passed
NULL. You can't know.

Stefan.



More information about the SDL mailing list