Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: mojo/examples/png_viewer/png_viewer.cc

Issue 684543003: Move //mojo/examples to //examples (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/examples/png_viewer/DEPS ('k') | mojo/examples/sample_app/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include <algorithm>
6
7 #include "base/macros.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_tokenizer.h"
11 #include "mojo/application/application_runner_chromium.h"
12 #include "mojo/examples/bitmap_uploader/bitmap_uploader.h"
13 #include "mojo/examples/media_viewer/media_viewer.mojom.h"
14 #include "mojo/public/c/system/main.h"
15 #include "mojo/public/cpp/application/application_connection.h"
16 #include "mojo/public/cpp/application/application_delegate.h"
17 #include "mojo/public/cpp/application/application_impl.h"
18 #include "mojo/public/cpp/application/interface_factory_impl.h"
19 #include "mojo/public/cpp/application/service_provider_impl.h"
20 #include "mojo/services/public/cpp/view_manager/types.h"
21 #include "mojo/services/public/cpp/view_manager/view.h"
22 #include "mojo/services/public/cpp/view_manager/view_manager.h"
23 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
24 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
25 #include "mojo/services/public/cpp/view_manager/view_observer.h"
26 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h"
27 #include "skia/ext/platform_canvas.h"
28 #include "skia/ext/refptr.h"
29 #include "third_party/skia/include/core/SkBitmap.h"
30 #include "third_party/skia/include/core/SkCanvas.h"
31 #include "third_party/skia/include/core/SkPaint.h"
32 #include "third_party/skia/include/core/SkScalar.h"
33 #include "ui/gfx/codec/png_codec.h"
34
35 namespace mojo {
36 namespace examples {
37
38 class PNGViewer;
39
40 // TODO(aa): Hook up ZoomableMedia interface again.
41 class PNGView : public ViewManagerDelegate, public ViewObserver {
42 public:
43 static void Spawn(URLResponsePtr response,
44 ServiceProviderImpl* exported_services,
45 scoped_ptr<ServiceProvider> imported_services,
46 Shell* shell) {
47 // PNGView deletes itself when its View is destroyed.
48 new PNGView(
49 response.Pass(), exported_services, imported_services.Pass(), shell);
50 }
51
52 private:
53 static const uint16_t kMaxZoomPercentage = 400;
54 static const uint16_t kMinZoomPercentage = 20;
55 static const uint16_t kDefaultZoomPercentage = 100;
56 static const uint16_t kZoomStep = 20;
57
58 PNGView(URLResponsePtr response,
59 ServiceProviderImpl* exported_services,
60 scoped_ptr<ServiceProvider> imported_services,
61 Shell* shell)
62 : imported_services_(imported_services.Pass()),
63 shell_(shell),
64 root_(nullptr),
65 view_manager_client_factory_(shell, this),
66 zoom_percentage_(kDefaultZoomPercentage) {
67 exported_services->AddService(&view_manager_client_factory_);
68 DecodePNG(response.Pass());
69 }
70
71 virtual ~PNGView() {
72 if (root_)
73 root_->RemoveObserver(this);
74 }
75
76 // Overridden from ViewManagerDelegate:
77 virtual void OnEmbed(ViewManager* view_manager,
78 View* root,
79 ServiceProviderImpl* exported_services,
80 scoped_ptr<ServiceProvider> imported_services) override {
81 root_ = root;
82 root_->AddObserver(this);
83 bitmap_uploader_.reset(new BitmapUploader(root_));
84 bitmap_uploader_->Init(shell_);
85 bitmap_uploader_->SetColor(SK_ColorGRAY);
86 if (!bitmap_.isNull())
87 DrawBitmap();
88 }
89
90 virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
91 // TODO(aa): Need to figure out how shutdown works.
92 }
93
94 // Overridden from ViewObserver:
95 virtual void OnViewBoundsChanged(View* view,
96 const Rect& old_bounds,
97 const Rect& new_bounds) override {
98 DCHECK_EQ(view, root_);
99 DrawBitmap();
100 }
101
102 virtual void OnViewDestroyed(View* view) override {
103 DCHECK_EQ(view, root_);
104 delete this;
105 }
106
107 void DecodePNG(URLResponsePtr response) {
108 int content_length = GetContentLength(response->headers);
109 scoped_ptr<unsigned char[]> data(new unsigned char[content_length]);
110 unsigned char* buf = data.get();
111 uint32_t bytes_remaining = content_length;
112 uint32_t num_bytes = bytes_remaining;
113 while (bytes_remaining > 0) {
114 MojoResult result = ReadDataRaw(
115 response->body.get(), buf, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
116 if (result == MOJO_RESULT_SHOULD_WAIT) {
117 Wait(response->body.get(),
118 MOJO_HANDLE_SIGNAL_READABLE,
119 MOJO_DEADLINE_INDEFINITE);
120 } else if (result == MOJO_RESULT_OK) {
121 buf += num_bytes;
122 num_bytes = bytes_remaining -= num_bytes;
123 } else {
124 break;
125 }
126 }
127
128 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data.get()),
129 content_length,
130 &bitmap_);
131 }
132
133 void DrawBitmap() {
134 if (!root_)
135 return;
136
137 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::CreatePlatformCanvas(
138 root_->bounds().width, root_->bounds().height, true)));
139 canvas->drawColor(SK_ColorGRAY);
140 SkPaint paint;
141 SkScalar scale =
142 SkFloatToScalar(zoom_percentage_ * 1.0f / kDefaultZoomPercentage);
143 canvas->scale(scale, scale);
144 canvas->drawBitmap(bitmap_, 0, 0, &paint);
145 bitmap_uploader_->SetBitmap(
146 skia::GetTopDevice(*canvas)->accessBitmap(true));
147 }
148
149 void ZoomIn() {
150 if (zoom_percentage_ >= kMaxZoomPercentage)
151 return;
152 zoom_percentage_ += kZoomStep;
153 DrawBitmap();
154 }
155
156 void ZoomOut() {
157 if (zoom_percentage_ <= kMinZoomPercentage)
158 return;
159 zoom_percentage_ -= kZoomStep;
160 DrawBitmap();
161 }
162
163 void ZoomToActualSize() {
164 if (zoom_percentage_ == kDefaultZoomPercentage)
165 return;
166 zoom_percentage_ = kDefaultZoomPercentage;
167 DrawBitmap();
168 }
169
170 int GetContentLength(const Array<String>& headers) {
171 for (size_t i = 0; i < headers.size(); ++i) {
172 base::StringTokenizer t(headers[i], ": ;=");
173 while (t.GetNext()) {
174 if (!t.token_is_delim() && t.token() == "Content-Length") {
175 while (t.GetNext()) {
176 if (!t.token_is_delim())
177 return atoi(t.token().c_str());
178 }
179 }
180 }
181 }
182 return 0;
183 }
184
185 SkBitmap bitmap_;
186 scoped_ptr<ServiceProvider> imported_services_;
187 Shell* shell_;
188 View* root_;
189 ViewManagerClientFactory view_manager_client_factory_;
190 uint16_t zoom_percentage_;
191 scoped_ptr<BitmapUploader> bitmap_uploader_;
192
193 DISALLOW_COPY_AND_ASSIGN(PNGView);
194 };
195
196 class ContentHandlerImpl : public InterfaceImpl<ContentHandler> {
197 public:
198 explicit ContentHandlerImpl(Shell* shell) : shell_(shell) {}
199 virtual ~ContentHandlerImpl() {}
200
201 private:
202 // Overridden from ContentHandler:
203 virtual void OnConnect(
204 const mojo::String& requestor_url,
205 URLResponsePtr response,
206 InterfaceRequest<ServiceProvider> service_provider) override {
207 ServiceProviderImpl* exported_services = new ServiceProviderImpl();
208 BindToRequest(exported_services, &service_provider);
209 scoped_ptr<ServiceProvider> remote(
210 exported_services->CreateRemoteServiceProvider());
211 PNGView::Spawn(response.Pass(), exported_services, remote.Pass(), shell_);
212 }
213
214 Shell* shell_;
215
216 DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl);
217 };
218
219 class PNGViewer : public ApplicationDelegate {
220 public:
221 PNGViewer() {}
222 private:
223 // Overridden from ApplicationDelegate:
224 virtual void Initialize(ApplicationImpl* app) override {
225 content_handler_factory_.reset(
226 new InterfaceFactoryImplWithContext<ContentHandlerImpl, Shell>(
227 app->shell()));
228 }
229
230 // Overridden from ApplicationDelegate:
231 virtual bool ConfigureIncomingConnection(
232 ApplicationConnection* connection) override {
233 connection->AddService(content_handler_factory_.get());
234 return true;
235 }
236
237 scoped_ptr<InterfaceFactoryImplWithContext<ContentHandlerImpl, Shell> >
238 content_handler_factory_;
239
240 DISALLOW_COPY_AND_ASSIGN(PNGViewer);
241 };
242
243 } // namespace examples
244 } // namespace mojo
245
246 MojoResult MojoMain(MojoHandle shell_handle) {
247 mojo::ApplicationRunnerChromium runner(new mojo::examples::PNGViewer);
248 return runner.Run(shell_handle);
249 }
OLDNEW
« no previous file with comments | « mojo/examples/png_viewer/DEPS ('k') | mojo/examples/sample_app/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698