SkiaExamples improvements.
Make it possible for a client to write a Hello World in less than 50 lines. R=caryclark@google.com Review URL: https://codereview.chromium.org/18574002 git-svn-id: http://skia.googlecode.com/svn/trunk@10319 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
03d5f4b598
commit
43f2b2c833
@ -7,7 +7,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BaseExample.h"
|
||||
#include "SkExample.h"
|
||||
|
||||
#include "SkApplication.h"
|
||||
#include "SkDraw.h"
|
||||
@ -15,98 +15,96 @@
|
||||
#include "SkGraphics.h"
|
||||
#include "SkUnitMappers.h"
|
||||
|
||||
class HelloSkia : public BaseExample {
|
||||
public:
|
||||
HelloSkia(void* hWnd, int argc, char** argv)
|
||||
: INHERITED(hWnd, argc, argv)
|
||||
{
|
||||
fBGColor = SK_ColorWHITE;
|
||||
fRotationAngle = SkIntToScalar(0);
|
||||
class HelloSkia : public SkExample {
|
||||
public:
|
||||
HelloSkia(SkExampleWindow* window) : SkExample(window) {
|
||||
fName = "HelloSkia";
|
||||
fBGColor = SK_ColorWHITE;
|
||||
fRotationAngle = SkIntToScalar(0);
|
||||
|
||||
setupBackend(kGPU_DeviceType);
|
||||
// Another option is software rendering:
|
||||
// setupBackend(kRaster_DeviceType);
|
||||
}
|
||||
fWindow->setupBackend(SkExampleWindow::kGPU_DeviceType);
|
||||
// Another option is software rendering:
|
||||
// setupBackend(SkExampleWindow::kRaster_DeviceType);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void draw(SkCanvas* canvas) SK_OVERRIDE {
|
||||
// Clear background
|
||||
canvas->drawColor(fBGColor);
|
||||
protected:
|
||||
void draw(SkCanvas* canvas) {
|
||||
// Clear background
|
||||
canvas->drawColor(fBGColor);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorRED);
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorRED);
|
||||
|
||||
// Draw a rectangle with blue paint
|
||||
SkRect rect = {
|
||||
// Draw a rectangle with blue paint
|
||||
SkRect rect = {
|
||||
SkIntToScalar(10), SkIntToScalar(10),
|
||||
SkIntToScalar(128), SkIntToScalar(128)
|
||||
};
|
||||
canvas->drawRect(rect, paint);
|
||||
};
|
||||
canvas->drawRect(rect, paint);
|
||||
|
||||
// Set up a linear gradient and draw a circle
|
||||
{
|
||||
SkPoint linearPoints[] = {
|
||||
// Set up a linear gradient and draw a circle
|
||||
{
|
||||
SkPoint linearPoints[] = {
|
||||
{SkIntToScalar(0), SkIntToScalar(0)},
|
||||
{SkIntToScalar(300), SkIntToScalar(300)}
|
||||
};
|
||||
SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
|
||||
};
|
||||
SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
|
||||
|
||||
SkUnitMapper* linearMapper = new SkDiscreteMapper(100);
|
||||
SkAutoUnref lm_deleter(linearMapper);
|
||||
SkUnitMapper* linearMapper = new SkDiscreteMapper(100);
|
||||
SkAutoUnref lm_deleter(linearMapper);
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateLinear(
|
||||
linearPoints, linearColors, NULL, 2,
|
||||
SkShader::kMirror_TileMode, linearMapper);
|
||||
SkAutoUnref shader_deleter(shader);
|
||||
SkShader* shader = SkGradientShader::CreateLinear(
|
||||
linearPoints, linearColors, NULL, 2,
|
||||
SkShader::kMirror_TileMode, linearMapper);
|
||||
SkAutoUnref shader_deleter(shader);
|
||||
|
||||
paint.setShader(shader);
|
||||
paint.setFlags(SkPaint::kAntiAlias_Flag);
|
||||
paint.setShader(shader);
|
||||
paint.setFlags(SkPaint::kAntiAlias_Flag);
|
||||
|
||||
canvas->drawCircle(SkIntToScalar(200), SkIntToScalar(200),
|
||||
SkIntToScalar(64), paint);
|
||||
canvas->drawCircle(SkIntToScalar(200), SkIntToScalar(200),
|
||||
SkIntToScalar(64), paint);
|
||||
|
||||
// Detach shader
|
||||
paint.setShader(NULL);
|
||||
}
|
||||
|
||||
|
||||
// Draw a message with a nice black paint.
|
||||
paint.setFlags(
|
||||
SkPaint::kAntiAlias_Flag |
|
||||
SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating.
|
||||
SkPaint::kUnderlineText_Flag);
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
paint.setTextSize(SkIntToScalar(20));
|
||||
|
||||
canvas->save();
|
||||
|
||||
static const char message[] = "Hello Skia!!!";
|
||||
|
||||
// Translate and rotate
|
||||
canvas->translate(SkIntToScalar(300), SkIntToScalar(300));
|
||||
fRotationAngle += SkDoubleToScalar(0.2);
|
||||
if (fRotationAngle > SkDoubleToScalar(360.0)) {
|
||||
fRotationAngle -= SkDoubleToScalar(360.0);
|
||||
}
|
||||
canvas->rotate(fRotationAngle);
|
||||
|
||||
// Draw the text:
|
||||
canvas->drawText(message, strlen(message), SkIntToScalar(0), SkIntToScalar(0), paint);
|
||||
|
||||
canvas->restore();
|
||||
|
||||
// Invalidate the window to force a redraw. Poor man's animation mechanism.
|
||||
this->inval(NULL);
|
||||
|
||||
INHERITED::draw(canvas);
|
||||
// Detach shader
|
||||
paint.setShader(NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
SkScalar fRotationAngle;
|
||||
SkColor fBGColor;
|
||||
typedef BaseExample INHERITED;
|
||||
// Draw a message with a nice black paint.
|
||||
paint.setFlags(
|
||||
SkPaint::kAntiAlias_Flag |
|
||||
SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating.
|
||||
SkPaint::kUnderlineText_Flag);
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
paint.setTextSize(SkIntToScalar(20));
|
||||
|
||||
canvas->save();
|
||||
|
||||
static const char message[] = "Hello Skia!!!";
|
||||
|
||||
// Translate and rotate
|
||||
canvas->translate(SkIntToScalar(300), SkIntToScalar(300));
|
||||
fRotationAngle += SkDoubleToScalar(0.2);
|
||||
if (fRotationAngle > SkDoubleToScalar(360.0)) {
|
||||
fRotationAngle -= SkDoubleToScalar(360.0);
|
||||
}
|
||||
canvas->rotate(fRotationAngle);
|
||||
|
||||
// Draw the text:
|
||||
canvas->drawText(message, strlen(message), SkIntToScalar(0), SkIntToScalar(0), paint);
|
||||
|
||||
canvas->restore();
|
||||
|
||||
// Invalidate the window to force a redraw. Poor man's animation mechanism.
|
||||
this->fWindow->inval(NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
SkScalar fRotationAngle;
|
||||
SkColor fBGColor;
|
||||
};
|
||||
|
||||
SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
|
||||
return new HelloSkia(hwnd, argc, argv);
|
||||
static SkExample* MyFactory(SkExampleWindow* window) {
|
||||
return new HelloSkia(window);
|
||||
}
|
||||
|
||||
// Register this class as a Skia Example.
|
||||
SkExample::Registry registry(MyFactory);
|
||||
|
@ -7,15 +7,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BaseExample.h"
|
||||
#include "SkExample.h"
|
||||
|
||||
#include "gl/GrGLUtil.h"
|
||||
#include "gl/GrGLDefines.h"
|
||||
#include "gl/GrGLInterface.h"
|
||||
#include "SkApplication.h"
|
||||
#include "SkCommandLineFlags.h"
|
||||
#include "SkGpuDevice.h"
|
||||
#include "SkGraphics.h"
|
||||
|
||||
DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \
|
||||
"Multiple matches may be separated by spaces.\n" \
|
||||
"~ causes a matching test to always be skipped\n" \
|
||||
"^ requires the start of the test to match\n" \
|
||||
"$ requires the end of the test to match\n" \
|
||||
"^ and $ requires an exact match\n" \
|
||||
"If a test does not match any list entry,\n" \
|
||||
"it is skipped unless some list entry starts with ~");
|
||||
|
||||
void application_init() {
|
||||
SkGraphics::Init();
|
||||
SkEvent::Init();
|
||||
@ -26,10 +36,24 @@ void application_term() {
|
||||
SkGraphics::Term();
|
||||
}
|
||||
|
||||
BaseExample::BaseExample(void* hWnd, int argc, char** argv)
|
||||
: INHERITED(hWnd) {}
|
||||
SkExampleWindow::SkExampleWindow(void* hwnd)
|
||||
: INHERITED(hwnd) {
|
||||
fRegistry = SkExample::Registry::Head();
|
||||
fCurrExample = fRegistry->factory()(this);
|
||||
|
||||
void BaseExample::tearDownBackend() {
|
||||
if (FLAGS_match.count()) {
|
||||
for(int i = 0; i < FLAGS_match.count(); ++i) {
|
||||
fMatchStrs.push(FLAGS_match[i]);
|
||||
}
|
||||
// Start with the a matching sample if possible.
|
||||
bool found = this->findNextMatch();
|
||||
if (!found) {
|
||||
SkDebugf("No matching SkExample found.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkExampleWindow::tearDownBackend() {
|
||||
if (kGPU_DeviceType == fType) {
|
||||
SkSafeUnref(fContext);
|
||||
fContext = NULL;
|
||||
@ -44,7 +68,7 @@ void BaseExample::tearDownBackend() {
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseExample::setupBackend(DeviceType type) {
|
||||
bool SkExampleWindow::setupBackend(DeviceType type) {
|
||||
fType = type;
|
||||
|
||||
this->setConfig(SkBitmap::kARGB_8888_Config);
|
||||
@ -70,7 +94,7 @@ bool BaseExample::setupBackend(DeviceType type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseExample::setupRenderTarget() {
|
||||
void SkExampleWindow::setupRenderTarget() {
|
||||
GrBackendRenderTargetDesc desc;
|
||||
desc.fWidth = SkScalarRound(width());
|
||||
desc.fHeight = SkScalarRound(height());
|
||||
@ -88,7 +112,7 @@ void BaseExample::setupRenderTarget() {
|
||||
fContext->setRenderTarget(fRenderTarget);
|
||||
}
|
||||
|
||||
SkCanvas* BaseExample::createCanvas() {
|
||||
SkCanvas* SkExampleWindow::createCanvas() {
|
||||
if (fType == kGPU_DeviceType) {
|
||||
if (NULL != fContext && NULL != fRenderTarget) {
|
||||
SkAutoTUnref<SkDevice> device(new SkGpuDevice(fContext, fRenderTarget));
|
||||
@ -100,7 +124,10 @@ SkCanvas* BaseExample::createCanvas() {
|
||||
return INHERITED::createCanvas();
|
||||
}
|
||||
|
||||
void BaseExample::draw(SkCanvas* canvas) {
|
||||
void SkExampleWindow::draw(SkCanvas* canvas) {
|
||||
if (NULL != fCurrExample) {
|
||||
fCurrExample->draw(canvas);
|
||||
}
|
||||
if (fType == kGPU_DeviceType) {
|
||||
|
||||
SkASSERT(NULL != fContext);
|
||||
@ -118,12 +145,12 @@ void BaseExample::draw(SkCanvas* canvas) {
|
||||
INHERITED::present();
|
||||
}
|
||||
|
||||
void BaseExample::onSizeChange() {
|
||||
void SkExampleWindow::onSizeChange() {
|
||||
setupRenderTarget();
|
||||
}
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
void BaseExample::onHandleInval(const SkIRect& rect) {
|
||||
void SkExampleWindow::onHandleInval(const SkIRect& rect) {
|
||||
RECT winRect;
|
||||
winRect.top = rect.top();
|
||||
winRect.bottom = rect.bottom();
|
||||
@ -132,3 +159,39 @@ void BaseExample::onHandleInval(const SkIRect& rect) {
|
||||
InvalidateRect((HWND)this->getHWND(), &winRect, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SkExampleWindow::findNextMatch() {
|
||||
bool found = false;
|
||||
// Avoid infinite loop by knowing where we started.
|
||||
const SkExample::Registry* begin = fRegistry;
|
||||
while (!found) {
|
||||
fRegistry = fRegistry->next();
|
||||
if (NULL == fRegistry) { // Reached the end of the registered samples. GOTO head.
|
||||
fRegistry = SkExample::Registry::Head();
|
||||
}
|
||||
SkExample* next = fRegistry->factory()(this);
|
||||
if (!SkCommandLineFlags::ShouldSkip(fMatchStrs, next->getName().c_str())) {
|
||||
fCurrExample = next;
|
||||
found = true;
|
||||
}
|
||||
if (begin == fRegistry) { // We looped through every sample without finding anything.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
bool SkExampleWindow::onHandleChar(SkUnichar unichar) {
|
||||
if ('n' == unichar) {
|
||||
bool found = findNextMatch();
|
||||
if (!found) {
|
||||
SkDebugf("No SkExample that matches your query\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
|
||||
SkCommandLineFlags::Parse(argc, argv);
|
||||
return new SkExampleWindow(hwnd);
|
||||
}
|
@ -7,23 +7,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BaseExample_DEFINED
|
||||
#define BaseExample_DEFINED
|
||||
#ifndef SkExample_DEFINED
|
||||
#define SkExample_DEFINED
|
||||
|
||||
#include "SkWindow.h"
|
||||
#include "SkTRegistry.h"
|
||||
|
||||
class GrContext;
|
||||
struct GrGLInterface;
|
||||
class GrRenderTarget;
|
||||
class SkCanvas;
|
||||
class SkExampleWindow;
|
||||
|
||||
class BaseExample : public SkOSWindow {
|
||||
class SkExample : public SkNoncopyable {
|
||||
public:
|
||||
SkExample(SkExampleWindow* window) : fWindow(window) {}
|
||||
|
||||
// Your class should override this method to do its thing.
|
||||
virtual void draw(SkCanvas* canvas) = 0;
|
||||
|
||||
SkString getName() { return fName; };
|
||||
// Use this public registry to tell the world about your sample.
|
||||
typedef SkTRegistry<SkExample*, SkExampleWindow*> Registry;
|
||||
|
||||
protected:
|
||||
SkExampleWindow* fWindow;
|
||||
SkString fName;
|
||||
};
|
||||
|
||||
class SkExampleWindow : public SkOSWindow {
|
||||
public:
|
||||
enum DeviceType {
|
||||
kRaster_DeviceType,
|
||||
kGPU_DeviceType,
|
||||
};
|
||||
BaseExample(void* hWnd, int argc, char** argv);
|
||||
SkExampleWindow(void* hwnd);
|
||||
|
||||
// Changes the device type of the object.
|
||||
bool setupBackend(DeviceType type);
|
||||
@ -32,7 +50,6 @@ public:
|
||||
DeviceType getDeviceType() const { return fType; }
|
||||
|
||||
protected:
|
||||
// Your class should override this method to do its thing.
|
||||
virtual void draw(SkCanvas* canvas) SK_OVERRIDE;
|
||||
|
||||
virtual void onSizeChange() SK_OVERRIDE;
|
||||
@ -44,14 +61,22 @@ protected:
|
||||
SkCanvas* createCanvas() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
bool findNextMatch(); // Set example to the first one that matches FLAGS_match.
|
||||
void setupRenderTarget();
|
||||
bool onHandleChar(SkUnichar unichar) SK_OVERRIDE;
|
||||
|
||||
DeviceType fType;
|
||||
|
||||
SkExample* fCurrExample;
|
||||
const SkExample::Registry* fRegistry;
|
||||
SkTDArray<const char*> fMatchStrs;
|
||||
GrContext* fContext;
|
||||
GrRenderTarget* fRenderTarget;
|
||||
AttachmentInfo fAttachmentInfo;
|
||||
const GrGLInterface* fInterface;
|
||||
|
||||
typedef SkOSWindow INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,76 +0,0 @@
|
||||
{
|
||||
'targets' : [
|
||||
{
|
||||
'target_name': 'SkiaExamples',
|
||||
'type': 'executable',
|
||||
'mac_bundle' : 1,
|
||||
'include_dirs' : [],
|
||||
'includes': [],
|
||||
'sources': [
|
||||
'../experimental/SkiaExamples/HelloSkiaExample.cpp',
|
||||
'../experimental/SkiaExamples/BaseExample.h',
|
||||
'../experimental/SkiaExamples/BaseExample.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_lib.gyp:skia_lib',
|
||||
'views.gyp:views',
|
||||
'xml.gyp:xml',
|
||||
],
|
||||
'conditions' : [
|
||||
[ 'skia_gpu == 1', {
|
||||
'include_dirs' : [
|
||||
'../src/gpu', #gl/GrGLUtil.h
|
||||
]
|
||||
}],
|
||||
[ 'skia_os == "win"', {
|
||||
'sources' : [
|
||||
'../src/views/win/SkOSWindow_Win.cpp',
|
||||
'../src/views/win/skia_win.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
[ 'skia_os == "mac"', {
|
||||
'sources': [
|
||||
|
||||
# SkiaExamples specific files
|
||||
'../experimental/SkiaExamples/SkiaExamples-Info.plist',
|
||||
'../experimental/SkiaExamples/SkExampleNSView.h',
|
||||
'../experimental/SkiaExamples/SkExampleNSView.mm',
|
||||
|
||||
# Mac files
|
||||
'../src/views/mac/SampleAppDelegate.h',
|
||||
'../src/views/mac/SampleAppDelegate.mm',
|
||||
'../src/views/mac/SkEventNotifier.mm',
|
||||
'../src/views/mac/skia_mac.mm',
|
||||
'../src/views/mac/SkNSView.h',
|
||||
'../src/views/mac/SkNSView.mm',
|
||||
'../src/views/mac/SkOptionsTableView.h',
|
||||
'../src/views/mac/SkOptionsTableView.mm',
|
||||
'../src/views/mac/SkOSWindow_Mac.mm',
|
||||
'../src/views/mac/SkTextFieldCell.h',
|
||||
'../src/views/mac/SkTextFieldCell.m',
|
||||
],
|
||||
'include_dirs' : [
|
||||
'../src/views/mac/'
|
||||
],
|
||||
'link_settings': {
|
||||
},
|
||||
'xcode_settings' : {
|
||||
'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
|
||||
},
|
||||
'mac_bundle_resources' : [
|
||||
'../experimental/SkiaExamples/SkiaExamples.xib'
|
||||
],
|
||||
}
|
||||
],
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:2
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=2 shiftwidth=2:
|
@ -18,6 +18,75 @@
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
'target_name': 'SkiaExamples',
|
||||
'type': 'executable',
|
||||
'mac_bundle' : 1,
|
||||
'include_dirs' : [
|
||||
'../tools/flags',
|
||||
],
|
||||
'includes': [],
|
||||
'sources': [
|
||||
'../experimental/SkiaExamples/SkExample.h',
|
||||
'../experimental/SkiaExamples/SkExample.cpp',
|
||||
'../experimental/SkiaExamples/HelloSkiaExample.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_lib.gyp:skia_lib',
|
||||
'views.gyp:views',
|
||||
'xml.gyp:xml',
|
||||
'flags.gyp:flags'
|
||||
],
|
||||
'conditions' : [
|
||||
[ 'skia_gpu == 1', {
|
||||
'include_dirs' : [
|
||||
'../src/gpu', #gl/GrGLUtil.h
|
||||
]
|
||||
}],
|
||||
[ 'skia_os == "win"', {
|
||||
'sources' : [
|
||||
'../src/views/win/SkOSWindow_Win.cpp',
|
||||
'../src/views/win/skia_win.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
[ 'skia_os == "mac"', {
|
||||
'sources': [
|
||||
|
||||
# SkiaExamples specific files
|
||||
'../experimental/SkiaExamples/SkiaExamples-Info.plist',
|
||||
'../experimental/SkiaExamples/SkExampleNSView.h',
|
||||
'../experimental/SkiaExamples/SkExampleNSView.mm',
|
||||
|
||||
# Mac files
|
||||
'../src/views/mac/SampleAppDelegate.h',
|
||||
'../src/views/mac/SampleAppDelegate.mm',
|
||||
'../src/views/mac/SkEventNotifier.mm',
|
||||
'../src/views/mac/skia_mac.mm',
|
||||
'../src/views/mac/SkNSView.h',
|
||||
'../src/views/mac/SkNSView.mm',
|
||||
'../src/views/mac/SkOptionsTableView.h',
|
||||
'../src/views/mac/SkOptionsTableView.mm',
|
||||
'../src/views/mac/SkOSWindow_Mac.mm',
|
||||
'../src/views/mac/SkTextFieldCell.h',
|
||||
'../src/views/mac/SkTextFieldCell.m',
|
||||
],
|
||||
'include_dirs' : [
|
||||
'../src/views/mac/'
|
||||
],
|
||||
'link_settings': {
|
||||
},
|
||||
'xcode_settings' : {
|
||||
'INFOPLIST_FILE' : '../experimental/SkiaExamples/SkiaExamples-Info.plist',
|
||||
},
|
||||
'mac_bundle_resources' : [
|
||||
'../experimental/SkiaExamples/SkiaExamples.xib'
|
||||
],
|
||||
}
|
||||
],
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user