From 00e78eb76c9a0085015a6c86b9db9068c927681a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 1 Oct 2022 16:24:05 +0200 Subject: [PATCH] Highres mode config option - display utilizes full pixel density --- src/ant/ant/antService.cc | 17 ++++---- src/laybasic/laybasic/layLayoutCanvas.cc | 41 +++++++++++++++----- src/laybasic/laybasic/layLayoutCanvas.h | 9 ++++- src/laybasic/laybasic/layLayoutViewBase.cc | 7 ++++ src/laybasic/laybasic/layLayoutViewConfig.cc | 1 + src/laybasic/laybasic/layViewObject.h | 2 +- src/laybasic/laybasic/laybasicConfig.h | 1 + src/layui/layui/LayoutViewConfigPage7.ui | 20 ++++++++-- src/layui/layui/layLayoutViewConfigPages.cc | 5 +++ 9 files changed, 81 insertions(+), 22 deletions(-) diff --git a/src/ant/ant/antService.cc b/src/ant/ant/antService.cc index cb48588f9..49c3bca93 100644 --- a/src/ant/ant/antService.cc +++ b/src/ant/ant/antService.cc @@ -32,6 +32,7 @@ #include "laybasicConfig.h" #include "layConverters.h" #include "layLayoutCanvas.h" +#include "layFixedFont.h" #if defined(HAVE_QT) # include "layProperties.h" #endif @@ -45,6 +46,8 @@ namespace ant { double angle_ruler_radius_factor = 0.9; +double ruler_tick_length = 8.0; +double ruler_arrow_width = 8.0; // ------------------------------------------------------------- // Convert buttons to an angle constraint @@ -132,8 +135,8 @@ draw_ruler (const db::DPoint &q1, bool last_segment, bool no_line = false) { - double arrow_width = 8 / renderer.resolution (); - double arrow_length = 12 / renderer.resolution (); + double arrow_width = ruler_arrow_width / renderer.resolution (); + double arrow_length = 1.5 * arrow_width; double sel_width = 2 / renderer.resolution (); if (length_u < 1e-5 /*micron*/ && style != ant::Object::STY_cross_both && style != ant::Object::STY_cross_end && style != ant::Object::STY_cross_start) { @@ -152,7 +155,7 @@ draw_ruler (const db::DPoint &q1, } else { // compute the tick distribution - double tick_length = (style == ant::Object::STY_ruler ? 8 : 0) / renderer.resolution (); + double tick_length = (style == ant::Object::STY_ruler ? ruler_tick_length : 0) / renderer.resolution (); double ticks = -1.0; int minor_ticks = -1; @@ -363,8 +366,8 @@ draw_text (const db::DPoint &q1, return; } - double arrow_width = 8 / renderer.resolution (); - double arrow_length = 12 / renderer.resolution (); + double arrow_width = ruler_arrow_width / renderer.resolution (); + double arrow_length = 1.5 * arrow_width; // Currently, "auto" means p2. if (pos == ant::Object::POS_auto) { @@ -383,7 +386,7 @@ draw_text (const db::DPoint &q1, } else { // compute the tick distribution - double tick_length = (style == ant::Object::STY_ruler ? 8 : 0) / renderer.resolution (); + double tick_length = (style == ant::Object::STY_ruler ? ruler_tick_length : 0) / renderer.resolution (); // normal and unit vector @@ -778,7 +781,7 @@ draw_ruler_angle (const ant::Object &ruler, const db::DCplxTrans &trans, bool se // draw ticks if required - minor at 5 degree, major at 10 degree - double tick_length = 8 / renderer.resolution (); + double tick_length = ruler_tick_length / renderer.resolution (); double da = 5.0 / 180.0 * M_PI; unsigned int major_ticks = 2; diff --git a/src/laybasic/laybasic/layLayoutCanvas.cc b/src/laybasic/laybasic/layLayoutCanvas.cc index 0a65906bf..ad89580fa 100644 --- a/src/laybasic/laybasic/layLayoutCanvas.cc +++ b/src/laybasic/laybasic/layLayoutCanvas.cc @@ -281,6 +281,7 @@ LayoutCanvas::LayoutCanvas (lay::LayoutViewBase *view) mp_image_fg (0), m_background (0), m_foreground (0), m_active (0), m_oversampling (1), + m_hrm (false), m_need_redraw (false), m_redraw_clearing (false), m_redraw_force_update (true), @@ -330,18 +331,28 @@ LayoutCanvas::~LayoutCanvas () #if defined(HAVE_QT) && QT_VERSION >= 0x050000 double -LayoutCanvas::dpr () +LayoutCanvas::dpr () const { return widget () ? widget ()->devicePixelRatio () : 1.0; } #else double -LayoutCanvas::dpr () +LayoutCanvas::dpr () const { return 1.0; } #endif +double +LayoutCanvas::resolution () const +{ + if (m_hrm) { + return 1.0 / m_oversampling; + } else { + return 1.0 / (m_oversampling * dpr ()); + } +} + #if defined(HAVE_QT) void LayoutCanvas::init_ui (QWidget *parent) @@ -407,6 +418,16 @@ LayoutCanvas::set_oversampling (unsigned int os) } } +void +LayoutCanvas::set_highres_mode (bool hrm) +{ + if (hrm != m_hrm) { + m_image_cache.clear (); + m_hrm = hrm; + do_redraw_all (); + } +} + void LayoutCanvas::set_colors (tl::Color background, tl::Color foreground, tl::Color active) { @@ -477,7 +498,7 @@ LayoutCanvas::prepare_drawing () { if (m_need_redraw) { - BitmapViewObjectCanvas::set_size (m_viewport_l.width (), m_viewport_l.height (), 1.0 / double (m_oversampling * dpr ())); + BitmapViewObjectCanvas::set_size (m_viewport_l.width (), m_viewport_l.height (), resolution ()); if (! mp_image || (unsigned int) mp_image->width () != m_viewport_l.width () || @@ -513,7 +534,7 @@ LayoutCanvas::prepare_drawing () ++c; } - mp_redraw_thread->commit (m_layers, m_viewport_l, 1.0 / double (m_oversampling * dpr ())); + mp_redraw_thread->commit (m_layers, m_viewport_l, resolution ()); if (tl::verbosity () >= 20) { tl::info << "Restored image from cache"; @@ -563,7 +584,7 @@ LayoutCanvas::prepare_drawing () } if (m_redraw_clearing) { - mp_redraw_thread->start (mp_view->synchronous () ? 0 : mp_view->drawing_workers (), m_layers, m_viewport_l, 1.0 / double (m_oversampling * dpr ()), m_redraw_force_update); + mp_redraw_thread->start (mp_view->synchronous () ? 0 : mp_view->drawing_workers (), m_layers, m_viewport_l, resolution (), m_redraw_force_update); } else { mp_redraw_thread->restart (m_need_redraw_layer); } @@ -634,7 +655,7 @@ LayoutCanvas::paint_event () } // render the main bitmaps - to_image (scaled_view_ops (m_oversampling * dpr ()), dither_pattern (), line_styles (), m_oversampling * dpr (), background_color (), foreground_color (), active_color (), this, *mp_image, m_viewport_l.width (), m_viewport_l.height ()); + to_image (scaled_view_ops (1.0 / resolution ()), dither_pattern (), line_styles (), 1.0 / resolution (), background_color (), foreground_color (), active_color (), this, *mp_image, m_viewport_l.width (), m_viewport_l.height ()); if (mp_image_fg) { delete mp_image_fg; @@ -664,7 +685,7 @@ LayoutCanvas::paint_event () if (fg_bitmaps () > 0) { tl::PixelBuffer full_image (*mp_image); - bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dither_pattern (), line_styles (), m_oversampling * dpr (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); + bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dither_pattern (), line_styles (), 1.0 / resolution (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); // render the foreground parts .. if (m_oversampling == 1) { @@ -711,7 +732,7 @@ LayoutCanvas::paint_event () full_image.set_transparent (true); full_image.fill (0); - bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dither_pattern (), line_styles (), m_oversampling * dpr (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); + bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dither_pattern (), line_styles (), 1.0 / resolution (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); // render the foreground parts .. if (m_oversampling == 1) { @@ -986,13 +1007,13 @@ LayoutCanvas::screenshot () tl::PixelBuffer img (m_viewport.width (), m_viewport.height ()); img.fill (m_background); - DetachedViewObjectCanvas vo_canvas (background_color (), foreground_color (), active_color (), m_viewport_l.width (), m_viewport_l.height (), 1.0 / double (m_oversampling * dpr ()), &img); + DetachedViewObjectCanvas vo_canvas (background_color (), foreground_color (), active_color (), m_viewport_l.width (), m_viewport_l.height (), resolution (), &img); // and paint the background objects. It uses "img" to paint on. do_render_bg (m_viewport_l, vo_canvas); // paint the layout bitmaps - to_image (scaled_view_ops (m_oversampling * dpr ()), dither_pattern (), line_styles (), m_oversampling * dpr (), background_color (), foreground_color (), active_color (), this, *vo_canvas.bg_image (), m_viewport_l.width (), m_viewport_l.height ()); + to_image (scaled_view_ops (1.0 / resolution ()), dither_pattern (), line_styles (), 1.0 / resolution (), background_color (), foreground_color (), active_color (), this, *vo_canvas.bg_image (), m_viewport_l.width (), m_viewport_l.height ()); // subsample current image to provide the background for the foreground objects vo_canvas.make_background (); diff --git a/src/laybasic/laybasic/layLayoutCanvas.h b/src/laybasic/laybasic/layLayoutCanvas.h index ae4f58da2..32100c05d 100644 --- a/src/laybasic/laybasic/layLayoutCanvas.h +++ b/src/laybasic/laybasic/layLayoutCanvas.h @@ -256,6 +256,11 @@ public: */ void set_oversampling (unsigned int os); + /** + * @brief Set high-resolution mode (utilize full DPI on high-DPI displays) + */ + void set_highres_mode (bool hrm); + /** * @brief Sets the depth of the image cache */ @@ -380,6 +385,7 @@ private: lay::LineStyles m_line_styles; std::map > m_scaled_view_ops; unsigned int m_oversampling; + bool m_hrm; double m_gamma; bool m_need_redraw; @@ -417,7 +423,8 @@ private: void do_redraw_all (bool force_redraw = true); void prepare_drawing (); - double dpr (); + double dpr () const; + virtual double resolution () const; const std::vector &scaled_view_ops (unsigned int lw); }; diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index e2ec59bce..4852504d7 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -780,6 +780,13 @@ LayoutViewBase::configure (const std::string &name, const std::string &value) mp_canvas->set_oversampling (os); return true; + } else if (name == cfg_highres_mode) { + + bool hrm = false; + tl::from_string (value, hrm); + mp_canvas->set_highres_mode (hrm); + return true; + } else if (name == cfg_image_cache_size) { int sz = 0; diff --git a/src/laybasic/laybasic/layLayoutViewConfig.cc b/src/laybasic/laybasic/layLayoutViewConfig.cc index 3d9f5878b..9ed60be0d 100644 --- a/src/laybasic/laybasic/layLayoutViewConfig.cc +++ b/src/laybasic/laybasic/layLayoutViewConfig.cc @@ -107,6 +107,7 @@ public: options.push_back (std::pair (cfg_drop_small_cells_value, "10")); options.push_back (std::pair (cfg_array_border_instances, "false")); options.push_back (std::pair (cfg_bitmap_oversampling, "1")); + options.push_back (std::pair (cfg_highres_mode, "false")); options.push_back (std::pair (cfg_image_cache_size, "1")); options.push_back (std::pair (cfg_default_font_size, "0")); options.push_back (std::pair (cfg_color_palette, lay::ColorPalette ().to_string ())); diff --git a/src/laybasic/laybasic/layViewObject.h b/src/laybasic/laybasic/layViewObject.h index 34e7207c6..f14c36cdd 100644 --- a/src/laybasic/laybasic/layViewObject.h +++ b/src/laybasic/laybasic/layViewObject.h @@ -966,7 +966,7 @@ public: /** * @brief Gets the QWidget representing this canvas visually in Qt */ - QWidget *widget () + QWidget *widget () const { return mp_widget; } diff --git a/src/laybasic/laybasic/laybasicConfig.h b/src/laybasic/laybasic/laybasicConfig.h index 0b84bf38f..ff816a0d8 100644 --- a/src/laybasic/laybasic/laybasicConfig.h +++ b/src/laybasic/laybasic/laybasicConfig.h @@ -120,6 +120,7 @@ static const std::string cfg_reader_options_show_always ("reader-options-show-al static const std::string cfg_tip_window_hidden ("tip-window-hidden"); static const std::string cfg_bitmap_oversampling ("bitmap-oversampling"); +static const std::string cfg_highres_mode ("highres-mode"); static const std::string cfg_image_cache_size ("image-cache-size"); static const std::string cfg_default_font_size ("default-font-size"); diff --git a/src/layui/layui/LayoutViewConfigPage7.ui b/src/layui/layui/LayoutViewConfigPage7.ui index ae9b834a9..c5f922f10 100644 --- a/src/layui/layui/LayoutViewConfigPage7.ui +++ b/src/layui/layui/LayoutViewConfigPage7.ui @@ -7,7 +7,7 @@ 0 0 791 - 385 + 403 @@ -32,7 +32,7 @@ - Oversampling + Display Quality @@ -53,7 +53,14 @@ - Use oversampling: + Oversampling mode + + + + + + + High resolution mode utilizes the full pixel density on high-DPI displays. Features may look small but rich in details. @@ -99,6 +106,13 @@ + + + + High resolution mode enabled + + + diff --git a/src/layui/layui/layLayoutViewConfigPages.cc b/src/layui/layui/layLayoutViewConfigPages.cc index ab8406b8e..84ff043fa 100644 --- a/src/layui/layui/layLayoutViewConfigPages.cc +++ b/src/layui/layui/layLayoutViewConfigPages.cc @@ -1476,6 +1476,10 @@ LayoutViewConfigPage7::setup (lay::Dispatcher *root) root->config_get (cfg_bitmap_oversampling, oversampling); mp_ui->oversampling->setCurrentIndex (oversampling - 1); + bool highres_mode = false; + root->config_get (cfg_highres_mode, highres_mode); + mp_ui->highres_mode->setChecked (highres_mode); + int default_font_size = 0; root->config_get (cfg_default_font_size, default_font_size); mp_ui->default_font_size->setCurrentIndex (default_font_size); @@ -1499,6 +1503,7 @@ void LayoutViewConfigPage7::commit (lay::Dispatcher *root) { root->config_set (cfg_bitmap_oversampling, mp_ui->oversampling->currentIndex () + 1); + root->config_set (cfg_highres_mode, mp_ui->highres_mode->isChecked ()); root->config_set (cfg_default_font_size, mp_ui->default_font_size->currentIndex ()); root->config_set (cfg_global_trans, db::DCplxTrans (db::DFTrans (mp_ui->global_trans->currentIndex ())).to_string ()); root->config_set (cfg_initial_hier_depth, mp_ui->def_depth->value ());