mirror of https://github.com/KLayout/klayout.git
WIP: enabling PixelBuffer and BitmapBuffer for RBA::LayoutView
This commit is contained in:
parent
32813b80f2
commit
3c11fe61c3
|
|
@ -80,7 +80,7 @@ public:
|
|||
}
|
||||
|
||||
lay::Color contrast;
|
||||
if (c.green () > 128) {
|
||||
if (c.to_mono ()) {
|
||||
contrast = lay::Color (0, 0, 0);
|
||||
} else {
|
||||
contrast = lay::Color (255, 255, 255);
|
||||
|
|
|
|||
|
|
@ -327,18 +327,26 @@ static void save_as2 (lay::LayoutView *view, unsigned int index, const std::stri
|
|||
view->save_as (index, filename, tl::OutputStream::OM_Auto, options, true, 0);
|
||||
}
|
||||
|
||||
#if defined(HAVE_QTBINDINGS) // @@@
|
||||
#if defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
static QImage get_image_with_options (lay::LayoutView *view, unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, const db::DBox &target_box, bool monochrome)
|
||||
{
|
||||
return view->get_image_with_options (width, height, linewidth, oversampling, resolution, lay::Color (), lay::Color (), lay::Color (), target_box, monochrome);
|
||||
}
|
||||
#endif
|
||||
|
||||
static lay::PixelBuffer get_pixels_with_options (lay::LayoutView *view, unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, const db::DBox &target_box)
|
||||
{
|
||||
return view->get_pixels_with_options (width, height, linewidth, oversampling, resolution, lay::Color (), lay::Color (), lay::Color (), target_box);
|
||||
}
|
||||
|
||||
static lay::BitmapBuffer get_pixels_with_options_mono (lay::LayoutView *view, unsigned int width, unsigned int height, int linewidth, const db::DBox &target_box)
|
||||
{
|
||||
return view->get_pixels_with_options_mono (width, height, linewidth, lay::Color (), lay::Color (), lay::Color (), target_box);
|
||||
}
|
||||
|
||||
static void save_image_with_options (lay::LayoutView *view, const std::string &fn, unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, const db::DBox &target_box, bool monochrome)
|
||||
{
|
||||
#if defined(HAVE_QT) // @@@
|
||||
view->save_image_with_options (fn, width, height, linewidth, oversampling, resolution, lay::Color (), lay::Color (), lay::Color (), target_box, monochrome);
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::vector<std::string>
|
||||
|
|
@ -1128,7 +1136,7 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
"Show the layout in full depth down to the deepest level of hierarchy. "
|
||||
"This method may cause a redraw."
|
||||
) +
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
#if defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
gsi::method ("get_screenshot", &lay::LayoutView::get_screenshot,
|
||||
"@brief Gets a screenshot as a \\QImage\n"
|
||||
"\n"
|
||||
|
|
@ -1157,12 +1165,61 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
"@param monochrome If true, monochrome images will be produced.\n"
|
||||
"\n"
|
||||
"The image contains the current scene (layout, annotations etc.).\n"
|
||||
"The image is written as a PNG file to the given file. "
|
||||
"The image is drawn synchronously with the given width and height. Drawing may take some time. "
|
||||
"Monochrome images don't have background or annotation objects currently.\n"
|
||||
"\n"
|
||||
"This method has been introduced in 0.23.10.\n"
|
||||
) +
|
||||
#endif
|
||||
gsi::method ("get_screenshot_pixels", &lay::LayoutView::get_screenshot_pb,
|
||||
"@brief Gets a screenshot as a \\PixelBuffer\n"
|
||||
"\n"
|
||||
"Getting the image requires the drawing to be complete. Ideally, synchronous mode is switched on "
|
||||
"for the application to guarantee this condition. The image will have the size of the viewport "
|
||||
"showing the current layout."
|
||||
"\n"
|
||||
"This method has been introduced in 0.28.\n"
|
||||
) +
|
||||
gsi::method ("get_pixels", &lay::LayoutView::get_pixels, gsi::arg ("width"), gsi::arg ("height"),
|
||||
"@brief Gets the layout image as a \\PixelBuffer\n"
|
||||
"\n"
|
||||
"@param width The width of the image to render in pixel.\n"
|
||||
"@param height The height of the image to render in pixel.\n"
|
||||
"\n"
|
||||
"The image contains the current scene (layout, annotations etc.).\n"
|
||||
"The image is drawn synchronously with the given width and height. Drawing may take some time. "
|
||||
"\n"
|
||||
"This method has been introduced in 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("get_pixels_with_options", &get_pixels_with_options, gsi::arg ("width"), gsi::arg ("height"), gsi::arg ("linewidth"), gsi::arg ("oversampling"), gsi::arg ("resolution"), gsi::arg ("target"),
|
||||
"@brief Gets the layout image as a \\PixelBuffer (with options)\n"
|
||||
"\n"
|
||||
"@param width The width of the image to render in pixel.\n"
|
||||
"@param height The height of the image to render in pixel.\n"
|
||||
"@param linewidth The width of a line in pixels (usually 1) or 0 for default.\n"
|
||||
"@param oversampling The oversampling factor (1..3) or 0 for default.\n"
|
||||
"@param resolution The resolution (pixel size compared to a screen pixel size, i.e 1/oversampling) or 0 for default.\n"
|
||||
"@param target_box The box to draw or an empty box for default.\n"
|
||||
"\n"
|
||||
"The image contains the current scene (layout, annotations etc.).\n"
|
||||
"The image is drawn synchronously with the given width and height. Drawing may take some time. "
|
||||
"\n"
|
||||
"This method has been introduced in 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("get_pixels_with_options_mono", &get_pixels_with_options_mono, gsi::arg ("width"), gsi::arg ("height"), gsi::arg ("linewidth"), gsi::arg ("target"),
|
||||
"@brief Gets the layout image as a \\PixelBuffer (with options)\n"
|
||||
"\n"
|
||||
"@param width The width of the image to render in pixel.\n"
|
||||
"@param height The height of the image to render in pixel.\n"
|
||||
"@param linewidth The width of a line in pixels (usually 1) or 0 for default.\n"
|
||||
"@param target_box The box to draw or an empty box for default.\n"
|
||||
"\n"
|
||||
"The image contains the current scene (layout, annotations etc.).\n"
|
||||
"The image is drawn synchronously with the given width and height. Drawing may take some time. "
|
||||
"Monochrome images don't have background or annotation objects currently.\n"
|
||||
"\n"
|
||||
"This method has been introduced in 0.28.\n"
|
||||
) +
|
||||
gsi::method ("save_screenshot", &lay::LayoutView::save_screenshot, gsi::arg ("filename"),
|
||||
"@brief Saves a screenshot to the given file\n"
|
||||
"\n"
|
||||
|
|
@ -1184,7 +1241,6 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
"The image is written as a PNG file to the given file. "
|
||||
"The image is drawn synchronously with the given width and height. Drawing may take some time. "
|
||||
) +
|
||||
#endif
|
||||
gsi::method_ext ("save_image_with_options", &save_image_with_options, gsi::arg ("filename"), gsi::arg ("width"), gsi::arg ("height"), gsi::arg ("linewidth"), gsi::arg ("oversampling"), gsi::arg ("resolution"), gsi::arg ("target"), gsi::arg ("monochrome"),
|
||||
"@brief Saves the layout as an image to the given file (with options)\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
#include "gsiDecl.h"
|
||||
#include "layPixelBuffer.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#if defined(HAVE_QT)
|
||||
# include <QBuffer>
|
||||
#endif
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
|
|
|||
|
|
@ -142,6 +142,14 @@ public:
|
|||
return (m_color & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts the color into monochrome "on" value
|
||||
*/
|
||||
bool to_mono () const
|
||||
{
|
||||
return (m_color & 0x8000) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the HSV color components
|
||||
* hue: 0..359
|
||||
|
|
|
|||
|
|
@ -933,12 +933,16 @@ LayoutCanvas::image_with_options (unsigned int width, unsigned int height, int l
|
|||
}
|
||||
|
||||
lay::BitmapBuffer
|
||||
LayoutCanvas::image_with_options_mono (unsigned int width, unsigned int height, int linewidth, bool background, bool foreground, bool active, const db::DBox &target_box)
|
||||
LayoutCanvas::image_with_options_mono (unsigned int width, unsigned int height, int linewidth, lay::Color background_c, lay::Color foreground_c, lay::Color active_c, const db::DBox &target_box)
|
||||
{
|
||||
if (linewidth <= 0) {
|
||||
linewidth = 1;
|
||||
}
|
||||
|
||||
bool background = background_c.is_valid () ? background_c.to_mono () : background_color ().to_mono ();
|
||||
bool foreground = foreground_c.is_valid () ? foreground_c.to_mono () : foreground_color ().to_mono ();
|
||||
bool active = active_c.is_valid () ? active_c.to_mono () : active_color ().to_mono ();
|
||||
|
||||
// provide canvas objects for the layout bitmaps and the foreground/background objects
|
||||
BitmapRedrawThreadCanvas rd_canvas;
|
||||
DetachedViewObjectCanvasMono vo_canvas (background, foreground, active, width, height);
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public:
|
|||
lay::PixelBuffer screenshot ();
|
||||
lay::PixelBuffer image (unsigned int width, unsigned int height);
|
||||
lay::PixelBuffer image_with_options (unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, lay::Color background, lay::Color foreground, lay::Color active_color, const db::DBox &target_box);
|
||||
lay::BitmapBuffer image_with_options_mono (unsigned int width, unsigned int height, int linewidth, bool background, bool foreground, bool active_color, const db::DBox &target_box);
|
||||
lay::BitmapBuffer image_with_options_mono (unsigned int width, unsigned int height, int linewidth, lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box);
|
||||
|
||||
void update_image ();
|
||||
|
||||
|
|
|
|||
|
|
@ -2468,7 +2468,7 @@ LayoutViewBase::init_layer_properties (LayerProperties &p, const LayerProperties
|
|||
p.set_marked (false);
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT) // @@@ add methods without QImage!!!!
|
||||
#if defined(HAVE_QT)
|
||||
QImage
|
||||
LayoutViewBase::get_screenshot ()
|
||||
{
|
||||
|
|
@ -2479,31 +2479,52 @@ LayoutViewBase::get_screenshot ()
|
|||
|
||||
return mp_canvas->screenshot ().to_image_copy ();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
lay::PixelBuffer
|
||||
LayoutViewBase::get_screenshot_pb ()
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save screenshot")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
return mp_canvas->screenshot ();
|
||||
}
|
||||
|
||||
static std::vector<std::pair<std::string, std::string> >
|
||||
png_texts (const lay::LayoutViewBase *view, const db::DBox &box)
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string> > texts;
|
||||
|
||||
// Unfortunately the PNG writer does not allow writing of long strings.
|
||||
// We separate the description into a set of keys:
|
||||
|
||||
for (unsigned int i = 0; i < view->cellviews (); ++i) {
|
||||
if (view->cellview (i).is_valid ()) {
|
||||
std::string name = view->cellview (i)->layout ().cell_name (view->cellview (i).cell_index ());
|
||||
texts.push_back (std::make_pair (std::string ("Cell") + tl::to_string (int (i) + 1), name));
|
||||
}
|
||||
}
|
||||
|
||||
texts.push_back (std::make_pair (std::string ("Rect"), box.to_string ()));
|
||||
|
||||
return texts;
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
LayoutViewBase::save_screenshot (const std::string &fn)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save screenshot")));
|
||||
|
||||
QImageWriter writer (tl::to_qstring (fn), QByteArray ("PNG"));
|
||||
|
||||
// Unfortunately the PNG writer does not allow writing of long strings.
|
||||
// We separate the description into a set of keys:
|
||||
|
||||
for (unsigned int i = 0; i < cellviews (); ++i) {
|
||||
if (cellview (i).is_valid ()) {
|
||||
std::string name = cellview (i)->layout ().cell_name (cellview (i).cell_index ());
|
||||
writer.setText (tl::to_qstring ("Cell" + tl::to_string (int (i) + 1)), tl::to_qstring (name));
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string> > texts = png_texts (this, box ());
|
||||
for (auto i = texts.begin (); i != texts.end (); ++i) {
|
||||
writer.setText (tl::to_qstring (i->first), tl::to_qstring (i->second));
|
||||
}
|
||||
|
||||
db::DBox b (box ());
|
||||
std::string desc;
|
||||
desc += tl::micron_to_string (b.left ()) + "," + tl::micron_to_string (b.bottom ());
|
||||
desc += "/";
|
||||
desc += tl::micron_to_string (b.right ()) + "," + tl::micron_to_string (b.top ());
|
||||
writer.setText (QString::fromUtf8 ("Rect"), tl::to_qstring (desc));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
|
|
@ -2513,54 +2534,104 @@ LayoutViewBase::save_screenshot (const std::string &fn)
|
|||
|
||||
tl::log << "Saved screen shot to " << fn;
|
||||
}
|
||||
#else
|
||||
void
|
||||
LayoutViewBase::save_screenshot (const std::string &fn)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save screenshot")));
|
||||
|
||||
QImage
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
tl::OutputStream stream (fn);
|
||||
// @@@ TODO: add texts
|
||||
// @@@ mp_canvas->screenshot ().write_png (stream, png_texts (this, box ()));
|
||||
mp_canvas->screenshot ().write_png (stream);
|
||||
|
||||
tl::log << "Saved screen shot to " << fn;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
QImage
|
||||
LayoutViewBase::get_image (unsigned int width, unsigned int height)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Get image")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
return mp_canvas->image (width, height).to_image_copy ();
|
||||
}
|
||||
#endif
|
||||
|
||||
QImage
|
||||
lay::PixelBuffer
|
||||
LayoutViewBase::get_pixels (unsigned int width, unsigned int height)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Get image")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
return mp_canvas->image (width, height);
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
QImage
|
||||
LayoutViewBase::get_image_with_options (unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box, bool monochrome)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Get image")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
if (monochrome) {
|
||||
return mp_canvas->image_with_options_mono (width, height, linewidth, background.green () >= 128, foreground.green () >= 128, active.green () >= 128, target_box).to_image_copy ();
|
||||
return mp_canvas->image_with_options_mono (width, height, linewidth, background, foreground, active, target_box).to_image_copy ();
|
||||
} else {
|
||||
return mp_canvas->image_with_options (width, height, linewidth, oversampling, resolution, background, foreground, active, target_box).to_image_copy ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
lay::PixelBuffer
|
||||
LayoutViewBase::get_pixels_with_options (unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Get image")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
return mp_canvas->image_with_options (width, height, linewidth, oversampling, resolution, background, foreground, active, target_box);
|
||||
}
|
||||
|
||||
lay::BitmapBuffer
|
||||
LayoutViewBase::get_pixels_with_options_mono (unsigned int width, unsigned int height, int linewidth,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Get image")));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
return mp_canvas->image_with_options_mono (width, height, linewidth, background, foreground, active, target_box);
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
LayoutViewBase::save_image (const std::string &fn, unsigned int width, unsigned int height)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
|
||||
QImageWriter writer (tl::to_qstring (fn), QByteArray ("PNG"));
|
||||
|
||||
// Unfortunately the PNG writer does not allow writing of long strings.
|
||||
// We separate the description into a set of keys:
|
||||
|
||||
for (unsigned int i = 0; i < cellviews (); ++i) {
|
||||
if (cellview (i).is_valid ()) {
|
||||
std::string name = cellview (i)->layout ().cell_name (cellview (i).cell_index ());
|
||||
writer.setText (tl::to_qstring ("Cell" + tl::to_string (int (i) + 1)), tl::to_qstring (name));
|
||||
}
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
std::vector<std::pair<std::string, std::string> > texts = png_texts (this, vp.box ());
|
||||
for (auto i = texts.begin (); i != texts.end (); ++i) {
|
||||
writer.setText (tl::to_qstring (i->first), tl::to_qstring (i->second));
|
||||
}
|
||||
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
writer.setText (QString::fromUtf8 ("Rect"), tl::to_qstring (vp.box ().to_string ()));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
|
|
@ -2568,36 +2639,48 @@ LayoutViewBase::save_image (const std::string &fn, unsigned int width, unsigned
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("Unable to write screenshot to file: %s (%s)")), fn, tl::to_string (writer.errorString ()));
|
||||
}
|
||||
|
||||
tl::log << "Saved screen shot to " << fn;
|
||||
tl::log << "Saved image to " << fn;
|
||||
}
|
||||
#else
|
||||
void
|
||||
LayoutViewBase::save_image (const std::string &fn, unsigned int width, unsigned int height)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
|
||||
void
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
std::vector<std::pair<std::string, std::string> > texts = png_texts (this, vp.box ());
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
tl::OutputStream stream (fn);
|
||||
mp_canvas->image (width, height).write_png (stream);
|
||||
|
||||
tl::log << "Saved image to " << fn;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
LayoutViewBase::save_image_with_options (const std::string &fn,
|
||||
unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box, bool monochrome)
|
||||
unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box, bool monochrome)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
|
||||
QImageWriter writer (tl::to_qstring (fn), QByteArray ("PNG"));
|
||||
|
||||
// Unfortunately the PNG writer does not allow writing of long strings.
|
||||
// We separate the description into a set of keys:
|
||||
|
||||
for (unsigned int i = 0; i < cellviews (); ++i) {
|
||||
if (cellview (i).is_valid ()) {
|
||||
std::string name = cellview (i)->layout ().cell_name (cellview (i).cell_index ());
|
||||
writer.setText (tl::to_qstring ("Cell" + tl::to_string (int (i) + 1)), tl::to_qstring (name));
|
||||
}
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
std::vector<std::pair<std::string, std::string> > texts = png_texts (this, vp.box ());
|
||||
for (auto i = texts.begin (); i != texts.end (); ++i) {
|
||||
writer.setText (tl::to_qstring (i->first), tl::to_qstring (i->second));
|
||||
}
|
||||
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
writer.setText (QString::fromUtf8 ("Rect"), tl::to_qstring (vp.box ().to_string ()));
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
if (monochrome) {
|
||||
if (! writer.write (mp_canvas->image_with_options_mono (width, height, linewidth, background.green () >= 128, foreground.green () >= 128, active.green () >= 128, target_box).to_image ())) {
|
||||
if (! writer.write (mp_canvas->image_with_options_mono (width, height, linewidth, background.to_mono (), foreground.to_mono (), active.to_mono (), target_box).to_image ())) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Unable to write screenshot to file: %s (%s)")), fn, tl::to_string (writer.errorString ()));
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2606,7 +2689,30 @@ LayoutViewBase::save_image_with_options (const std::string &fn,
|
|||
}
|
||||
}
|
||||
|
||||
tl::log << "Saved screen shot to " << fn;
|
||||
tl::log << "Saved image to " << fn;
|
||||
}
|
||||
#else
|
||||
void
|
||||
LayoutViewBase::save_image_with_options (const std::string &fn,
|
||||
unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution,
|
||||
lay::Color background, lay::Color foreground, lay::Color active, const db::DBox &target_box, bool monochrome)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Save image")));
|
||||
|
||||
lay::Viewport vp (width, height, mp_canvas->viewport ().target_box ());
|
||||
std::vector<std::pair<std::string, std::string> > texts = png_texts (this, vp.box ());
|
||||
|
||||
// Execute all deferred methods - ensure there are no pending tasks
|
||||
tl::DeferredMethodScheduler::execute ();
|
||||
|
||||
tl::OutputStream stream (fn);
|
||||
if (monochrome) {
|
||||
mp_canvas->image_with_options_mono (width, height, linewidth, background.to_mono (), foreground.to_mono (), active.to_mono (), target_box).write_png (stream);
|
||||
} else {
|
||||
mp_canvas->image_with_options (width, height, linewidth, oversampling, resolution, background, foreground, active, target_box).write_png (stream);
|
||||
}
|
||||
|
||||
tl::log << "Saved image to " << fn;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3591,7 +3697,7 @@ LayoutViewBase::do_prop_changed ()
|
|||
void
|
||||
LayoutViewBase::set_view_ops ()
|
||||
{
|
||||
bool bright_background = (mp_canvas->background_color ().green () > 128);
|
||||
bool bright_background = (mp_canvas->background_color ().to_mono ());
|
||||
int brightness_for_context = ((bright_background ? m_ctx_dimming : -m_ctx_dimming) * 256) / 100;
|
||||
int brightness_for_child_context = ((bright_background ? m_child_ctx_dimming : -m_child_ctx_dimming) * 256) / 100;
|
||||
|
||||
|
|
@ -4185,7 +4291,7 @@ LayoutViewBase::background_color (lay::Color c)
|
|||
}
|
||||
|
||||
lay::Color contrast;
|
||||
if (c.green () > 128) {
|
||||
if (c.to_mono ()) {
|
||||
contrast = lay::Color (0, 0, 0);
|
||||
} else {
|
||||
contrast = lay::Color (255, 255, 255);
|
||||
|
|
|
|||
|
|
@ -798,16 +798,22 @@ public:
|
|||
*/
|
||||
void load_layer_props (const std::string &fn, int cv_index, bool add_default);
|
||||
|
||||
#if defined(HAVE_QT) // @@@
|
||||
/**
|
||||
* @brief Save the screen content to a file
|
||||
*/
|
||||
void save_screenshot (const std::string &fn);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
/**
|
||||
* @brief Get the screen content as a QImage object
|
||||
*/
|
||||
QImage get_screenshot ();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Gets the screen content as a lay::PixelBuffer object
|
||||
*/
|
||||
lay::PixelBuffer get_screenshot_pb ();
|
||||
|
||||
/**
|
||||
* @brief Save an image file with the given width and height
|
||||
|
|
@ -831,11 +837,19 @@ public:
|
|||
*/
|
||||
void save_image_with_options (const std::string &fn, unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, Color background, Color foreground, Color active_color, const db::DBox &target_box, bool monochrome);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
/**
|
||||
* @brief Get the screen content as a QImage object with the given width and height
|
||||
*/
|
||||
QImage get_image (unsigned int width, unsigned int height);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Gets the screen content as a lay::PixelBuffer object
|
||||
*/
|
||||
lay::PixelBuffer get_pixels (unsigned int width, unsigned int height);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
/**
|
||||
* @brief Get the screen content as a QImage object with the given width and height
|
||||
*
|
||||
|
|
@ -853,6 +867,38 @@ public:
|
|||
QImage get_image_with_options (unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, lay::Color background, lay::Color foreground, lay::Color active_color, const db::DBox &target_box, bool monochrome);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the screen content as a lay::PixelBuffer object with the given width and height
|
||||
*
|
||||
* @param width The width of the image in pixels
|
||||
* @param height The height of the image
|
||||
* @param linewidth The width of a line in pixels (usually 1) or 0 for default
|
||||
* @param oversampling The oversampling factor (1..3) or 0 for default
|
||||
* @param resolution The resolution (pixel size compared to a screen pixel size, i.e 1/oversampling) or 0 for default
|
||||
* @param background The background color or lay::Color() for default
|
||||
* @param foreground The foreground color or lay::Color() for default
|
||||
* @param active The active color or lay::Color() for default
|
||||
* @param target_box The box to draw or db::DBox() for default
|
||||
*/
|
||||
lay::PixelBuffer get_pixels_with_options (unsigned int width, unsigned int height, int linewidth, int oversampling, double resolution, lay::Color background, lay::Color foreground, lay::Color active_color, const db::DBox &target_box);
|
||||
|
||||
/**
|
||||
* @brief Get the screen content as a monochrome lay::BitmapBuffer object with the given options
|
||||
*
|
||||
* @param width The width of the image in pixels
|
||||
* @param height The height of the image
|
||||
* @param linewidth The width of a line in pixels (usually 1) or 0 for default
|
||||
* @param oversampling The oversampling factor (1..3) or 0 for default
|
||||
* @param resolution The resolution (pixel size compared to a screen pixel size, i.e 1/oversampling) or 0 for default
|
||||
* @param background The background color or lay::Color() for default
|
||||
* @param foreground The foreground color or lay::Color() for default
|
||||
* @param active The active color or lay::Color() for default
|
||||
* @param target_box The box to draw or db::DBox() for default
|
||||
*
|
||||
* The colors will are converted to "on" pixels with a green channel value >= 50%.
|
||||
*/
|
||||
lay::BitmapBuffer get_pixels_with_options_mono (unsigned int width, unsigned int height, int linewidth, lay::Color background, lay::Color foreground, lay::Color active_color, const db::DBox &target_box);
|
||||
|
||||
/**
|
||||
* @brief Hierarchy level selection setter
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1099,7 +1099,7 @@ lay::Color
|
|||
NetlistBrowserPage::make_valid_color (const lay::Color &color)
|
||||
{
|
||||
if (! color.is_valid () && mp_view) {
|
||||
return mp_view->background_color ().green () < 128 ? lay::Color (255, 255, 255) : lay::Color (0, 0, 0);
|
||||
return mp_view->background_color ().to_mono () ? lay::Color (0, 0, 0) : lay::Color (255, 255, 255);
|
||||
} else {
|
||||
return color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,8 +138,6 @@ DEFINES += MAKE_LAYBASIC_LIBRARY
|
|||
layNetlistBrowserPage.cc \
|
||||
layNetlistBrowserTreeModel.cc \
|
||||
layNetlistCrossReferenceModel.cc \
|
||||
layPixelBuffer.cc \
|
||||
layPixelBufferPainter.cc \
|
||||
layPluginConfigPage.cc \
|
||||
layProperties.cc \
|
||||
layPropertiesDialog.cc \
|
||||
|
|
@ -213,8 +211,6 @@ DEFINES += MAKE_LAYBASIC_LIBRARY
|
|||
layNetlistBrowserPage.h \
|
||||
layNetlistBrowserTreeModel.h \
|
||||
layNetlistCrossReferenceModel.h \
|
||||
layPixelBuffer.h \
|
||||
layPixelBufferPainter.h \
|
||||
layPluginConfigPage.h \
|
||||
layProperties.h \
|
||||
layPropertiesDialog.h \
|
||||
|
|
@ -267,6 +263,8 @@ SOURCES += \
|
|||
layNetColorizer.cc \
|
||||
layObjectInstPath.cc \
|
||||
layParsedLayerSource.cc \
|
||||
layPixelBuffer.cc \
|
||||
layPixelBufferPainter.cc \
|
||||
layPlugin.cc \
|
||||
layRedrawLayerInfo.cc \
|
||||
layRedrawThread.cc \
|
||||
|
|
@ -308,6 +306,8 @@ HEADERS += \
|
|||
layNetColorizer.h \
|
||||
layObjectInstPath.h \
|
||||
layParsedLayerSource.h \
|
||||
layPixelBuffer.h \
|
||||
layPixelBufferPainter.h \
|
||||
layPlugin.h \
|
||||
layRedrawLayerInfo.h \
|
||||
layRedrawThread.h \
|
||||
|
|
|
|||
|
|
@ -1640,7 +1640,7 @@ NetTracerDialog::update_highlights ()
|
|||
mp_markers.back ()->set_line_width (original->width (true));
|
||||
mp_markers.back ()->set_vertex_size (1);
|
||||
mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
|
||||
if (view ()->background_color ().green () < 128) {
|
||||
if (! view ()->background_color ().to_mono ()) {
|
||||
mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1090,10 +1090,10 @@ D25ViewWidget::paintGL ()
|
|||
glViewport (0, 0, width () * retina_scale, height () * retina_scale);
|
||||
|
||||
lay::Color c = mp_view->background_color ();
|
||||
float foreground_rgb = (c.green () > 128 ? 0.0f : 1.0f);
|
||||
float ambient = (c.green () > 128 ? 0.8f : 0.25f);
|
||||
float mist_factor = (c.green () > 128 ? 0.2f : 0.4f);
|
||||
float mist_add = (c.green () > 128 ? 0.8f : 0.2f);
|
||||
float foreground_rgb = (c.to_mono () ? 0.0f : 1.0f);
|
||||
float ambient = (c.to_mono () ? 0.8f : 0.25f);
|
||||
float mist_factor = (c.to_mono () ? 0.2f : 0.4f);
|
||||
float mist_add = (c.to_mono () ? 0.8f : 0.2f);
|
||||
glClearColor (float (c.red ()) / 255.0f, float (c.green ()) / 255.0f, float (c.blue ()) / 255.0f, 1.0);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue