Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize for str hex color values #3302

Merged
merged 1 commit into from
Jan 25, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 30 additions & 40 deletions src_c/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,67 +484,53 @@ _hextoint(char *hex, Uint8 *val)
static tristate
_hexcolor(PyObject *color, Uint8 rgba[])
{
size_t len;
tristate rcode = TRISTATE_FAIL;
char *name;
PyObject *ascii = PyUnicode_AsASCIIString(color);
if (ascii == NULL) {
rcode = TRISTATE_ERROR;
goto Fail;
}
name = PyBytes_AsString(ascii);
Py_ssize_t len;
char *name = (char *)PyUnicode_AsUTF8AndSize(color, &len);
if (name == NULL) {
goto Fail;
return TRISTATE_ERROR;
}

len = strlen(name);
/* hex colors can be
* #RRGGBB
* #RRGGBBAA
* 0xRRGGBB
* 0xRRGGBBAA
*/
if (len < 7) {
goto Fail;
return TRISTATE_FAIL;
}

if (name[0] == '#') {
if (len != 7 && len != 9)
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 1, &rgba[0]))
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 3, &rgba[1]))
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 5, &rgba[2]))
goto Fail;
return TRISTATE_FAIL;
rgba[3] = 255;
if (len == 9 && !_hextoint(name + 7, &rgba[3])) {
goto Fail;
return TRISTATE_FAIL;
}
goto Success;
return TRISTATE_SUCCESS;
}
else if (name[0] == '0' && name[1] == 'x') {
if (len != 8 && len != 10)
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 2, &rgba[0]))
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 4, &rgba[1]))
goto Fail;
return TRISTATE_FAIL;
if (!_hextoint(name + 6, &rgba[2]))
goto Fail;
return TRISTATE_FAIL;
rgba[3] = 255;
if (len == 10 && !_hextoint(name + 8, &rgba[3])) {
goto Fail;
return TRISTATE_FAIL;
}
goto Success;
return TRISTATE_SUCCESS;
}
goto Fail;

Success:
rcode = TRISTATE_SUCCESS;
Fail:
Py_XDECREF(ascii);
return rcode;
return TRISTATE_FAIL;
}

static int
Expand Down Expand Up @@ -601,6 +587,17 @@ _parse_color_from_text(PyObject *str_obj, Uint8 *rgba)
color = PyDict_GetItem(_COLORDICT,
str_obj); // optimize for correct color names
if (!color) {
switch (_hexcolor(str_obj, rgba)) {
case TRISTATE_FAIL:
/* Do re-handling of colordict path below */
break;
case TRISTATE_ERROR:
/* Some python error raised, so forward it */
return -1;
default:
/* rgba is set, we are done here */
return 0;
}
name1 = PyObject_CallMethod(str_obj, "replace", "(ss)", " ", "");
if (!name1) {
return -1;
Expand All @@ -613,15 +610,8 @@ _parse_color_from_text(PyObject *str_obj, Uint8 *rgba)
color = PyDict_GetItem(_COLORDICT, name2);
Py_DECREF(name2);
if (!color) {
switch (_hexcolor(str_obj, rgba)) {
case TRISTATE_FAIL:
PyErr_SetString(PyExc_ValueError, "invalid color name");
return -1;
case TRISTATE_ERROR:
return -1;
default:
return 0;
}
PyErr_SetString(PyExc_ValueError, "invalid color name");
return -1;
}
}

Expand Down
Loading