@@ -535,18 +535,120 @@ bool XMLColorToInt(const char* szColor, unsigned long& ulColor)
535535
536536bool XMLColorToInt (const char * szColor, unsigned char & ucRed, unsigned char & ucGreen, unsigned char & ucBlue, unsigned char & ucAlpha)
537537{
538- // Convert it to an integer first
539- unsigned long ulColor;
540- if (!XMLColorToInt (szColor, ulColor))
541- {
538+ // If we're empty, let's just stop right away
539+ if (!szColor || strlen (szColor) == 0 )
542540 return false ;
541+
542+ std::vector<SColorRGBA> vecColors;
543+ unsigned char ucCount;
544+
545+ if (ColorStringToRGBA (szColor, SColorRGBA (ucRed, ucGreen, ucBlue, ucAlpha), vecColors, ucCount))
546+ {
547+ ucRed = vecColors[0 ].R ;
548+ ucGreen = vecColors[0 ].G ;
549+ ucBlue = vecColors[0 ].B ;
550+ ucAlpha = vecColors[0 ].A ;
551+
552+ return true ;
553+ }
554+
555+ return false ;
556+ }
557+
558+ bool ColorStringToRGBA (const char * szColor, SColorRGBA defaultColor, std::vector<SColorRGBA>& vecColors, unsigned char & ucCount, bool bIgnoreAlpha)
559+ {
560+ std::stringstream ss (szColor);
561+ SColorRGBA color = defaultColor;
562+ bool bPreviousWasHex = false ;
563+ unsigned int uiRGBAIndex = 0 ;
564+ unsigned long ulColor;
565+ unsigned char ucValue;
566+ unsigned char ucLength = bIgnoreAlpha ? 3 : 4 ;
567+
568+ while (ss.good ())
569+ {
570+ // Ambiguous value before a comma
571+ SString strValue;
572+ getline (ss, strValue, ' ,' );
573+
574+ // Remove spaces
575+ ReplaceOccurrencesInString (strValue, " " , " " );
576+
577+ // Is the value looking like a hexadecimal?
578+ if (strValue[0 ] == ' #' )
579+ {
580+ // Try converting it to an integer
581+ if (XMLColorToInt (strValue.c_str (), ulColor))
582+ {
583+ // If a previous RGBA wasn't finished, let's finish it now
584+ if (!bPreviousWasHex && uiRGBAIndex != 0 )
585+ {
586+ vecColors.push_back (color);
587+ ucCount += ucLength - uiRGBAIndex;
588+ color = defaultColor;
589+ }
590+
591+ color.R = static_cast <unsigned char >(ulColor);
592+ color.G = static_cast <unsigned char >(ulColor >> 8 );
593+ color.B = static_cast <unsigned char >(ulColor >> 16 );
594+
595+ if (!bIgnoreAlpha)
596+ color.A = static_cast <unsigned char >(ulColor >> 24 );
597+
598+ bPreviousWasHex = true ;
599+ ucCount += ucLength;
600+ }
601+ else
602+ return false ;
603+ }
604+ // It looks like we have an empty value, let's skip the value but treat it as RGB
605+ else if (strValue.empty ())
606+ {
607+ if (bPreviousWasHex || uiRGBAIndex % ucLength == 0 )
608+ {
609+ bPreviousWasHex = false ;
610+ uiRGBAIndex = 0 ;
611+ }
612+
613+ uiRGBAIndex++;
614+ ucCount++;
615+
616+ if (uiRGBAIndex % ucLength != 0 && ss.good ())
617+ continue ;
618+ }
619+ // It looks like a plain number so let's treat it as a RGBA value
620+ else if (strValue.find_first_not_of (" 0123456789" ) == std::string::npos)
621+ {
622+ ucValue = atoi (strValue.c_str ());
623+
624+ if (bPreviousWasHex || uiRGBAIndex % ucLength == 0 )
625+ {
626+ color.R = ucValue;
627+ bPreviousWasHex = false ;
628+ uiRGBAIndex = 0 ;
629+ }
630+ else if (uiRGBAIndex % ucLength == 1 )
631+ color.G = ucValue;
632+ else if (uiRGBAIndex % ucLength == 2 )
633+ color.B = ucValue;
634+ else if (uiRGBAIndex % ucLength == 3 )
635+ color.A = ucValue;
636+
637+ uiRGBAIndex++;
638+ ucCount++;
639+
640+ if (uiRGBAIndex % ucLength != 0 && ss.good ())
641+ continue ;
642+ }
643+ else
644+ return false ;
645+
646+ // We have a color, so let's push it
647+ vecColors.push_back (color);
648+ color = defaultColor;
649+ uiRGBAIndex = 0 ;
543650 }
544651
545- // Convert it to red, green, blue and alpha
546- ucRed = static_cast <unsigned char >(ulColor);
547- ucGreen = static_cast <unsigned char >(ulColor >> 8 );
548- ucBlue = static_cast <unsigned char >(ulColor >> 16 );
549- ucAlpha = static_cast <unsigned char >(ulColor >> 24 );
550652 return true ;
551653}
552654
0 commit comments