[MacRuby-devel] MacRuby 0.5 vs. CG Bitmap Context

Brian Chapados chapbr at gmail.com
Sat Mar 6 15:11:46 PST 2010


Hi Scott,

The problem is due to the way the macruby Pointer class handles types,
which apparently is due to an LLVM issue... The Pointer class is
defined in compiler.cpp. See this comment:

---
VALUE
rb_pointer_new(const char *type_str, void *val, size_t len)
{
    // LLVM doesn't allow to get a pointer to Type::VoidTy, and for convenience
    // reasons we map a pointer to void as a pointer to unsigned char.
    if (*type_str == 'v') {
        type_str = "C";
    }
---

The good news is that you might not need to worry about it in this
case. In 10.6, you can pass NULL (use 'nil' in MacRuby) as the first
argument to CGBitmapContextCreate, as long as you don't mind letting
CoreGraphics manage the memory allocation for you:

from the docs:
---
"In Mac OS X v10.6 and later, you can pass NULL if you do not care
where the data is stored. This frees you from managing your own
memory, which reduces memory leak issues. Quartz has more flexibility
when it manages data storage for you. For example, it’s possible for
Quartz to use OpenGL for rendering if it takes care of the memory."
---

So you should be able to do something like this:

framework 'ApplicationServices'

bitmap_context = CGBitmapContextCreate(nil, 512, 512, 8, 512,
CGColorSpaceCreateDeviceGray(), KCGImageAlphaNone)

Brian

On Fri, Mar 5, 2010 at 8:34 AM, Scott Thompson <easco at mac.com> wrote:
> I'm using MacRuby to work with CoreGraphics and having some trouble with
> pointers.
> My first attempt was to create the data for a bitmap context using
> NSMutableData:
> bitmap_data = NSMutableData.alloc.initWithLength(image_data_size)
> bitmap_context = CGBitmapContextCreate(
>                           bitmap_data.mutableBytes(),
>                           image_width, image_height,
>                           8, image_width,
>                           gray_color_space, KCGImageAlphaNone)
>
> If I do this, I get an error that "expected instance of Pointer of type 'v',
> got 'C' (TypeError)"
> I gather from this that CGBitmapContextCreate was expecting a (void *) and
> got a (UInt8 *).  In C I would just type the difference away, but Ruby
> doesn't like ti.
> I tried something like:
> bitmap_data_ptr = Pointer.new_of_type('v')
> bitmap_data_ptr.assign(bitmap_data.mutableBytes())
> This didn't work very well either.  I get an error that the system can't do
> a "sizeof" of an unsized type (presumably void *)
> I also tried doing similar using CFDataRef (not much difference really).  It
> looked like:
> bitmap_data = CFDataCreateMutable(nil, image_data_size)
> CFDataSetLength(bitmap_data, image_data_size)
> bitmap_data_ptr = CFDataGetMutableBytePtr(bitmap_data)
> bitmap_context = CGBitmapContextCreate(
>                           CFDataGetMutableBytePtr(bitmap_data),
>                           image_width, image_height,
>                           8, image_width,
>                           gray_color_space, KCGImageAlphaNone)
>
> In this case, I get an error that "expected instance of Pointer, got '""'
> (NSMutableString) (TypeError)
> Evidently MacRuby sees the return value of CFDataGetMutableBytePtr as being
> a string, subsequently typecasts it as such, and goes on.
> Is there anything I can do to typecast the pointers to a type that MacRuby
> will accept?
> Scott
>
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>
>


More information about the MacRuby-devel mailing list