Skip to content

Commit bd712ff

Browse files
authored
Merge pull request #3302 from pygame-community/ankith26-color-speedup
Optimize for str hex color values
2 parents 9dbecc5 + d0d9e0a commit bd712ff

File tree

1 file changed

+30
-40
lines changed

1 file changed

+30
-40
lines changed

src_c/color.c

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -484,67 +484,53 @@ _hextoint(char *hex, Uint8 *val)
484484
static tristate
485485
_hexcolor(PyObject *color, Uint8 rgba[])
486486
{
487-
size_t len;
488-
tristate rcode = TRISTATE_FAIL;
489-
char *name;
490-
PyObject *ascii = PyUnicode_AsASCIIString(color);
491-
if (ascii == NULL) {
492-
rcode = TRISTATE_ERROR;
493-
goto Fail;
494-
}
495-
name = PyBytes_AsString(ascii);
487+
Py_ssize_t len;
488+
char *name = (char *)PyUnicode_AsUTF8AndSize(color, &len);
496489
if (name == NULL) {
497-
goto Fail;
490+
return TRISTATE_ERROR;
498491
}
499492

500-
len = strlen(name);
501493
/* hex colors can be
502494
* #RRGGBB
503495
* #RRGGBBAA
504496
* 0xRRGGBB
505497
* 0xRRGGBBAA
506498
*/
507499
if (len < 7) {
508-
goto Fail;
500+
return TRISTATE_FAIL;
509501
}
510502

511503
if (name[0] == '#') {
512504
if (len != 7 && len != 9)
513-
goto Fail;
505+
return TRISTATE_FAIL;
514506
if (!_hextoint(name + 1, &rgba[0]))
515-
goto Fail;
507+
return TRISTATE_FAIL;
516508
if (!_hextoint(name + 3, &rgba[1]))
517-
goto Fail;
509+
return TRISTATE_FAIL;
518510
if (!_hextoint(name + 5, &rgba[2]))
519-
goto Fail;
511+
return TRISTATE_FAIL;
520512
rgba[3] = 255;
521513
if (len == 9 && !_hextoint(name + 7, &rgba[3])) {
522-
goto Fail;
514+
return TRISTATE_FAIL;
523515
}
524-
goto Success;
516+
return TRISTATE_SUCCESS;
525517
}
526518
else if (name[0] == '0' && name[1] == 'x') {
527519
if (len != 8 && len != 10)
528-
goto Fail;
520+
return TRISTATE_FAIL;
529521
if (!_hextoint(name + 2, &rgba[0]))
530-
goto Fail;
522+
return TRISTATE_FAIL;
531523
if (!_hextoint(name + 4, &rgba[1]))
532-
goto Fail;
524+
return TRISTATE_FAIL;
533525
if (!_hextoint(name + 6, &rgba[2]))
534-
goto Fail;
526+
return TRISTATE_FAIL;
535527
rgba[3] = 255;
536528
if (len == 10 && !_hextoint(name + 8, &rgba[3])) {
537-
goto Fail;
529+
return TRISTATE_FAIL;
538530
}
539-
goto Success;
531+
return TRISTATE_SUCCESS;
540532
}
541-
goto Fail;
542-
543-
Success:
544-
rcode = TRISTATE_SUCCESS;
545-
Fail:
546-
Py_XDECREF(ascii);
547-
return rcode;
533+
return TRISTATE_FAIL;
548534
}
549535

550536
static int
@@ -601,6 +587,17 @@ _parse_color_from_text(PyObject *str_obj, Uint8 *rgba)
601587
color = PyDict_GetItem(_COLORDICT,
602588
str_obj); // optimize for correct color names
603589
if (!color) {
590+
switch (_hexcolor(str_obj, rgba)) {
591+
case TRISTATE_FAIL:
592+
/* Do re-handling of colordict path below */
593+
break;
594+
case TRISTATE_ERROR:
595+
/* Some python error raised, so forward it */
596+
return -1;
597+
default:
598+
/* rgba is set, we are done here */
599+
return 0;
600+
}
604601
name1 = PyObject_CallMethod(str_obj, "replace", "(ss)", " ", "");
605602
if (!name1) {
606603
return -1;
@@ -613,15 +610,8 @@ _parse_color_from_text(PyObject *str_obj, Uint8 *rgba)
613610
color = PyDict_GetItem(_COLORDICT, name2);
614611
Py_DECREF(name2);
615612
if (!color) {
616-
switch (_hexcolor(str_obj, rgba)) {
617-
case TRISTATE_FAIL:
618-
PyErr_SetString(PyExc_ValueError, "invalid color name");
619-
return -1;
620-
case TRISTATE_ERROR:
621-
return -1;
622-
default:
623-
return 0;
624-
}
613+
PyErr_SetString(PyExc_ValueError, "invalid color name");
614+
return -1;
625615
}
626616
}
627617

0 commit comments

Comments
 (0)