Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 61a7154

Browse files
committed
Create a temporary bitmap context if needed
1 parent d22f626 commit 61a7154

File tree

1 file changed

+56
-18
lines changed

1 file changed

+56
-18
lines changed

src/_macosx.m

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)