From 3a6143d91f06d01f07b3b0e8adfa703a574d2bec Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 11 Dec 2013 17:34:58 +0000 Subject: [PATCH] Added canvas.fillStyle with support for just the "#RRGGBB" style of colors. Also renamed drawRect to fillRect, which now take x,y,w,h parameters. BUG= R=robertphillips@google.com Author: jcgregorio@google.com Review URL: https://codereview.chromium.org/108813004 git-svn-id: http://skia.googlecode.com/svn/trunk@12621 2bbb7eff-a529-9590-31e7-b0007b416f81 --- experimental/SkV8Example/SkV8Example.cpp | 108 +++++++++++++++++------ experimental/SkV8Example/SkV8Example.h | 28 ++++-- 2 files changed, 100 insertions(+), 36 deletions(-) diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/SkV8Example.cpp index 3c7a5f3642..a57232e7a5 100644 --- a/experimental/SkV8Example/SkV8Example.cpp +++ b/experimental/SkV8Example/SkV8Example.cpp @@ -19,6 +19,7 @@ using namespace v8; #include "SkDraw.h" #include "SkGpuDevice.h" #include "SkGraphics.h" +#include "SkScalar.h" void application_init() { @@ -79,37 +80,83 @@ SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) : INHERITED(hwnd) , fJsCanvas(canvas) { - fRotationAngle = SkIntToScalar(0); this->setConfig(SkBitmap::kARGB_8888_Config); this->setVisibleP(true); this->setClipToBounds(false); } -JsCanvas* JsCanvas::unwrap(Handle obj) { +JsCanvas* JsCanvas::Unwrap(Handle obj) { Handle field = Handle::Cast(obj->GetInternalField(0)); void* ptr = field->Value(); return static_cast(ptr); } -void JsCanvas::inval(const v8::FunctionCallbackInfo& args) { - unwrap(args.This())->fWindow->inval(NULL); +void JsCanvas::Inval(const v8::FunctionCallbackInfo& args) { + Unwrap(args.This())->fWindow->inval(NULL); } -void JsCanvas::drawRect(const v8::FunctionCallbackInfo& args) { - SkCanvas* canvas = unwrap(args.This())->fCanvas; +void JsCanvas::FillRect(const v8::FunctionCallbackInfo& args) { + JsCanvas* jsCanvas = Unwrap(args.This()); + SkCanvas* canvas = jsCanvas->fCanvas; - canvas->drawColor(SK_ColorWHITE); + if (args.Length() != 4) { + args.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + args.GetIsolate(), "Error: 4 arguments required.")); + return; + } + // TODO(jcgregorio) Really figure out the conversion from JS numbers to + // SkScalars. Maybe test if int first? Not sure of the performance impact. + double x = args[0]->NumberValue(); + double y = args[1]->NumberValue(); + double w = args[2]->NumberValue(); + double h = args[3]->NumberValue(); - // Draw a rectangle with red paint. - SkPaint paint; - paint.setColor(SK_ColorRED); SkRect rect = { - SkIntToScalar(10), SkIntToScalar(10), - SkIntToScalar(128), SkIntToScalar(128) + SkDoubleToScalar(x), + SkDoubleToScalar(y), + SkDoubleToScalar(x) + SkDoubleToScalar(w), + SkDoubleToScalar(y) + SkDoubleToScalar(h) }; - canvas->drawRect(rect, paint); + canvas->drawRect(rect, jsCanvas->fFillStyle); } +void JsCanvas::GetFillStyle(Local name, + const PropertyCallbackInfo& info) { + JsCanvas* jsCanvas = Unwrap(info.This()); + SkColor color = jsCanvas->fFillStyle.getColor(); + char buf[8]; + sprintf(buf, "#%02X%02X%02X", SkColorGetR(color), SkColorGetG(color), + SkColorGetB(color)); + + info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buf)); +} + +void JsCanvas::SetFillStyle(Local name, Local value, + const PropertyCallbackInfo& info) { + JsCanvas* jsCanvas = Unwrap(info.This()); + Local s = value->ToString(); + if (s->Length() != 7) { + info.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + info.GetIsolate(), "Invalid fill style format.")); + return; + } + char buf[8]; + s->WriteUtf8(buf, sizeof(buf)); + + if (buf[0] != '#') { + info.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + info.GetIsolate(), "Invalid fill style format.")); + return; + } + + long color = strtol(buf+1, NULL, 16); + jsCanvas->fFillStyle.setColor(SkColorSetA(SkColor(color), SK_AlphaOPAQUE)); +} + + Persistent JsCanvas::fCanvasTemplate; Handle JsCanvas::makeCanvasTemplate() { @@ -121,14 +168,19 @@ Handle JsCanvas::makeCanvasTemplate() { result->SetInternalFieldCount(1); // Add accessors for each of the fields of the canvas object. + result->SetAccessor( + String::NewFromUtf8(fIsolate, "fillStyle", String::kInternalizedString), + GetFillStyle, SetFillStyle); + + // Add methods. result->Set( String::NewFromUtf8( - fIsolate, "drawRect", String::kInternalizedString), - FunctionTemplate::New(drawRect)); + fIsolate, "fillRect", String::kInternalizedString), + FunctionTemplate::New(FillRect)); result->Set( String::NewFromUtf8( fIsolate, "inval", String::kInternalizedString), - FunctionTemplate::New(inval)); + FunctionTemplate::New(Inval)); // Return the result through the current handle scope. return handleScope.Escape(result); @@ -214,13 +266,7 @@ void JsCanvas::onDraw(SkCanvas* canvas, SkOSWindow* window) { void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { canvas->save(); - - fRotationAngle += SkDoubleToScalar(0.2); - if (fRotationAngle > SkDoubleToScalar(360.0)) { - fRotationAngle -= SkDoubleToScalar(360.0); - } - - canvas->rotate(fRotationAngle); + canvas->drawColor(SK_ColorWHITE); // Now jump into JS and call the onDraw(canvas) method defined there. fJsCanvas->onDraw(canvas, this); @@ -310,6 +356,7 @@ bool JsCanvas::initialize(const char script[]) { Handle fn_val = context->Global()->Get(fn_name); if (!fn_val->IsFunction()) { + printf("Not a function.\n"); return false; } @@ -332,10 +379,17 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { Isolate* isolate = Isolate::GetCurrent(); JsCanvas* jsCanvas = new JsCanvas(isolate); - const char* script = "function onDraw(canvas){" - "canvas.drawRect();" - "canvas.inval();" - "};"; + const char* script = +"var onDraw = function(){ \n" +" var tick = 0; \n" +" function f(canvas) { \n" +" tick += 0.001; \n" +" canvas.fillStyle = '#00FF00'; \n" +" canvas.fillRect(20, 20, 100, Math.abs(Math.cos(tick)*100)); \n" +" canvas.inval(); \n" +" }; \n" +" return f; \n" +"}(); \n"; if (!jsCanvas->initialize(script)) { printf("Failed to initialize.\n"); exit(1); diff --git a/experimental/SkV8Example/SkV8Example.h b/experimental/SkV8Example/SkV8Example.h index 878e1f0f1f..9ed0eccb12 100644 --- a/experimental/SkV8Example/SkV8Example.h +++ b/experimental/SkV8Example/SkV8Example.h @@ -13,6 +13,7 @@ #include #include "SkWindow.h" +#include "SkPaint.h" using namespace v8; @@ -32,7 +33,6 @@ protected: private: typedef SkOSWindow INHERITED; - SkScalar fRotationAngle; JsCanvas* fJsCanvas; }; @@ -41,17 +41,19 @@ private: // that's used to bridge from C++ to JS. Should be used in JS as: // // function onDraw(canvas) { -// canvas.drawRect(); -// canvas.inval(); +// canvas.fillStyle="#FF0000"; +// canvas.fillRect(x, y, w, h); +// canvas.inval(); // } -// class JsCanvas { public: JsCanvas(Isolate* isolate) : fIsolate(isolate) , fCanvas(NULL) , fWindow(NULL) - {} + { + fFillStyle.setColor(SK_ColorRED); + } ~JsCanvas(); // Parse the script. @@ -61,14 +63,20 @@ public: void onDraw(SkCanvas* canvas, SkOSWindow* window); private: - // Implementation of the canvas.drawRect() JS function. - static void drawRect(const v8::FunctionCallbackInfo& args); + // Implementation of the canvas.fillStyle field. + static void GetFillStyle(Local name, + const PropertyCallbackInfo& info); + static void SetFillStyle(Local name, Local value, + const PropertyCallbackInfo& info); + + // Implementation of the canvas.fillRect() JS function. + static void FillRect(const v8::FunctionCallbackInfo& args); // Implementation of the canvas.inval() JS function. - static void inval(const v8::FunctionCallbackInfo& args); + static void Inval(const v8::FunctionCallbackInfo& args); // Get the pointer out of obj. - static JsCanvas* unwrap(Handle obj); + static JsCanvas* Unwrap(Handle obj); // Create a template for JS object associated with JsCanvas, called lazily // by Wrap() and the results are stored in fCanvasTemplate; @@ -82,6 +90,8 @@ private: // Only valid when inside OnDraw(). SkCanvas* fCanvas; + SkPaint fFillStyle; + // Only valid when inside OnDraw(). SkOSWindow* fWindow;