[Pythonmac-SIG] info on CoreGraphics

eric eric@enthought.com
Thu, 18 Apr 2002 10:37:57 -0400


Hello group,

Within the last couple of days, I've gotten an iMac with OSX on my desk, and am
feeling my way around in the dark so to speak.  Getting up to speed on a new
platform is always a disorienting experience.

The sole reason for getting the iMac was to experiment with the CoreGraphics
library and DisplayPDF (ok, so they look cool too.)  We (Enthought) are writing
an open source, cross platform drawing library using DisplayPDF as a general
model.  The beginnings of the (un-announced shhhh.) project, called Chaco, are
available through CVS from the SciPy repository.  It is supported by the Space
Telescope Science Institute (think Hubble...) and will be the foundation for a
scientific plotting library (the real reason for this project).

I have a rough set of routines that can draw paths (no bezier stuff) and text
written in wxPython (the first target platform).  I'm to the point where I need
to start testing "corners" of the design, and I'd like to compare with how
quartz handles them.

So, to this point, I've been writing little routines in C using Project Builder
to generate a PDF file that I can look at to see what Quartz does (I've attached
one at the end).  I'd really rather write these in (Mac)Python, and it seems
like it should be possible.  I see a Carbon.CoreGraphics module, but I didn't
find anything but constants in it.  Am I looking in the wrong place for the
CoreGraphics routines, or have they just not made it into the package yet?

The best scenario would be to get a version of Chaco that sits directly on
CoreGraphics so I can do one-to-one comparisons with other platforms.

Any pointers are appreciated.  As a last resort, I can try to wrapper some of
these puppies on my own.  But I'm a stranger in a foreign land right now, and
hardly know which end is "up" on the compiler tools.  It doesn't even look like
I have the recommended setup (Code Warrior).

thanks,
eric

//////////////////////////////////////////
// example C code of what I'm playing with
//////////////////////////////////////////

#include "draw.h"
CGContextRef CreatePDFContext( const CGRect * inMediaBox,
                                CFStringRef inFileName )
{
    CGContextRef        outContext = NULL;
    CFURLRef            url;
    CGDataConsumerRef   dataConsumer;

    // Generate PDF to a file using a data consumer.
    // Use CoreFoundation's URL object to represent the file
    url = CFURLCreateWithFileSystemPath(NULL, /* use default allocator */
                                        inFileName,
                                        kCFURLPOSIXPathStyle,
                                        FALSE /* == not a directory*/ );

    // Create the data consumer
    if( url != NULL )
    {
        dataConsumer = CGDataConsumerCreateWithURL( url );
        if( dataConsumer != NULL )
        {
            // Create the context
            outContext = CGPDFContextCreate( dataConsumer, inMediaBox,
                                                                NULL );

            // The context retains a reference to the data consumer,
            // so we can (and should) release our reference to it to
            // avoid a memory leak
            CGDataConsumerRelease( dataConsumer );

        }
    }

    return outContext;
}

int angle()
{
    const float         kMediaHeight        = 100.0;
    const float         kMediaWidth         = 100.0;

    CGContextRef        context;
    CGRect              mediaBox;

    // Create the context
    mediaBox = CGRectMake( 0, 0, kMediaWidth, kMediaHeight );

    context = CreatePDFContext( &mediaBox, CFSTR("Star1.pdf") );

    if( context != NULL )
    {
        // We must begin a new page before drawing to a PDF context
        CGContextBeginPage( context, &mediaBox );

        CGContextSaveGState(context);
        CGContextTranslateCTM( context, 5.0, 5.0 );
        //CGContextRotateCTM( context, 0.1 );

        // first line
        // This is an unscaled line that should provide a gage for other
        // lines to be compared to.
//        CGContextScaleCTM(context, .2, .2);
//        CGContextSetRGBStrokeColor(context, 0,0,0,1.0);
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, 0,0);
        CGContextAddLineToPoint(context, 10, 0);
        CGContextStrokePath( context );
        CGContextRestoreGState(context);

        // second line
        // This is two lines at a right angle.  The second line has been
        // scaled by 5.  It demonstrates that, even though the lines are
        // drawn with different scales, both lines have their width scaled
        // equivalently using the scaling value in affect when StrokePath
        // is called.
        CGContextSaveGState(context);
        CGContextTranslateCTM( context, 0.0, 20.0 );
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, 0,0);
        CGContextAddLineToPoint(context, 10, 0);
        CGContextScaleCTM(context, 5, 5);
        CGContextSetRGBStrokeColor(context, .5,.5,.5,.5);
        // based on scaling, this should end up being a vertical line.
        CGContextAddLineToPoint(context, 2, 2);
        CGContextStrokePath( context );
        CGContextRestoreGState(context);


        // third line
        // how are line widths scaled when the scaling of x and y are different?
        CGContextSaveGState(context);
        CGContextTranslateCTM( context, 0.0, 40.0 );
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, 0,0);
        CGContextAddLineToPoint(context, 10, 0);
        CGContextScaleCTM(context, 2.5, 5);
        CGContextRotateCTM(context, 3.14159/4.);

        CGContextSetRGBStrokeColor(context, .5,.5,.5,.5);
        // based on scaling, this should end up being a vertical line.
        //CGContextAddLineToPoint(context, 4, 2);
        CGContextAddLineToPoint(context, 8, 2);
        CGContextStrokePath( context );
        CGContextRestoreGState(context);

        // We've finished rendering the page
        CGContextEndPage( context );

        // Release any objects we explicitly allocated
        CGContextRelease( context );
    }

    return 0;
}


int main()
{
    angle();
    return 0;
}

--
Eric Jones <eric at enthought.com>
Enthought, Inc. [www.enthought.com and www.scipy.org]
(512) 536-1057