Changed: Add text-shadow and text-stroke style properties

--HG--
branch : develop
This commit is contained in:
Nimetu 2018-08-10 14:09:34 +03:00
parent 1525b03a83
commit 33f6b64bb9
9 changed files with 276 additions and 60 deletions

View file

@ -88,7 +88,7 @@ public:
void setShadeOutline (bool b) { _ShadeOutline = b; }
void setShadeExtent (float shext) { _ShadeExtent = shext; }
void setShadeExtent (float x, float y) { _ShadeExtentX = x; _ShadeExtentY = y; }
/// The alpha of the shade is multiplied at each draw with the alpha of the color. Default: (0,0,0,255)
void setShadeColor (NLMISC::CRGBA color) { _ShadeColor = color; }
@ -157,19 +157,20 @@ public:
rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8);
if (_ShadeOutline)
{
float rext = _ShadeExtent * 0.7071f;
rCS.render2D(*_Driver, x+rext, z-rext, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-rext, z-rext, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-rext, z+rext, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x+rext, z+rext, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x+_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-_ShadeExtent, z, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ);
float rextX = _ShadeExtentX * 0.7071f;
float rextY = _ShadeExtentY * 0.7071f;
rCS.render2D(*_Driver, x+rextX, z-rextY, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-rextX, z-rextY, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-rextX, z+rextY, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x+rextX, z+rextY, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x+_ShadeExtentX, z, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x-_ShadeExtentX, z, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x, z-_ShadeExtentY, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x, z-_ShadeExtentY, _HotSpot, _ScaleX, _ScaleZ);
}
else
{
rCS.render2D(*_Driver, x+_ShadeExtent, z-_ShadeExtent, _HotSpot, _ScaleX, _ScaleZ);
rCS.render2D(*_Driver, x+_ShadeExtentX, z-_ShadeExtentY, _HotSpot, _ScaleX, _ScaleZ);
}
rCS.Color= bkup;
}
@ -190,19 +191,20 @@ public:
rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8);
if (_ShadeOutline)
{
float rext = _ShadeExtent * 0.7071f;
rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z-rext, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z-rext, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-rext, z+rext, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x+rext, z+rext, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtent, z, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x, z+_ShadeExtent, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x, z-_ShadeExtent, xmin, ymin, xmax, ymax);
float rextX = _ShadeExtentX * 0.7071f;
float rextY = _ShadeExtentY * 0.7071f;
rCS.render2DClip(*_Driver, rdrBuffer, x+rextX, z-rextY, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-rextX, z-rextY, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-rextX, z+rextY, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x+rextX, z+rextY, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtentX, z, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x-_ShadeExtentX, z, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x, z+_ShadeExtentY, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x, z-_ShadeExtentY, xmin, ymin, xmax, ymax);
}
else
{
rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtent, z-_ShadeExtent, xmin, ymin, xmax, ymax);
rCS.render2DClip(*_Driver, rdrBuffer, x+_ShadeExtentX, z-_ShadeExtentY, xmin, ymin, xmax, ymax);
}
rCS.Color= bkup;
}
@ -223,19 +225,20 @@ public:
rCS.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8);
if (_ShadeOutline)
{
float rext = _ShadeExtent * 0.7071f;
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y-rext, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y-rext, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rext, y+rext, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rext, y+rext, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtent, y, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y+_ShadeExtent, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax);
float rextX = _ShadeExtentX * 0.7071f;
float rextY = _ShadeExtentY * 0.7071f;
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rextX, y-rextY, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rextX, y-rextY, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-rextX, y+rextY, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+rextX, y+rextY, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtentX, y, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x-_ShadeExtentX, y, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y+_ShadeExtentY, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x, y-_ShadeExtentY, depth, xmin, ymin, xmax, ymax);
}
else
{
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtent, y-_ShadeExtent, depth, xmin, ymin, xmax, ymax);
rCS.render2DUnProjected (*_Driver, renderBuffer, frustum, scaleMatrix, x+_ShadeExtentX, y-_ShadeExtentY, depth, xmin, ymin, xmax, ymax);
}
rCS.Color= bkup;
}
@ -258,19 +261,20 @@ public:
_TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8);
if (_ShadeOutline)
{
float rext = _ShadeExtent * 0.7071f;
_TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
float rextX = _ShadeExtentX * 0.7071f;
float rextY = _ShadeExtentY * 0.7071f;
_TempString.render2D(*_Driver,x+rextX,z-rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rextX,z-rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rextX,z+rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+rextX,z+rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+_ShadeExtentX,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-_ShadeExtentX,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z+_ShadeExtentY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z-_ShadeExtentY,_HotSpot,_ScaleX,_ScaleZ);
}
else
{
_TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver, x+_ShadeExtentX, z-_ShadeExtentY, _HotSpot, _ScaleX, _ScaleZ);
}
_TempString.Color = bkup;
}
@ -297,19 +301,20 @@ public:
_TempString.Color.A = (uint8)((uint(bkup.A) * uint(_ShadeColor.A)+1)>>8);
if (_ShadeOutline)
{
float rext = _ShadeExtent * 0.7071f;
_TempString.render2D(*_Driver,x+rext,z-rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rext,z-rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rext,z+rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+rext,z+rext,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-_ShadeExtent,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z+_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
float rextX = _ShadeExtentX * 0.7071f;
float rextY = _ShadeExtentY * 0.7071f;
_TempString.render2D(*_Driver,x+rextX,z-rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rextX,z-rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-rextX,z+rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+rextX,z+rextY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x+_ShadeExtentX,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x-_ShadeExtentX,z,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z+_ShadeExtentY,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver,x,z-_ShadeExtentY,_HotSpot,_ScaleX,_ScaleZ);
}
else
{
_TempString.render2D(*_Driver,x+_ShadeExtent,z-_ShadeExtent,_HotSpot,_ScaleX,_ScaleZ);
_TempString.render2D(*_Driver, x+_ShadeExtentX, z-_ShadeExtentY, _HotSpot, _ScaleX, _ScaleZ);
}
_TempString.Color = bkup;
}
@ -412,7 +417,8 @@ private:
bool _ShadeOutline;
/// shade's extent (shadow size)
float _ShadeExtent;
float _ShadeExtentX;
float _ShadeExtentY;
/// Shade color (default is black)
NLMISC::CRGBA _ShadeColor;

View file

@ -80,7 +80,7 @@ public:
bool getShaded() const;
void setShadeOutline(bool b);
bool getShadeOutline() const;
void setShadeExtent(float shext) ;
void setShadeExtent(float x, float y);
void setShadeColor (NLMISC::CRGBA sc);
NLMISC::CRGBA getShadeColor () const;
void setKeep800x600Ratio(bool keep);

View file

@ -205,7 +205,7 @@ public:
* set the shadow's size
* \param the shade extent
*/
virtual void setShadeExtent (float shext) = 0;
virtual void setShadeExtent (float x, float y) = 0;
/**
* set the shadow's color
* The alpha of the shade is multiplied at each draw with the alpha of the color. Default: (0,0,0,255)

View file

@ -75,11 +75,26 @@ namespace NLGUI
};
static SWebOptions options;
// text-shadow
struct STextShadow
{
public:
STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
: Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
{ }
bool Enabled;
bool Outline;
sint32 X;
sint32 Y;
NLMISC::CRGBA Color;
};
class CStyleParams
{
public:
CStyleParams () : FontFamily(""), TextColor(255,255,255,255)
CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
{
FontSize=10;
FontWeight=400;
@ -97,6 +112,7 @@ namespace NLGUI
bool FontOblique;
std::string FontFamily;
NLMISC::CRGBA TextColor;
STextShadow TextShadow;
bool GlobalColor;
bool Underlined;
bool StrikeThrough;
@ -595,6 +611,14 @@ namespace NLGUI
return _TR.back();
}
std::vector<STextShadow> _TextShadow;
inline STextShadow getTextShadow() const
{
if (_TextShadow.empty())
return STextShadow();
return _TextShadow.back();
}
// Forms
class CForm
{

View file

@ -88,6 +88,7 @@ namespace NLGUI
void setShadow (bool bShadow);
void setShadowOutline (bool bShadowOutline);
void setShadowColor (const NLMISC::CRGBA &color);
void setShadowOffset (sint x, sint y);
void setLineMaxW (sint nMaxW, bool invalidate=true);
void setMultiLine (bool bMultiLine);
void setMultiLineSpace (sint nMultiLineSpace);
@ -112,6 +113,7 @@ namespace NLGUI
bool getShadow() { return _Shadow; }
bool getShadowOutline() { return _ShadowOutline; }
NLMISC::CRGBA getShadowColor() { return _ShadowColor; }
void getShadowOffset(sint &x, sint &y) { x = _ShadowX; y = _ShadowY; }
sint getLineMaxW() const { return _LineMaxW; }
bool getMultiLine() const { return _MultiLine; }
sint getMultiLineSpace() const { return _MultiLineSpace; }
@ -247,6 +249,8 @@ namespace NLGUI
/// the shadow mode
bool _Shadow;
bool _ShadowOutline;
sint32 _ShadowX;
sint32 _ShadowY;
/// the case mode
TCaseMode _CaseMode;
/// the text shadow color

View file

@ -47,7 +47,8 @@ CTextContext::CTextContext()
_Shaded = false;
_ShadeOutline = false;
_ShadeExtent = 0.001f;
_ShadeExtentX = 0.001f;
_ShadeExtentY = 0.001f;
_ShadeColor = NLMISC::CRGBA(0,0,0);
_Keep800x600Ratio= true;

View file

@ -187,11 +187,11 @@ bool CTextContextUser::getShadeOutline() const
return _TextContext.getShadeOutline();
}
void CTextContextUser::setShadeExtent(float shext)
void CTextContextUser::setShadeExtent(float x, float y)
{
H_AUTO2;
_TextContext.setShadeExtent(shext);
_TextContext.setShadeExtent(x, y);
}
void CTextContextUser::setShadeColor (NLMISC::CRGBA sc)
{

View file

@ -1057,6 +1057,29 @@ namespace NLGUI
_CellParams.push_back (cellParams); \
}
static bool scanCssLength(const std::string& str, uint32 &px)
{
if (fromString(str, px))
return true;
if (str == "thin")
{
px = 1;
return true;
}
if (str == "medium")
{
px = 3;
return true;
}
if (str == "thick")
{
px = 5;
return true;
}
return false;
}
static bool isHexa(char c)
{
@ -2378,6 +2401,7 @@ namespace NLGUI
_Style.FontWeight = FONT_WEIGHT_NORMAL;
_Style.FontOblique = false;
_Style.FontSize = TextFontSize;
_Style.TextShadow = STextShadow(true);
if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
getStyleParams(value[MY_HTML_TEXTAREA_STYLE], _Style);
@ -4351,8 +4375,17 @@ namespace NLGUI
if (_CurrentViewLink)
{
bool skipLine = !_CurrentViewLink->getText().empty() && *(_CurrentViewLink->getText().rbegin()) == (ucchar) '\n';
bool sameShadow = _Style.TextShadow.Enabled && _CurrentViewLink->getShadow();
if (sameShadow && _Style.TextShadow.Enabled)
{
sint sx, sy;
_CurrentViewLink->getShadowOffset(sx, sy);
sameShadow = (_Style.TextShadow.Color == _CurrentViewLink->getShadowColor());
sameShadow = sameShadow && (_Style.TextShadow.Outline == _CurrentViewLink->getShadowOutline());
sameShadow = sameShadow && (_Style.TextShadow.X == sx) && (_Style.TextShadow.Y == sy);
}
// Compatible with current parameters ?
if (!skipLine &&
if (!skipLine && sameShadow &&
(_Style.TextColor == _CurrentViewLink->getColor()) &&
(_Style.FontFamily == _CurrentViewLink->getFontName()) &&
(_Style.FontSize == (uint)_CurrentViewLink->getFontSize()) &&
@ -4431,6 +4464,13 @@ namespace NLGUI
newLink->setMultiLineSpace((uint)((float)(_Style.FontSize)*LineSpaceFontFactor));
newLink->setMultiLine(true);
newLink->setModulateGlobalColor(_Style.GlobalColor);
if (_Style.TextShadow.Enabled)
{
newLink->setShadow(true);
newLink->setShadowColor(_Style.TextShadow.Color);
newLink->setShadowOutline(_Style.TextShadow.Outline);
newLink->setShadowOffset(_Style.TextShadow.X, _Style.TextShadow.Y);
}
// newLink->setLineAtBottom (true);
registerAnchor(newLink);
@ -4553,6 +4593,14 @@ namespace NLGUI
templateParams.push_back (std::pair<std::string,std::string> ("enter_recover_focus", "false"));
if (maxlength > 0)
templateParams.push_back (std::pair<std::string,std::string> ("max_num_chars", toString(maxlength)));
templateParams.push_back (std::pair<std::string,std::string> ("shadow", toString(_Style.TextShadow.Enabled)));
if (_Style.TextShadow.Enabled)
{
templateParams.push_back (std::pair<std::string,std::string> ("shadow_x", toString(_Style.TextShadow.X)));
templateParams.push_back (std::pair<std::string,std::string> ("shadow_y", toString(_Style.TextShadow.Y)));
templateParams.push_back (std::pair<std::string,std::string> ("shadow_color", _Style.TextShadow.Color.toString()));
templateParams.push_back (std::pair<std::string,std::string> ("shadow_outline", toString(_Style.TextShadow.Outline)));
}
CInterfaceGroup *textArea = CWidgetManager::getInstance()->getParser()->createGroupInstance (templateName.c_str(),
getParagraph()->getId(), templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size());
@ -6229,6 +6277,115 @@ namespace NLGUI
style.StrikeThrough = (prop.find("line-through") != std::string::npos);
}
else
if (it->first == "text-stroke" || it->first == "-webkit-text-stroke")
{
// text-stroke: length || color
bool success = false;
uint px = 0;
CRGBA color;
std::vector<std::string> parts;
NLMISC::splitString(it->second, " ", parts);
if (parts.size() == 1)
{
success = scanCssLength(parts[0], px);
if (!success)
success = scanHTMLColor(parts[0].c_str(), color);
}
else if (parts.size() == 2)
{
success = scanCssLength(parts[0], px);
if (success)
success = scanHTMLColor(parts[1].c_str(), color);
else
{
success = scanHTMLColor(parts[0].c_str(), color);
success = success && scanCssLength(parts[1], px);
}
}
// do not disable shadow if one is already set
if (success)
{
style.TextShadow.Enabled = (px > 0);
style.TextShadow.Color = color;
style.TextShadow.X = px;
style.TextShadow.Y = px;
style.TextShadow.Outline = true;
}
}
else
if (it->first == "text-shadow")
{
if (it->second == "none")
style.TextShadow = STextShadow(false);
else
if (it->second == "inherit")
style.TextShadow = current.TextShadow;
else
{
// text-shadow: offset-x offset-y | blur | #color
// text-shadow: #color | offset-x offset-y
bool success = true;
std::string prop(it->second);
size_t pos;
pos = prop.find_first_of(",\n\r");
if (pos != std::string::npos)
prop = prop.substr(0, pos);
std::vector<std::string> parts;
NLMISC::splitString(prop, " ", parts);
switch(parts.size())
{
case 1:
{
success = scanHTMLColor(it->second.c_str(), style.TextShadow.Color);
break;
}
// no case 2:
case 3:
{
if (!fromString(parts[0], style.TextShadow.X))
{
success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
success = success && fromString(parts[1], style.TextShadow.X);
success = success && fromString(parts[2], style.TextShadow.Y);
}
else
{
success = fromString(parts[1], style.TextShadow.Y);
success = success && scanHTMLColor(parts[2].c_str(), style.TextShadow.Color);
}
break;
}
case 4:
{
if (!fromString(parts[0], style.TextShadow.X))
{
success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
success = success && fromString(parts[1], style.TextShadow.X);
success = success && fromString(parts[2], style.TextShadow.Y);
// ignore blur [3]
}
else
{
success = fromString(parts[0], style.TextShadow.X);
success = success && fromString(parts[1], style.TextShadow.Y);
// ignore blur [2]
success = success && scanHTMLColor(parts[3].c_str(), style.TextShadow.Color);
}
break;
}
default:
{
// unsupported rule
break;
}
}
style.TextShadow.Enabled = success;
}
}
else
if (it->first == "width")
getPercentage(style.Width, tmpf, it->second.c_str());
else

View file

@ -72,6 +72,8 @@ namespace NLGUI
_Shadow = false;
_ShadowOutline = false;
_ShadowColor = CRGBA(0,0,0,255);
_ShadowX = 1;
_ShadowY = 1;
_MultiLine = false;
_TextMode = DontClipWord;
@ -955,6 +957,19 @@ namespace NLGUI
((_YReal) > (ClipY+ClipH)) || ((_YReal+_HReal) < ClipY))
return;
// hack: allow shadow to overflow outside parent box.
// In CGroupHTML context, clip is set for row
if (std::abs(_ShadowX) > 0)
{
ClipX -= 3;
ClipW += 3;
}
if (std::abs(_ShadowY) > 0)
{
ClipY -= 3;
ClipH += 3;
}
// *** Screen Minimized?
uint32 w, h;
float oow, ooh;
@ -992,6 +1007,7 @@ namespace NLGUI
TextContext->setShaded (_Shadow);
TextContext->setShadeOutline (_ShadowOutline);
TextContext->setShadeColor (shcol);
TextContext->setShadeExtent (_ShadowX*oow, _ShadowY*ooh);
TextContext->setFontSize (_FontSize);
TextContext->setEmbolden (_Embolden);
TextContext->setOblique (_Oblique);
@ -1119,6 +1135,7 @@ namespace NLGUI
TextContext->setShaded (_Shadow);
TextContext->setShadeOutline (_ShadowOutline);
TextContext->setShadeColor (shcol);
TextContext->setShadeExtent (_ShadowX*oow, _ShadowY*ooh);
TextContext->setFontSize (_FontSize);
TextContext->setEmbolden (_Embolden);
TextContext->setOblique (_Oblique);
@ -1339,6 +1356,13 @@ namespace NLGUI
_ShadowColor = color;
}
// ***************************************************************************
void CViewText::setShadowOffset(sint32 x, sint32 y)
{
_ShadowX = x;
_ShadowY = y;
}
// ***************************************************************************
void CViewText::setLineMaxW (sint nMaxW, bool invalidate)
{