greghendershott / racket-mode

Emacs major and minor modes for Racket: edit, REPL, check-syntax, debug, profile, packages, and more.
https://www.racket-mode.com/
GNU General Public License v3.0
683 stars 92 forks source link

Image size should not depend on font size #529

Closed sorawee closed 3 years ago

sorawee commented 3 years ago

In DrRacket, the program:

#lang racket

(require 2htdp/image)

(circle 50 "solid" "red")

produces an image. I can increase/decrease font size, but evaluating the program will always produce the image with the same size.

However, in Racket Mode, evaluating the program when font size is large will produce a large circle, while evaluating the program when font size is small will produce a small circle.

((alist-get 'racket-mode package-alist))
((emacs-version "27.1")
 (system-type darwin)
 (x-gtk-use-system-tooltips UNDEFINED)
 (major-mode racket-mode)
 (racket--el-source-dir "/Users/sorawee/.emacs.d/.local/straight/build-27.1/racket-mode/")
 (racket--rkt-source-dir "/Users/sorawee/.emacs.d/.local/straight/build-27.1/racket-mode/racket/")
 (racket-program "racket")
 (racket-command-timeout 10)
 (racket-xp-after-change-refresh-delay 1)
 (racket-xp-highlight-unused-regexp "^[^_]")
 (racket-repl-buffer-name-function nil)
 (racket-memory-limit 2048)
 (racket-error-context medium)
 (racket-history-filter-regexp "\\`\\s *\\'")
 (racket-images-inline t)
 (racket-images-keep-last 100)
 (racket-images-system-viewer "open")
 (racket-images-system-viewer "open")
 (racket-use-repl-submit-predicate nil)
 (racket-pretty-print t)
 (racket-indent-curly-as-sequence t)
 (racket-indent-sequence-depth 0)
 (racket-pretty-lambda nil)
 (racket-smart-open-bracket-enable nil)
 (racket-module-forms "\\s(\\(?:module[*+]?\\|library\\)")
 (racket-logger-config
  ((cm-accomplice . warning)
   (GC . info)
   (module-prefetch . warning)
   (optimizer . info)
   (racket/contract . error)
   (sequence-specialization . info)
   (* . fatal)))
 (racket-show-functions
  (racket-show-pseudo-tooltip)))
(enabled-minor-modes
 (+popup-mode)
 (auto-composition-mode)
 (auto-compression-mode)
 (auto-encryption-mode)
 (auto-fill-mode)
 (auto-save-mode)
 (better-jumper-local-mode)
 (better-jumper-mode)
 (centaur-tabs-mode)
 (column-number-mode)
 (company-mode)
 (delete-selection-mode)
 (diff-hl-margin-mode)
 (display-fill-column-indicator-mode)
 (display-line-numbers-mode)
 (doom-modeline-mode)
 (dtrt-indent-mode)
 (editorconfig-mode)
 (electric-indent-mode)
 (evil-escape-mode)
 (evil-goggles-mode)
 (evil-local-mode)
 (evil-mode)
 (evil-snipe-override-local-mode)
 (evil-snipe-override-mode)
 (evil-surround-mode)
 (file-name-shadow-mode)
 (flycheck-mode)
 (flycheck-popup-tip-mode)
 (font-lock-mode)
 (gcmh-mode)
 (general-override-mode)
 (global-company-mode)
 (global-eldoc-mode)
 (global-evil-surround-mode)
 (global-flycheck-mode)
 (global-font-lock-mode)
 (global-git-commit-mode)
 (global-hl-line-mode)
 (global-so-long-mode)
 (global-undo-fu-session-mode)
 (global-visual-line-mode)
 (highlight-indent-guides-mode)
 (highlight-numbers-mode)
 (highlight-quoted-mode)
 (hl-line-mode)
 (hl-todo-mode)
 (hs-minor-mode)
 (ivy-mode)
 (ivy-rich-mode)
 (ivy-rich-project-root-cache-mode)
 (line-number-mode)
 (lispy-mode)
 (lispyville-mode)
 (mac-mouse-wheel-mode)
 (ns-auto-titlebar-mode)
 (persp-mode)
 (projectile-mode)
 (racket-xp-mode)
 (rainbow-delimiters-mode)
 (ranger-override-dired-mode)
 (recentf-mode)
 (save-place-mode)
 (savehist-mode)
 (semantic-minor-modes-format)
 (shell-dirtrack-mode)
 (show-paren-mode)
 (show-smartparens-global-mode)
 (show-smartparens-mode)
 (size-indication-mode)
 (smartparens-global-mode)
 (smartparens-mode)
 (solaire-global-mode)
 (solaire-mode)
 (transient-mark-mode)
 (undo-fu-mode)
 (undo-fu-session-mode)
 (vi-tilde-fringe-mode)
 (visual-line-mode)
 (which-key-mode)
 (whitespace-mode)
 (window-divider-mode)
 (winner-mode)
 (ws-butler-global-mode)
 (ws-butler-mode)
 (yas-minor-mode))
(disabled-minor-modes
 (+emacs-lisp-ert-mode)
 (+javascript-gulp-mode)
 (+javascript-npm-mode)
 (+lsp-optimization-mode)
 (+org-pretty-mode)
 (+popup-buffer-mode)
 (+web-angularjs-mode)
 (+web-django-mode)
 (+web-jekyll-mode)
 (+web-phaser-mode)
 (+web-react-mode)
 (+web-wordpress-mode)
 (abbrev-mode)
 (amx-debug-mode)
 (amx-mode)
 (auto-fill-function)
 (auto-revert-mode)
 (auto-revert-tail-mode)
 (auto-save-visited-mode)
 (avy-linum-mode)
 (blink-cursor-mode)
 (buffer-face-mode)
 (buffer-read-only)
 (bug-reference-mode)
 (bug-reference-prog-mode)
 (centaur-tabs-local-mode)
 (cl-old-struct-compat-mode)
 (company-search-mode)
 (compilation-minor-mode)
 (compilation-shell-minor-mode)
 (completion-in-region-mode)
 (counsel-mode)
 (counsel-projectile-mode)
 (cursor-intangible-mode)
 (cursor-sensor-mode)
 (dash-fontify-mode)
 (defining-kbd-macro)
 (diff-auto-refine-mode)
 (diff-hl-dir-mode)
 (diff-hl-dired-mode)
 (diff-hl-margin-local-mode)
 (diff-hl-mode)
 (diff-minor-mode)
 (dired-hide-details-mode)
 (doom-big-font-mode)
 (dtrt-indent-global-mode)
 (edebug-mode)
 (eldoc-mode)
 (electric-layout-mode)
 (electric-quote-mode)
 (evil-collection-magit-toggle-text-minor-mode)
 (evil-snipe-local-mode)
 (evil-snipe-mode)
 (flyspell-mode)
 (general-override-local-mode)
 (git-commit-mode)
 (git-gutter-mode)
 (global-auto-revert-mode)
 (global-dash-fontify-mode)
 (global-diff-hl-mode)
 (global-display-fill-column-indicator-mode)
 (global-display-line-numbers-mode)
 (global-git-gutter-mode)
 (global-hide-mode-line-mode)
 (global-hl-todo-mode)
 (global-prettify-symbols-mode)
 (global-reveal-mode)
 (global-semantic-highlight-edits-mode)
 (global-semantic-highlight-func-mode)
 (global-semantic-show-parser-state-mode)
 (global-semantic-show-unmatched-syntax-mode)
 (global-semantic-stickyfunc-mode)
 (global-vi-tilde-fringe-mode)
 (global-whitespace-mode)
 (global-whitespace-newline-mode)
 (goto-address-mode)
 (goto-address-prog-mode)
 (hide-mode-line-mode)
 (horizontal-scroll-bar-mode)
 (ibuffer-auto-mode)
 (ido-everywhere)
 (isearch-mode)
 (ispell-minor-mode)
 (jit-lock-debug-mode)
 (lispy-goto-mode)
 (lispy-other-mode)
 (mac-auto-ascii-mode)
 (mac-auto-operator-composition-mode)
 (mac-font-panel-mode)
 (magit-auto-revert-mode)
 (magit-blame-mode)
 (magit-blame-read-only-mode)
 (magit-blob-mode)
 (magit-gitflow-mode)
 (magit-popup-help-mode)
 (magit-todos-mode)
 (magit-wip-after-apply-mode)
 (magit-wip-after-save-local-mode)
 (magit-wip-after-save-mode)
 (magit-wip-before-change-mode)
 (magit-wip-initial-backup-mode)
 (magit-wip-mode)
 (mail-abbrevs-mode)
 (menu-bar-mode)
 (mml-mode)
 (mouse-wheel-mode)
 (next-error-follow-minor-mode)
 (org-capture-mode)
 (org-cdlatex-mode)
 (org-list-checkbox-radio-mode)
 (org-src-mode)
 (org-table-follow-field-mode)
 (org-table-header-line-mode)
 (orgtbl-mode)
 (outline-minor-mode)
 (overwrite-mode)
 (paragraph-indent-minor-mode)
 (pcre-mode)
 (prettify-symbols-mode)
 (racket-smart-open-bracket-mode)
 (rectangle-mark-mode)
 (reveal-mode)
 (rxt--read-pcre-mode)
 (rxt-global-mode)
 (rxt-mode)
 (semantic-highlight-edits-mode)
 (semantic-highlight-func-mode)
 (semantic-mode)
 (semantic-show-parser-state-mode)
 (semantic-show-unmatched-syntax-mode)
 (semantic-stickyfunc-mode)
 (server-mode)
 (sh-electric-here-document-mode)
 (shell-command-with-editor-mode)
 (smartparens-global-strict-mode)
 (smartparens-strict-mode)
 (smerge-mode)
 (so-long-minor-mode)
 (tab-bar-history-mode)
 (tab-bar-mode)
 (temp-buffer-resize-mode)
 (text-scale-mode)
 (tool-bar-mode)
 (tooltip-mode)
 (transient-resume-mode)
 (unify-8859-on-decoding-mode)
 (unify-8859-on-encoding-mode)
 (url-handler-mode)
 (use-hard-newlines)
 (vc-parent-buffer)
 (view-mode)
 (visible-mode)
 (vterm-copy-mode)
 (which-function-mode)
 (whitespace-newline-mode)
 (with-editor-mode)
 (xref-etags-mode)
 (yas-global-mode))
greghendershott commented 3 years ago

Thanks for the report. Some related issues are here. Possibly this is related to the Racket Mode back end converting to SVG (rather than PNG). I'll have to investigate more.

greghendershott commented 3 years ago

I took a moment to reproduce this, but can't seem to, yet.

I tried changing the font size various ways, using:

I didn't see a change to the size of:

Can you say more which combination(s) cause the resize, for you?

p.s. I tried using Emacs 25.2.2 on Linux. You're using 27.2 on Mac. I wonder if that matters. e.g. Could there be a new feature where Emacs resizes images with the font? If so can it be disabled?

sorawee commented 3 years ago

Ah, I just realized that cmd + and cmd - in my Emacs are bound to doom/increase-font-size and doom/decrease-font-size as defined here: https://github.com/hlissner/doom-emacs/blob/develop/core/autoload/fonts.el. So perhaps this is a Doom Emacs issue rather than Racket Mode's.

greghendershott commented 3 years ago

Glancing at that Doom code, it seems to change the frame's base font size (by a different method than what I mentioned, but I think the same effect).


Trying Emacs 28.0.50.0 snapshot I built locally:

Do you see the same distinction?

If so I think we're looking at the same underlying issue; this seems unrelated to Doom, and instead to a change in Emacs starting around 27.

I think Emacs 27 is when they replaced imagemagick with native support. Apparently this affects how Emacs loads/sizes the SVG files created by Racket Mode's back end, or something like that.

If that theory is correct, I guess I'll need to see how I might be able to compensate.

sorawee commented 3 years ago
  • The per-buffer text-scale commands do not change the size of images.
  • Changing the frame's base font size:

    • does not change the size of existing images in the buffer
    • does change the size of new images created thereafter by subsequent runs

Do you see the same distinction?

Yes and yes!

greghendershott commented 3 years ago

Other factoids:

greghendershott commented 3 years ago

Comparing doc strings for create-image in Emacs 25.2.2 vs. 28.0.50.0, this phrase is added to the latter:

create-image is an autoloaded compiled Lisp function in ‘image.el’.

(create-image FILE-OR-DATA &optional TYPE DATA-P &rest PROPS)

Probably introduced at or before Emacs version 21.1.

Create an image. FILE-OR-DATA is an image file name or image data.

Optional TYPE is a symbol describing the image type. If TYPE is omitted or nil, try to determine the image type from its first few bytes of image data. If that doesn’t work, and FILE-OR-DATA is a file name, use its file extension as image type.

Optional DATA-P non-nil means FILE-OR-DATA is a string containing image data.

Optional PROPS are additional image attributes to assign to the image, like, e.g. ‘:mask MASK’. If the property ‘:scale’ is not given and the display has a high resolution (more exactly, when the average width of a character in the default font is more than 10 pixels), the image is automatically scaled up in proportion to the default font.

Value is the image created, or nil if images of type TYPE are not supported.

Images should not be larger than specified by ‘max-image-size’.

Image file names that are not absolute are searched for in the "images" sub-directory of ‘data-directory’ and ‘x-bitmap-file-path’ (in that order).

It seems like adding :scale 1.0 would avoid this behavior.

I'm not yet sure the downside.

greghendershott commented 3 years ago

I think my action plan needs to be doing some learning/thinking, first:

greghendershott commented 3 years ago

I found time to look into this.

I convinced myself the correct thing to do here is simply supply the new :scale 1.0 property to create-image.

I have a commit which I'll merge after tests pass.