GUI: Fix hard shadow under HiDPI rendering (#4908)
This commit is contained in:
parent
1bab29825a
commit
c577b1d616
5 changed files with 40 additions and 12 deletions
|
@ -52,6 +52,7 @@ void VectorRenderer::drawStep(const Common::Rect &area, const Common::Rect &clip
|
||||||
setStrokeWidth(step.stroke);
|
setStrokeWidth(step.stroke);
|
||||||
setFillMode((FillMode)step.fillMode);
|
setFillMode((FillMode)step.fillMode);
|
||||||
setClippingRect(applyStepClippingRect(area, clip, step));
|
setClippingRect(applyStepClippingRect(area, clip, step));
|
||||||
|
setShadowIntensity(step.shadowIntensity);
|
||||||
|
|
||||||
_dynamicData = extra;
|
_dynamicData = extra;
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,8 @@ struct DrawStep {
|
||||||
|
|
||||||
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
|
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
|
||||||
|
|
||||||
|
uint32 shadowIntensity; /**< interval for drawing shadows in FIXED POINT with 16 bits mantissa */
|
||||||
|
|
||||||
GUI::ThemeEngine::AutoScaleMode autoscale; /**< scale alphaimage if present */
|
GUI::ThemeEngine::AutoScaleMode autoscale; /**< scale alphaimage if present */
|
||||||
|
|
||||||
DrawStep() {
|
DrawStep() {
|
||||||
|
@ -107,6 +109,7 @@ struct DrawStep {
|
||||||
shadowFillMode = 0;
|
shadowFillMode = 0;
|
||||||
extraData = 0;
|
extraData = 0;
|
||||||
scale = 0;
|
scale = 0;
|
||||||
|
shadowIntensity = 1 << 16;
|
||||||
autoscale = GUI::ThemeEngine::kAutoScaleNone;
|
autoscale = GUI::ThemeEngine::kAutoScaleNone;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -375,6 +378,18 @@ public:
|
||||||
_gradientFactor = factor;
|
_gradientFactor = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pixel interval for drawing shadows
|
||||||
|
*
|
||||||
|
* @param shadowIntensity interval for drawing shadows
|
||||||
|
*/
|
||||||
|
virtual void setShadowIntensity(uint32 shadowIntensity) {
|
||||||
|
if (shadowIntensity > 0)
|
||||||
|
_shadowIntensity = shadowIntensity;
|
||||||
|
else
|
||||||
|
warning("setShadowIntensity(): zero intensity");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the clipping rectangle to be used by draw calls.
|
* Sets the clipping rectangle to be used by draw calls.
|
||||||
*
|
*
|
||||||
|
@ -544,6 +559,7 @@ protected:
|
||||||
uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */
|
uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */
|
||||||
|
|
||||||
int _gradientFactor; /**< Multiplication factor of the active gradient */
|
int _gradientFactor; /**< Multiplication factor of the active gradient */
|
||||||
|
uint32 _shadowIntensity; /**< Intensity of the shadow */
|
||||||
};
|
};
|
||||||
/** @} */
|
/** @} */
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
|
@ -1286,9 +1286,9 @@ drawRoundedSquare(int x, int y, int r, int w, int h) {
|
||||||
&& y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h
|
&& y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h
|
||||||
&& h > (Base::_shadowOffset + 1) * 2) {
|
&& h > (Base::_shadowOffset + 1) * 2) {
|
||||||
if (useOriginal) {
|
if (useOriginal) {
|
||||||
drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset);
|
drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset, Base::_shadowIntensity);
|
||||||
} else {
|
} else {
|
||||||
drawRoundedSquareShadowClip(x, y, r, w, h, Base::_shadowOffset);
|
drawRoundedSquareShadowClip(x, y, r, w, h, Base::_shadowOffset, Base::_shadowIntensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3666,7 +3666,7 @@ drawSquareShadowClip(int x, int y, int w, int h, int offset) {
|
||||||
|
|
||||||
template<typename PixelType>
|
template<typename PixelType>
|
||||||
void VectorRendererSpec<PixelType>::
|
void VectorRendererSpec<PixelType>::
|
||||||
drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
|
drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset, uint32 shadowIntensity) {
|
||||||
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
|
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
|
||||||
|
|
||||||
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
|
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
|
||||||
|
@ -3686,7 +3686,9 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
|
||||||
|
|
||||||
// Soft shadows are constructed by drawing increasingly
|
// Soft shadows are constructed by drawing increasingly
|
||||||
// darker and smaller rectangles on top of each other.
|
// darker and smaller rectangles on top of each other.
|
||||||
for (int i = offset; i >= 0; i--) {
|
uint32 targetOffset = (uint32)offset << 16;
|
||||||
|
int curOffset = 0;
|
||||||
|
for (uint32 i = shadowIntensity; i <= targetOffset; i += shadowIntensity) {
|
||||||
int f, ddF_x, ddF_y;
|
int f, ddF_x, ddF_y;
|
||||||
int x, y, px, py;
|
int x, y, px, py;
|
||||||
|
|
||||||
|
@ -3747,7 +3749,8 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make shadow smaller each iteration
|
// Make shadow smaller each iteration
|
||||||
shadowRect.grow(-1);
|
shadowRect.grow(curOffset - (i >> 16));
|
||||||
|
curOffset = i >> 16;
|
||||||
|
|
||||||
if (_shadowFillMode == kShadowExponential)
|
if (_shadowFillMode == kShadowExponential)
|
||||||
// Multiply with expfactor
|
// Multiply with expfactor
|
||||||
|
@ -3757,7 +3760,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
|
||||||
|
|
||||||
template<typename PixelType>
|
template<typename PixelType>
|
||||||
void VectorRendererSpec<PixelType>::
|
void VectorRendererSpec<PixelType>::
|
||||||
drawRoundedSquareShadowClip(int x1, int y1, int r, int w, int h, int offset) {
|
drawRoundedSquareShadowClip(int x1, int y1, int r, int w, int h, int offset, uint32 shadowIntensity) {
|
||||||
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
|
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
|
||||||
|
|
||||||
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
|
// "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
|
||||||
|
@ -3777,7 +3780,13 @@ drawRoundedSquareShadowClip(int x1, int y1, int r, int w, int h, int offset) {
|
||||||
|
|
||||||
// Soft shadows are constructed by drawing increasingly
|
// Soft shadows are constructed by drawing increasingly
|
||||||
// darker and smaller rectangles on top of each other.
|
// darker and smaller rectangles on top of each other.
|
||||||
for (int i = offset; i >= 0; i--) {
|
|
||||||
|
// HACK: shadowIntensity is tailed with 16-bits mantissa. We also represent the
|
||||||
|
// offset as a 16.16 fixed point number here as termination condition to simplify
|
||||||
|
// looping logic.
|
||||||
|
uint32 targetOffset = (uint32)offset << 16;
|
||||||
|
int curOffset = 0;
|
||||||
|
for (uint32 i = shadowIntensity; i <= targetOffset; i += shadowIntensity) {
|
||||||
int f, ddF_x, ddF_y;
|
int f, ddF_x, ddF_y;
|
||||||
int x, y, px, py;
|
int x, y, px, py;
|
||||||
|
|
||||||
|
@ -3840,7 +3849,8 @@ drawRoundedSquareShadowClip(int x1, int y1, int r, int w, int h, int offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make shadow smaller each iteration
|
// Make shadow smaller each iteration
|
||||||
shadowRect.grow(-1);
|
shadowRect.grow(curOffset - (i >> 16));
|
||||||
|
curOffset = i >> 16;
|
||||||
|
|
||||||
if (_shadowFillMode == kShadowExponential)
|
if (_shadowFillMode == kShadowExponential)
|
||||||
// Multiply with expfactor
|
// Multiply with expfactor
|
||||||
|
|
|
@ -258,8 +258,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void drawSquareShadow(int x, int y, int w, int h, int offset);
|
virtual void drawSquareShadow(int x, int y, int w, int h, int offset);
|
||||||
virtual void drawSquareShadowClip(int x, int y, int w, int h, int offset);
|
virtual void drawSquareShadowClip(int x, int y, int w, int h, int offset);
|
||||||
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset);
|
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset, uint32 shadowIntensity);
|
||||||
virtual void drawRoundedSquareShadowClip(int x, int y, int r, int w, int h, int offset);
|
virtual void drawRoundedSquareShadowClip(int x, int y, int r, int w, int h, int offset, uint32 shadowIntensity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the color gradient on a given point.
|
* Calculates the color gradient on a given point.
|
||||||
|
@ -380,8 +380,8 @@ protected:
|
||||||
|
|
||||||
virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
|
virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
|
||||||
|
|
||||||
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset) {
|
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset, uint32 shadowIntensity) {
|
||||||
Base::drawRoundedSquareShadow(x, y, r, w, h, offset);
|
Base::drawRoundedSquareShadow(x, y, r, w, h, offset, shadowIntensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void drawTabAlg(int x, int y, int w, int h, int r,
|
virtual void drawTabAlg(int x, int y, int w, int h, int r,
|
||||||
|
|
|
@ -161,6 +161,7 @@ Graphics::DrawStep *ThemeParser::defaultDrawStep() {
|
||||||
step->fillMode = Graphics::VectorRenderer::kFillDisabled;
|
step->fillMode = Graphics::VectorRenderer::kFillDisabled;
|
||||||
step->scale = (1 << 16);
|
step->scale = (1 << 16);
|
||||||
step->radius = 0xFF;
|
step->radius = 0xFF;
|
||||||
|
step->shadowIntensity = SCALEVALUE((1 << 16));
|
||||||
|
|
||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue