Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / mojo / examples / png_viewer / png_viewer.cc
blobee4b530a91dd2be296b038993afd29f3eef35a58
1 // Copyright 2014 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.
5 #include <algorithm>
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_tokenizer.h"
9 #include "mojo/examples/media_viewer/media_viewer.mojom.h"
10 #include "mojo/public/c/system/main.h"
11 #include "mojo/public/cpp/application/application_connection.h"
12 #include "mojo/public/cpp/application/application_delegate.h"
13 #include "mojo/public/cpp/application/application_runner_chromium.h"
14 #include "mojo/public/cpp/application/interface_factory_impl.h"
15 #include "mojo/services/public/cpp/view_manager/types.h"
16 #include "mojo/services/public/cpp/view_manager/view.h"
17 #include "mojo/services/public/cpp/view_manager/view_manager.h"
18 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
19 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
20 #include "mojo/services/public/cpp/view_manager/view_observer.h"
21 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
22 #include "skia/ext/platform_canvas.h"
23 #include "skia/ext/refptr.h"
24 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkPaint.h"
27 #include "third_party/skia/include/core/SkScalar.h"
28 #include "ui/gfx/codec/png_codec.h"
30 namespace mojo {
31 namespace examples {
33 class PNGViewer;
35 class ZoomableMediaImpl : public InterfaceImpl<ZoomableMedia> {
36 public:
37 explicit ZoomableMediaImpl(PNGViewer* viewer) : viewer_(viewer) {}
38 virtual ~ZoomableMediaImpl() {}
40 private:
41 // Overridden from ZoomableMedia:
42 virtual void ZoomIn() OVERRIDE;
43 virtual void ZoomOut() OVERRIDE;
44 virtual void ZoomToActualSize() OVERRIDE;
46 PNGViewer* viewer_;
48 DISALLOW_COPY_AND_ASSIGN(ZoomableMediaImpl);
51 class NavigatorImpl : public InterfaceImpl<Navigator> {
52 public:
53 explicit NavigatorImpl(PNGViewer* viewer) : viewer_(viewer) {}
54 virtual ~NavigatorImpl() {}
56 private:
57 // Overridden from Navigator:
58 virtual void Navigate(
59 uint32_t view_id,
60 NavigationDetailsPtr navigation_details,
61 ResponseDetailsPtr response_details) OVERRIDE {
62 int content_length = GetContentLength(response_details->response->headers);
63 unsigned char* data = new unsigned char[content_length];
64 unsigned char* buf = data;
65 uint32_t bytes_remaining = content_length;
66 uint32_t num_bytes = bytes_remaining;
67 while (bytes_remaining > 0) {
68 MojoResult result = ReadDataRaw(
69 response_details->response->body.get(),
70 buf,
71 &num_bytes,
72 MOJO_READ_DATA_FLAG_NONE);
73 if (result == MOJO_RESULT_SHOULD_WAIT) {
74 Wait(response_details->response->body.get(),
75 MOJO_HANDLE_SIGNAL_READABLE,
76 MOJO_DEADLINE_INDEFINITE);
77 } else if (result == MOJO_RESULT_OK) {
78 buf += num_bytes;
79 num_bytes = bytes_remaining -= num_bytes;
80 } else {
81 break;
85 SkBitmap bitmap;
86 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data),
87 content_length, &bitmap);
88 UpdateView(view_id, bitmap);
90 delete[] data;
93 void UpdateView(Id view_id, const SkBitmap& bitmap);
95 int GetContentLength(const Array<String>& headers) {
96 for (size_t i = 0; i < headers.size(); ++i) {
97 base::StringTokenizer t(headers[i], ": ;=");
98 while (t.GetNext()) {
99 if (!t.token_is_delim() && t.token() == "Content-Length") {
100 while (t.GetNext()) {
101 if (!t.token_is_delim())
102 return atoi(t.token().c_str());
107 return 0;
110 PNGViewer* viewer_;
112 DISALLOW_COPY_AND_ASSIGN(NavigatorImpl);
115 class PNGViewer
116 : public ApplicationDelegate,
117 public ViewManagerDelegate,
118 public ViewObserver {
119 public:
120 PNGViewer()
121 : navigator_factory_(this),
122 zoomable_media_factory_(this),
123 view_manager_client_factory_(this),
124 root_(NULL),
125 zoom_percentage_(kDefaultZoomPercentage) {}
126 virtual ~PNGViewer() {
127 if (root_)
128 root_->RemoveObserver(this);
131 void UpdateView(Id view_id, const SkBitmap& bitmap) {
132 bitmap_ = bitmap;
133 zoom_percentage_ = kDefaultZoomPercentage;
134 DrawBitmap();
137 void ZoomIn() {
138 if (zoom_percentage_ >= kMaxZoomPercentage)
139 return;
140 zoom_percentage_ += kZoomStep;
141 DrawBitmap();
144 void ZoomOut() {
145 if (zoom_percentage_ <= kMinZoomPercentage)
146 return;
147 zoom_percentage_ -= kZoomStep;
148 DrawBitmap();
151 void ZoomToActualSize() {
152 if (zoom_percentage_ == kDefaultZoomPercentage)
153 return;
154 zoom_percentage_ = kDefaultZoomPercentage;
155 DrawBitmap();
158 private:
159 static const uint16_t kMaxZoomPercentage = 400;
160 static const uint16_t kMinZoomPercentage = 20;
161 static const uint16_t kDefaultZoomPercentage = 100;
162 static const uint16_t kZoomStep = 20;
164 // Overridden from ApplicationDelegate:
165 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
166 MOJO_OVERRIDE {
167 connection->AddService(&navigator_factory_);
168 connection->AddService(&zoomable_media_factory_);
169 connection->AddService(&view_manager_client_factory_);
170 return true;
173 // Overridden from ViewManagerDelegate:
174 virtual void OnEmbed(ViewManager* view_manager,
175 View* root,
176 ServiceProviderImpl* exported_services,
177 scoped_ptr<ServiceProvider> imported_services) OVERRIDE {
178 root_ = root;
179 root_->AddObserver(this);
180 root_->SetColor(SK_ColorGRAY);
181 if (!bitmap_.isNull())
182 DrawBitmap();
184 virtual void OnViewManagerDisconnected(
185 ViewManager* view_manager) OVERRIDE {
186 base::MessageLoop::current()->Quit();
189 void DrawBitmap() {
190 if (!root_)
191 return;
193 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
194 root_->bounds().width(),
195 root_->bounds().height(),
196 true)));
197 canvas->drawColor(SK_ColorGRAY);
198 SkPaint paint;
199 SkScalar scale =
200 SkFloatToScalar(zoom_percentage_ * 1.0f / kDefaultZoomPercentage);
201 canvas->scale(scale, scale);
202 canvas->drawBitmap(bitmap_, 0, 0, &paint);
203 root_->SetContents(skia::GetTopDevice(*canvas)->accessBitmap(true));
206 // ViewObserver:
207 virtual void OnViewBoundsChanged(View* view,
208 const gfx::Rect& old_bounds,
209 const gfx::Rect& new_bounds) OVERRIDE {
210 DCHECK_EQ(view, root_);
211 DrawBitmap();
213 virtual void OnViewDestroyed(View* view) OVERRIDE {
214 DCHECK_EQ(view, root_);
215 view->RemoveObserver(this);
216 root_ = NULL;
219 InterfaceFactoryImplWithContext<NavigatorImpl, PNGViewer> navigator_factory_;
220 InterfaceFactoryImplWithContext<ZoomableMediaImpl, PNGViewer>
221 zoomable_media_factory_;
222 ViewManagerClientFactory view_manager_client_factory_;
224 View* root_;
225 SkBitmap bitmap_;
226 uint16_t zoom_percentage_;
228 DISALLOW_COPY_AND_ASSIGN(PNGViewer);
231 void ZoomableMediaImpl::ZoomIn() {
232 viewer_->ZoomIn();
235 void ZoomableMediaImpl::ZoomOut() {
236 viewer_->ZoomOut();
239 void ZoomableMediaImpl::ZoomToActualSize() {
240 viewer_->ZoomToActualSize();
243 void NavigatorImpl::UpdateView(Id view_id,
244 const SkBitmap& bitmap) {
245 viewer_->UpdateView(view_id, bitmap);
248 } // namespace examples
249 } // namespace mojo
251 MojoResult MojoMain(MojoHandle shell_handle) {
252 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer);
253 return runner.Run(shell_handle);