Can't get DrawText and other graphics text functions to work

I’m developing a plugin control, and I have the various graphics Draw/Fill calls for shapes working correctly, but I can’t get the methods that involve text (string) to work. This includes DrawText, TextWidth, and TextHeight.

Here’s how I map into the Xojo methods:

    typedef double (* TextWidthFuncTy)(REALgraphics, REALstring);
    TextWidthFuncTy TextWidth = (TextWidthFuncTy)REALLoadObjectMethod(context, "TextWidth(value As String) As Double");
    typedef double (* TextHeightFuncTy)(REALgraphics, REALstring, RBInteger);
    TextHeightFuncTy TextHeight = (TextHeightFuncTy)REALLoadObjectMethod(context, "TextHeight(value As String, wrapWidth as Integer) As Double");
    typedef void (* DrawTextFuncTy)(REALgraphics, REALstring, double, double, double, bool);
    DrawTextFuncTy DrawText = (DrawTextFuncTy)REALLoadObjectMethod(context, "DrawText(str As String, x As Double, y As Double, wrapWidth As Double, condense As Boolean)");

Then I call a method like so:

DrawText(context, data->someString, left, base, 0, false);

or

data->myHeight = TextHeight(context, data->someString, 9999));

where context is the passed REALgraphics object, someString is a REALstring and left & base are doubles.

But these always cause Xojo to crash. If I wrap the calls in an if like so:

if (DrawText) {
     DrawText(context, data->someString, left, base, 0, false);
}

then it doesn’t crash, but the functions don’t run. Meaning the mapping is not successful.

What am I missing?

BTW, this is in Xojo 2021 R1.1 on a Mac, though I’ll need to compile it for Windows also once it’s working correctly.

Never use bool, it is not same as RBBoolean, and you will eventually cause memory clobbering in some cases if you use bool when talking to Xojo since their structure size is not the same.

This one here is copy paste from a plugin of mine so I know 100% that this one works:

EGraphicsDrawStringF = (void(*)(REALgraphics, REALstring, double, double, double, RBBoolean)) REALLoadObjectMethod((REALobject)g, “DrawString(str as String,x as Double,y as Double,width as Double,condense as Boolean)”);

Note though if you want to support any range of Xojo versions then you will need to do more than this. This should for this particular method work down to 2018.

Björn,

When I compile your code I get errors about undeclared identifier ‘EGraphicsDrawStringF’ and ‘g’.

I’m not a C++ expert so I don’t understand the differences between your code and mine. Mine is based on the code I found in the few examples included in the SDK. Nowhere have I found an explanation of how this “mapping” (as I call it) works.

You need to define the EGraphicsDrawStringF variable, its of same type as the Type cast indicates. And the g is same as context in your code

Again, not a C++ expert (or even proficient). Not sure what the exact Type cast is, but that’s what I thought my code was already doing. And mine works for the other graphics functions, such as:

    typedef void (* FillRectangleFuncTy)(REALgraphics, double x, double y, double w, double h);
    FillRectangleFuncTy FillRectangle = (FillRectangleFuncTy)REALLoadObjectMethod(context, "FillRectangle(x As Double, y As Double, w As Double, h As Double)");

which I then call like so:

	REALSetPropValueColor((REALobject)context, "DrawingColor", data->BackgroundColor);
	FillRectangle(context, r.left, r.top, width, height);

And it works fine.

So what’s different about my DrawText one? (or DrawString - shouldn’t matter in my case).

Is it the return value? Or the passing of string values? I don’t know, and don’t know how to “debug” it. Is there a way to debug it from Xojo?

*Edit: shouldn’t be the return value for DrawText, was thinking about TextHeight and TextWidth.

I did not really see anything wrong with your DrawString, except the bool you had in it instead of RBBoolean.

Yes, I already changed the bool to RBBoolean, but that’s not the issue (possibly an issue down the road, as you pointed out - thanks).

So, what is the definition of your EGraphicsDrawStringF variable? That should allow me to see your version run successfully. Then I’ll have something to test against.

Same signature as the typecast:

so like this:

void(*EGraphicsDrawStringF )(REALgraphics, REALstring, double, double, double, RBBoolean);

Ok, finally figured out the problems.

The bool instead of RBBoolean was the problem with DrawText. But I didn’t realize that change fixed it because I had the drawing coordinates incorrect, so never saw evidence of it working. When I commented out the “if (DrawText)”, it no longer crashed, which meant the call was working.

The problem with TextHeight was the wrapWidth parameter definition. I had RBInteger when it should be double.

Finally, TextWidth was working all along, but because of the other problems it wasn’t evident.

Not being able to directly debug this stuff is a real challenge!

Thanks Björn for helping me sleuth it out.