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); bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform, const SwSize& clip, SwBBox& bbox);
void shapeFree(SwShape* shape); void shapeFree(SwShape* shape);
void shapeDelStroke(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 shapeResetFill(SwShape* shape);
void shapeDelFill(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); bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform);
void imageFree(SwImage* image); 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 fillReset(SwFill* fill);
void fillFree(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); 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) #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) { if (!fill->ctable) {
fill->ctable = static_cast<uint32_t*>(malloc(GRADIENT_STOP_SIZE * sizeof(uint32_t))); 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; 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 r = ALPHA_MULTIPLY(pColors->r, a);
auto g = ALPHA_MULTIPLY(pColors->g, pColors->a); auto g = ALPHA_MULTIPLY(pColors->g, a);
auto b = ALPHA_MULTIPLY(pColors->b, pColors->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 inc = 1.0f / static_cast<float>(GRADIENT_STOP_SIZE);
auto pos = 1.5f * inc; auto pos = 1.5f * inc;
uint32_t i = 0; uint32_t i = 0;
@ -69,13 +70,14 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surfac
auto curr = colors + j; auto curr = colors + j;
auto next = curr + 1; auto next = curr + 1;
auto delta = 1.0f / (next->offset - curr->offset); 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 r = ALPHA_MULTIPLY(next->r, a);
auto g = ALPHA_MULTIPLY(next->g, next->a); auto g = ALPHA_MULTIPLY(next->g, a);
auto b = ALPHA_MULTIPLY(next->b, next->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) { while (pos < next->offset && i < GRADIENT_STOP_SIZE) {
auto t = (pos - curr->offset) * delta; 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; if (!fill) return false;
fill->spread = fdata->spread(); fill->spread = fdata->spread();
if (ctable) { if (ctable) {
if (!_updateColorTable(fill, fdata, surface)) return false; if (!_updateColorTable(fill, fdata, surface, opacity)) return false;
} }
if (fdata->id() == FILL_ID_LINEAR) { if (fdata->id() == FILL_ID_LINEAR) {

View file

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