1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030623: Draw Harness - support hex color codes within ViewerTest::ParseColor()

ViewerTest::ParseColor() function is improved to be able to parse the following set of input arguments:
  - "Red Green Blue [Alpha]", where Red, Green, Blue, Alpha must be integers within the range [0, 255] or reals within the range [0.0, 1.0]. Note that "0 0 1" triple is parsed as "0.0 0.0 1.0" and will be interpreted as a blue color.
  - "ColorName [Alpha]", where ColorName is one of WHITE, BLACK, RED, GREEN, BLUE, etc. (look at Quantity_NameOfColor enumeration for all possible variants). Alpha may be integer or real, as described at the previous list item.
  - #HHH, [#]HHH[H], [#]HHHHHH[HH], where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F). There are a short hexadecimal RGB, RGBA formats, and a usual RGB[A], respectively.
This commit is contained in:
tiv
2019-04-12 10:45:25 +03:00
committed by bugmaster
parent a5278fc126
commit f9b30c0db3
13 changed files with 583 additions and 66 deletions

View File

@@ -82,9 +82,169 @@ extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
#define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
#define DEFAULT_MATERIAL Graphic3d_NOM_BRASS
namespace
{
const Standard_Integer THE_MAX_INTEGER_COLOR_COMPONENT = 255;
const Standard_ShortReal THE_MAX_REAL_COLOR_COMPONENT = 1.0f;
//! Parses string and get an integer color component (only values within range 0 .. 255 are allowed)
//! @param theColorComponentString the string representing the color component
//! @param theIntegerColorComponent an integer color component that is a result of parsing
//! @return true if parsing was successful, or false otherwise
static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
Standard_Integer& theIntegerColorComponent)
{
Standard_Integer anIntegerColorComponent;
if (!Draw::ParseInteger (theColorComponentString, anIntegerColorComponent))
{
return false;
}
if ((anIntegerColorComponent < 0) || (anIntegerColorComponent > THE_MAX_INTEGER_COLOR_COMPONENT))
{
return false;
}
theIntegerColorComponent = anIntegerColorComponent;
return true;
}
//! Parses the string and gets a real color component from it (only values within range 0.0 .. 1.0 are allowed)
//! @param theColorComponentString the string representing the color component
//! @param theRealColorComponent a real color component that is a result of parsing
//! @return true if parsing was successful, or false otherwise
static bool parseNumericalColorComponent (const Standard_CString theColorComponentString,
Standard_ShortReal& theRealColorComponent)
{
Standard_Real aRealColorComponent;
if (!Draw::ParseReal (theColorComponentString, aRealColorComponent))
{
return false;
}
const Standard_ShortReal aShortRealColorComponent = static_cast<Standard_ShortReal> (aRealColorComponent);
if ((aShortRealColorComponent < 0.0f) || (aShortRealColorComponent > THE_MAX_REAL_COLOR_COMPONENT))
{
return false;
}
theRealColorComponent = aShortRealColorComponent;
return true;
}
//! Parses the string and gets a real color component from it (integer values 2 .. 255 are scaled to the 0.0 .. 1.0
//! range, values 0 and 1 are leaved as they are)
//! @param theColorComponentString the string representing the color component
//! @param theColorComponent a color component that is a result of parsing
//! @return true if parsing was successful, or false otherwise
static bool parseColorComponent (const Standard_CString theColorComponentString,
Standard_ShortReal& theColorComponent)
{
Standard_Integer anIntegerColorComponent;
if (parseNumericalColorComponent (theColorComponentString, anIntegerColorComponent))
{
if (anIntegerColorComponent == 1)
{
theColorComponent = THE_MAX_REAL_COLOR_COMPONENT;
}
else
{
theColorComponent = anIntegerColorComponent * 1.0f / THE_MAX_INTEGER_COLOR_COMPONENT;
}
return true;
}
return parseNumericalColorComponent (theColorComponentString, theColorComponent);
}
//! Parses the array of strings and gets an integer color (only values within range 0 .. 255 are allowed and at least
//! one of components must be greater than 1)
//! @tparam TheNumber the type of resulting color vector elements
//! @param theNumberOfColorComponents the number of color components
//! @param theColorComponentStrings the array of strings representing color components
//! @param theNumericalColor a 4-component vector that is a result of parsing
//! @return true if parsing was successful, or false otherwise
template <typename TheNumber>
static bool parseNumericalColor (Standard_Integer& theNumberOfColorComponents,
const char* const* const theColorComponentStrings,
NCollection_Vec4<TheNumber>& theNumericalColor)
{
for (Standard_Integer aColorComponentIndex = 0; aColorComponentIndex < theNumberOfColorComponents;
++aColorComponentIndex)
{
const char* const aColorComponentString = theColorComponentStrings[aColorComponentIndex];
TheNumber aNumericalColorComponent;
if (parseNumericalColorComponent (aColorComponentString, aNumericalColorComponent))
{
theNumericalColor[aColorComponentIndex] = aNumericalColorComponent;
}
else
{
if (aColorComponentIndex == 3)
{
theNumberOfColorComponents = 3;
}
else
{
return false;
}
}
}
return true;
}
//! Parses an array of strings and get an integer color (only values within range 0 .. 255 are allowed and at least
//! one of components must be greater than 1)
//! @param theNumberOfColorComponents the number of color components
//! @param theColorComponentStrings the array of strings representing color components
//! @param theColor a color that is a result of parsing
//! @return true if parsing was successful, or false otherwise
static bool parseIntegerColor (Standard_Integer& theNumberOfColorComponents,
const char* const* const theColorComponentStrings,
Quantity_ColorRGBA& theColor)
{
const Standard_Integer THE_COLOR_COMPONENT_NOT_PARSED = -1;
Graphic3d_Vec4i anIntegerColor (THE_COLOR_COMPONENT_NOT_PARSED);
if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, anIntegerColor))
{
return false;
}
const bool hasColorComponentGreaterThanOne = (anIntegerColor.maxComp() > 1);
if (anIntegerColor.a() == THE_COLOR_COMPONENT_NOT_PARSED)
{
anIntegerColor.a() = THE_MAX_INTEGER_COLOR_COMPONENT;
}
Graphic3d_Vec4 aRealColor (anIntegerColor);
if (hasColorComponentGreaterThanOne)
{
aRealColor /= static_cast<Standard_ShortReal> (THE_MAX_INTEGER_COLOR_COMPONENT);
}
theColor = Quantity_ColorRGBA (aRealColor);
return true;
}
//! Parses an array of strings and get a real color (only values within range 0.0 .. 1.0 are allowed)
//! @param theNumberOfColorComponents the number of color components
//! @param theColorComponentStrings the array of strings representing color components
//! @param theColor a color that is a result of parsing
//! @return true if parsing was successful, or false otherwise
static bool parseRealColor (Standard_Integer& theNumberOfColorComponents,
const char* const* const theColorComponentStrings,
Quantity_ColorRGBA& theColor)
{
Graphic3d_Vec4 aRealColor (THE_MAX_REAL_COLOR_COMPONENT);
if (!parseNumericalColor (theNumberOfColorComponents, theColorComponentStrings, aRealColor))
{
return false;
}
theColor = Quantity_ColorRGBA (aRealColor);
return true;
}
} // namespace
//=======================================================================
//function : GetColorFromName
//purpose : get the Quantity_NameOfColor from a string
// function : GetColorFromName
// purpose : get the Quantity_NameOfColor from a string
//=======================================================================
Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
@@ -94,67 +254,47 @@ Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theNam
return aColor;
}
//=======================================================================
//function : parseColor
//purpose :
// function : parseColor
// purpose :
//=======================================================================
Standard_Integer ViewerTest::parseColor (Standard_Integer theArgNb,
const char** theArgVec,
Quantity_ColorRGBA& theColor,
bool theToParseAlpha)
Standard_Integer ViewerTest::parseColor (const Standard_Integer theArgNb,
const char* const* const theArgVec,
Quantity_ColorRGBA& theColor,
const bool theToParseAlpha)
{
Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
if (theArgNb >= 1
&& Quantity_Color::ColorFromName (theArgVec[0], aColor))
if ((theArgNb >= 1) && Quantity_ColorRGBA::ColorFromHex (theArgVec[0], theColor, !theToParseAlpha))
{
theColor = Quantity_ColorRGBA (aColor);
if (theArgNb >= 2
&& theToParseAlpha)
return 1;
}
if (theArgNb >= 1 && Quantity_ColorRGBA::ColorFromName (theArgVec[0], theColor))
{
if (theArgNb >= 2 && theToParseAlpha)
{
const TCollection_AsciiString anAlphaStr (theArgVec[1]);
if (anAlphaStr.IsRealValue())
const Standard_CString anAlphaStr = theArgVec[1];
Standard_ShortReal anAlphaComponent;
if (parseColorComponent (anAlphaStr, anAlphaComponent))
{
float anAlpha = (float )anAlphaStr.RealValue();
if (anAlpha < 0.0f || anAlpha > 1.0f)
{
std::cout << "Syntax error: alpha should be within range 0..1!\n";
return 0;
}
theColor.SetAlpha (anAlphaComponent);
return 2;
}
}
return 1;
}
else if (theArgNb >= 3)
if (theArgNb >= 3)
{
Graphic3d_Vec4 anRgba (0.0f, 0.0f, 0.0f, 1.0f);
Standard_Integer aNbComps = Min (theArgNb, theToParseAlpha ? 4 : 3);
for (int aCompIter = 0; aCompIter < aNbComps; ++aCompIter)
const Standard_Integer aNumberOfColorComponentsToParse = Min (theArgNb, theToParseAlpha ? 4 : 3);
Standard_Integer aNumberOfColorComponentsParsed = aNumberOfColorComponentsToParse;
if (parseIntegerColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
{
const TCollection_AsciiString anRgbaStr (theArgVec[aCompIter]);
if (!anRgbaStr.IsRealValue())
{
if (aCompIter == 3)
{
anRgba.a() = 1.0f;
aNbComps = 3;
break;
}
return 0;
}
anRgba[aCompIter] = (float )anRgbaStr.RealValue();
if (anRgba[aCompIter] < 0.0 || anRgba[aCompIter] > 1.0)
{
std::cout << "Error: RGBA color values should be within range 0..1!\n";
return 0;
}
return aNumberOfColorComponentsParsed;
}
theColor = Quantity_ColorRGBA (anRgba);
return aNbComps;
if (parseRealColor (aNumberOfColorComponentsParsed, theArgVec, theColor))
{
return aNumberOfColorComponentsParsed;
}
return 0;
}
return 0;
}

View File

@@ -153,22 +153,22 @@ public:
//! Handles either color specified by name (single argument)
//! or by RGB(A) components (3-4 arguments) in range 0..1.
//! The result is stored in theColor on success.
//! Returns number of handled arguments (1, 3 or 4) or 0 on syntax error.
static Standard_Integer ParseColor (Standard_Integer theArgNb,
const char** theArgVec,
Quantity_ColorRGBA& theColor)
//! Returns number of handled arguments (1, 2, 3 or 4) or 0 on syntax error.
static Standard_Integer ParseColor (const Standard_Integer theArgNb,
const char* const* const theArgVec,
Quantity_ColorRGBA& theColor)
{
return parseColor (theArgNb, theArgVec, theColor, true);
}
//! Parses RGB color argument(s).
//! Returns number of handled arguments (1 or 3) or 0 on syntax error.
static Standard_Integer ParseColor (Standard_Integer theArgNb,
const char** theArgVec,
Quantity_Color& theColor)
static Standard_Integer ParseColor (const Standard_Integer theArgNb,
const char* const* const theArgVec,
Quantity_Color& theColor)
{
Quantity_ColorRGBA anRgba;
Standard_Integer aNbParsed = parseColor (theArgNb, theArgVec, anRgba, false);
const Standard_Integer aNbParsed = parseColor (theArgNb, theArgVec, anRgba, false);
if (aNbParsed != 0)
{
theColor = anRgba.GetRGB();
@@ -236,11 +236,11 @@ private:
//! Handles either color specified by name (single argument)
//! or by RGB(A) components (3-4 arguments) in range 0..1.
//! The result is stored in theColor on success.
//! Returns number of handled arguments (1, 3 or 4) or 0 on syntax error.
Standard_EXPORT static Standard_Integer parseColor (Standard_Integer theArgNb,
const char** theArgVec,
//! Returns number of handled arguments (1, 2, 3 or 4) or 0 on syntax error.
Standard_EXPORT static Standard_Integer parseColor (Standard_Integer theArgNb,
const char* const* theArgVec,
Quantity_ColorRGBA& theColor,
bool theToParseAlpha);
bool theToParseAlpha);
//! Parses ZLayer name.
//! @param theArg [in] layer name, enumeration alias or index (of existing Layer)