@@ -2767,15 +2767,32 @@ static CGFloat _get_device_scale(CGContextRef cr)
27672767 float height;
27682768
27692769 CGRect rect;
2770-
27712770 CGPoint point;
2771+
27722772 CTFontRef font;
27732773
2774+ char data[8 ];
2775+
27742776 CGContextRef cr = self->cr ;
27752777 if (!cr)
27762778 {
2777- PyErr_SetString (PyExc_RuntimeError, " CGContextRef is NULL" );
2778- return NULL ;
2779+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray ();
2780+ if (!colorspace) {
2781+ PyErr_SetString (PyExc_MemoryError, " Failed to create color space" );
2782+ goto exit;
2783+ }
2784+ cr = CGBitmapContextCreate (data,
2785+ 1 ,
2786+ 1 ,
2787+ 8 ,
2788+ 1 ,
2789+ colorspace,
2790+ 0 );
2791+ CGColorSpaceRelease (colorspace);
2792+ if (!cr) {
2793+ PyErr_SetString (PyExc_MemoryError, " Failed to create bitmap context" );
2794+ goto exit;
2795+ }
27792796 }
27802797
27812798#if PY33
@@ -2785,7 +2802,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
27852802 &family,
27862803 &size,
27872804 &weight,
2788- &italic)) return NULL ;
2805+ &italic)) goto exit ;
27892806 CFStringRef s = CFStringCreateWithCString (kCFAllocatorDefault , text, kCFStringEncodingUTF8 );
27902807#else
27912808 if (!PyArg_ParseTuple (args, " u#Ofss" ,
@@ -2801,7 +2818,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
28012818 if (!(font = setfont (cr, family, size, weight, italic)))
28022819 {
28032820 CFRelease (s);
2804- return NULL ;
2821+ goto exit ;
28052822 };
28062823
28072824 CFStringRef keys[1 ];
@@ -2830,18 +2847,22 @@ static CGFloat _get_device_scale(CGContextRef cr)
28302847 {
28312848 PyErr_SetString (PyExc_RuntimeError,
28322849 " CTLineCreateWithAttributedString failed" );
2833- return NULL ;
2850+ goto exit ;
28342851 }
28352852
28362853 point = CGContextGetTextPosition (cr);
28372854 rect = CTLineGetImageBounds (line, cr);
28382855 CFRelease (line);
2856+ if (!self->cr ) CGContextRelease (cr);
28392857
28402858 width = rect.size .width ;
28412859 height = rect.size .height ;
28422860 descent = point.y - rect.origin .y ;
28432861
28442862 return Py_BuildValue (" fff" , width, height, descent);
2863+ exit:
2864+ if (cr && !self->cr ) CGContextRelease (cr);
2865+ return NULL ;
28452866}
28462867
28472868#else // Text drawing for OSX versions <10.5
@@ -2956,19 +2977,33 @@ static CGFloat _get_device_scale(CGContextRef cr)
29562977 ATSFontRef atsfont;
29572978 Rect rect;
29582979
2980+ char data[8 ];
2981+
29592982 CGContextRef cr = self->cr ;
29602983 if (!cr)
29612984 {
2962- PyErr_SetString (PyExc_RuntimeError, " CGContextRef is NULL" );
2963- return NULL ;
2985+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray ();
2986+ if (!colorspace) {
2987+ PyErr_SetString (PyExc_MemoryError, " Failed to create color space" );
2988+ goto exit;
2989+ }
2990+ cr = CGBitmapContextCreate (data,
2991+ 1 ,
2992+ 1 ,
2993+ 8 ,
2994+ 1 ,
2995+ colorspace,
2996+ 0 );
2997+ CGColorSpaceRelease (colorspace);
2998+ if (!cr) {
2999+ PyErr_SetString (PyExc_MemoryError, " Failed to create bitmap context" );
3000+ goto exit;
3001+ }
29643002 }
29653003
2966- if (!PyArg_ParseTuple (args, " u#Ofss" , &text, &n, &family, &size, &weight, &italic)) return NULL ;
3004+ if (!PyArg_ParseTuple (args, " u#Ofss" , &text, &n, &family, &size, &weight, &italic)) goto exit ;
29673005
2968- if (!(atsfont = setfont (cr, family, size, weight, italic)))
2969- {
2970- return NULL ;
2971- }
3006+ if (!(atsfont = setfont (cr, family, size, weight, italic))) goto exit;
29723007
29733008 OSStatus status = noErr;
29743009 ATSUAttributeTag tags[] = {kATSUFontTag ,
@@ -2988,7 +3023,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
29883023 if (status!=noErr)
29893024 {
29903025 PyErr_SetString (PyExc_RuntimeError, " ATSUSetAttributes failed" );
2991- return NULL ;
3026+ goto exit ;
29923027 }
29933028
29943029 status = ATSUSetTextPointerLocation (layout,
@@ -3000,7 +3035,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
30003035 {
30013036 PyErr_SetString (PyExc_RuntimeError,
30023037 " ATSUCreateTextLayoutWithTextPtr failed" );
3003- return NULL ;
3038+ goto exit ;
30043039 }
30053040
30063041 status = ATSUSetRunStyle (layout,
@@ -3010,7 +3045,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
30103045 if (status!=noErr)
30113046 {
30123047 PyErr_SetString (PyExc_RuntimeError, " ATSUSetRunStyle failed" );
3013- return NULL ;
3048+ goto exit ;
30143049 }
30153050
30163051 ATSUAttributeTag tag = kATSUCGContextTag ;
@@ -3020,7 +3055,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
30203055 if (status!=noErr)
30213056 {
30223057 PyErr_SetString (PyExc_RuntimeError, " ATSUSetLayoutControls failed" );
3023- return NULL ;
3058+ goto exit ;
30243059 }
30253060
30263061 status = ATSUMeasureTextImage (layout,
@@ -3029,14 +3064,17 @@ static CGFloat _get_device_scale(CGContextRef cr)
30293064 if (status!=noErr)
30303065 {
30313066 PyErr_SetString (PyExc_RuntimeError, " ATSUMeasureTextImage failed" );
3032- return NULL ;
3067+ goto exit ;
30333068 }
30343069
30353070 const float width = rect.right -rect.left ;
30363071 const float height = rect.bottom -rect.top ;
30373072 const float descent = rect.bottom ;
30383073
30393074 return Py_BuildValue (" fff" , width, height, descent);
3075+ exit:
3076+ if (cr && !self->cr ) CGContextRelease (cr);
3077+ return NULL ;
30403078}
30413079#endif
30423080
0 commit comments