From a2e69336c79fe27c728edc2576cb53f69c4e53fe Mon Sep 17 00:00:00 2001 From: rolandlo Date: Fri, 29 Jan 2021 11:27:31 +0100 Subject: [PATCH] add plugin for migrating font sizes --- debian/control | 1 + plugins/MigrateFontSizes/dialog.glade | 341 ++++++++++++++++++++++++++ plugins/MigrateFontSizes/main.lua | 87 +++++++ plugins/MigrateFontSizes/plugin.ini | 15 ++ readme/LinuxBuild.md | 8 +- src/plugin/luapi_application.h | 49 ++++ 6 files changed, 497 insertions(+), 4 deletions(-) create mode 100644 plugins/MigrateFontSizes/dialog.glade create mode 100644 plugins/MigrateFontSizes/main.lua create mode 100644 plugins/MigrateFontSizes/plugin.ini diff --git a/debian/control b/debian/control index c5dc1c24..1952387f 100644 --- a/debian/control +++ b/debian/control @@ -9,6 +9,7 @@ Homepage: https://github.com/xournalpp/xournalpp/ Package: xournalpp Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-0 (>= 2.32), libgtk-3-0 (>= 3.18), libpoppler-glib8 (>= 0.41.0), libxml2 (>= 2.0.0), libportaudiocpp0 (>= 12), libsndfile1 (>= 1.0.25), liblua5.3-0, libzip4 (>= 1.0.1) | libzip5, zlib1g, libc6, librsvg2-2 (>= 2.40) +Recommends: lua-lgi Suggests: texlive-base, texlive-latex-extra Description: Xournal++ - Open source hand note-taking program Xournal++ is a hand note taking software written in C++ with the target of diff --git a/plugins/MigrateFontSizes/dialog.glade b/plugins/MigrateFontSizes/dialog.glade new file mode 100644 index 00000000..5d1144f1 --- /dev/null +++ b/plugins/MigrateFontSizes/dialog.glade @@ -0,0 +1,341 @@ + + + + + + 13 + 400 + 223 + 1 + 10 + + + 0.17999999999999999 + 5.5499999999999998 + 3.0899999999999999 + 0.01 + 1 + + + False + False + dialog + + + + + + False + 12 + 12 + 12 + 12 + vertical + 2 + + + False + end + + + gtk-cancel + True + True + True + True + + + True + True + 0 + + + + + gtk-apply + True + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + True + False + 12 + vertical + 12 + + + True + False + Migrate font sizes + + + + + + False + True + 0 + + + + + True + True + + + True + False + In Xournal++ versions 1.0.x and earlier version of 1.1.0+dev font sizes were relative +to the display DPI setting from the preferences (slider in the zoom panel). Only +with the standard setting of 72 DPI the fonts were saved with their true size. With a +20 pt Sans Regular font, two subsequent lines of text should be separated exactly +by the distance between two subsequent lines of the ruled paper background. +With 144 DPI (i.e. the doubled value) you however needed a font size of 10 pt +(the half value) for that purpose. This was confusing. + +We have changed that so that 20 pt Sans Regular will always fit to the ruled paper +background lines regardless of the display DPI setting. + +If you have created documents with a different display DPI setting than 72, you will +now see font sizes that are of different size then they looked like when you created +them. This plugin allows to correct that in the current document for once and +forever. For that purpose we need to scale all font sizes of the document with the +factor f = OldDPI / 72, where OldDPI is the display DPI value with which the +document was created. + True + 55 + + + + + True + False + Show help + + + + + + + + False + True + 1 + + + + + True + False + 12 + + + True + False + Current Display DPI + + + + + + False + True + 0 + + + + + True + False + 24 + 223 + 5 + 5 + + + False + True + 1 + + + + + False + True + 2 + + + + + True + False + 12 + 6 + + + True + False + start + Scale Factor + + + + + + 4 + 0 + + + + + True + False + start + DPI Normalization + + + + + + 2 + 0 + + + + + True + False + start + Old DPI + + + + + + 0 + 0 + + + + + True + True + 6 + 5 + 223 + adjOldDpi + True + 232 + + + 0 + 1 + + + + + True + False + 24 + / + + + 1 + 1 + + + + + True + False + 24 + = + + + 3 + 1 + + + + + True + True + 10 + 8 + 0.01 + adjScaleFactor + 4 + True + 3.0899999999999999 + + + 4 + 1 + + + + + True + False + 72 + + + 2 + 1 + + + + + + + + + + + False + True + 3 + + + + + True + False + start + 12 + Click "Apply" to scale font sizes of all elements of the document by the scale factor. +Save the document, when you are done. + + + False + True + 4 + + + + + False + True + 1 + + + + + + diff --git a/plugins/MigrateFontSizes/main.lua b/plugins/MigrateFontSizes/main.lua new file mode 100644 index 00000000..2a44c35b --- /dev/null +++ b/plugins/MigrateFontSizes/main.lua @@ -0,0 +1,87 @@ +-- Register all Toolbar actions and intialize all UI stuff +function initUi() + app.registerUi({["menu"] = "Migrate font sizes with factor displayDPI / 72", ["callback"] = "migrate"}); + app.registerUi({["menu"] = "Show font size migration dialog", ["callback"] = "showDialog"}); + + lgiInstallPaths = "/usr/share/lua/5.3/?.lua; /usr/local/share/lua/5.3/?.lua" -- change this if your lgi.lua file is located in a different directory + package.path = package.path .. ";../?.lua;" .. lgiInstallPaths + + sourcePath = debug.getinfo(1).source:match("@?(.*/)") +end + +function migrate() + local displayDpi = app.getDisplayDpi() + local dpiNormalizationFactor = 72 + local factor = displayDpi / dpiNormalizationFactor + -- print("Display DPI is " .. displayDpi .. " => scaling by factor " .. displayDpi .. "/72 = " .. factor) + local result = app.msgbox("Display DPI is " .. displayDpi .. ". By proceeding the font sizes of all text elements will be scaled by the factor " .. displayDpi .. "/72 = " .. factor, {[1]="Cancel", [2]="OK"}) + if result == 2 then + resize(factor) + end +end + +local currDpi + +function showDialog() + local hasLgi, lgi = pcall(require, "lgi") + if not hasLgi then + app.msgbox("You need to have the Lua lgi-module installed in order to use the GUI for migrating font sizes. \n\n Also check the lgi module install paths in the file \n\n " .. sourcePath .. "main.lua \n\n Currently \n\n" .. lgiInstallPaths .. "\n\n is specified", {[1]="OK"}) + return + end + + --lgi module has been found + local Gtk = lgi.Gtk + local Gdk = lgi.Gdk + local assert = lgi.assert + local builder = Gtk.Builder() + assert(builder:add_from_file(sourcePath .. "dialog.glade")) + local ui = builder.objects + local dialog = ui.dlgMigrateFontSizes + + if not currDpi then + currDpi = app.getDisplayDpi() + end + ui.spbtOldDpi:set_value(currDpi) + ui.lblCurrentDpi:set_text(app.getDisplayDpi()) + +-- Connect actions + function ui.btApply.on_clicked() + local factor = ui.spbtScaleFactor:get_value() + resize(factor) + end + + function ui.btCancel.on_clicked() + dialog:destroy() + end + + function ui.spbtScaleFactor.on_value_changed() + factor = ui.spbtScaleFactor:get_value() + currDpi = math.floor(factor*72+0.5) + ui.spbtOldDpi:set_value(currDpi) + end + + function ui.spbtOldDpi.on_value_changed() + oldDpi = ui.spbtOldDpi:get_value() + ui.spbtScaleFactor:set_value(oldDpi/72) + end + + dialog:show_all() +end + +function resize(factor) + local docStructure = app.getDocumentStructure() + local numPages = #docStructure["pages"] + local page = docStructure["currentPage"] + local layer = docStructure["pages"][page]["currentLayer"] + + for i=1, numPages do + app.setCurrentPage(i) + local numLayers = #docStructure["pages"][page]["layers"] + for j=1, numLayers do + app.setCurrentLayer(j) + app.scaleTextElements(factor) + end + end + app.setCurrentPage(page) + app.setCurrentLayer(layer) +end diff --git a/plugins/MigrateFontSizes/plugin.ini b/plugins/MigrateFontSizes/plugin.ini new file mode 100644 index 00000000..01868db1 --- /dev/null +++ b/plugins/MigrateFontSizes/plugin.ini @@ -0,0 +1,15 @@ +[about] +## Author / Copyright notice +author=Roland Lötscher + +description=Migrate font sizes to Display DPI independent font size handling since Feb 2021 + +## If the plugin is packed with Xournal++, use +## then it gets the same version number +version= + +[default] +enabled=true + +[plugin] +mainfile=main.lua diff --git a/readme/LinuxBuild.md b/readme/LinuxBuild.md index 63883dee..9afb188b 100644 --- a/readme/LinuxBuild.md +++ b/readme/LinuxBuild.md @@ -24,26 +24,26 @@ The minimum required CMake version is 3.10, but we recommend to use >=3.15. #### For Arch ```bash sudo pacman -S cmake gtk3 base-devel libxml2 cppunit portaudio libsndfile \ -poppler-glib texlive-bin texlive-pictures gettext libzip +poppler-glib texlive-bin texlive-pictures gettext libzip lua53 lua53-lgi ``` #### For Fedora/CentOS/RHEL: ```bash sudo dnf install gcc-c++ cmake gtk3-devel libxml2-devel cppunit-devel portaudio-devel libsndfile-devel \ poppler-glib-devel texlive-scheme-basic texlive-dvipng 'tex(standalone.cls)' gettext libzip-devel \ -librsvg2-devel +librsvg2-devel lua-devel lua-lgi ``` #### For Ubuntu/Debian and Raspberry Pi OS: ````bash sudo apt-get install cmake libgtk-3-dev libpoppler-glib-dev portaudio19-dev libsndfile-dev \ -libcppunit-dev dvipng texlive libxml2-dev liblua5.3-dev libzip-dev librsvg2-dev gettext +libcppunit-dev dvipng texlive libxml2-dev liblua5.3-dev libzip-dev librsvg2-dev gettext lua-lgi ```` #### For openSUSE: ```bash sudo zypper install cmake gtk3-devel cppunit-devel portaudio-devel libsndfile-devel \ -texlive-dvipng texlive libxml2-devel libpoppler-glib-devel libzip-devel librsvg-devel +texlive-dvipng texlive libxml2-devel libpoppler-glib-devel libzip-devel librsvg-devel lua-lgi ``` #### For Solus: diff --git a/src/plugin/luapi_application.h b/src/plugin/luapi_application.h index 16165315..2e424043 100644 --- a/src/plugin/luapi_application.h +++ b/src/plugin/luapi_application.h @@ -17,7 +17,9 @@ #include "control/Tool.h" #include "control/layer/LayerController.h" #include "control/pagetype/PageTypeHandler.h" +#include "gui/XournalView.h" #include "gui/widgets/XournalWidget.h" +#include "model/Text.h" #include "StringUtils.h" #include "XojMsgBox.h" @@ -784,6 +786,51 @@ static int applib_setBackgroundName(lua_State* L) { } +/** + * Scales all text elements of the current layer by the given scale factor. + * This means the font sizes get scaled, wheras the position of the left upper corner + * of the bounding box remains unchanged + * + * Example: app.scaleTextElements(2.3) + * scales all text elements on the current layer with factor 2.3 + **/ +static int applib_scaleTextElements(lua_State* L) { + Plugin* plugin = Plugin::getPluginFromLua(L); + Control* control = plugin->getControl(); + + double f = luaL_checknumber(L, 1); + + control->clearSelectionEndText(); + + std::vector elements = *control->getCurrentPage()->getSelectedLayer()->getElements(); + + for (Element* e: elements) { + if (e->getType() == ELEMENT_TEXT) { + Text* t = static_cast(e); + t->scale(t->getX(), t->getY(), f, f, 0.0, false); + } + } + + elements.clear(); + + return 1; +} + + +/** + * Gets the display DPI. + * Example: app.getDisplayDpi() + **/ +static int applib_getDisplayDpi(lua_State* L) { + Plugin* plugin = Plugin::getPluginFromLua(L); + Control* control = plugin->getControl(); + int dpi = control->getSettings()->getDisplayDpi(); + lua_pushinteger(L, dpi); + + return 1; +} + + /* * The full Lua Plugin API. * See above for example usage of each function. @@ -807,6 +854,8 @@ static const luaL_Reg applib[] = {{"msgbox", applib_msgbox}, {"setLayerVisibility", applib_setLayerVisibility}, {"setCurrentLayerName", applib_setCurrentLayerName}, {"setBackgroundName", applib_setBackgroundName}, + {"scaleTextElements", applib_scaleTextElements}, + {"getDisplayDpi", applib_getDisplayDpi}, // Placeholder // {"MSG_BT_OK", nullptr},