2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Helge Norberg, helge.norberg@svt.se
22 #include "../../stdafx.h"
24 #include "freehand_producer.h"
26 #include <core/producer/frame_producer.h>
27 #include <core/frame/frame.h>
28 #include <core/frame/draw_frame.h>
29 #include <core/frame/frame_factory.h>
30 #include <core/frame/pixel_format.h>
31 #include <core/monitor/monitor.h>
33 namespace caspar { namespace core {
35 std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> empty_drawing(
36 int width, int height)
38 std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> result;
40 result.resize(width * height * 4);
41 std::fill(result.begin(), result.end(), 0);
43 return std::move(result);
46 class freehand_producer : public frame_producer_base
48 std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> drawing_;
49 spl::shared_ptr<core::frame_factory> frame_factory_;
50 constraints constraints_;
55 explicit freehand_producer(
56 const spl::shared_ptr<core::frame_factory>& frame_factory,
59 : drawing_(std::move(empty_drawing(width, height)))
60 , frame_factory_(frame_factory)
61 , constraints_(width, height)
62 , frame_(create_frame())
63 , button_pressed_(false)
66 CASPAR_LOG(info) << print() << L" Initialized";
69 draw_frame create_frame()
71 pixel_format_desc desc(pixel_format_def::bgra);
72 desc.planes.push_back(pixel_format_desc::plane(
73 static_cast<int>(constraints_.width.get()),
74 static_cast<int>(constraints_.height.get()),
76 auto frame = frame_factory_->create_frame(this, desc);
78 std::memcpy(frame.image_data().begin(), drawing_.data(), drawing_.size());
80 return draw_frame(std::move(frame));
85 void on_interaction(const interaction_event::ptr& event) override
87 if (is<mouse_move_event>(event) && button_pressed_)
89 auto mouse_move = as<mouse_move_event>(event);
91 int x = static_cast<int>(mouse_move->x * constraints_.width.get());
92 int y = static_cast<int>(mouse_move->y * constraints_.height.get());
94 if (x >= constraints_.width.get()
95 || y >= constraints_.height.get()
100 uint8_t* b = drawing_.data() + (y * static_cast<int>(constraints_.width.get()) + x) * 4;
112 else if (is<mouse_button_event>(event))
114 auto button_event = as<mouse_button_event>(event);
116 if (button_event->button == 0)
117 button_pressed_ = button_event->pressed;
118 else if (button_event->button == 1 && button_event->pressed)
120 std::memset(drawing_.data(), 0, drawing_.size());
126 bool collides(double x, double y) const override
131 draw_frame receive_impl() override
135 frame_ = create_frame();
142 constraints& pixel_constraints() override
147 std::wstring print() const override
149 return L"freehand[]";
152 std::wstring name() const override
157 boost::property_tree::wptree info() const override
159 boost::property_tree::wptree info;
160 info.add(L"type", L"freehand");
164 monitor::source& monitor_output()
166 static monitor::subject monitor_subject(""); return monitor_subject;
170 spl::shared_ptr<frame_producer> create_freehand_producer(const spl::shared_ptr<frame_factory>& frame_factory, const std::vector<std::wstring>& params)
172 if(params.size() < 3 || !boost::iequals(params.at(0), L"[FREEHAND]"))
173 return core::frame_producer::empty();
175 int width = boost::lexical_cast<int>(params.at(1));
176 int height = boost::lexical_cast<int>(params.at(2));
178 return spl::make_shared<freehand_producer>(frame_factory, width, height);