SkPDF: fix repeat tilemode with alpha
Also fix the corners of clamp mode with alpha. Also, add a GM. Bug:chromium:957275 Change-Id: Icd288ff522e7ea70662380791f5ee2de628a5ef2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/211594 Auto-Submit: Hal Canary <halcanary@google.com> Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
347034865b
commit
b82ac3660c
27
gm/tilemodes_alpha.cpp
Normal file
27
gm/tilemodes_alpha.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2019 Google LLC.
|
||||
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
#include "gm/gm.h"
|
||||
#include "tools/Resources.h"
|
||||
// http://crbug.com/957275
|
||||
DEF_SIMPLE_GM(tilemodes_alpha, canvas, 512, 512) {
|
||||
sk_sp<SkImage> image = GetResourceAsImage("images/mandrill_64.png");
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
constexpr SkTileMode kModes[4] = {
|
||||
SkTileMode::kClamp,
|
||||
SkTileMode::kRepeat,
|
||||
SkTileMode::kMirror,
|
||||
SkTileMode::kDecal,
|
||||
};
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
SkRect rect = SkRect::MakeXYWH(128 * x + 1, 128 * y + 1, 126, 126);
|
||||
SkMatrix matrix = SkMatrix::MakeTrans(rect.x(), rect.y());
|
||||
SkPaint paint;
|
||||
paint.setAlphaf(0.5f);
|
||||
paint.setShader(image->makeShader(kModes[x], kModes[y], &matrix));
|
||||
canvas->drawRect(rect, paint);
|
||||
}
|
||||
}
|
||||
}
|
@ -351,6 +351,7 @@ gm_sources = [
|
||||
"$_gm/tiledscaledbitmap.cpp",
|
||||
"$_gm/tileimagefilter.cpp",
|
||||
"$_gm/tilemodes.cpp",
|
||||
"$_gm/tilemodes_alpha.cpp",
|
||||
"$_gm/tilemodes_scaled.cpp",
|
||||
"$_gm/tinybitmap.cpp",
|
||||
"$_gm/transparency.cpp",
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/pdf/SkPDFShader.h"
|
||||
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkMath.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkStream.h"
|
||||
#include "include/core/SkSurface.h"
|
||||
@ -37,6 +38,13 @@ static void draw_bitmap_matrix(SkCanvas* canvas, const SkBitmap& bm,
|
||||
canvas->drawBitmap(bm, 0, 0, &paint);
|
||||
}
|
||||
|
||||
SkColor mix(SkColor c, U8CPU alpha) {
|
||||
return SkColorSetARGB(SkMulDiv255Round(alpha, SkColorGetA(c)),
|
||||
SkColorGetR(c),
|
||||
SkColorGetG(c),
|
||||
SkColorGetB(c));
|
||||
}
|
||||
|
||||
static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
||||
const SkPDFImageShaderKey& key,
|
||||
SkImage* image) {
|
||||
@ -81,16 +89,17 @@ static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
||||
// Undo the translation in the final matrix
|
||||
finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(key.fPaintColor);
|
||||
|
||||
// If the bitmap is out of bounds (i.e. clamp mode where we only see the
|
||||
// stretched sides), canvas will clip this out and the extraneous data
|
||||
// won't be saved to the PDF.
|
||||
canvas.drawImage(image, 0, 0);
|
||||
canvas.drawImage(image, 0, 0, &paint);
|
||||
|
||||
SkScalar width = SkIntToScalar(image->width());
|
||||
SkScalar height = SkIntToScalar(image->height());
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(key.fPaintColor);
|
||||
// Tiling is implied. First we handle mirroring.
|
||||
if (tileModes[0] == SkTileMode::kMirror) {
|
||||
SkMatrix xMirror;
|
||||
@ -130,34 +139,35 @@ static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
||||
// (Which are just a rectangles of the corner colors.)
|
||||
if (tileModes[0] == SkTileMode::kClamp && tileModes[1] == SkTileMode::kClamp) {
|
||||
SkASSERT(!bitmap.drawsNothing());
|
||||
SkPaint paint;
|
||||
U8CPU alpha = SkColorGetA(key.fPaintColor);
|
||||
SkPaint paint2;
|
||||
SkRect rect;
|
||||
rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0);
|
||||
if (!rect.isEmpty()) {
|
||||
paint.setColor(bitmap.getColor(0, 0));
|
||||
canvas.drawRect(rect, paint);
|
||||
paint2.setColor(mix(bitmap.getColor(0, 0), alpha));
|
||||
canvas.drawRect(rect, paint2);
|
||||
}
|
||||
|
||||
rect = SkRect::MakeLTRB(width, deviceBounds.top(),
|
||||
deviceBounds.right(), 0);
|
||||
if (!rect.isEmpty()) {
|
||||
paint.setColor(bitmap.getColor(bitmap.width() - 1, 0));
|
||||
canvas.drawRect(rect, paint);
|
||||
paint2.setColor(mix(bitmap.getColor(bitmap.width() - 1, 0), alpha));
|
||||
canvas.drawRect(rect, paint2);
|
||||
}
|
||||
|
||||
rect = SkRect::MakeLTRB(width, height,
|
||||
deviceBounds.right(), deviceBounds.bottom());
|
||||
if (!rect.isEmpty()) {
|
||||
paint.setColor(bitmap.getColor(bitmap.width() - 1,
|
||||
bitmap.height() - 1));
|
||||
canvas.drawRect(rect, paint);
|
||||
paint2.setColor(mix(bitmap.getColor(bitmap.width() - 1,
|
||||
bitmap.height() - 1), alpha));
|
||||
canvas.drawRect(rect, paint2);
|
||||
}
|
||||
|
||||
rect = SkRect::MakeLTRB(deviceBounds.left(), height,
|
||||
0, deviceBounds.bottom());
|
||||
if (!rect.isEmpty()) {
|
||||
paint.setColor(bitmap.getColor(0, bitmap.height() - 1));
|
||||
canvas.drawRect(rect, paint);
|
||||
paint2.setColor(mix(bitmap.getColor(0, bitmap.height() - 1), alpha));
|
||||
canvas.drawRect(rect, paint2);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user