From 029284f48ad1c338a72a61d7f68fee9d4dd9f607 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 18 Sep 2022 20:56:37 +0200 Subject: [PATCH] Some refactoring, layer icons are scaled for high DPI too now. --- src/edt/edt/edtMainService.cc | 8 ++- src/edt/edt/edtRecentConfigurationPage.cc | 8 ++- src/laybasic/laybasic/layBitmapsToImage.cc | 23 +++---- src/laybasic/laybasic/layBitmapsToImage.h | 7 ++- src/laybasic/laybasic/layDitherPattern.cc | 55 +++++++++++++++- src/laybasic/laybasic/layDitherPattern.h | 9 +++ src/laybasic/laybasic/layLayoutCanvas.cc | 36 +++-------- src/laybasic/laybasic/layLayoutCanvas.h | 4 +- src/laybasic/laybasic/layLayoutViewBase.h | 4 -- src/laybasic/laybasic/layLineStyles.cc | 38 +++++++++-- src/laybasic/laybasic/layLineStyles.h | 6 ++ .../laybasic/layRedrawThreadCanvas.cc | 12 ++-- src/laybasic/laybasic/layRedrawThreadCanvas.h | 4 +- src/laybasic/unit_tests/layBitmapsToImage.cc | 2 +- src/layui/layui/layLayerTreeModel.cc | 63 +++++++++++-------- src/layui/layui/layLayerTreeModel.h | 3 +- src/layui/layui/layLayoutViewConfigPages.cc | 3 +- src/layui/layui/laySelectStippleForm.cc | 6 +- src/layui/layui/layWidgets.cc | 12 ++-- 19 files changed, 196 insertions(+), 107 deletions(-) diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index 1ea0436cf..f2a91af17 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -2204,6 +2204,12 @@ MainService::cm_tap () #if defined(HAVE_QT) // TODO: what to do here in Qt-less case? Store results in configuration so they can be retrieved externally? +#if QT_VERSION >= 0x050000 + double dpr = view_widget->devicePixelRatio (); +#else + double dpr = 1.0; +#endif + std::unique_ptr menu (new QMenu (view_widget)); menu->show (); @@ -2213,7 +2219,7 @@ MainService::cm_tap () QPoint mp = view ()->canvas ()->widget ()->mapToGlobal (QPoint (mp_local.x (), mp_local.y ())); for (std::vector::const_iterator l = tapped_layers.begin (); l != tapped_layers.end (); ++l) { - QAction *a = menu->addAction (lay::LayerTreeModel::icon_for_layer (*l, view (), icon_size, icon_size, 0, true), tl::to_qstring ((*l)->display_string (view (), true, true /*with source*/))); + QAction *a = menu->addAction (lay::LayerTreeModel::icon_for_layer (*l, view (), icon_size, icon_size, dpr, 0, true), tl::to_qstring ((*l)->display_string (view (), true, true /*with source*/))); a->setData (int (l - tapped_layers.begin ())); } diff --git a/src/edt/edt/edtRecentConfigurationPage.cc b/src/edt/edt/edtRecentConfigurationPage.cc index 191ddbb5c..84f831c8d 100644 --- a/src/edt/edt/edtRecentConfigurationPage.cc +++ b/src/edt/edt/edtRecentConfigurationPage.cc @@ -161,6 +161,12 @@ lp_iter_from_string (lay::LayoutViewBase *view, const std::string &s) void RecentConfigurationPage::render_to (QTreeWidgetItem *item, int column, const std::vector &values, RecentConfigurationPage::ConfigurationRendering rendering) { +#if QT_VERSION >= 0x050000 + double dpr = devicePixelRatio (); +#else + double dpr = 1.0; +#endif + // store original value item->setData (column, Qt::UserRole, tl::to_qstring (values [column])); @@ -190,7 +196,7 @@ RecentConfigurationPage::render_to (QTreeWidgetItem *item, int column, const std tl::error << tl::to_string (tr ("Configuration error (Layer): ")) << ex.msg (); } if (! l.is_null () && ! l.at_end ()) { - item->setIcon (column, lay::LayerTreeModel::icon_for_layer (l, view (), icon_size, icon_size, 0, true)); + item->setIcon (column, lay::LayerTreeModel::icon_for_layer (l, view (), icon_size, icon_size, dpr, 0, true)); item->setText (column, tl::to_qstring (values [column])); } else { item->setIcon (column, QIcon ()); diff --git a/src/laybasic/laybasic/layBitmapsToImage.cc b/src/laybasic/laybasic/layBitmapsToImage.cc index 66d10b2d3..17e062233 100644 --- a/src/laybasic/laybasic/layBitmapsToImage.cc +++ b/src/laybasic/laybasic/layBitmapsToImage.cc @@ -405,8 +405,7 @@ static void create_precursor_bitmaps (const std::vector &view_ops_i } lay::Bitmap &bp = precursors.insert (std::make_pair (bm_index, lay::Bitmap (width, height, 1.0))).first->second; - LineStyleInfo ls_info = ls.style (op.line_style_index ()); - ls_info.scale_pattern (op.width ()); + const LineStyleInfo &ls_info = ls.style (op.line_style_index ()).scaled (op.width ()); for (unsigned int y = 0; y < height; y++) { render_scanline_std_edge (ls_info.pattern (), ls_info.pattern_stride (), pbitmaps_in [bm_index], y, width, height, bp.scanline (y)); @@ -426,6 +425,7 @@ bitmaps_to_image (const std::vector &view_ops_in, const std::vector &pbitmaps_in, const lay::DitherPattern &dp, const lay::LineStyles &ls, + double dpr, tl::PixelBuffer *pimage, unsigned int width, unsigned int height, bool use_bitmap_index, tl::Mutex *mutex) @@ -547,8 +547,8 @@ bitmaps_to_image (const std::vector &view_ops_in, const ViewOp &op = view_ops [i]; if (op.width () > 1 || (op.width () == 1 && (non_empty_sls [i] & ne_mask) != 0)) { - const LineStyleInfo &ls_info = ls.style (op.line_style_index ()); - const DitherPatternInfo &dp_info = dp.pattern (op.dither_index ()); + const LineStyleInfo &ls_info = ls.style (op.line_style_index ()).scaled (op.width ()); + const DitherPatternInfo &dp_info = dp.pattern (op.dither_index ()).scaled (dpr); const uint32_t *dither = dp_info.pattern () [(y + op.dither_offset ()) % dp_info.height ()]; if (dither != 0) { @@ -666,6 +666,7 @@ bitmaps_to_image (const std::vector &view_ops_in, const std::vector &pbitmaps_in, const lay::DitherPattern &dp, const lay::LineStyles &ls, + double dpr, tl::BitmapBuffer *pimage, unsigned int width, unsigned int height, bool use_bitmap_index, tl::Mutex *mutex) @@ -784,8 +785,8 @@ bitmaps_to_image (const std::vector &view_ops_in, const ViewOp &op = view_ops [i]; if (op.width () > 1 || (op.width () == 1 && (non_empty_sls [i] & ne_mask) != 0)) { - const LineStyleInfo &ls_info = ls.style (op.line_style_index ()); - const DitherPatternInfo &dp_info = dp.pattern (op.dither_index ()); + const LineStyleInfo &ls_info = ls.style (op.line_style_index ()).scaled (op.width ()); + const DitherPatternInfo &dp_info = dp.pattern (op.dither_index ()).scaled (dpr); const uint32_t *dither = dp_info.pattern () [(y + op.dither_offset ()) % dp_info.height ()]; if (dither != 0) { @@ -871,7 +872,8 @@ bitmap_to_bitmap (const lay::ViewOp &view_op, const lay::Bitmap &bitmap, unsigned char *data, unsigned int width, unsigned int height, const lay::DitherPattern &dp, - const lay::LineStyles &ls) + const lay::LineStyles &ls, + double dpr) { // quick exit, if line width is zero if (view_op.width () == 0) { @@ -885,12 +887,12 @@ bitmap_to_bitmap (const lay::ViewOp &view_op, const lay::Bitmap &bitmap, unsigned int x = 0xc0000001; unsigned char x0 = ((unsigned char *) &x) [0]; - const DitherPatternInfo &dp_info = dp.pattern (view_op.dither_index ()); - const LineStyleInfo &ls_info = ls.style (view_op.line_style_index ()); + const DitherPatternInfo &dp_info = dp.pattern (view_op.dither_index ()).scaled (dpr); + const LineStyleInfo &ls_info = ls.style (view_op.line_style_index ()).scaled (view_op.width ()); for (unsigned int y = 0; y < height; ++y) { - unsigned nbytes = ((width + 7) / 8); + unsigned int nbytes = ((width + 7) / 8); if (view_op.width () > 1 || ! bitmap.is_scanline_empty (height - 1 - y)) { @@ -917,7 +919,6 @@ bitmap_to_bitmap (const lay::ViewOp &view_op, const lay::Bitmap &bitmap, precursor = lay::Bitmap (width, height, 1.0); LineStyleInfo lsi = ls_info; - lsi.scale_pattern (view_op.width ()); for (unsigned int y = 0; y < height; y++) { render_scanline_std_edge (lsi.pattern (), lsi.pattern_stride (), bp, y, width, height, precursor.scanline (y)); diff --git a/src/laybasic/laybasic/layBitmapsToImage.h b/src/laybasic/laybasic/layBitmapsToImage.h index 000f964c1..76066a0e1 100644 --- a/src/laybasic/laybasic/layBitmapsToImage.h +++ b/src/laybasic/laybasic/layBitmapsToImage.h @@ -56,12 +56,15 @@ class Bitmap; * The "use_bitmap_index" parameter specifies whether the bitmap_index * parameter of the operators is being used to map a operator to a certain * bitmap. + * "dpr" is the device pixel ratio and will be used to scale line widths, + * stipple pattern and line styles. */ LAYBASIC_PUBLIC void bitmaps_to_image (const std::vector &view_ops, const std::vector &pbitmaps, const lay::DitherPattern &dp, const lay::LineStyles &ls, + double dpr, tl::PixelBuffer *pimage, unsigned int width, unsigned int height, bool use_bitmap_index, tl::Mutex *mutex); @@ -76,6 +79,7 @@ bitmaps_to_image (const std::vector &view_ops, const std::vector &pbitmaps, const lay::DitherPattern &dp, const lay::LineStyles &ls, + double dpr, tl::BitmapBuffer *pimage, unsigned int width, unsigned int height, bool use_bitmap_index, tl::Mutex *mutex); @@ -92,7 +96,8 @@ bitmap_to_bitmap (const lay::ViewOp &view_op, const lay::Bitmap &bitmap, unsigned char *data, unsigned int width, unsigned int height, const lay::DitherPattern &dp, - const lay::LineStyles &ls); + const lay::LineStyles &ls, + double dpr); } // namespace lay diff --git a/src/laybasic/laybasic/layDitherPattern.cc b/src/laybasic/laybasic/layDitherPattern.cc index e070c44bb..c10ac4ae2 100644 --- a/src/laybasic/laybasic/layDitherPattern.cc +++ b/src/laybasic/laybasic/layDitherPattern.cc @@ -24,6 +24,7 @@ #include "layDitherPattern.h" #include "tlAssert.h" +#include "tlThreads.h" #include #include @@ -596,13 +597,26 @@ DitherPatternInfo::get_bitmap (int width, int height, int frame_width) const #endif +static tl::Mutex s_mutex; + void DitherPatternInfo::set_pattern (const uint32_t *pt, unsigned int w, unsigned int h) +{ + { + tl::MutexLocker locker (& s_mutex); + m_scaled_pattern.reset (0); + } + + set_pattern_impl (pt, w, h); +} + +void +DitherPatternInfo::set_pattern_impl (const uint32_t *pt, unsigned int w, unsigned int h) { // pattern size must be 1x1 at least if (w == 0 || h == 0) { uint32_t zero = 0; - set_pattern (&zero, 1, 1); + set_pattern_impl (&zero, 1, 1); return; } @@ -654,11 +668,22 @@ DitherPatternInfo::set_pattern (const uint32_t *pt, unsigned int w, unsigned int void DitherPatternInfo::set_pattern (const uint64_t *pt, unsigned int w, unsigned int h) +{ + { + tl::MutexLocker locker (& s_mutex); + m_scaled_pattern.reset (0); + } + + set_pattern_impl (pt, w, h); +} + +void +DitherPatternInfo::set_pattern_impl (const uint64_t *pt, unsigned int w, unsigned int h) { // pattern size must be 1x1 at least if (w == 0 || h == 0) { uint32_t zero = 0; - set_pattern (&zero, 1, 1); + set_pattern_impl (&zero, 1, 1); return; } @@ -708,6 +733,30 @@ DitherPatternInfo::set_pattern (const uint64_t *pt, unsigned int w, unsigned int } } +const DitherPatternInfo & +DitherPatternInfo::scaled (unsigned int n) const +{ + if (n <= 1) { + return *this; + } + + tl::MutexLocker locker (& s_mutex); + + if (! m_scaled_pattern.get ()) { + m_scaled_pattern.reset (new std::map ()); + } + + auto i = m_scaled_pattern->find (n); + if (i != m_scaled_pattern->end ()) { + return i->second; + } + + DitherPatternInfo &sp = (*m_scaled_pattern) [n]; + sp = *this; + sp.scale_pattern (n); + return sp; +} + void DitherPatternInfo::scale_pattern (unsigned int n) { @@ -802,7 +851,7 @@ DitherPatternInfo::scale_pattern (unsigned int n) } - set_pattern (new_pattern.begin ().operator-> (), n * m_width, n * m_height); + set_pattern_impl (new_pattern.begin ().operator-> (), n * m_width, n * m_height); } std::string diff --git a/src/laybasic/laybasic/layDitherPattern.h b/src/laybasic/laybasic/layDitherPattern.h index a0980e581..cb1bde7a8 100644 --- a/src/laybasic/laybasic/layDitherPattern.h +++ b/src/laybasic/laybasic/layDitherPattern.h @@ -206,6 +206,11 @@ public: */ void scale_pattern (unsigned int n); + /** + * @brief Gets a scaled version of the pattern + */ + const DitherPatternInfo &scaled (unsigned int n) const; + /** * @brief Load from a string */ @@ -233,6 +238,10 @@ private: unsigned int m_pattern_stride; unsigned int m_order_index; std::string m_name; + mutable std::unique_ptr > m_scaled_pattern; + + void set_pattern_impl (const uint32_t *pattern, unsigned int w, unsigned int h); + void set_pattern_impl (const uint64_t *pattern, unsigned int w, unsigned int h); }; /** diff --git a/src/laybasic/laybasic/layLayoutCanvas.cc b/src/laybasic/laybasic/layLayoutCanvas.cc index 134057b6b..058b77bb7 100644 --- a/src/laybasic/laybasic/layLayoutCanvas.cc +++ b/src/laybasic/laybasic/layLayoutCanvas.cc @@ -438,7 +438,6 @@ LayoutCanvas::set_dither_pattern (const lay::DitherPattern &p) { if (p != m_dither_pattern) { m_dither_pattern = p; - m_scaled_dither_pattern.clear (); update_image (); } } @@ -473,25 +472,6 @@ LayoutCanvas::scaled_view_ops (unsigned int lw) return scaled_view_ops; } -const lay::DitherPattern & -LayoutCanvas::scaled_dither_pattern (unsigned int lw) -{ - if (lw <= 1) { - return m_dither_pattern; - } - - auto cached = m_scaled_dither_pattern.find (lw); - if (cached != m_scaled_dither_pattern.end ()) { - return cached->second; - } - - lay::DitherPattern &scaled_dither_pattern = m_scaled_dither_pattern [lw]; - scaled_dither_pattern = m_dither_pattern; - scaled_dither_pattern.scale_pattern (lw); - - return scaled_dither_pattern; -} - void LayoutCanvas::prepare_drawing () { @@ -654,7 +634,7 @@ LayoutCanvas::paint_event () } // render the main bitmaps - to_image (scaled_view_ops (m_oversampling * dpr ()), scaled_dither_pattern (m_oversampling * dpr ()), line_styles (), background_color (), foreground_color (), active_color (), this, *mp_image, m_viewport_l.width (), m_viewport_l.height ()); + 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 ()); if (mp_image_fg) { delete mp_image_fg; @@ -684,7 +664,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 (), &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 (), m_oversampling * dpr (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); // render the foreground parts .. if (m_oversampling == 1) { @@ -731,7 +711,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 (), &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 (), m_oversampling * dpr (), &full_image, m_viewport_l.width (), m_viewport_l.height (), false, &m_mutex); // render the foreground parts .. if (m_oversampling == 1) { @@ -820,10 +800,10 @@ public: if (mp_image_l) { unsigned int os = mp_image_l->width () / width; blowup (*mp_image, *mp_image_l, os); - bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dp, ls, mp_image_l, mp_image_l->width (), mp_image_l->height (), false, 0); + bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dp, ls, 1.0 / resolution (), mp_image_l, mp_image_l->width (), mp_image_l->height (), false, 0); subsample (*mp_image_l, *mp_image, os, m_gamma); } else { - bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dp, ls, mp_image, width, height, false, 0); + bitmaps_to_image (fg_view_op_vector (), fg_bitmap_vector (), dp, ls, 1.0 / resolution (), mp_image, width, height, false, 0); } clear_fg_bitmaps (); } @@ -945,7 +925,7 @@ LayoutCanvas::image_with_options (unsigned int width, unsigned int height, int l do_render_bg (vp, vo_canvas); // paint the layout bitmaps - rd_canvas.to_image (scaled_view_ops (linewidth), scaled_dither_pattern (1.0 / resolution + 0.5), line_styles (), background, foreground, active, this, *vo_canvas.bg_image (), vp.width (), vp.height ()); + rd_canvas.to_image (scaled_view_ops (linewidth), dither_pattern (), line_styles (), 1.0 / resolution, background, foreground, active, this, *vo_canvas.bg_image (), vp.width (), vp.height ()); // subsample current image to provide the background for the foreground objects vo_canvas.make_background (); @@ -992,7 +972,7 @@ LayoutCanvas::image_with_options_mono (unsigned int width, unsigned int height, tl::BitmapBuffer img (width, height); img.fill (background); - rd_canvas.to_image_mono (scaled_view_ops (linewidth), scaled_dither_pattern (linewidth), line_styles (), background, foreground, active, this, img, vp.width (), vp.height ()); + rd_canvas.to_image_mono (scaled_view_ops (linewidth), dither_pattern (), line_styles (), linewidth, background, foreground, active, this, img, vp.width (), vp.height ()); return img; } @@ -1012,7 +992,7 @@ LayoutCanvas::screenshot () do_render_bg (m_viewport_l, vo_canvas); // paint the layout bitmaps - to_image (scaled_view_ops (m_oversampling * dpr ()), scaled_dither_pattern (m_oversampling * dpr ()), line_styles (), background_color (), foreground_color (), active_color (), this, *vo_canvas.bg_image (), m_viewport_l.width (), m_viewport_l.height ()); + 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 ()); // 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 1a4aaad26..ae4f58da2 100644 --- a/src/laybasic/laybasic/layLayoutCanvas.h +++ b/src/laybasic/laybasic/layLayoutCanvas.h @@ -379,7 +379,6 @@ private: lay::DitherPattern m_dither_pattern; lay::LineStyles m_line_styles; std::map > m_scaled_view_ops; - std::map m_scaled_dither_pattern; unsigned int m_oversampling; double m_gamma; @@ -420,8 +419,7 @@ private: void prepare_drawing (); double dpr (); - const std::vector &scaled_view_ops(unsigned int lw); - const DitherPattern &scaled_dither_pattern(unsigned int lw); + const std::vector &scaled_view_ops (unsigned int lw); }; } // namespace lay diff --git a/src/laybasic/laybasic/layLayoutViewBase.h b/src/laybasic/laybasic/layLayoutViewBase.h index df8612f84..5837c042d 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.h +++ b/src/laybasic/laybasic/layLayoutViewBase.h @@ -53,10 +53,6 @@ #include "tlTimer.h" #include "dbInstElement.h" -#if defined(HAVE_QT) -# include -#endif - namespace rdb { class Database; } diff --git a/src/laybasic/laybasic/layLineStyles.cc b/src/laybasic/laybasic/layLineStyles.cc index 72fb20c02..993552722 100644 --- a/src/laybasic/laybasic/layLineStyles.cc +++ b/src/laybasic/laybasic/layLineStyles.cc @@ -24,6 +24,7 @@ #include "layLineStyles.h" #include "tlAssert.h" +#include "tlThreads.h" #include #include @@ -200,9 +201,16 @@ LineStyleInfo::get_bitmap (int width, int height) const } #endif +static tl::Mutex s_mutex; + void LineStyleInfo::set_pattern (uint32_t pt, unsigned int w) { + { + tl::MutexLocker locker (& s_mutex); + m_scaled_pattern.reset (0); + } + memset (m_pattern, 0, sizeof (m_pattern)); if (w >= 32) { @@ -244,6 +252,30 @@ LineStyleInfo::set_pattern (uint32_t pt, unsigned int w) } } +const LineStyleInfo & +LineStyleInfo::scaled (unsigned int n) const +{ + if (n <= 1) { + return *this; + } + + tl::MutexLocker locker (& s_mutex); + + if (! m_scaled_pattern.get ()) { + m_scaled_pattern.reset (new std::map ()); + } + + auto i = m_scaled_pattern->find (n); + if (i != m_scaled_pattern->end ()) { + return i->second; + } + + LineStyleInfo &sp = (*m_scaled_pattern) [n]; + sp = *this; + sp.scale_pattern (n); + return sp; +} + void LineStyleInfo::scale_pattern (unsigned int n) { @@ -298,6 +330,8 @@ LineStyleInfo::scale_pattern (unsigned int n) m_width = w; } + + std::string LineStyleInfo::to_string () const { @@ -413,11 +447,8 @@ LineStyles::style (unsigned int i) const void LineStyles::replace_style (unsigned int i, const LineStyleInfo &p) { - bool chg = false; - while (i >= count ()) { m_styles.push_back (LineStyleInfo ()); - chg = true; } if (m_styles [i] != p) { @@ -425,7 +456,6 @@ LineStyles::replace_style (unsigned int i, const LineStyleInfo &p) manager ()->queue (this, new ReplaceLineStyleOp (i, m_styles [i], p)); } m_styles [i] = p; - chg = true; } } diff --git a/src/laybasic/laybasic/layLineStyles.h b/src/laybasic/laybasic/layLineStyles.h index 5cd760f3a..288e8f22a 100644 --- a/src/laybasic/laybasic/layLineStyles.h +++ b/src/laybasic/laybasic/layLineStyles.h @@ -168,6 +168,11 @@ public: */ void scale_pattern (unsigned int n); + /** + * @brief Gets a scaled version of the pattern + */ + const LineStyleInfo &scaled (unsigned int n) const; + /** * @brief Gets the pattern stride * @@ -209,6 +214,7 @@ private: unsigned int m_pattern_stride; unsigned int m_order_index; std::string m_name; + mutable std::unique_ptr > m_scaled_pattern; }; /** diff --git a/src/laybasic/laybasic/layRedrawThreadCanvas.cc b/src/laybasic/laybasic/layRedrawThreadCanvas.cc index ff5c6228a..537f2e8b2 100644 --- a/src/laybasic/laybasic/layRedrawThreadCanvas.cc +++ b/src/laybasic/laybasic/layRedrawThreadCanvas.cc @@ -392,7 +392,7 @@ BitmapRedrawThreadCanvas::initialize_plane (lay::CanvasPlane *plane, unsigned in } void -BitmapRedrawThreadCanvas::to_image (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, tl::Color background, tl::Color foreground, tl::Color active, const lay::Drawings *drawings, tl::PixelBuffer &img, unsigned int width, unsigned int height) +BitmapRedrawThreadCanvas::to_image (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, double dpr, tl::Color background, tl::Color foreground, tl::Color active, const lay::Drawings *drawings, tl::PixelBuffer &img, unsigned int width, unsigned int height) { if (width > m_width) { width = m_width; @@ -402,17 +402,17 @@ BitmapRedrawThreadCanvas::to_image (const std::vector &view_ops, c } // convert the plane data to image data - bitmaps_to_image (view_ops, mp_plane_buffers, dp, ls, &img, width, height, true, &mutex ()); + bitmaps_to_image (view_ops, mp_plane_buffers, dp, ls, dpr, &img, width, height, true, &mutex ()); // convert the planes of the "drawing" objects too: std::vector >::const_iterator bt = mp_drawing_plane_buffers.begin (); for (lay::Drawings::const_iterator d = drawings->begin (); d != drawings->end () && bt != mp_drawing_plane_buffers.end (); ++d, ++bt) { - bitmaps_to_image (d->get_view_ops (*this, background, foreground, active), *bt, dp, ls, &img, width, height, true, &mutex ()); + bitmaps_to_image (d->get_view_ops (*this, background, foreground, active), *bt, dp, ls, dpr, &img, width, height, true, &mutex ()); } } void -BitmapRedrawThreadCanvas::to_image_mono (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, bool background, bool foreground, bool active, const lay::Drawings *drawings, tl::BitmapBuffer &img, unsigned int width, unsigned int height) +BitmapRedrawThreadCanvas::to_image_mono (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, double dpr, bool background, bool foreground, bool active, const lay::Drawings *drawings, tl::BitmapBuffer &img, unsigned int width, unsigned int height) { if (width > m_width) { width = m_width; @@ -424,12 +424,12 @@ BitmapRedrawThreadCanvas::to_image_mono (const std::vector &view_o unsigned int all_one = 0xffffffff; // convert the plane data to image data - bitmaps_to_image (view_ops, mp_plane_buffers, dp, ls, &img, width, height, true, &mutex ()); + bitmaps_to_image (view_ops, mp_plane_buffers, dp, ls, dpr, &img, width, height, true, &mutex ()); // convert the planes of the "drawing" objects too: std::vector >::const_iterator bt = mp_drawing_plane_buffers.begin (); for (lay::Drawings::const_iterator d = drawings->begin (); d != drawings->end () && bt != mp_drawing_plane_buffers.end (); ++d, ++bt) { - bitmaps_to_image (d->get_view_ops (*this, background ? all_one : 0, foreground ? all_one : 0, active ? all_one : 0), *bt, dp, ls, &img, width, height, true, &mutex ()); + bitmaps_to_image (d->get_view_ops (*this, background ? all_one : 0, foreground ? all_one : 0, active ? all_one : 0), *bt, dp, ls, dpr, &img, width, height, true, &mutex ()); } } diff --git a/src/laybasic/laybasic/layRedrawThreadCanvas.h b/src/laybasic/laybasic/layRedrawThreadCanvas.h index 8fdab9f0e..fbd32f77b 100644 --- a/src/laybasic/laybasic/layRedrawThreadCanvas.h +++ b/src/laybasic/laybasic/layRedrawThreadCanvas.h @@ -319,12 +319,12 @@ public: /** * @brief Transfer the content to a PixelBuffer */ - void to_image (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, tl::Color background, tl::Color foreground, tl::Color active, const lay::Drawings *drawings, tl::PixelBuffer &img, unsigned int width, unsigned int height); + void to_image (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, double dpr, tl::Color background, tl::Color foreground, tl::Color active, const lay::Drawings *drawings, tl::PixelBuffer &img, unsigned int width, unsigned int height); /** * @brief Transfer the content to a BitmapBuffer (monochrome) */ - void to_image_mono (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, bool background, bool foreground, bool active, const lay::Drawings *drawings, tl::BitmapBuffer &img, unsigned int width, unsigned int height); + void to_image_mono (const std::vector &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, double dpr, bool background, bool foreground, bool active, const lay::Drawings *drawings, tl::BitmapBuffer &img, unsigned int width, unsigned int height); /** * @brief Gets the current bitmap data as a BitmapCanvasData object diff --git a/src/laybasic/unit_tests/layBitmapsToImage.cc b/src/laybasic/unit_tests/layBitmapsToImage.cc index 879924deb..271e2d554 100644 --- a/src/laybasic/unit_tests/layBitmapsToImage.cc +++ b/src/laybasic/unit_tests/layBitmapsToImage.cc @@ -92,7 +92,7 @@ TEST(1) lay::LineStyles ls; tl::Mutex m; - lay::bitmaps_to_image (view_ops, pbitmaps, dp, ls, &img, 32, 32, 0, &m); + lay::bitmaps_to_image (view_ops, pbitmaps, dp, ls, 1.0, &img, 32, 32, 0, &m); EXPECT_EQ (to_string (img, 0x800000), "................................\n" diff --git a/src/layui/layui/layLayerTreeModel.cc b/src/layui/layui/layLayerTreeModel.cc index 383d75fd3..fe3f1a97f 100644 --- a/src/layui/layui/layLayerTreeModel.cc +++ b/src/layui/layui/layLayerTreeModel.cc @@ -526,23 +526,6 @@ LayerTreeModel::parent (const QModelIndex &index) const } } -/** - * @brief A helper function to create an image from a single bitmap - */ -static void -single_bitmap_to_image (const lay::ViewOp &view_op, lay::Bitmap &bitmap, - tl::PixelBuffer *pimage, const lay::DitherPattern &dither_pattern, const lay::LineStyles &line_styles, - unsigned int width, unsigned int height) -{ - std::vector view_ops; - view_ops.push_back (view_op); - - std::vector pbitmaps; - pbitmaps.push_back (&bitmap); - - lay::bitmaps_to_image (view_ops, pbitmaps, dither_pattern, line_styles, pimage, width, height, false, 0); -} - bool LayerTreeModel::is_hidden (const QModelIndex &index) const { @@ -637,12 +620,29 @@ LayerTreeModel::empty_within_view_predicate (const QModelIndex &index) const } } +/** + * @brief A helper function to create an image from a single bitmap + */ +static void +single_bitmap_to_image (const lay::ViewOp &view_op, lay::Bitmap &bitmap, + tl::PixelBuffer *pimage, const lay::DitherPattern &dither_pattern, const lay::LineStyles &line_styles, + double dpr, unsigned int width, unsigned int height) +{ + std::vector view_ops; + view_ops.push_back (view_op); + + std::vector pbitmaps; + pbitmaps.push_back (&bitmap); + + lay::bitmaps_to_image (view_ops, pbitmaps, dither_pattern, line_styles, dpr, pimage, width, height, false, 0); +} + LAYUI_PUBLIC QIcon -LayerTreeModel::icon_for_layer (const lay::LayerPropertiesConstIterator &iter, lay::LayoutViewBase *view, unsigned int w, unsigned int h, unsigned int di_off, bool no_state) +LayerTreeModel::icon_for_layer (const lay::LayerPropertiesConstIterator &iter, lay::LayoutViewBase *view, unsigned int w, unsigned int h, double dpr, unsigned int di_off, bool no_state) { - h = std::max ((unsigned int) 16, h); - w = std::max ((unsigned int) 16, w); + h = std::max ((unsigned int) 16, h) * dpr + 0.5; + w = std::max ((unsigned int) 16, w) * dpr + 0.5; tl::color_t def_color = 0x808080; tl::color_t fill_color = iter->has_fill_color (true) ? iter->eff_fill_color (true) : def_color; @@ -701,6 +701,7 @@ LayerTreeModel::icon_for_layer (const lay::LayerPropertiesConstIterator &iter, l // default line width is 0 for parents and 1 for leafs lw = iter->has_children () ? 0 : 1; } + lw = lw * dpr + 0.5; int p0 = lw / 2; p0 = std::max (0, std::min (int (w / 4 - 1), p0)); @@ -770,19 +771,22 @@ LayerTreeModel::icon_for_layer (const lay::LayerPropertiesConstIterator &iter, l lay::ViewOp::Mode mode = lay::ViewOp::Copy; // create fill - single_bitmap_to_image (lay::ViewOp (fill_color, mode, 0, iter->eff_dither_pattern (true), di_off), fill, &image, view->dither_pattern (), view->line_styles (), w, h); + single_bitmap_to_image (lay::ViewOp (fill_color, mode, 0, iter->eff_dither_pattern (true), di_off), fill, &image, view->dither_pattern (), view->line_styles (), dpr, w, h); // create frame if (lw == 0) { - single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0 /*solid line*/, 2 /*dotted*/, 0), frame, &image, view->dither_pattern (), view->line_styles (), w, h); + single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0 /*solid line*/, 2 /*dotted*/, 0), frame, &image, view->dither_pattern (), view->line_styles (), dpr, w, h); } else { - single_bitmap_to_image (lay::ViewOp (frame_color, mode, iter->eff_line_style (true), 0, 0, lay::ViewOp::Rect, lw), frame, &image, view->dither_pattern (), view->line_styles (), w, h); + single_bitmap_to_image (lay::ViewOp (frame_color, mode, iter->eff_line_style (true), 0, 0, lay::ViewOp::Rect, lw), frame, &image, view->dither_pattern (), view->line_styles (), dpr, w, h); } // create text - single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0, 0, 0), text, &image, view->dither_pattern (), view->line_styles (), w, h); + single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0, 0, 0), text, &image, view->dither_pattern (), view->line_styles (), dpr, w, h); // create vertex - single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0, 0, 0, lay::ViewOp::Cross, iter->marked (true) ? 9/*mark size*/ : 0), vertex, &image, view->dither_pattern (), view->line_styles (), w, h); + single_bitmap_to_image (lay::ViewOp (frame_color, mode, 0, 0, 0, lay::ViewOp::Cross, iter->marked (true) ? 9/*mark size*/ : 0), vertex, &image, view->dither_pattern (), view->line_styles (), dpr, w, h); - QPixmap pixmap = QPixmap::fromImage (image.to_image ()); // Qt 4.6.0 workaround + QPixmap pixmap = QPixmap::fromImage (image.to_image ()); +#if QT_VERSION >= 0x050000 + pixmap.setDevicePixelRatio (dpr); +#endif return QIcon (pixmap); } @@ -841,7 +845,12 @@ LayerTreeModel::data (const QModelIndex &index, int role) const QSize is = icon_size (); if (animate_visible) { - return QVariant (icon_for_layer (iter, mp_view, is.width (), is.height (), di_off)); +#if QT_VERSION >= 0x050000 + double dpr = mp_parent ? mp_parent->devicePixelRatio () : 1.0; +#else + double dpr = 1.0; +#endif + return QVariant (icon_for_layer (iter, mp_view, is.width (), is.height (), dpr, di_off)); } else { return QVariant (QIcon ()); } diff --git a/src/layui/layui/layLayerTreeModel.h b/src/layui/layui/layLayerTreeModel.h index 47132c990..902166bdd 100644 --- a/src/layui/layui/layLayerTreeModel.h +++ b/src/layui/layui/layLayerTreeModel.h @@ -27,6 +27,7 @@ #include "dbBox.h" #include "layuiCommon.h" +#include "layDitherPattern.h" #include #include @@ -109,7 +110,7 @@ public: /** * @brief Provides an icon for a given layer style */ - static QIcon icon_for_layer (const lay::LayerPropertiesConstIterator &iter, lay::LayoutViewBase *view, unsigned int w, unsigned int h, unsigned int di_offset, bool no_state = false); + static QIcon icon_for_layer (const lay::LayerPropertiesConstIterator &iter, lay::LayoutViewBase *view, unsigned int w, unsigned int h, double dpr, unsigned int di_offset, bool no_state = false); /** * @brief Gets the preferred icon size diff --git a/src/layui/layui/layLayoutViewConfigPages.cc b/src/layui/layui/layLayoutViewConfigPages.cc index 9ce5194fa..ab8406b8e 100644 --- a/src/layui/layui/layLayoutViewConfigPages.cc +++ b/src/layui/layui/layLayoutViewConfigPages.cc @@ -1239,8 +1239,7 @@ LayoutViewConfigPage6::update () image.fill (color0.rgb ()); // copying code from layLayerToolbox.cc - lay::DitherPatternInfo info = m_pattern.pattern ((unsigned int) s); - info.scale_pattern (dpr); + const lay::DitherPatternInfo &info = m_pattern.pattern ((unsigned int) s).scaled (dpr); QBitmap bitmap = info.get_bitmap (w * dpr, h * dpr, dpr); QPainter painter (&image); diff --git a/src/layui/layui/laySelectStippleForm.cc b/src/layui/layui/laySelectStippleForm.cc index ca15ca0f2..609fab80e 100644 --- a/src/layui/layui/laySelectStippleForm.cc +++ b/src/layui/layui/laySelectStippleForm.cc @@ -105,8 +105,7 @@ SelectStippleForm::update () name = tl::sprintf ("#%d", std::distance (m_pattern.begin (), i)); } - lay::DitherPatternInfo dp_info = *i; - dp_info.scale_pattern (dpr); + const lay::DitherPatternInfo &dp_info = i->scaled (dpr); QBitmap bitmap = dp_info.get_bitmap (icon_size.width () * dpr, icon_size.height () * dpr, dpr); #if QT_VERSION >= 0x050000 bitmap.setDevicePixelRatio (dpr); @@ -124,8 +123,7 @@ SelectStippleForm::update () name = tl::sprintf ("custom #%d", (*i)->order_index ()); } - lay::DitherPatternInfo dp_info = **i; - dp_info.scale_pattern (dpr); + const lay::DitherPatternInfo &dp_info = (*i)->scaled (dpr); QBitmap bitmap = dp_info.get_bitmap (icon_size.width () * dpr, icon_size.height () * dpr, dpr); #if QT_VERSION >= 0x050000 bitmap.setDevicePixelRatio (dpr); diff --git a/src/layui/layui/layWidgets.cc b/src/layui/layui/layWidgets.cc index 12f7b61a5..6be7675c6 100644 --- a/src/layui/layui/layWidgets.cc +++ b/src/layui/layui/layWidgets.cc @@ -177,19 +177,15 @@ DitherPatternSelectionButton::update_pattern () } else { - lay::DitherPatternInfo dp_info; + const lay::DitherPatternInfo *dp_info; if (mp_view) { - dp_info = mp_view->dither_pattern ().pattern ((unsigned int) m_dither_pattern); + dp_info = & mp_view->dither_pattern ().pattern ((unsigned int) m_dither_pattern).scaled (dpr); } else { static lay::DitherPattern default_pattern; - dp_info= default_pattern.pattern ((unsigned int) m_dither_pattern); + dp_info = & default_pattern.pattern ((unsigned int) m_dither_pattern).scaled (dpr); } - if (dpr > 1) { - dp_info.scale_pattern (dpr); - } - - QPushButton::setIcon (dp_info.get_bitmap (rt.width () * dpr, rt.height () * dpr, dpr)); + QPushButton::setIcon (dp_info->get_bitmap (rt.width () * dpr, rt.height () * dpr, dpr)); } }