string_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++; -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2019, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include "string_display.h"
37 
38 #include <string>
39 
40 #include <boost/algorithm/string.hpp>
41 #include <boost/format.hpp>
42 #include <jsk_topic_tools/log_utils.h>
43 #include <OGRE/OgreHardwarePixelBuffer.h>
44 #include <OGRE/OgreMaterialManager.h>
45 #include <OGRE/OgreTexture.h>
47 #include <QFontDatabase>
48 #include <QPainter>
49 #include <QStaticText>
50 #include <QTextDocument>
52 
53 namespace jsk_rviz_plugins
54 {
55  StringDisplay::StringDisplay() : Display(),
56  texture_width_(0), texture_height_(0),
57  text_size_(14),
58  line_width_(2),
59  text_(""), font_(""),
60  bg_color_(0, 0, 0, 0),
61  fg_color_(255, 255, 255, 255.0),
62  require_update_texture_(false)
63  {
64  update_topic_property_ = new rviz::RosTopicProperty(
65  "Topic", "",
66  ros::message_traits::datatype<std_msgs::String>(),
67  "std_msgs::String topic to subscribe to.",
68  this, SLOT(updateTopic()));
69  overtake_position_properties_property_ = new rviz::BoolProperty(
70  "Overtake Position Properties", false,
71  "overtake position properties specified by message such as left, top and font",
72  this, SLOT(updateOvertakePositionProperties()));
73  overtake_color_properties_property_ = new rviz::BoolProperty(
74  "Overtake Color Properties", false,
75  "overtake color properties specified by message such as foreground/background color and alpha",
76  this, SLOT(updateOvertakeColorProperties()));
77  align_bottom_property_ = new rviz::BoolProperty(
78  "Align Bottom", false,
79  "align text with the bottom of the overlay region",
80  this, SLOT(updateAlignBottom()));
81  top_property_ = new rviz::IntProperty(
82  "top", 0,
83  "top position",
84  this, SLOT(updateTop()));
85  top_property_->setMin(0);
86  left_property_ = new rviz::IntProperty(
87  "left", 0,
88  "left position",
89  this, SLOT(updateLeft()));
90  left_property_->setMin(0);
91  width_property_ = new rviz::IntProperty(
92  "width", 128,
93  "width position",
94  this, SLOT(updateWidth()));
95  width_property_->setMin(0);
96  height_property_ = new rviz::IntProperty(
97  "height", 128,
98  "height position",
99  this, SLOT(updateHeight()));
100  height_property_->setMin(0);
101  text_size_property_ = new rviz::IntProperty(
102  "text size", 12,
103  "text size",
104  this, SLOT(updateTextSize()));
105  text_size_property_->setMin(0);
106  line_width_property_ = new rviz::IntProperty(
107  "line width", 2,
108  "line width",
109  this, SLOT(updateLineWidth()));
110  line_width_property_->setMin(0);
111  fg_color_property_ = new rviz::ColorProperty(
112  "Foreground Color", QColor(25, 255, 240),
113  "Foreground Color",
114  this, SLOT(updateFGColor()));
115  fg_alpha_property_ = new rviz::FloatProperty(
116  "Foreground Alpha", 0.8, "Foreground Alpha",
117  this, SLOT(updateFGAlpha()));
118  fg_alpha_property_->setMin(0.0);
119  fg_alpha_property_->setMax(1.0);
120  bg_color_property_ = new rviz::ColorProperty(
121  "Background Color", QColor(0, 0, 0),
122  "Background Color",
123  this, SLOT(updateBGColor()));
124  bg_alpha_property_ = new rviz::FloatProperty(
125  "Background Alpha", 0.8, "Background Alpha",
126  this, SLOT(updateBGAlpha()));
127  bg_alpha_property_->setMin(0.0);
128  bg_alpha_property_->setMax(1.0);
129 
130  QFontDatabase database;
131  font_families_ = database.families();
132  font_property_ = new rviz::EnumProperty(
133  "font", "DejaVu Sans Mono",
134  "font", this,
135  SLOT(updateFont()));
136  for (size_t i = 0; i < font_families_.size(); i++)
137  {
138  font_property_->addOption(font_families_[i], static_cast<int>(i));
139  }
140  }
141 
143  {
144  onDisable();
145  //delete overlay_;
146  delete update_topic_property_;
149  delete align_bottom_property_;
150  delete top_property_;
151  delete left_property_;
152  delete width_property_;
153  delete height_property_;
154  delete text_size_property_;
155  delete line_width_property_;
156  delete bg_color_property_;
157  delete bg_alpha_property_;
158  delete fg_color_property_;
159  delete fg_alpha_property_;
160  delete font_property_;
161  }
162 
164  {
165  if (overlay_)
166  {
167  overlay_->show();
168  }
169  subscribe();
170  }
171 
173  {
174  if (overlay_)
175  {
176  overlay_->hide();
177  }
178  unsubscribe();
179  }
180 
182  {
183  sub_.shutdown();
184  }
185 
187  {
188  std::string topic_name = update_topic_property_->getTopicStd();
189  if (topic_name.length() > 0 && topic_name != "/")
190  {
191  sub_ = ros::NodeHandle().subscribe(topic_name, 1, &StringDisplay::processMessage, this);
192  }
193  }
194 
196  {
197  unsubscribe();
198  subscribe();
199  }
200 
201  // only the first time
203  {
205  updateTopic();
209  updateTop();
210  updateLeft();
211  updateWidth();
212  updateHeight();
214  updateFGColor();
215  updateFGAlpha();
216  updateBGColor();
217  updateBGAlpha();
219  updateLineWidth();
221  }
222 
223  void StringDisplay::update(float wall_dt, float ros_dt)
224  {
226  {
227  return;
228  }
229  if (!isEnabled())
230  {
231  return;
232  }
233  if (!overlay_)
234  {
235  return;
236  }
237  overlay_->setPosition(left_, top_);
238  overlay_->updateTextureSize(texture_width_, texture_height_);
239  {
240  ScopedPixelBuffer buffer = overlay_->getBuffer();
241  QImage Hud = buffer.getQImage(*overlay_, bg_color_);
242  QPainter painter( &Hud );
243  painter.setRenderHint(QPainter::Antialiasing, true);
244  painter.setPen(QPen(fg_color_, line_width_ || 1, Qt::SolidLine));
245  uint16_t w = overlay_->getTextureWidth();
246  uint16_t h = overlay_->getTextureHeight();
247 
248  // font
249  if (text_size_ != 0)
250  {
251  QFont font(font_.length() > 0 ? font_.c_str(): "Liberation Sans");
252  font.setPointSize(text_size_);
253  font.setBold(true);
254  painter.setFont(font);
255  }
256  if (text_.length() > 0)
257  {
258  std::string color_wrapped_text
259  = (boost::format("<span style=\"color: rgba(%2%, %3%, %4%, %5%)\">%1%</span>")
260  % text_ % fg_color_.red() % fg_color_.green() % fg_color_.blue() %
261  fg_color_.alpha()).str();
262  QStaticText static_text(
263  boost::algorithm::replace_all_copy(color_wrapped_text, "\n", "<br >").c_str());
264  static_text.setTextWidth(w);
265  if (!align_bottom_)
266  {
267  painter.drawStaticText(0, 0, static_text);
268  }
269  else
270  {
271  QStaticText only_wrapped_text(color_wrapped_text.c_str());
272  QFontMetrics fm(painter.fontMetrics());
273  QRect text_rect = fm.boundingRect(0, 0, w, h,
274  Qt::TextWordWrap | Qt::AlignLeft | Qt::AlignTop,
275  only_wrapped_text.text().remove(QRegExp("<[^>]*>")));
276  painter.drawStaticText(0, h - text_rect.height(), static_text);
277  }
278  }
279  painter.end();
280  }
281  overlay_->setDimensions(overlay_->getTextureWidth(), overlay_->getTextureHeight());
282  require_update_texture_ = false;
283  }
284 
286  (const std_msgs::String::ConstPtr& msg)
287  {
288  if (!isEnabled())
289  {
290  return;
291  }
292  if (!overlay_)
293  {
294  static int count = 0;
296  ss << "StringDisplayObject" << count++;
297  overlay_.reset(new OverlayObject(ss.str()));
298  overlay_->show();
299  }
300  if (overlay_)
301  {
302  overlay_->show();
303  }
304 
305  // store message for update method
306  text_ = msg->data;
308  }
309 
311  {
314  {
315  updateTop();
316  updateLeft();
317  updateWidth();
319  updateTextSize();
321  }
325  {
326  top_property_->show();
327  left_property_->show();
331  }
332  else
333  {
334  top_property_->hide();
335  left_property_->hide();
339  }
340  }
341 
343  {
346  {
347  // read all the parameters from properties
348  updateFGColor();
349  updateFGAlpha();
350  updateBGColor();
351  updateBGAlpha();
352  updateFont();
353  updateLineWidth();
355  }
358  {
364  font_property_->show();
365  }
366  else
367  {
373  font_property_->hide();
374  }
375  }
376 
378  {
380  {
382  }
384  }
385 
387  {
390  {
392  }
393  }
394 
396  {
399  {
401  }
402  }
403 
405  {
408  {
410  }
411  }
412 
414  {
417  {
419  }
420  }
421 
423  {
426  {
428  }
429  }
430 
432  {
433  QColor c = bg_color_property_->getColor();
434  bg_color_.setRed(c.red());
435  bg_color_.setGreen(c.green());
436  bg_color_.setBlue(c.blue());
438  {
440  }
441  }
442 
444  {
445  bg_color_.setAlpha(bg_alpha_property_->getFloat() * 255.0);
447  {
449  }
450  }
451 
453  {
455  fg_color_.setRed(c.red());
456  fg_color_.setGreen(c.green());
457  fg_color_.setBlue(c.blue());
459  {
461  }
462  }
463 
465  {
466  fg_color_.setAlpha(fg_alpha_property_->getFloat() * 255.0);
468  {
470  }
471  }
472 
474  {
475  int font_index = font_property_->getOptionInt();
476  if (font_index < font_families_.size())
477  {
478  font_ = font_families_[font_index].toStdString();
479  }
480  else
481  {
482  ROS_FATAL("Unexpected error at selecting font index %d.", font_index);
483  return;
484  }
486  {
488  }
489  }
490 
492  {
495  {
497  }
498  }
499 
500  bool StringDisplay::isInRegion(int x, int y)
501  {
502  return (top_ < y && top_ + texture_height_ > y &&
503  left_ < x && left_ + texture_width_ > x);
504  }
505 
506  void StringDisplay::movePosition(int x, int y)
507  {
508  top_ = y;
509  left_ = x;
510  }
511 
512  void StringDisplay::setPosition(int x, int y)
513  {
516  }
517 
518 } // namespace jsk_rviz_plugins
519 
jsk_rviz_plugins::StringDisplay::left_
int left_
Definition: string_display.h:148
rviz::BoolProperty::getBool
virtual bool getBool() const
rviz::EnumProperty::getOptionInt
virtual int getOptionInt()
jsk_rviz_plugins::StringDisplay::overlay_
OverlayObject::Ptr overlay_
Definition: string_display.h:133
rviz::Display::isEnabled
bool isEnabled() const
jsk_rviz_plugins::StringDisplay::line_width_property_
rviz::IntProperty * line_width_property_
Definition: string_display.h:170
jsk_rviz_plugins::StringDisplay::updateOvertakeColorProperties
void updateOvertakeColorProperties()
Definition: string_display.cpp:374
jsk_rviz_plugins::StringDisplay::StringDisplay
StringDisplay()
Definition: string_display.cpp:87
jsk_rviz_plugins::StringDisplay::isInRegion
virtual bool isInRegion(int x, int y)
Definition: string_display.cpp:532
rviz::RosTopicProperty
rviz::ColorProperty::getColor
virtual QColor getColor() const
jsk_rviz_plugins::StringDisplay::updateBGAlpha
void updateBGAlpha()
Definition: string_display.cpp:475
jsk_rviz_plugins::StringDisplay::top_
int top_
Definition: string_display.h:149
jsk_rviz_plugins::StringDisplay::updateOvertakePositionProperties
void updateOvertakePositionProperties()
Definition: string_display.cpp:342
msg
msg
jsk_rviz_plugins::StringDisplay::overtake_color_properties_
bool overtake_color_properties_
Definition: string_display.h:138
jsk_rviz_plugins::StringDisplay::texture_width_
int texture_width_
Definition: string_display.h:135
jsk_rviz_plugins::StringDisplay::text_size_
int text_size_
Definition: string_display.h:143
jsk_rviz_plugins::StringDisplay::processMessage
void processMessage(const std_msgs::String::ConstPtr &msg)
Definition: string_display.cpp:318
jsk_rviz_plugins::StringDisplay::overtake_position_properties_
bool overtake_position_properties_
Definition: string_display.h:139
jsk_rviz_plugins::ScopedPixelBuffer
Definition: overlay_utils.h:100
jsk_rviz_plugins::StringDisplay::updateHeight
void updateHeight()
Definition: string_display.cpp:445
rviz::Property::show
void show()
bounding_box_sample.w
w
Definition: bounding_box_sample.py:29
jsk_rviz_plugins::StringDisplay::updateTopic
void updateTopic()
Definition: string_display.cpp:227
jsk_rviz_plugins::StringDisplay::left_property_
rviz::IntProperty * left_property_
Definition: string_display.h:166
jsk_rviz_plugins::StringDisplay::update
virtual void update(float wall_dt, float ros_dt)
Definition: string_display.cpp:255
rviz::BoolProperty
jsk_rviz_plugins::StringDisplay::movePosition
virtual void movePosition(int x, int y)
Definition: string_display.cpp:538
jsk_rviz_plugins::StringDisplay::~StringDisplay
virtual ~StringDisplay()
Definition: string_display.cpp:174
jsk_rviz_plugins::StringDisplay::font_
std::string font_
Definition: string_display.h:147
str
string str
jsk_rviz_plugins::StringDisplay::require_update_texture_
bool require_update_texture_
Definition: string_display.h:160
string_display.h
ros::Subscriber::shutdown
void shutdown()
jsk_rviz_plugins::StringDisplay::updateLeft
void updateLeft()
Definition: string_display.cpp:427
rviz::UniformStringStream
jsk_rviz_plugins::StringDisplay::align_bottom_property_
rviz::BoolProperty * align_bottom_property_
Definition: string_display.h:164
jsk_rviz_plugins::StringDisplay::updateAlignBottom
void updateAlignBottom()
Definition: string_display.cpp:409
jsk_rviz_plugins::StringDisplay::setPosition
virtual void setPosition(int x, int y)
Definition: string_display.cpp:544
jsk_rviz_plugins::StringDisplay::text_size_property_
rviz::IntProperty * text_size_property_
Definition: string_display.h:169
jsk_rviz_plugins::StringDisplay::updateTextSize
void updateTextSize()
Definition: string_display.cpp:454
rviz::ColorProperty
jsk_rviz_plugins::StringDisplay::texture_height_
int texture_height_
Definition: string_display.h:136
rviz::Display
rviz::EnumProperty
rviz::FloatProperty
rviz::IntProperty::setValue
bool setValue(const QVariant &new_value) override
class_list_macros.h
rviz::Property::hide
void hide()
jsk_rviz_plugins::StringDisplay::fg_color_
QColor fg_color_
Definition: string_display.h:142
jsk_rviz_plugins::StringDisplay::unsubscribe
virtual void unsubscribe()
Definition: string_display.cpp:213
jsk_rviz_plugins::StringDisplay::font_families_
QStringList font_families_
Definition: string_display.h:146
jsk_rviz_plugins::StringDisplay::top_property_
rviz::IntProperty * top_property_
Definition: string_display.h:165
jsk_rviz_plugins::StringDisplay::updateFGAlpha
void updateFGAlpha()
Definition: string_display.cpp:496
overlay_sample.font
font
Definition: overlay_sample.py:30
rviz::FloatProperty::getFloat
virtual float getFloat() const
jsk_rviz_plugins::StringDisplay::updateFGColor
void updateFGColor()
Definition: string_display.cpp:484
bounding_box_sample.x
x
Definition: bounding_box_sample.py:26
jsk_rviz_plugins::StringDisplay::sub_
ros::Subscriber sub_
Definition: string_display.h:151
jsk_rviz_plugins::StringDisplay::updateLineWidth
void updateLineWidth()
Definition: string_display.cpp:523
jsk_rviz_plugins::StringDisplay::onDisable
virtual void onDisable()
Definition: string_display.cpp:204
jsk_rviz_plugins::StringDisplay
Definition: string_display.h:88
jsk_rviz_plugins::StringDisplay::fg_alpha_property_
rviz::FloatProperty * fg_alpha_property_
Definition: string_display.h:174
bounding_box_sample.y
y
Definition: bounding_box_sample.py:27
jsk_rviz_plugins::StringDisplay::updateFont
void updateFont()
Definition: string_display.cpp:505
rviz::RosTopicProperty::getTopicStd
std::string getTopicStd() const
jsk_rviz_plugins::StringDisplay::fg_color_property_
rviz::ColorProperty * fg_color_property_
Definition: string_display.h:173
ROS_FATAL
#define ROS_FATAL(...)
jsk_rviz_plugins::StringDisplay::onInitialize
virtual void onInitialize()
Definition: string_display.cpp:234
jsk_rviz_plugins::StringDisplay::line_width_
int line_width_
Definition: string_display.h:144
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::PictogramArrayDisplay, rviz::Display)
jsk_rviz_plugins::StringDisplay::bg_color_
QColor bg_color_
Definition: string_display.h:141
jsk_rviz_plugins::StringDisplay::align_bottom_
bool align_bottom_
Definition: string_display.h:140
jsk_rviz_plugins::StringDisplay::overtake_color_properties_property_
rviz::BoolProperty * overtake_color_properties_property_
Definition: string_display.h:163
jsk_rviz_plugins::StringDisplay::bg_color_property_
rviz::ColorProperty * bg_color_property_
Definition: string_display.h:171
jsk_rviz_plugins::StringDisplay::update_topic_property_
rviz::RosTopicProperty * update_topic_property_
Definition: string_display.h:161
jsk_rviz_plugins::StringDisplay::onEnable
virtual void onEnable()
Definition: string_display.cpp:195
jsk_rviz_plugins::StringDisplay::text_
std::string text_
Definition: string_display.h:145
jsk_rviz_plugins::StringDisplay::updateTop
void updateTop()
Definition: string_display.cpp:418
point_test.count
int count
Definition: point_test.py:15
jsk_rviz_plugins::StringDisplay::subscribe
virtual void subscribe()
Definition: string_display.cpp:218
jsk_rviz_plugins::ScopedPixelBuffer::getQImage
virtual QImage getQImage(unsigned int width, unsigned int height)
Definition: overlay_utils.cpp:89
jsk_rviz_plugins::StringDisplay::bg_alpha_property_
rviz::FloatProperty * bg_alpha_property_
Definition: string_display.h:172
rviz::IntProperty::getInt
virtual int getInt() const
jsk_rviz_plugins::StringDisplay::overtake_position_properties_property_
rviz::BoolProperty * overtake_position_properties_property_
Definition: string_display.h:162
jsk_rviz_plugins::StringDisplay::updateWidth
void updateWidth()
Definition: string_display.cpp:436
jsk_rviz_plugins::StringDisplay::font_property_
rviz::EnumProperty * font_property_
Definition: string_display.h:175
jsk_rviz_plugins::StringDisplay::updateBGColor
void updateBGColor()
Definition: string_display.cpp:463
jsk_rviz_plugins::StringDisplay::width_property_
rviz::IntProperty * width_property_
Definition: string_display.h:167
jsk_rviz_plugins
Definition: __init__.py:1
rviz::MessageFilterDisplay< jsk_recognition_msgs::SimpleOccupancyGridArray >::updateTopic
void updateTopic() override
ros::NodeHandle
uniform_string_stream.h
rviz::IntProperty
jsk_rviz_plugins::StringDisplay::height_property_
rviz::IntProperty * height_property_
Definition: string_display.h:168


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Fri Aug 2 2024 08:50:15