sw_engine: apply opacity to graident fill case.

previously, opacity value is ignored to gradient fill.

This patch implements that case.
This commit is contained in:
Hermet Park 2020-12-30 12:38:32 +09:00 committed by GitHub
parent f096570360
commit cfa2d187bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 21 deletions

View file

@ -284,7 +284,7 @@ void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transfor
bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform, const SwSize& clip, SwBBox& bbox);
void shapeFree(SwShape* shape);
void shapeDelStroke(SwShape* shape);
bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, bool ctable);
bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
void shapeResetFill(SwShape* shape);
void shapeDelFill(SwShape* shape);
@ -301,7 +301,7 @@ void imageReset(SwImage* image);
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform);
void imageFree(SwImage* image);
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, bool ctable);
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
void fillReset(SwFill* fill);
void fillFree(SwFill* fill);
void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len);

View file

@ -33,7 +33,7 @@
#define FIXPT_SIZE (1<<FIXPT_BITS)
static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surface)
static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surface, uint32_t opacity)
{
if (!fill->ctable) {
fill->ctable = static_cast<uint32_t*>(malloc(GRADIENT_STOP_SIZE * sizeof(uint32_t)));
@ -46,13 +46,14 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surfac
auto pColors = colors;
if (pColors->a < 255) fill->translucent = true;
auto a = (pColors->a * opacity) / 255;
if (a < 255) fill->translucent = true;
auto r = ALPHA_MULTIPLY(pColors->r, pColors->a);
auto g = ALPHA_MULTIPLY(pColors->g, pColors->a);
auto b = ALPHA_MULTIPLY(pColors->b, pColors->a);
auto r = ALPHA_MULTIPLY(pColors->r, a);
auto g = ALPHA_MULTIPLY(pColors->g, a);
auto b = ALPHA_MULTIPLY(pColors->b, a);
auto rgba = surface->blender.join(r, g, b, pColors->a);
auto rgba = surface->blender.join(r, g, b, a);
auto inc = 1.0f / static_cast<float>(GRADIENT_STOP_SIZE);
auto pos = 1.5f * inc;
uint32_t i = 0;
@ -69,13 +70,14 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surfac
auto curr = colors + j;
auto next = curr + 1;
auto delta = 1.0f / (next->offset - curr->offset);
if (next->a < 255) fill->translucent = true;
a = (next->a * opacity) / 255;
if (!fill->translucent && a < 255) fill->translucent = true;
auto r = ALPHA_MULTIPLY(next->r, next->a);
auto g = ALPHA_MULTIPLY(next->g, next->a);
auto b = ALPHA_MULTIPLY(next->b, next->a);
auto r = ALPHA_MULTIPLY(next->r, a);
auto g = ALPHA_MULTIPLY(next->g, a);
auto b = ALPHA_MULTIPLY(next->b, a);
auto rgba2 = surface->blender.join(r, g, b, next->a);
auto rgba2 = surface->blender.join(r, g, b, a);
while (pos < next->offset && i < GRADIENT_STOP_SIZE) {
auto t = (pos - curr->offset) * delta;
@ -270,14 +272,14 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x,
}
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, bool ctable)
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable)
{
if (!fill) return false;
fill->spread = fdata->spread();
if (ctable) {
if (!_updateColorTable(fill, fdata, surface)) return false;
if (!_updateColorTable(fill, fdata, surface, opacity)) return false;
}
if (fdata->id() == FILL_ID_LINEAR) {

View file

@ -109,12 +109,13 @@ struct SwShapeTask : SwTask
}
//Fill
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) {
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
auto fill = sdata->fill();
if (fill) {
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
if (ctable) shapeResetFill(&shape);
if (!shapeGenFillColors(&shape, fill, transform, surface, ctable)) goto end;
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto end;
++addStroking;
} else {
shapeDelFill(&shape);
}
@ -147,7 +148,7 @@ struct SwShapeTask : SwTask
}
end:
shapeDelOutline(&shape, tid);
if (addStroking == 2 && opacity < 255) cmpStroking = true;
if (addStroking > 1 && opacity < 255) cmpStroking = true;
else cmpStroking = false;
}
@ -319,7 +320,6 @@ bool SwRenderer::renderShape(RenderData data, TVG_UNUSED Compositor* cmp)
uint8_t r, g, b, a;
if (auto fill = task->sdata->fill()) {
//FIXME: pass opacity to apply gradient fill?
rasterGradientShape(surface, &task->shape, fill->id());
} else{
task->sdata->fillColor(&r, &g, &b, &a);

View file

@ -643,9 +643,9 @@ fail:
}
bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, bool ctable)
bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable)
{
return fillGenColorTable(shape->fill, fill, transform, surface, ctable);
return fillGenColorTable(shape->fill, fill, transform, surface, opacity, ctable);
}