/* * Copyright 2015 Google Inc. * * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * */ #include "HelloWorld.h" #include "gl/GrGLInterface.h" #include "SkApplication.h" #include "SkCanvas.h" #include "SkGradientShader.h" #include "SkGraphics.h" #include "SkGr.h" void application_init() { SkGraphics::Init(); SkEvent::Init(); } void application_term() { SkEvent::Term(); } HelloWorldWindow::HelloWorldWindow(void* hwnd) : INHERITED(hwnd) { fType = kGPU_DeviceType; fRenderTarget = NULL; fRotationAngle = 0; this->setTitle(); this->setUpBackend(); } HelloWorldWindow::~HelloWorldWindow() { tearDownBackend(); } void HelloWorldWindow::tearDownBackend() { SkSafeUnref(fContext); fContext = NULL; SkSafeUnref(fInterface); fInterface = NULL; SkSafeUnref(fRenderTarget); fRenderTarget = NULL; INHERITED::detach(); } void HelloWorldWindow::setTitle() { SkString title("Hello World "); title.appendf(fType == kRaster_DeviceType ? "raster" : "opengl"); INHERITED::setTitle(title.c_str()); } bool HelloWorldWindow::setUpBackend() { this->setColorType(kRGBA_8888_SkColorType); this->setVisibleP(true); this->setClipToBounds(false); bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo); if (false == result) { SkDebugf("Not possible to create backend.\n"); detach(); return false; } fInterface = GrGLCreateNativeInterface(); SkASSERT(NULL != fInterface); fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface); SkASSERT(NULL != fContext); this->setUpRenderTarget(); return true; } void HelloWorldWindow::setUpRenderTarget() { SkSafeUnref(fRenderTarget); fRenderTarget = this->renderTarget(fAttachmentInfo, fInterface, fContext); } void HelloWorldWindow::drawContents(SkCanvas* canvas) { // Clear background canvas->drawColor(SK_ColorWHITE); SkPaint paint; paint.setColor(SK_ColorRED); // Draw a rectangle with red paint SkRect rect = { 10, 10, 128, 128 }; canvas->drawRect(rect, paint); // Set up a linear gradient and draw a circle { SkPoint linearPoints[] = { {0, 0}, {300, 300} }; SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK}; SkShader* shader = SkGradientShader::CreateLinear( linearPoints, linearColors, NULL, 2, SkShader::kMirror_TileMode); SkAutoUnref shader_deleter(shader); paint.setShader(shader); paint.setFlags(SkPaint::kAntiAlias_Flag); canvas->drawCircle(200, 200, 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(20); canvas->save(); static const char message[] = "Hello World"; // Translate and rotate canvas->translate(300, 300); fRotationAngle += 0.2f; if (fRotationAngle > 360) { fRotationAngle -= 360; } canvas->rotate(fRotationAngle); // Draw the text: canvas->drawText(message, strlen(message), 0, 0, paint); canvas->restore(); } void HelloWorldWindow::draw(SkCanvas* canvas) { drawContents(canvas); // in case we have queued drawing calls fContext->flush(); // Invalidate the window to force a redraw. Poor man's animation mechanism. this->inval(NULL); if (kRaster_DeviceType == fType) { // need to send the raster bits to the (gpu) window SkImage* snap = fSurface->newImageSnapshot(); size_t rowBytes; SkImageInfo info; const void* pixels = snap->peekPixels(&info, &rowBytes); fRenderTarget->writePixels(0, 0, snap->width(), snap->height(), SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(), info.profileType()), pixels, rowBytes, GrContext::kFlushWrites_PixelOp); SkSafeUnref(snap); } INHERITED::present(); } void HelloWorldWindow::onSizeChange() { setUpRenderTarget(); } bool HelloWorldWindow::onHandleChar(SkUnichar unichar) { if (' ' == unichar) { fType = fType == kRaster_DeviceType ? kGPU_DeviceType: kRaster_DeviceType; tearDownBackend(); setUpBackend(); this->setTitle(); this->inval(NULL); } return true; } SkOSWindow* create_sk_window(void* hwnd, int , char** ) { return new HelloWorldWindow(hwnd); }