diff --git a/CMakeLists.txt b/CMakeLists.txt index ff221ffef..cc6b65e3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,6 +305,7 @@ pkg_check_modules (GTHREAD REQUIRED gthread-2.0>=2.44) pkg_check_modules (GOBJECT REQUIRED gobject-2.0>=2.44) pkg_check_modules (SIGC REQUIRED sigc++-2.0>=2.3.1) pkg_check_modules (LENSFUN REQUIRED lensfun>=0.2) +pkg_check_modules (RSVG REQUIRED librsvg-2.0>=2.40) if(WIN32) add_definitions(-DWIN32) diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 526f58ba3..7cc81b93f 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -8,16 +8,9 @@ file(GLOB FONTS "fonts/*") set(PROFILESDIR "profiles") set(THEMEDIR "themes") -# Images, mostly icons, which are generated using the generatePngIcons script: -set(IMAGES_THEMED - "images/themed/png/1" - "images/themed/png/2" - ) - # Other images which are generated manually: file(GLOB IMAGES_NONTHEMED LIST_DIRECTORIES false "images/non-themed/png/*") -file(GLOB IMAGES_NONTHEMED_1 LIST_DIRECTORIES false "images/non-themed/png/1/*") -file(GLOB IMAGES_NONTHEMED_2 LIST_DIRECTORIES false "images/non-themed/png/2/*") +file(GLOB SVG_THEMED LIST_DIRECTORIES false "images/themed/svg/*") if(WIN32) set(OPTIONSFILE "options/options.win") @@ -54,16 +47,10 @@ endif() install(DIRECTORY ${PROFILESDIR} DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") install(DIRECTORY ${THEMEDIR} DESTINATION "${DATADIR}") -foreach(theme ${IMAGES_THEMED}) - install(DIRECTORY ${theme} DESTINATION "${DATADIR}/images") -endforeach() - #install(DIRECTORY ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images" FILES_MATCHING PATTERN "*.png") #install(DIRECTORY ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images/") -install(FILES ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images") - -install(FILES ${IMAGES_NONTHEMED_1} DESTINATION "${DATADIR}/images/1") -install(FILES ${IMAGES_NONTHEMED_2} DESTINATION "${DATADIR}/images/2") +install(FILES ${IMAGES_NONTHEMED} DESTINATION "${DATADIR}/images") +install(FILES ${SVG_THEMED} DESTINATION "${DATADIR}/images") if(APPLE) # CMake escapes first item quote character. Do not remove 'DUMMY_VARIABLE=' diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 4ffad24a1..2b97da7a5 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories(${EXTRA_INCDIR} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} ${LENSFUN_INCLUDE_DIRS} + ${RSVG_INCLUDE_DIRS} ) link_directories("${PROJECT_SOURCE_DIR}/rtexif" @@ -23,6 +24,7 @@ link_directories("${PROJECT_SOURCE_DIR}/rtexif" ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS} + ${RSVG_LIBRARY_DIRS} ) set(CAMCONSTSFILE "camconst.json") @@ -65,7 +67,6 @@ set(RTENGINESOURCEFILES hilite_recon.cc iccjpeg.cc iccstore.cc - icons.cc iimage.cc image16.cc image8.cc @@ -184,6 +185,7 @@ target_link_libraries(rtengine rtexif ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} + ${RSVG_LIBRARIES} ) install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/icons.cc b/rtengine/icons.cc deleted file mode 100644 index 660b805bf..000000000 --- a/rtengine/icons.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * Copyright (c) 2018 Jean-Christophe FRISCH - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ - -#include "icons.h" - -#include - -namespace rtengine -{ - -Glib::ustring imagePath; -Glib::ustring imagePath1; -Glib::ustring imagePath2; - -Glib::ustring findIconAbsolutePath (const Glib::ustring& iconName, double &dpi) -{ - try { - double fallBackDPI = 0.; - Glib::ustring path; - Glib::ustring fallBackPath; - - if (dpi == 96.) { - path = imagePath1; - fallBackPath = imagePath2; - fallBackDPI = 192.; - } else { - path = imagePath2; - fallBackPath = imagePath1; - dpi = 192.; - fallBackDPI = 96.; - } - - auto iconPath = Glib::build_filename(path, iconName); - - if (Glib::file_test(iconPath, Glib::FILE_TEST_IS_REGULAR)) { - return iconPath; - } else { - // fallback solution - iconPath = Glib::build_filename(fallBackPath, iconName); - if (Glib::file_test(iconPath, Glib::FILE_TEST_IS_REGULAR)) { - dpi = fallBackDPI; - return iconPath; - } else { - // second fallback solution: icon not resolution dependent - iconPath = Glib::build_filename(imagePath, iconName); - if (Glib::file_test(iconPath, Glib::FILE_TEST_IS_REGULAR)) { - dpi = -1; - return iconPath; - } - } - } - - } catch(const Glib::Exception&) {} - - if (options.rtSettings.verbose) { - std::cerr << "Icon \"" << iconName << "\" (" << dpi << " dpi) could not be found!" << std::endl; - } - - return Glib::ustring(); -} - -void setPaths () -{ - // TODO: Forcing the Dark theme, so reading the icon set files is useless for now... - - /*Glib::ustring iconSet; - - // Either use the system icon set or the one specified in the options. - if (options.useSystemTheme) { - iconSet = Glib::build_filename (argv0, "themes", "system.iconset"); - } else { - iconSet = Glib::build_filename (argv0, "themes", options.theme + ".iconset"); - } - - imagePaths.clear (); - - if (!loadIconSet (iconSet)) { - // If the preferred icon set is unavailable, fall back to the default icon set. - loadIconSet (Glib::build_filename (argv0, "themes", "Default.iconset")); - }*/ - - imagePath1 = Glib::build_filename(argv0, "images", "1", "dark"); - imagePath2 = Glib::build_filename(argv0, "images", "2", "dark"); - - // The images folder is the second fallback solution. - imagePath = Glib::build_filename(argv0, "images"); -} - -} diff --git a/rtengine/icons.h b/rtengine/icons.h deleted file mode 100644 index d8572efca..000000000 --- a/rtengine/icons.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * Copyright (c) 2018 Jean-Christophe FRISCH - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _ICONS_ -#define _ICONS_ - -#include -#include "../rtgui/options.h" - -namespace rtengine -{ - -/** - * @brief Find the absolute path for an icon name of the desired DPI. - * - * @return the absolute path to the icon file - * @return deiredDPI is updated to another DPI if the desired one wasn't found but a fallback solution exist, or -1 if the icon is not resolution dependent - */ -Glib::ustring findIconAbsolutePath (const Glib::ustring& iconName, double &dpi); -void setPaths (); - -} - -#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 5ec204fc6..238ad8344 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -182,6 +182,7 @@ if(WIN32) ${GTKMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${LENSFUN_INCLUDE_DIRS} + ${RSVG_INCLUDE_DIRS} ) link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} @@ -192,6 +193,7 @@ if(WIN32) ${GTKMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS} + ${RSVG_LIBRARY_DIRS} ) else() include_directories(${EXTRA_INCDIR} @@ -209,6 +211,7 @@ else() ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} ${LENSFUN_INCLUDE_DIRS} + ${RSVG_INCLUDE_DIRS} ) link_directories(${EXTRA_LIBDIR} ${CANBERRA-GTK_LIBRARY_DIRS} @@ -225,6 +228,7 @@ else() ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} ${LENSFUN_LIBRARY_DIRS} + ${RSVG_LIBRARY_DIRS} ) endif() @@ -276,6 +280,7 @@ target_link_libraries(rth rtengine ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} + ${RSVG_LIBRARIES} ) target_link_libraries(rth-cli rtengine @@ -296,6 +301,7 @@ target_link_libraries(rth-cli rtengine ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} + ${RSVG_LIBRARIES} ) # Install executables diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 4d08e4c7d..bb6a590b6 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -56,25 +56,27 @@ void CursorManager::init (Glib::RefPtr mainWindow) Glib::RefPtr rotate = RTImage::createPixbufFromFile("rotate-aroundnode-hicontrast.png"); Glib::RefPtr wait = RTImage::createPixbufFromFile("gears.png"); // Currently unused, create *-hicontrast once used. - cAdd = add ? Gdk::Cursor::create(display, add, 8, 8) : Gdk::Cursor::create(display, Gdk::PLUS); - cAddPicker = colPickAdd ? Gdk::Cursor::create(display, colPickAdd, 4, 21) : Gdk::Cursor::create(display, Gdk::PLUS); - cCropDraw = cropDraw ? Gdk::Cursor::create(display, cropDraw, 3, 3) : Gdk::Cursor::create(display, Gdk::DIAMOND_CROSS); - cCrosshair = crosshair ? Gdk::Cursor::create(display, crosshair, 12, 12) : Gdk::Cursor::create(display, Gdk::CROSSHAIR); - cEmpty = empty ? Gdk::Cursor::create(display, empty, 12, 12) : Gdk::Cursor::create(display, Gdk::BLANK_CURSOR); - cHandClosed = handClosed ? Gdk::Cursor::create(display, handClosed, 12, 12) : Gdk::Cursor::create(display, Gdk::HAND1); - cHandOpen = handOpen ? Gdk::Cursor::create(display, handOpen, 12, 12) : Gdk::Cursor::create(display, Gdk::HAND2); - cMoveBL = moveBL ? Gdk::Cursor::create(display, moveBL, 12, 12) : Gdk::Cursor::create(display, Gdk::BOTTOM_LEFT_CORNER); - cMoveBR = moveBR ? Gdk::Cursor::create(display, moveBR, 12, 12) : Gdk::Cursor::create(display, Gdk::BOTTOM_RIGHT_CORNER); - cMoveL = moveL ? Gdk::Cursor::create(display, moveL, 12, 12) : Gdk::Cursor::create(display, Gdk::SB_LEFT_ARROW); - cMoveR = moveR ? Gdk::Cursor::create(display, moveR, 12, 12) : Gdk::Cursor::create(display, Gdk::SB_RIGHT_ARROW); - cMoveTL = moveTL ? Gdk::Cursor::create(display, moveTL, 12, 12) : Gdk::Cursor::create(display, Gdk::TOP_LEFT_CORNER); - cMoveTR = moveTR ? Gdk::Cursor::create(display, moveTR, 12, 12) : Gdk::Cursor::create(display, Gdk::TOP_RIGHT_CORNER); - cMoveX = moveX ? Gdk::Cursor::create(display, moveX, 12, 12) : Gdk::Cursor::create(display, Gdk::SB_H_DOUBLE_ARROW); - cMoveXY = moveXY ? Gdk::Cursor::create(display, moveXY, 12, 12) : Gdk::Cursor::create(display, Gdk::FLEUR); - cMoveY = moveY ? Gdk::Cursor::create(display, moveY, 12, 12) : Gdk::Cursor::create(display, Gdk::SB_V_DOUBLE_ARROW); - cRotate = rotate ? Gdk::Cursor::create(display, rotate, 12, 12) : Gdk::Cursor::create(display, Gdk::EXCHANGE); - cWB = colPick ? Gdk::Cursor::create(display, colPick, 4, 21) : Gdk::Cursor::create(display, Gdk::TARGET); - cWait = wait ? Gdk::Cursor::create(display, wait, 12, 12) : Gdk::Cursor::create(display, Gdk::CLOCK); + double s = RTScalable::getTweakedDPI() / 92.; // RTScalable::getDPI() might be preferable, however it imply a lot of work to support this option + + cAdd = add ? Gdk::Cursor::create(display, add, (int)(8.*s), (int)(8.*s)) : Gdk::Cursor::create(display, Gdk::PLUS); + cAddPicker = colPickAdd ? Gdk::Cursor::create(display, colPickAdd, (int)(4.*s), (int)(21.*s)) : Gdk::Cursor::create(display, Gdk::PLUS); + cCropDraw = cropDraw ? Gdk::Cursor::create(display, cropDraw, (int)(3.*s), (int)(3.*s)) : Gdk::Cursor::create(display, Gdk::DIAMOND_CROSS); + cCrosshair = crosshair ? Gdk::Cursor::create(display, crosshair, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::CROSSHAIR); + cEmpty = empty ? Gdk::Cursor::create(display, empty, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BLANK_CURSOR); + cHandClosed = handClosed ? Gdk::Cursor::create(display, handClosed, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND1); + cHandOpen = handOpen ? Gdk::Cursor::create(display, handOpen, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND2); + cMoveBL = moveBL ? Gdk::Cursor::create(display, moveBL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BOTTOM_LEFT_CORNER); + cMoveBR = moveBR ? Gdk::Cursor::create(display, moveBR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BOTTOM_RIGHT_CORNER); + cMoveL = moveL ? Gdk::Cursor::create(display, moveL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_LEFT_ARROW); + cMoveR = moveR ? Gdk::Cursor::create(display, moveR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_RIGHT_ARROW); + cMoveTL = moveTL ? Gdk::Cursor::create(display, moveTL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::TOP_LEFT_CORNER); + cMoveTR = moveTR ? Gdk::Cursor::create(display, moveTR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::TOP_RIGHT_CORNER); + cMoveX = moveX ? Gdk::Cursor::create(display, moveX, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_H_DOUBLE_ARROW); + cMoveXY = moveXY ? Gdk::Cursor::create(display, moveXY, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::FLEUR); + cMoveY = moveY ? Gdk::Cursor::create(display, moveY, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_V_DOUBLE_ARROW); + cRotate = rotate ? Gdk::Cursor::create(display, rotate, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::EXCHANGE); + cWB = colPick ? Gdk::Cursor::create(display, colPick, (int)(4.*s), (int)(21.*s)) : Gdk::Cursor::create(display, Gdk::TARGET); + cWait = wait ? Gdk::Cursor::create(display, wait, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::CLOCK); window = mainWindow; } diff --git a/rtgui/edit.cc b/rtgui/edit.cc index c7b1ca937..eb91d3fda 100644 --- a/rtgui/edit.cc +++ b/rtgui/edit.cc @@ -18,7 +18,6 @@ */ #include "edit.h" -#include "../rtengine/icons.h" ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(nullptr), objectMode(OM_255), dataProvider(dataProvider) {} diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index b93d7eede..3a5a0378d 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -23,7 +23,8 @@ #include #include "rtimage.h" #include "threadutils.h" -#include "../rtengine/icons.h" + +extern Glib::ustring argv0; // Check if the system has more than one display and option is set bool EditWindow::isMultiDisplayEnabled() @@ -148,23 +149,20 @@ void EditWindow::setAppIcon() downsize = true; } } - double resolution2 = resolution; - Glib::ustring fullPath = rtengine::findIconAbsolutePath(fName, resolution2); - if (!fullPath.empty()) { - const Glib::RefPtr pixbuf = Gdk::Pixbuf::create_from_file(fullPath); - if (!pixbuf) { - return; - } - if (downsize) { - int size = int((48. * resolution) / 192.); - pixbuf->scale_simple(size, size, Gdk::InterpType::INTERP_BILINEAR); - } + Glib::ustring icon_path = Glib::build_filename (argv0, "images", fName); + const Glib::RefPtr pixbuf = Gdk::Pixbuf::create_from_file(icon_path); + if (!pixbuf) { + return; + } + if (downsize) { + int size = int((48. * resolution) / 192.); + pixbuf->scale_simple(size, size, Gdk::InterpType::INTERP_BILINEAR); + } - try { - set_default_icon(pixbuf); - } catch(Glib::Exception& ex) { - printf ("%s\n", ex.what().c_str()); - } + try { + set_default_icon(pixbuf); + } catch(Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); } } diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 14f00bc29..9e991dd9e 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -22,7 +22,6 @@ #include "options.h" #include "../rtengine/rt_math.h" #include "../rtengine/utils.h" -#include "../rtengine/icons.h" #include "rtimage.h" #include "multilangmgr.h" diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 584412120..e5172c7e7 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -22,7 +22,6 @@ #include "multilangmgr.h" #include "cachemanager.h" #include "addsetids.h" -#include "../rtengine/icons.h" #include "../rtengine/color.h" #include "rtimage.h" #ifdef _OPENMP diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index df9b53c78..ddd42eb6a 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "../rtengine/icons.h" #include "soundman.h" #include "rtimage.h" #include "version.h" @@ -195,8 +194,6 @@ int main (int argc, char **argv) options.defProfImg = DEFPROFILE_INTERNAL; } - rtengine::setPaths(); - TIFFSetWarningHandler (nullptr); // avoid annoying message boxes #ifndef WIN32 diff --git a/rtgui/main.cc b/rtgui/main.cc index 134402ece..422edc0eb 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -28,7 +28,6 @@ #include #include #include -#include "../rtengine/icons.h" #include "rtwindow.h" #include #include @@ -253,8 +252,6 @@ RTWindow *create_rt_window() Glib::RefPtr defaultIconTheme = Gtk::IconTheme::get_default(); defaultIconTheme->append_search_path (icon_path); - rtengine::setPaths(); - // ------- loading theme files Glib::RefPtr screen = Gdk::Screen::get_default(); @@ -327,7 +324,7 @@ RTWindow *create_rt_window() css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", options.fontFamily, options.fontSize * scale); #endif //GTK318 - fontScale = options.fontSize / 9; + fontScale = options.fontSize / 9.f; } else if (scale == 2) { Glib::RefPtr style = Gtk::StyleContext::create(); Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); @@ -343,6 +340,7 @@ RTWindow *create_rt_window() if (isPix) { // 1pt = 1/72in @ 96 ppi + // HOMBRE: If the font unit is px, is it alredy scaled up to match the resolution ? double resolution = style->get_screen()->get_resolution(); // px >inch >pt >"scaled pt" int pt = (int)(fontSize / 96. * 72 * (96. / resolution) + 0.49); @@ -353,21 +351,20 @@ RTWindow *create_rt_window() pt /= 2.; } else { // fontSize is for scale==1, we have to scale up - css = Glib::ustring::compose ("* { font-size: %1px }", pt * scale); + css = Glib::ustring::compose ("* { font-size: %1pt }", pt * scale); } - fontScale = pt / 9; + fontScale = (float)pt / 9.f; } else { int pt = fontSize / Pango::SCALE; css = Glib::ustring::compose ("* { font-size: %1pt }", pt * scale); - fontScale = pt / 9; + fontScale = (float)pt / 9.f; } } else { - printf("La taille n'est pas specifiee\n"); fontScale = 1.f; } } if (!css.empty()) { - printf("CSS: %s", css.c_str()); + printf("CSS: %s\nfontScale: %.5f\n\n", css.c_str(), fontScale); try { cssForced = Gtk::CssProvider::create(); cssForced->load_from_data (css); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4151eacd4..c67d57fe6 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -22,7 +22,6 @@ #include "splash.h" #include "cachemanager.h" #include "addsetids.h" -#include "../rtengine/icons.h" #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" #include @@ -2099,7 +2098,6 @@ void Preferences::cancelPressed () { // set the initial theme back if (themeFNames.at (themeCBT->get_active_row_number ()).longFName != options.theme) { - rtengine::setPaths(); RTImage::updateImages(); switchThemeTo (options.theme); } @@ -2157,7 +2155,6 @@ void Preferences::themeChanged () { moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName; - rtengine::setPaths(); RTImage::updateImages(); switchThemeTo (moptions.theme); } diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 993b3e30b..bf74ebce6 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -23,7 +23,6 @@ #include #include "options.h" -#include "../rtengine/icons.h" namespace { @@ -85,7 +84,7 @@ void RTImage::setDPInScale (const double newDPI, const int newScale) RTScalable::setDPInScale(newDPI, newScale); dpiBack = getDPI(); scaleBack = getScale(); - printf("RTImage::setDPInScale : New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTImage\n", scaleBack, dpiBack, newDPI); + //printf("RTImage::setDPInScale : New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTImage\n", scaleBack, dpiBack, newDPI); updateImages(); } } @@ -96,13 +95,13 @@ void RTImage::changeImage (const Glib::ustring& imageName) if (pixbuf) { auto iterator = pixbufCache.find (imageName); - printf("changeImage / pixbufCache[%d] : \"%s\" %s!\n", (int)(pixbufCache.size()), imageName.c_str(), iterator == pixbufCache.end () ? "not found" : "found"); + //printf("changeImage / pixbufCache[%d] : \"%s\" %s!\n", (int)(pixbufCache.size()), imageName.c_str(), iterator == pixbufCache.end () ? "not found" : "found"); assert(iterator != pixbufCache.end ()); pixbuf = iterator->second; set(iterator->second); } else { // if no Pixbuf is set, we update or create a Cairo::ImageSurface auto iterator = surfaceCache.find (imageName); - printf("changeImage / surfaceCache[%d] : \"%s\" %s!\n", (int)(surfaceCache.size()), imageName.c_str(), iterator == surfaceCache.end () ? "not found" : "found"); + //printf("changeImage / surfaceCache[%d] : \"%s\" %s!\n", (int)(surfaceCache.size()), imageName.c_str(), iterator == surfaceCache.end () ? "not found" : "found"); if (iterator == surfaceCache.end ()) { auto surf = createImgSurfFromFile(imageName); iterator = surfaceCache.emplace (imageName, surf).first; @@ -139,37 +138,20 @@ Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::u { Cairo::RefPtr surf; - printf("Creating \"%s\"\n", fileName.c_str()); + //printf("Creating \"%s\"\n", fileName.c_str()); try { - - double requestedDPI = getDPI(); - const auto filePath = rtengine::findIconAbsolutePath (fileName, requestedDPI); - // requestedDPI is now the icon's DPI, not necessarily the one we asked - - if (!filePath.empty ()) { - surf = Cairo::ImageSurface::create_from_png(filePath); - } - - if (!surf) { - return surf; // nullptr - } - - if (getDPI() > 0. && requestedDPI != -1 && requestedDPI != getDPI()) { - // scale the bitmap - printf("Resizing from %.1f to %.1f DPI\n", requestedDPI, getDPI()); - resizeImage(surf, getDPI() / requestedDPI); - } + surf = loadImage(fileName, getTweakedDPI()); // HOMBRE: As of now, GDK_SCALE is forced to 1, so setting the Cairo::ImageSurface scale is not required /* double x=0., y=0.; cairo_surface_get_device_scale(surf->cobj(), &x, &y); - printf(" -> Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); + //printf(" -> Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); if (getScale() == 2) { cairo_surface_set_device_scale(surf->cobj(), 0.5, 0.5); cairo_surface_get_device_scale(surf->cobj(), &x, &y); surf->flush(); - printf(" Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); + //printf(" Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surf->get_width(), surf->get_height(), (float)x); } */ } catch (const Glib::Exception& exception) { diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 3f8c41a61..ff45f3d28 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -18,10 +18,18 @@ */ #include "rtscalable.h" -#include "../rtengine/icons.h" +#include +#include +#include +#include +#include +#include "options.h" double RTScalable::dpi = 0.; int RTScalable::scale = 0; + +extern Glib::ustring argv0; +extern Options options; extern float fontScale; extern unsigned char scale; Gtk::TextDirection RTScalable::direction = Gtk::TextDirection::TEXT_DIR_NONE; @@ -36,11 +44,16 @@ void RTScalable::setDPInScale (const double newDPI, const int newScale) if (scale == 2 && newDPI < 192) { dpi *= 2; } - printf("RTScalable::setDPInScale / New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTScalable\n", scale, dpi, newDPI); + //printf("RTScalable::setDPInScale / New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTScalable\n", scale, dpi, newDPI); } } double RTScalable::getDPI () +{ + return dpi; +} + +double RTScalable::getTweakedDPI () { return dpi * fontScale; } @@ -57,27 +70,114 @@ Gtk::TextDirection RTScalable::getDirection() void RTScalable::init(Gtk::Window *window) { - printf("RTScalable::init\n"); setDPInScale(window->get_screen()->get_resolution(), ::scale); direction = window->get_direction(); } -void RTScalable::resizeImage(Cairo::RefPtr &surf, double factor) +/* + * This function try to find the svg file converted to png in a cache and return + * the Cairo::ImageSurface. If it can't find it, it will generate it. + * + * If the provided filename doesn't end with ".svg" (and then we're assuming it's a png file), + * it will try to load that file directly from the source images folder. Scaling is disabled + * for anything else than svg files. + * + * This function will always return a usable value, but it might be a garbage image + * if something went wrong. + */ +Cairo::RefPtr RTScalable::loadImage(const Glib::ustring &fname, double dpi) { - if (options.fontFamily != "default") { - factor *= options.fontSize / 9; - } - int newWidth = int((double)surf->get_width() * factor); - int newHeight = int((double)surf->get_height() * factor); - printf("Resizing from %dx%d to %dx%d (factor: %.5f)\n", surf->get_width(), surf->get_height(), newWidth, newHeight, factor); - Cairo::RefPtr surf2 = Cairo::ImageSurface::create(surf->get_format(), newWidth, newHeight); - Cairo::RefPtr c = Cairo::Context::create(surf2); - c->scale (factor, factor); - c->set_source(surf, 0., 0.); - //Cairo::RefPtr p = Cairo::SurfacePattern::create(surf); - //p->set_filter (Cairo::FILTER_BILINEAR); - c->paint (); - surf2->flush(); + // Magic color : #2a7fff + // Dark theme color : #CCCCCC + // Light theme color : #252525 -- not used - surf = surf2; + Glib::ustring imagesFolder = Glib::build_filename (argv0, "images"); + Glib::ustring imagesCacheFolder = Glib::build_filename (options.cacheBaseDir, "svg2png"); + + // -------------------- Looking for the cached PNG file first -------------------- + + Glib::ustring imagesCacheFolderDPI = Glib::build_filename (imagesCacheFolder, Glib::ustring::compose("%1", (int)dpi)); + auto path = Glib::build_filename(imagesCacheFolderDPI, fname); + + if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { + return Cairo::ImageSurface::create_from_png(path); + } else { + + // -------------------- Looking for the PNG file in install directory -------------------- + + path = Glib::build_filename(imagesFolder, fname); + if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { + return Cairo::ImageSurface::create_from_png(path); + } + } + + // Last chance: looking for the svg file and creating the cached image file + + // -------------------- Creating the cache folder for PNGs -------------------- + + if (!Glib::file_test(imagesCacheFolderDPI.c_str(), Glib::FILE_TEST_EXISTS)) { + auto error = g_mkdir_with_parents (imagesCacheFolderDPI.c_str(), 0777); + if (error != 0) { + std::cerr << "ERROR: Can't create \"" << imagesCacheFolderDPI << "\" cache folder: " << g_strerror(error) << std::endl; + Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); + return surf; + } + } + + // -------------------- Loading the SVG file -------------------- + + std::string svgFile; + Glib::ustring iconNameSVG; + if (fname.find(".png") != Glib::ustring::npos) { + iconNameSVG = fname.substr(0, fname.length() - 3) + Glib::ustring("svg"); + } + try { + path = Glib::build_filename (imagesFolder, iconNameSVG); + //printf("Trying to get content of %s\n", path.c_str()); + svgFile = Glib::file_get_contents(Glib::build_filename (imagesFolder, iconNameSVG)); + } + catch (Glib::FileError &err) { + std::cerr << "ERROR: " << err.what() << std::endl; + Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); + return surf; + } + + // -------------------- Updating the the magic color -------------------- + + std::string updatedSVG = std::regex_replace(svgFile, std::regex("#2a7fff"), "#CCCCCC"); + + // -------------------- Creating the rsvg handle -------------------- + + GError **error = nullptr; + RsvgHandle *handle = rsvg_handle_new_from_data((unsigned const char*)updatedSVG.c_str(), updatedSVG.length(), error); + + if (handle == nullptr) { + std::cerr << "ERROR: Can't use the provided data for \"" << fname << "\" to create a RsvgHandle:" << std::endl + << Glib::ustring((*error)->message) << std::endl; + Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); + return surf; + } + + // -------------------- Drawing the image to a Cairo::ImageSurface -------------------- + + RsvgDimensionData dim; + rsvg_handle_get_dimensions(handle, &dim); + double r = dpi / 92.; + Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, (int)(dim.width * r + 0.499), (int)(dim.height * r + 0.499)); + Cairo::RefPtr c = Cairo::Context::create(surf); + c->set_source_rgba (0., 0., 0., 0.); + c->set_operator (Cairo::OPERATOR_CLEAR); + c->paint (); + c->set_operator (Cairo::OPERATOR_OVER); + c->scale(r, r); + rsvg_handle_render_cairo(handle, c->cobj()); + rsvg_handle_free(handle); + + // -------------------- Saving the image in cache -------------------- + + surf->write_to_png(Glib::build_filename(imagesCacheFolderDPI, fname)); + + // -------------------- Finished! Pfeeew ! -------------------- + + return surf; } diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index c375da46c..872fc2674 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -32,13 +32,13 @@ class RTScalable protected: static void setDPInScale (const double newDPI, const int newScale); - static double getDPI (); // The returned value is tweaked DPI to adapt to main the font size. Maybe not an ideal solution. - static int getScale (); - static void resizeImage(Cairo::RefPtr &surf, double factor); + static Cairo::RefPtr loadImage(const Glib::ustring &fname, double dpi); Gtk::TextDirection getDirection(); public: static void init(Gtk::Window *window); - + static double getDPI (); + static double getTweakedDPI (); // The returned value is tweaked DPI to adapt to main the font size. Maybe not an ideal solution. + static int getScale (); }; diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index d11e2c83f..faf1a750d 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -20,7 +20,6 @@ #include #include "options.h" -#include "../rtengine/icons.h" #include "rtsurface.h" namespace @@ -70,7 +69,7 @@ void RTSurface::setDPInScale (const double newDPI, const int newScale) RTScalable::setDPInScale(newDPI, newScale); dpiBack = getDPI(); scaleBack = getScale(); - printf("RTSurface::setDPInScale : New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTSurface\n", scaleBack, dpiBack, newDPI); + //printf("RTSurface::setDPInScale : New scale = %d & new DPI = %.3f (%.3f asked) -> Reloading all RTSurface\n", scaleBack, dpiBack, newDPI); updateImages(); } } @@ -80,26 +79,16 @@ void RTSurface::changeImage (Glib::ustring imageName) auto iterator = surfaceCache.find (imageName); if (iterator == surfaceCache.end ()) { - double requestedDPI = getDPI(); - const auto imagePath = rtengine::findIconAbsolutePath (imageName, requestedDPI); - surface = Cairo::ImageSurface::create_from_png(imagePath); - - if (getDPI() > 0. && requestedDPI != -1 && requestedDPI != getDPI()) { - // scale the bitmap - printf("Resizing from %.1f to %.1f DPI\n", requestedDPI, getDPI()); - resizeImage(surface, getDPI() / requestedDPI); - } + surface = loadImage(imageName, getTweakedDPI()); // HOMBRE: As of now, GDK_SCALE is forced to 1, so setting the Cairo::ImageSurface scale is not required + // Anyway, this might be of use one day /* double x=0., y=0.; cairo_surface_get_device_scale(surface->cobj(), &x, &y); - printf(" -> Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surface->get_width(), surface->get_height(), (float)x); if (getScale() == 2) { - cairo_surface_set_device_scale(surface->cobj(), 0.5, 0.5); - cairo_surface_get_device_scale(surface->cobj(), &x, &y); + cairo_surface_set_device_scale(surface->cobj(), 0.5, 0.5); // Not sure if it should be 0.5 or 2.0 here ! surface->flush(); - printf(" Cairo::ImageSurface is now %dx%d (scale: %.1f)\n", surface->get_width(), surface->get_height(), (float)x); } */ @@ -127,11 +116,10 @@ void RTSurface::init() void RTSurface::updateImages() { - for (auto& entry : surfaceCache) { - double imgDPI = getDPI(); - const auto imagePath = rtengine::findIconAbsolutePath (entry.first, imgDPI); - entry.second = Cairo::ImageSurface::create_from_png(imagePath); - printf("RTSurface::updateImages : %s\n", imagePath.c_str()); + double res = getTweakedDPI(); + for (auto entry : surfaceCache) { + entry.second = loadImage(entry.first, res); + //printf("RTSurface::updateImages : %s\n", entry.first.c_str()); } } diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index c40fa2850..58093d323 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -28,6 +28,7 @@ class RTSurface : public RTScalable { static double dpiBack; // used to keep track of master dpi change static int scaleBack; // used to keep track of master scale change + void changeImage (Glib::ustring imageName); public: Cairo::RefPtr surface; @@ -37,7 +38,6 @@ public: RTSurface (Glib::ustring fileName, Glib::ustring rtlFileName = Glib::ustring()); void setImage (Glib::ustring fileName, Glib::ustring rtlFileName = Glib::ustring()); - void changeImage (Glib::ustring imageName); int getWidth() const; int getHeight() const; bool hasSurface() const; diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 943a4b683..3fff7b70e 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -25,7 +25,6 @@ #include "cursormanager.h" #include "rtimage.h" #include "whitebalance.h" -#include "../rtengine/icons.h" extern int scale; @@ -93,11 +92,11 @@ RTWindow::RTWindow () { cacheMgr->init (); - WhiteBalance::init(); - ProfilePanel::init (this); RTScalable::init(this); RTSurface::init(); RTImage::init(); + WhiteBalance::init(); + ProfilePanel::init (this); MyExpander::init(); #ifndef WIN32