diff --git a/pd/nw/index.js b/pd/nw/index.js index e25c3a8885cb3cec9fcf33c29da2bd956407c754..7304cedb5cf56fd088440fea8cdff4179869d674 100644 --- a/pd/nw/index.js +++ b/pd/nw/index.js @@ -25,7 +25,7 @@ function have_args() { } function set_vars(win) { - var port_no, gui_dir; + var port_no, gui_dir, font_engine_sanity; // If the GUI was started by Pd, our port number is going to be // the first argument. If the GUI is supposed to start Pd, we won't // have any arguments and need to set it here. @@ -47,6 +47,7 @@ function set_vars(win) { pdgui.set_pwd(pwd); pdgui.set_gui_dir(gui_dir); pdgui.set_pd_window(win); + font_engine_sanity = pdgui.set_font_engine_sanity(win); pdgui.set_app_quitfn(app_quit); pdgui.set_open_html_fn(open_html); pdgui.set_open_textfile_fn(open_textfile); @@ -55,6 +56,11 @@ function set_vars(win) { // nw context callbacks (mostly just creating/destroying windows) pdgui.set_new_window_fn(nw_create_window); pdgui.set_close_window_fn(nw_close_window); + if (!font_engine_sanity) { + pdgui.post("warning: your system's font stack is maintained by troglodytes."); + } else { + pdgui.post("font stack check: using optimal font sizes."); + } } function app_quit() { diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js index b9ea297b8b0a4f602f379d071e49fc1c501aab80..40dfd2a9b60c21d900412be232318fe4c56be23f 100644 --- a/pd/nw/pd_canvas.js +++ b/pd/nw/pd_canvas.js @@ -521,7 +521,7 @@ var canvas_events = (function() { // mention that it was non-trivial for me to do the math // of inverting and multiplying the matrices from within // a Pd patch. And I'm the author of this API. Make - // of that what you will... + // of that what you will...) minv = draggable_elem.getCTM().inverse(), tx = minv.a * dx + minv.c * dy, ty = minv.b * dx + minv.d * dy; diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index ba198ad69071d0c7e51d79db6abcc4dbb462cfa0..951782ac92b7d041701fc9085a7a438f0dff6357 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -89,6 +89,47 @@ exports.set_pd_window = function(win) { exports.pd_window = win; } +var font_engine_sanity; + +// Here we use an HTML5 canvas hack to measure the width of +// the text to check for a font rendering anomaly. Here's why: +// +// It was reported that Ubuntu 16.04, Arch-- and probably most other Gnu/Linux +// distros going forward-- all end up with text extending past the box border. +// The test_text below is the string used in the bug report. +// OSX, Windows, and older Gnu/Linux stacks (like Ubuntu 14.04) all render +// this text with a width that is within half a pixel of each other (+- 217). +// +// Newer versions of Ubuntu and Arch measured nearly 7 pixels wider. +// +// I don't know what the new Gnu/Linux stack is up to (and I don't have the +// time to spelunk) but it's out of whack with the rest of the desktop +// rendering engines. Worse, there's some kind of quantization going on that +// keeps the new Gnu/Linux stack from hitting anything close to the font +// metrics of Pd Vanilla. +// +// Anyhow, we check for the discrepancy and try our best not to make newer +// versions of Gnu/Linux distros look too shitty... +exports.set_font_engine_sanity = function(win) { + var canvas = win.document.createElement("canvas"), + ctx = canvas.getContext("2d"), + test_text = "struct theremin float x float y"; + canvas.id = "font_sanity_checker_canvas"; + win.document.body.appendChild(canvas); + ctx.font = "11.65px DejaVu Sans Mono"; + if (Math.floor(ctx.measureText(test_text).width) <= 217) { + font_engine_sanity = true; + } else { + font_engine_sanity = false; + } + canvas.parentNode.removeChild(canvas); + return font_engine_sanity; +} + +function font_stack_is_maintained_by_troglodytes() { + return !font_engine_sanity; +} + var nw_create_window; var nw_close_window; var nw_app_quit; @@ -1694,24 +1735,46 @@ function text_to_tspans(canvasname, svg_text, text) { // we can revisit the issue. Even Pd-Vanilla's box sizing // changed at version 0.43, so we can break as well if // it comes to that. + +function font_map() { + return { + // pd_size: gui_size + 8: 8.33, + 12: 11.65, + 16: 16.65, + 24: 23.3, + 36: 36.6 + }; +} + +// This is a suboptimal font map, necessary because some genius "improved" +// the font stack on Gnu/Linux by delivering font metrics that don't match +// at all with what you get in OSX, Windows, nor even the previous version +// of the Gnu/Linux stack. +function suboptimal_font_map() { + return { + // pd_size: gui_size + 8: 8.45, + 12: 11.4, + 16: 16.45, + 24: 23.3, + 36: 36 + } +} + function gobj_fontsize_kludge(fontsize, return_type) { // These were tested on an X60 running Trisquel (based // on Ubuntu) var ret, prop, - fontmap = { - // pd_size: gui_size - 8: 8.33, - 12: 11.65, - 16: 16.65, - 24: 23.3, - 36: 36.6 }; + fmap = font_stack_is_maintained_by_troglodytes() ? + suboptimal_font_map() : font_map(); if (return_type === "gui") { - ret = fontmap[fontsize]; + ret = fmap[fontsize]; return ret ? ret : fontsize; } else { - for (prop in fontmap) { - if (fontmap.hasOwnProperty(prop)) { - if (fontmap[prop] == fontsize) { + for (prop in fmap) { + if (fmap.hasOwnProperty(prop)) { + if (fmap[prop] == fontsize) { return +prop; } }