Getting a CGContextRef in a plugin without QuickDraw

I’m converting an old RB plugin that uses QuickDraw to use CoreGraphics and I’m running into issues.

The old code looks like this:

// Note: rbContext is valid, passed in from the callback method
REALgraphics rbContext = …;

CGrafPtr rbPort;
CGContextRef cgContext;

REALSelectGraphics(rbContext);
GetPort(&rbPort);
QDBeginCGContext(rbPort, &cgContext);
[…]

After this, I have a valid CGContextRef to do all my drawing. But this requires me to link against the 10.6 SDK and Carbon.

I’d like to get a CGContextRef directly from a REALgraphics object. From rb_plugin.h, this looks like it fits the bill:

#if COCOA
CGContextRef REALGraphicsDC(REALgraphics context) DEPRECATED;
#endif

(Yeah, I see the DEPRECATED. All the graphics stuff is DEPRECATED :frowning: )

Problem is, the REALGraphicsDC method does not exist. The plugin shim can’t find it, so I end up with a 0x0 context. A quick check with nm shows that none of the Xojo frameworks export that symbol. confirming what I see in the plugin.

Have any of you written a graphics plugin for Xojo on Mac? Do you rely on QuickDraw?

Thanks,
Philippe

Use REALLoadObjectMethod to get and call the Handle function of the Graphics object.

I see. Something like this?

typedef int32_t (*HandleFuncPtr)(int32_t type);
HandleFuncPtr rbHandle = (HandleFuncPtr)REALLoadObjectMethod((REALobject)rbContext, “Handle(Type as Integer) as Integer”);
if (rbHandle) {
cgContext = (CGContextRef)rbHandle(5);
}

I probably typed something wrong because it crashes spectacularly…

[quote=144014:@Philippe Casgrain]I see. Something like this?

typedef int32_t (*HandleFuncPtr)(int32_t type);
HandleFuncPtr rbHandle = (HandleFuncPtr)REALLoadObjectMethod((REALobject)rbContext, “Handle(Type as Integer) as Integer”);
if (rbHandle) {
cgContext = (CGContextRef)rbHandle(5);
}

I probably typed something wrong because it crashes spectacularly…[/quote]

The prototype for the function pointer should be:

typedef RBInteger (*HandleFuncPtr)(REALobject, RBInteger type);

That makes sense, I see. With the new prototype I no longer get a crash, but the CGContextRef is still 0x0:

if (rbHandle) {
cgContext = (CGContextRef)rbHandle((REALobject)rbContext, 5);
}
NSLog(@“rbContext: %p”, rbContext);
NSLog(@“rbHandle: %p”, rbHandle);
NSLog(@“cgContext: %p”, cgContext);

2014-11-17 17:44:39,215 Debug[15412]: rbContext: 0x12808f90
2014-11-17 17:44:39,215 Debug[15412]: rbHandle: 0x158940
2014-11-17 17:44:39,215 Debug[15412]: cgContext: 0x0

Where does you Graphics object come from?

Passed-in from the Constructor:

REALmethodDefinition GKCGGraphicsMethods[] = {
{ (REALproc)GKCGGraphicsConstructorWithRBContext, REALnoImplementation, “Constructor( g as Graphics )” },
{ (REALproc)GKCGGraphicsConstructorWithCGContext, REALnoImplementation, “Constructor( context as Integer, width as Integer, height as Integer )” },
};

void GKCGGraphicsConstructorWithRBContext(REALobject inst, REALgraphics g, REALcontrolInstance control)
{
GKCGGraphicsData *me = GetGKCGGraphicsData( inst );
me->rbContext = g;
me->rbControl = control;
REALLockObject( (REALobject)control );
REALLockObject( (REALobject)g );
GKCGGraphicsBeginDocument(inst);

GKCGGraphicsSetupRBContext(inst);

}

The code snippets above are from GKCGGraphicsSetupRBContext().

I meant more in terms of where did the Xojo Graphics object come from? Paint event of a Canvas? A Picture?

Philippe, you should add code to check if g or control is nil to the constructor above.

Christian, thanks. g and control are not nil in the constructor as shown in the NSLog statement. This code also works fine when using QuickDraw. I am mostly concerned that I am unable to get a CGContextRef without using QD.

It’s a Picture, typically loaded from a binary stream that is valid.

Is this a Cocoa app or a Carbon one? This should work for Cocoa applications.

It’s currently a Carbon application in the process of being Cocoa-ified. Are you saying that once we “flip the switch” it should start to work? If so, I’ll pipe back when the switch has been flipped…

(We’re also very hopeful that this switch to Cocoa will fix https://forum.xojo.com/16850-typing-in-textboxes-sometimes-fails-in-yosemite-10-10 )

For Carbon, you still need QuickDraw, it think.
In my plugin I do a lot of workarounds to built still an Carbon support.
Apply removed most of the APIs already from headers.

For Cocoa, the CGContextRef is easy to get from graphics or picture objects via handles.

Yes.

I am happy to report that… it worked!

We flipped the figurative switch this weekend, and our Xojo app is now Cocoa-based as opposed to Carbon-based. And calling the Handle with type 5 gives me back a CGContextRef that I can mess with right away.

So far everything seems to work as normal: I can get bitmaps, dimensions, mess around with CGDataProviders, it’s all good. And it’s all built using the 10.8 SDK. Can’t wait to move to a later SDK! :slight_smile:

Thanks to everyone and esp. Joe, that helped a lot.