- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / examples / api / mouse_cursor / mouse_cursor.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <math.h>
6 #include <stdio.h>
7
8 #include "ppapi/c/ppb_mouse_cursor.h"
9 #include "ppapi/cpp/image_data.h"
10 #include "ppapi/cpp/instance.h"
11 #include "ppapi/cpp/module.h"
12 #include "ppapi/cpp/mouse_cursor.h"
13 #include "ppapi/cpp/size.h"
14 #include "ppapi/cpp/var.h"
15 #include "ppapi/utility/completion_callback_factory.h"
16
17 #ifdef WIN32
18 #undef PostMessage
19 // Allow 'this' in initializer list
20 #pragma warning(disable : 4355)
21 #endif
22
23 namespace {
24
25 uint32_t MakeColor(float r, float g, float b, float a) {
26   // Since we're using premultiplied alpha
27   // (PP_IMAGEDATAFORMAT_BGRA_PREMUL), we have to multiply each
28   // color component by the alpha value.
29   uint8_t a8 = static_cast<uint8_t>(255 * a);
30   uint8_t r8 = static_cast<uint8_t>(255 * r * a);
31   uint8_t g8 = static_cast<uint8_t>(255 * g * a);
32   uint8_t b8 = static_cast<uint8_t>(255 * b * a);
33   return (a8 << 24) | (r8 << 16) | (g8 << 8) | b8;
34 }
35
36 }
37
38 class MouseCursorInstance : public pp::Instance {
39  public:
40   explicit MouseCursorInstance(PP_Instance instance)
41       : pp::Instance(instance) {}
42
43   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
44     MakeCustomCursor();
45     return true;
46   }
47
48  private:
49   virtual void HandleMessage(const pp::Var& var_message) {
50     if (!var_message.is_number()) {
51       fprintf(stderr, "Unexpected message.\n");
52       return;
53     }
54
55     PP_MouseCursor_Type cursor =
56         static_cast<PP_MouseCursor_Type>(var_message.AsInt());
57     if (cursor == PP_MOUSECURSOR_TYPE_CUSTOM) {
58       pp::Point hot_spot(16, 16);
59       pp::MouseCursor::SetCursor(this, cursor, custom_cursor_, hot_spot);
60     } else {
61       pp::MouseCursor::SetCursor(this, cursor);
62     }
63   }
64
65   void MakeCustomCursor() {
66     pp::Size size(32, 32);
67     custom_cursor_ =
68         pp::ImageData(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true);
69     DrawCircle(16, 16, 9, 14, 0.8f, 0.8f, 0);
70     DrawCircle(11, 12, 2, 3, 0, 0, 0);
71     DrawCircle(21, 12, 2, 3, 0, 0, 0);
72     DrawHorizontalLine(12, 20, 21, 0.5f, 0, 0, 1.0f);
73   }
74
75   void DrawCircle(int cx, int cy, float alpha_radius, float radius,
76                   float r, float g, float b) {
77     pp::Size size = custom_cursor_.size();
78     uint32_t* data = static_cast<uint32_t*>(custom_cursor_.data());
79     // It's less efficient to loop over the entire image this way, but the
80     // image is small, and this is simpler.
81     for (int y = 0; y < size.width(); ++y) {
82       for (int x = 0; x < size.width(); ++x) {
83         int dx = (x - cx);
84         int dy = (y - cy);
85         float dist = sqrtf(dx * dx + dy * dy);
86
87         if (dist < radius) {
88           float a;
89           if (dist > alpha_radius) {
90             a = 1.f - (dist - alpha_radius) / (radius - alpha_radius);
91           } else {
92             a = 1.f;
93           }
94
95           data[y * size.width() + x] = MakeColor(r, g, b, a);
96         }
97       }
98     }
99   }
100
101   void DrawHorizontalLine(int x1, int x2, int y,
102                           float r, float g, float b, float a) {
103     pp::Size size = custom_cursor_.size();
104     uint32_t* data = static_cast<uint32_t*>(custom_cursor_.data());
105     for (int x = x1; x <= x2; ++x) {
106       data[y * size.width() + x] = MakeColor(r, g, b, a);
107     }
108   }
109
110   pp::ImageData custom_cursor_;
111 };
112
113 class MouseCursorModule : public pp::Module {
114  public:
115   MouseCursorModule() : pp::Module() {}
116   virtual ~MouseCursorModule() {}
117
118   virtual pp::Instance* CreateInstance(PP_Instance instance) {
119     return new MouseCursorInstance(instance);
120   }
121 };
122
123 namespace pp {
124 Module* CreateModule() { return new MouseCursorModule(); }
125 }  // namespace pp