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/tiledscaledbitmap.cpp",
|
||||||
"$_gm/tileimagefilter.cpp",
|
"$_gm/tileimagefilter.cpp",
|
||||||
"$_gm/tilemodes.cpp",
|
"$_gm/tilemodes.cpp",
|
||||||
|
"$_gm/tilemodes_alpha.cpp",
|
||||||
"$_gm/tilemodes_scaled.cpp",
|
"$_gm/tilemodes_scaled.cpp",
|
||||||
"$_gm/tinybitmap.cpp",
|
"$_gm/tinybitmap.cpp",
|
||||||
"$_gm/transparency.cpp",
|
"$_gm/transparency.cpp",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "src/pdf/SkPDFShader.h"
|
#include "src/pdf/SkPDFShader.h"
|
||||||
|
|
||||||
#include "include/core/SkData.h"
|
#include "include/core/SkData.h"
|
||||||
|
#include "include/core/SkMath.h"
|
||||||
#include "include/core/SkScalar.h"
|
#include "include/core/SkScalar.h"
|
||||||
#include "include/core/SkStream.h"
|
#include "include/core/SkStream.h"
|
||||||
#include "include/core/SkSurface.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);
|
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,
|
static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
||||||
const SkPDFImageShaderKey& key,
|
const SkPDFImageShaderKey& key,
|
||||||
SkImage* image) {
|
SkImage* image) {
|
||||||
@ -81,16 +89,17 @@ static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
|||||||
// Undo the translation in the final matrix
|
// Undo the translation in the final matrix
|
||||||
finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());
|
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
|
// 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
|
// stretched sides), canvas will clip this out and the extraneous data
|
||||||
// won't be saved to the PDF.
|
// won't be saved to the PDF.
|
||||||
canvas.drawImage(image, 0, 0);
|
canvas.drawImage(image, 0, 0, &paint);
|
||||||
|
|
||||||
SkScalar width = SkIntToScalar(image->width());
|
SkScalar width = SkIntToScalar(image->width());
|
||||||
SkScalar height = SkIntToScalar(image->height());
|
SkScalar height = SkIntToScalar(image->height());
|
||||||
|
|
||||||
SkPaint paint;
|
|
||||||
paint.setColor(key.fPaintColor);
|
|
||||||
// Tiling is implied. First we handle mirroring.
|
// Tiling is implied. First we handle mirroring.
|
||||||
if (tileModes[0] == SkTileMode::kMirror) {
|
if (tileModes[0] == SkTileMode::kMirror) {
|
||||||
SkMatrix xMirror;
|
SkMatrix xMirror;
|
||||||
@ -130,34 +139,35 @@ static SkPDFIndirectReference make_image_shader(SkPDFDocument* doc,
|
|||||||
// (Which are just a rectangles of the corner colors.)
|
// (Which are just a rectangles of the corner colors.)
|
||||||
if (tileModes[0] == SkTileMode::kClamp && tileModes[1] == SkTileMode::kClamp) {
|
if (tileModes[0] == SkTileMode::kClamp && tileModes[1] == SkTileMode::kClamp) {
|
||||||
SkASSERT(!bitmap.drawsNothing());
|
SkASSERT(!bitmap.drawsNothing());
|
||||||
SkPaint paint;
|
U8CPU alpha = SkColorGetA(key.fPaintColor);
|
||||||
|
SkPaint paint2;
|
||||||
SkRect rect;
|
SkRect rect;
|
||||||
rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0);
|
rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0);
|
||||||
if (!rect.isEmpty()) {
|
if (!rect.isEmpty()) {
|
||||||
paint.setColor(bitmap.getColor(0, 0));
|
paint2.setColor(mix(bitmap.getColor(0, 0), alpha));
|
||||||
canvas.drawRect(rect, paint);
|
canvas.drawRect(rect, paint2);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect = SkRect::MakeLTRB(width, deviceBounds.top(),
|
rect = SkRect::MakeLTRB(width, deviceBounds.top(),
|
||||||
deviceBounds.right(), 0);
|
deviceBounds.right(), 0);
|
||||||
if (!rect.isEmpty()) {
|
if (!rect.isEmpty()) {
|
||||||
paint.setColor(bitmap.getColor(bitmap.width() - 1, 0));
|
paint2.setColor(mix(bitmap.getColor(bitmap.width() - 1, 0), alpha));
|
||||||
canvas.drawRect(rect, paint);
|
canvas.drawRect(rect, paint2);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect = SkRect::MakeLTRB(width, height,
|
rect = SkRect::MakeLTRB(width, height,
|
||||||
deviceBounds.right(), deviceBounds.bottom());
|
deviceBounds.right(), deviceBounds.bottom());
|
||||||
if (!rect.isEmpty()) {
|
if (!rect.isEmpty()) {
|
||||||
paint.setColor(bitmap.getColor(bitmap.width() - 1,
|
paint2.setColor(mix(bitmap.getColor(bitmap.width() - 1,
|
||||||
bitmap.height() - 1));
|
bitmap.height() - 1), alpha));
|
||||||
canvas.drawRect(rect, paint);
|
canvas.drawRect(rect, paint2);
|
||||||
}
|
}
|
||||||
|
|
||||||
rect = SkRect::MakeLTRB(deviceBounds.left(), height,
|
rect = SkRect::MakeLTRB(deviceBounds.left(), height,
|
||||||
0, deviceBounds.bottom());
|
0, deviceBounds.bottom());
|
||||||
if (!rect.isEmpty()) {
|
if (!rect.isEmpty()) {
|
||||||
paint.setColor(bitmap.getColor(0, bitmap.height() - 1));
|
paint2.setColor(mix(bitmap.getColor(0, bitmap.height() - 1), alpha));
|
||||||
canvas.drawRect(rect, paint);
|
canvas.drawRect(rect, paint2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user