9dc0b9e2f8
We can't remove the loopers themselves, as they are still used by android and chrome (they just don't ever pass them to skia). Eventually each of those clients will resolve this, but for now we just keep the classes (and tests) in skia. Bug: skia:4783 Change-Id: I5f507e6bb82280f2bc7c0b21eebe59c287aa9265 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/230579 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
167 lines
5.2 KiB
C++
167 lines
5.2 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkColorPriv.h"
|
|
#include "include/core/SkStream.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/core/SkTypes.h"
|
|
#include "samplecode/DecodeFile.h"
|
|
#include "samplecode/Sample.h"
|
|
#include "src/core/SkBlurMask.h"
|
|
#include "src/core/SkOSFile.h"
|
|
#include "src/utils/SkOSPath.h"
|
|
#include "src/utils/SkUTF.h"
|
|
#include "tools/Resources.h"
|
|
#include "tools/ToolUtils.h"
|
|
|
|
/**
|
|
* Interprets c as an unpremultiplied color, and returns the
|
|
* premultiplied equivalent.
|
|
*/
|
|
static SkPMColor premultiply_unpmcolor(SkPMColor c) {
|
|
U8CPU a = SkGetPackedA32(c);
|
|
U8CPU r = SkGetPackedR32(c);
|
|
U8CPU g = SkGetPackedG32(c);
|
|
U8CPU b = SkGetPackedB32(c);
|
|
return SkPreMultiplyARGB(a, r, g, b);
|
|
}
|
|
|
|
class UnpremulView : public Sample {
|
|
public:
|
|
UnpremulView(SkString res)
|
|
: fResPath(res)
|
|
, fPremul(true)
|
|
, fDecodeSucceeded(false) {
|
|
this->nextImage();
|
|
}
|
|
|
|
protected:
|
|
SkString name() override { return SkString("unpremul"); }
|
|
|
|
bool onChar(SkUnichar uni) override {
|
|
char utf8[SkUTF::kMaxBytesInUTF8Sequence];
|
|
size_t size = SkUTF::ToUTF8(uni, utf8);
|
|
// Only consider events for single char keys
|
|
if (1 == size) {
|
|
switch (utf8[0]) {
|
|
case fNextImageChar:
|
|
this->nextImage();
|
|
return true;
|
|
case fTogglePremulChar:
|
|
this->togglePremul();
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void onDrawBackground(SkCanvas* canvas) override {
|
|
ToolUtils::draw_checkerboard(canvas, 0xFFCCCCCC, 0xFFFFFFFF, 12);
|
|
}
|
|
|
|
void onDrawContent(SkCanvas* canvas) override {
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
|
|
SkFont font;
|
|
font.setSize(24);
|
|
SkScalar height = font.getMetrics(nullptr);
|
|
if (!fDecodeSucceeded) {
|
|
SkString failure;
|
|
if (fResPath.size() == 0) {
|
|
failure.printf("resource path is required!");
|
|
} else {
|
|
failure.printf("Failed to decode %s", fCurrFile.c_str());
|
|
}
|
|
canvas->drawString(failure, 0, height, font, paint);
|
|
return;
|
|
}
|
|
|
|
// Name, size of the file, and whether or not it is premultiplied.
|
|
SkString header(SkOSPath::Basename(fCurrFile.c_str()));
|
|
header.appendf(" [%dx%d] %s", fBitmap.width(), fBitmap.height(),
|
|
(fPremul ? "premultiplied" : "unpremultiplied"));
|
|
canvas->drawString(header, 0, height, font, paint);
|
|
canvas->translate(0, height);
|
|
|
|
// Help messages
|
|
header.printf("Press '%c' to move to the next image.'", fNextImageChar);
|
|
canvas->drawString(header, 0, height, font, paint);
|
|
canvas->translate(0, height);
|
|
|
|
header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremulChar);
|
|
canvas->drawString(header, 0, height, font, paint);
|
|
|
|
// Now draw the image itself.
|
|
canvas->translate(height * 2, height * 2);
|
|
if (!fPremul) {
|
|
// A premultiplied bitmap cannot currently be drawn.
|
|
// Copy it to a bitmap which can be drawn, converting
|
|
// to premultiplied:
|
|
SkBitmap bm;
|
|
bm.allocN32Pixels(fBitmap.width(), fBitmap.height());
|
|
for (int i = 0; i < fBitmap.width(); ++i) {
|
|
for (int j = 0; j < fBitmap.height(); ++j) {
|
|
*bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j));
|
|
}
|
|
}
|
|
canvas->drawBitmap(bm, 0, 0);
|
|
} else {
|
|
canvas->drawBitmap(fBitmap, 0, 0);
|
|
}
|
|
}
|
|
|
|
private:
|
|
const SkString fResPath;
|
|
SkString fCurrFile;
|
|
bool fPremul;
|
|
bool fDecodeSucceeded;
|
|
SkBitmap fBitmap;
|
|
SkOSFile::Iter fFileIter;
|
|
|
|
static const char fNextImageChar = 'j';
|
|
static const char fTogglePremulChar = 'h';
|
|
|
|
void nextImage() {
|
|
if (fResPath.size() == 0) {
|
|
return;
|
|
}
|
|
SkString basename;
|
|
if (!fFileIter.next(&basename)) {
|
|
fFileIter.reset(fResPath.c_str());
|
|
if (!fFileIter.next(&basename)) {
|
|
// Perhaps this should draw some error message?
|
|
return;
|
|
}
|
|
}
|
|
fCurrFile = SkOSPath::Join(fResPath.c_str(), basename.c_str());
|
|
this->decodeCurrFile();
|
|
}
|
|
|
|
void decodeCurrFile() {
|
|
if (fCurrFile.size() == 0) {
|
|
fDecodeSucceeded = false;
|
|
return;
|
|
}
|
|
fDecodeSucceeded = decode_file(fCurrFile.c_str(), &fBitmap, kN32_SkColorType, !fPremul);
|
|
}
|
|
|
|
void togglePremul() {
|
|
fPremul = !fPremul;
|
|
this->decodeCurrFile();
|
|
}
|
|
|
|
typedef Sample INHERITED;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
DEF_SAMPLE( return new UnpremulView(GetResourcePath("images")); )
|