OLD | NEW |
(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 <string> |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/macros.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "mojo/application/application_runner_chromium.h" |
| 11 #include "mojo/data_pipe_utils/data_pipe_utils.h" |
| 12 #include "mojo/public/c/system/main.h" |
| 13 #include "mojo/ui/content_viewer_app.h" |
| 14 #include "mojo/ui/ganesh_view.h" |
| 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 16 #include "third_party/skia/include/core/SkCanvas.h" |
| 17 #include "third_party/skia/include/core/SkImage.h" |
| 18 #include "third_party/skia/include/core/SkSurface.h" |
| 19 #include "ui/gfx/codec/png_codec.h" |
| 20 |
| 21 namespace examples { |
| 22 |
| 23 namespace { |
| 24 constexpr uint32_t kContentImageResourceId = 1; |
| 25 constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId; |
| 26 } // namespace |
| 27 |
| 28 class PNGView : public mojo::ui::GaneshView { |
| 29 public: |
| 30 PNGView( |
| 31 mojo::ApplicationImpl* app_impl, |
| 32 const skia::RefPtr<SkImage>& image, |
| 33 const mojo::ui::ViewProvider::CreateViewCallback& create_view_callback) |
| 34 : GaneshView(app_impl, "PNGViewer", create_view_callback), image_(image) { |
| 35 DCHECK(image_); |
| 36 } |
| 37 |
| 38 ~PNGView() override {} |
| 39 |
| 40 private: |
| 41 // |GaneshView|: |
| 42 void OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params, |
| 43 mojo::Array<uint32_t> children_needing_layout, |
| 44 const OnLayoutCallback& callback) override { |
| 45 size_.width = layout_params->constraints->max_width; |
| 46 size_.height = layout_params->constraints->max_height; |
| 47 |
| 48 auto info = mojo::ui::ViewLayoutResult::New(); |
| 49 info->size = size_.Clone(); |
| 50 callback.Run(info.Pass()); |
| 51 |
| 52 UpdateScene(); |
| 53 } |
| 54 |
| 55 void UpdateScene() { |
| 56 mojo::Rect bounds; |
| 57 bounds.width = size_.width; |
| 58 bounds.height = size_.height; |
| 59 |
| 60 auto update = mojo::gfx::composition::SceneUpdate::New(); |
| 61 mojo::gfx::composition::ResourcePtr content_resource = |
| 62 ganesh_renderer()->DrawCanvas( |
| 63 size_, base::Bind(&PNGView::DrawContent, base::Unretained(this))); |
| 64 DCHECK(content_resource); |
| 65 update->resources.insert(kContentImageResourceId, content_resource.Pass()); |
| 66 |
| 67 auto root_node = mojo::gfx::composition::Node::New(); |
| 68 root_node->op = mojo::gfx::composition::NodeOp::New(); |
| 69 root_node->op->set_image(mojo::gfx::composition::ImageNodeOp::New()); |
| 70 root_node->op->get_image()->content_rect = bounds.Clone(); |
| 71 root_node->op->get_image()->image_resource_id = kContentImageResourceId; |
| 72 update->nodes.insert(kRootNodeId, root_node.Pass()); |
| 73 |
| 74 scene()->Update(update.Pass()); |
| 75 scene()->Publish(nullptr); |
| 76 } |
| 77 |
| 78 void DrawContent(SkCanvas* canvas) { |
| 79 canvas->clear(SK_ColorBLACK); |
| 80 |
| 81 int32_t w, h; |
| 82 if (size_.width * image_->height() < size_.height * image_->width()) { |
| 83 w = size_.width; |
| 84 h = image_->height() * size_.width / image_->width(); |
| 85 } else { |
| 86 w = image_->width() * size_.height / image_->height(); |
| 87 h = size_.height; |
| 88 } |
| 89 canvas->drawImageRect( |
| 90 image_.get(), SkRect::MakeWH(image_->width(), image_->height()), |
| 91 SkRect::MakeXYWH((size_.width - w) / 2, (size_.height - h) / 2, w, h), |
| 92 nullptr); |
| 93 } |
| 94 |
| 95 skia::RefPtr<SkImage> image_; |
| 96 mojo::Size size_; |
| 97 |
| 98 DISALLOW_COPY_AND_ASSIGN(PNGView); |
| 99 }; |
| 100 |
| 101 class PNGContentViewProviderApp : public mojo::ui::ViewProviderApp { |
| 102 public: |
| 103 PNGContentViewProviderApp(skia::RefPtr<SkImage> image) : image_(image) { |
| 104 DCHECK(image_); |
| 105 } |
| 106 |
| 107 ~PNGContentViewProviderApp() override {} |
| 108 |
| 109 bool CreateView( |
| 110 const std::string& connection_url, |
| 111 mojo::InterfaceRequest<mojo::ServiceProvider> services, |
| 112 mojo::ServiceProviderPtr exposed_services, |
| 113 const mojo::ui::ViewProvider::CreateViewCallback& callback) override { |
| 114 new PNGView(app_impl(), image_, callback); |
| 115 return true; |
| 116 } |
| 117 |
| 118 private: |
| 119 skia::RefPtr<SkImage> image_; |
| 120 |
| 121 DISALLOW_COPY_AND_ASSIGN(PNGContentViewProviderApp); |
| 122 }; |
| 123 |
| 124 class PNGContentViewerApp : public mojo::ui::ContentViewerApp { |
| 125 public: |
| 126 PNGContentViewerApp() {} |
| 127 |
| 128 ~PNGContentViewerApp() override {} |
| 129 |
| 130 mojo::ui::ViewProviderApp* LoadContent( |
| 131 const std::string& content_handler_url, |
| 132 mojo::URLResponsePtr response) override { |
| 133 std::string data; |
| 134 mojo::common::BlockingCopyToString(response->body.Pass(), &data); |
| 135 SkBitmap bitmap; |
| 136 if (!::gfx::PNGCodec::Decode( |
| 137 reinterpret_cast<const unsigned char*>(data.data()), data.length(), |
| 138 &bitmap) || |
| 139 bitmap.empty()) { |
| 140 LOG(ERROR) << "Could not decode PNG."; |
| 141 return nullptr; |
| 142 } |
| 143 |
| 144 return new PNGContentViewProviderApp( |
| 145 skia::AdoptRef(SkImage::NewFromBitmap(bitmap))); |
| 146 } |
| 147 |
| 148 private: |
| 149 DISALLOW_COPY_AND_ASSIGN(PNGContentViewerApp); |
| 150 }; |
| 151 |
| 152 } // namespace examples |
| 153 |
| 154 MojoResult MojoMain(MojoHandle application_request) { |
| 155 mojo::ApplicationRunnerChromium runner(new examples::PNGContentViewerApp()); |
| 156 return runner.Run(application_request); |
| 157 } |
OLD | NEW |