Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 01-12-2020, 02:32 PM   #1
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default Code: How to Retina/HiDPI-your gfx-windows.

We're working on retina/hidpi-changes in Ultraschall and I think we can provide some basic code-snippets in that regard.

And it seems to be real simple:

Code:
retval, dpi = reaper.ThemeLayout_GetLayout("mcp", -3) -- get the current dpi; 256 for non retina; 512 for retina


--Now we need to tell the gfx-functions, that Retina/HiDPI is available(512)
if dpi==512 then -- if dpi==retina, set the gfx.ext_retina to 1, else to 0
  gfx.ext_retina=1 -- Retina
else
  gfx.ext_retina=0 -- no Retina
end
This should immediately make your gfx-window HiDPI/Retina. You can see it, when the blurryness isn't there anymore.

If not, please post your questions, so we can figure the rest out together.

Thanks to @rstockm, who spend a lot of time to figure that out, reading WhiteTie's theme and script.
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want
mespotine is offline   Reply With Quote
Old 01-12-2020, 05:54 PM   #2
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 7,875
Default

so we have to add that to every gfx scripts ?


Is it compatible with reaper 5 without triggering error.?


also, no utlraschall dependency needed ?
X-Raym is offline   Reply With Quote
Old 01-12-2020, 06:40 PM   #3
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

Independent from Ultraschall-Api.

As if Reaper 5,it should work with all versions, who have the ThemeLayout-functions available,but haven't tested.

And yes, you need to add that to every script, otherwise it will not show Retina-stuff on Retina-devices.
Maybe setting gfx.ext_retina=1 works anyway but haven't tested yet.
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want

Last edited by mespotine; 01-12-2020 at 06:46 PM.
mespotine is offline   Reply With Quote
Old 01-14-2020, 09:16 AM   #4
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

I have worked some more on the code-snippet, as in some places, you need to scale things up, when Retina is existing.
So, the following not only works on Reaper 5, it also gives you an additional variable "scale", with which you can scale things up.

Just use the value*scale and it should work.

The following example-code scales properly on non-Retina/HiDPI and Retina/HiDPI:

Code:
-- backwards-compatibility with gfx-scripts who shall work with early
-- Reaper 5 versions, who don't have function ThemeLayout_GetLayout available
if reaper.ThemeLayout_GetLayout~=nil then
  -- if ThemeLayout_GetLayout exists, get the dpi-value
  retval, dpi = reaper.ThemeLayout_GetLayout("tcp", -3)
end


-- Now set the gfx-window to retina/HiDPI-style by setting gfx.ext_retina 
-- and decide the proper scaling.
-- The variable scale will hold the multiplier for that.
-- So every coordinate, font-size, image-scaling that isn't scaled by Reaper itself,
-- can be altered by value*scale
if dpi=="512" then
  gfx.ext_retina=1
  scale=2
else
  gfx.ext_retina=0
  scale=1
end


gfx.init()
-- load an image and show it with correct scaling; in this case 1*scale
gfx.loadimg(1, reaper.GetResourcePath().."/data/track_icons/pads.png")
gfx.blit(1, 1*scale, 0) -- show correctly scaled picture

-- show some text with correct font-size-scaling; in this case 20*scale
gfx.setfont(1, "Times", 20*scale)
gfx.drawstr("Hello World")
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want

Last edited by mespotine; 01-14-2020 at 11:56 AM.
mespotine is offline   Reply With Quote
Old 01-14-2020, 09:24 AM   #5
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 7,875
Default

@mespotine
Ok so if I'm correct, the * scale multiplicator have to be put in front of every blit and set font,


this means a bit more rewriting to update the scripts.


Don't you think it would be better if REAPER internally took care of blit and set font scale based on the gfx.ext_retina value ?
And why not if it also took care or determining DPI etc so we wouldn't have to update anything ?




Thx for digging this subject, it will come handy at some point
X-Raym is offline   Reply With Quote
Old 01-14-2020, 09:31 AM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Fonts aren't measured in pixels, so you can't necessarily multiply them directly by the scale. That is, 24pt Arial isn't twice the size of 12pt Arial.

The "correct" approach would be to measure the font for a given point size so you can convert 12pt -> 16px, double it to 32 px, and then 32px -> 18pt, etc. This can be done dynamically as each font size is requested by the script and memoized so calculations are only ever done once for a given size.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 01-14-2020, 09:33 AM   #7
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

I haven't tested these things completely, and I agree that this should be the case.

However, I think it's still better, if you can control, which thing is scaled and which not. We currently run into the same issue, that when retinarizing our theme, we need to rebuild many parts from scratch, even though it looked good on non-retina.
So I think, HiDPI/Retina isn't just "scale things up" but rather some more difficult.


tl;dr; just test it and share your experience. The code-snippet above is just meant to be a start, but all the edge-cases are completely undiscovered yet.
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want
mespotine is offline   Reply With Quote
Old 01-14-2020, 09:34 AM   #8
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

Quote:
Originally Posted by Lokasenna View Post
Fonts aren't measured in pixels, so you can't necessarily multiply them directly by the scale. That is, 24pt Arial isn't twice the size of 12pt Arial.

The "correct" approach would be to measure the font for a given point size so you can convert 12pt -> 16px, double it to 32 px, and then 32px -> 18pt, etc. This can be done dynamically as each font size is requested by the script and memoized so calculations are only ever done once for a given size.
Any idea on how to do that properly? Would be really helpful for us right now...
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want
mespotine is offline   Reply With Quote
Old 01-14-2020, 10:12 AM   #9
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by mespotine View Post
Any idea on how to do that properly? Would be really helpful for us right now...
I don't have Reaper on my work machine so I can't test this, but something like:
Code:
local scale = 1.3
local CHAR = "M"

local scaledFontCache = {
  --[[
  Will have the following structure:

  Arial = {     font face
    [12] = 18   original point size: scaled point size
  }
  ]]--
}

local fontSizeCache = {
  --[[
  Will have the following structure:

  Arial = {     font face
    [12] = 32   point size: pixel size
  }
  ]]--
}

local function getScaledFontSize(font, size)
  -- See if we've scaled this font + size already
  local cached = scaledFontCache[font] and scaledFontCache[font][size]
  if cached then return cached end

  -- Initialize tables for this font if necessary
  if not scaledFontCache[font] then 
    scaledFontCache[font] = {} 
    fontSizeCache[font] = {}
  end

  gfx.setfont(font, size)
  local _, originalHeight = gfx.measurestr(CHAR)
  local targetHeight = originalHeight * scale

  -- Increase the size and measure until we hit the target height
  -- This could be done more efficiently with something like a binary search
  local currentSize = size
  local currentHeight = 0
  repeat
    currentSize = currentSize + 1

    -- See if we've measured this font + size already
    if fontSizeCache[font][currentSize] then
      currentHeight = fontSizeCache[font][currentSize]
    else
      gfx.setfont(font, currentSize)
      _, currentHeight = gfx.measurestr(CHAR)

      -- Add this measurement to the size cache
      fontSizeCache[font][currentSize] = currentHeight
    end
  until (currentHeight >= targetHeight)

  -- Add this scaled font + size to the cache
  scaledFontCache[font][size] = currentSize

  return currentSize
end
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 01-14-2020, 10:13 AM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

My GUI does something similar but with every individual character in the font so it can fit text to a given size: https://github.com/jalovatt/Lokasenn...Core.lua#L1784
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 01-14-2020, 11:46 AM   #11
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 790
Default

Quote:
Originally Posted by mespotine View Post
Code:
if reaper.ThemeLayout_GetLayout~=nil then
  -- if ThemeLayout_GetLayout exists, get the dpi-value
  retval, dpi = reaper.ThemeLayout_GetLayout("tcp", -3)
end
...
if dpi==512 then
  gfx.ext_retina=1
  scale=2
else
  gfx.ext_retina=0
  scale=1
end
Since
Code:
 reaper.ThemeLayout_GetLayout()
returns a string as a value, shouldn't dpi be converted using
Code:
tonumber(dpi)
???
lexaproductions is offline   Reply With Quote
Old 01-14-2020, 11:48 AM   #12
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

Not necessary, as Lua should be able to convert it automatically.

Unlike other programming-languages.
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want
mespotine is offline   Reply With Quote
Old 01-14-2020, 11:53 AM   #13
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 7,875
Default

I think lexaproduction is right in this case :P


dpi = "512"
if dpi==512 then

scale=2
else

scale=1
end

print (scale)
-- this return scale = 1

Lua automatic type conversions works in other context like string concatenation.

Last edited by X-Raym; 01-14-2020 at 11:53 AM. Reason: type conversion
X-Raym is offline   Reply With Quote
Old 01-14-2020, 11:53 AM   #14
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by mespotine View Post
Not necessary, as Lua should be able to convert it automatically.

Unlike other programming-languages.
Not for comparisons; 512 == "512" is false in Lua.

"512" + 1 gives you 513.0 though.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 01-14-2020, 11:55 AM   #15
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 2,139
Default

Okay, these kind of edge-cases were a reason, why I always demand the right datatype in my US-API-functions.

I'll correct my code above...

Edit: put the 512 in "" now.
__________________
Use she/her, when contacting me, please. Thanks :) Not mentoring via PMs, sorry.
Ultraschall-API - 1423 ReaScript functions for Reaper - Reaper Internals - Developerdocs4Reaper - Donate, if you want
mespotine is offline   Reply With Quote
Old 01-14-2020, 11:59 AM   #16
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 790
Default

Well this works
Code:
  local function gfx_RetinaMode()
    local dpi_retval, dpi_value = reaper.ThemeLayout_GetLayout("mcp", -3)
    if tonumber(dpi_value) == 256 then
	gfx.ext_retina=0 -- no Retina
	return false
    end
    gfx.ext_retina=1 -- Retina
    return true
    end
  end
But this always return "TRUE" no matter if I use a retina laptop or not
Code:
  
  local function gfx_RetinaMode()
    local dpi_retval, dpi_value = reaper.ThemeLayout_GetLayout("mcp", -3)
    if dpi_value == 256 then
	gfx.ext_retina=0 -- no Retina
	return false
    end
    gfx.ext_retina=1 -- Retina
    return true
    end
  end

Edit: Ooops you guys beat me to it.
lexaproductions is offline   Reply With Quote
Old 12-18-2020, 03:52 PM   #17
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 6,517
Default

i think we don't need to set an additional scale variable. just use the gfx.ext_retina variable which will be 2 or 1 or 1.25 for example if font size is set to 125%, etc
you only need to activate it setting it to 1 first and then it will be assigned to the needed scaling factor
heda is offline   Reply With Quote
Old 12-18-2020, 04:47 PM   #18
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: Apr 2020
Location: Leipzig
Posts: 2,875
Default

It depends and there are some usecases, where such a scale-variable can be useful, but it's too long ago, since I worked through it so I don't remember the actual usecases for it.

The most important thing however is, to check, whether you system is HiDPI/Retina before setting gfx.ext_retina accordingly. Otherwise, the gfx-window can be too big for non-Retina-displays.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper
Bugreports&Docs notes please do here:https://github.com/Ultraschall/ultra...-reaper/issues - Donate, if you wish
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-18-2020, 05:11 PM   #19
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 6,517
Default

I just assumed that gfx.ext_retina = 1 would be ignored on non retina displays. But if we have to use ThemeLayout_GetLayout, then that is the way. Thanks!
heda is offline   Reply With Quote
Old 02-04-2021, 12:41 PM   #20
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 6,804
Default

Quote:
Originally Posted by heda View Post
i think we don't need to set an additional scale variable. just use the gfx.ext_retina variable which will be 2 or 1 or 1.25 for example if font size is set to 125%, etc
you only need to activate it setting it to 1 first and then it will be assigned to the needed scaling factor
Resurrecting an old thread here, since it seems to me that simply setting gfx.ext_retina = 1 and then have Reaper do all the scaling (or most of it, at least) would have been great. But does it really work that way?

In my MFXlist I set gfx.ext_init to 1 on HiDPI screen (as in Mespotine's code above) , and when I read it back, gfx.ext_retina is 2.0, so Reaper acknowledges it and sets it as expected. But the fonts are not scaled.

Am I missing something, or is this just the way it is?
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 07-26-2021, 06:07 PM   #21
Hypex
Human being with feelings
 
Join Date: Mar 2015
Location: Australia
Posts: 362
Default

Quote:
Originally Posted by Fabian View Post
Am I missing something, or is this just the way it is?

From what I can tell this is the way it is. On Windows and Linux if I set gfx.ext_retina to 1 it comes back as 1. By default it is set to 0.

But there is no auto font scaling. It has to be adjusted. What I would like to know is how the default font can found or set. I don't find the gfx_font() functions very useful. By default they are this small 8 pt font. And you can only set a font, you can't get a font unless you set one first, which doesn't look too useful. And I can't see a way to query Reaper what the font or size is. But Reaper surely knows because it keeps using it!

Last edited by Hypex; 07-26-2021 at 06:12 PM.
Hypex is offline   Reply With Quote
Old 10-24-2021, 02:38 PM   #22
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

I am trying to understand how this works, but I have no retina/hdpi screen to test.

Could any of you (retina/hdpi users) try this code and post a screenshot? Thanks!

Code:
gfx.ext_retina = 1
scale = gfx.ext_retina
width, height = 150, 150
font_size = 18
gfx.init("Retina test", width, height)
gfx.setfont( 1, "arial", font_size )
gfx.drawstr( string.format("Width: %.1f\nHeight: %.1f\nFont size: %i\nRetina: %.2f\nOS: %s", 
   gfx.w, gfx.h, gfx.texth, gfx.ext_retina, reaper.GetOS()) )
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 10-24-2021 at 02:45 PM.
amagalma is online now   Reply With Quote
Old 10-24-2021, 02:44 PM   #23
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 790
Default

Code:
function GetRetinaMode()
   local retina_mode = 1
   local dpi_retval, dpi_value = reaper.ThemeLayout_GetLayout('trans', -3) -- current dpi; 256 = non retina; 512 for retina
   if tonumber(dpi_value) == 256 then retina_mode = 0 end -- if dpi~=retina, set the gfx.ext_retina to 0
   gfx.ext_retina = retina_mode -- Retina
   return retina_mode
end
I usually run this function right before my gfx.init and it works great.
lexaproductions is offline   Reply With Quote
Old 10-24-2021, 02:49 PM   #24
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Quote:
Originally Posted by lexaproductions View Post
Code:
function GetRetinaMode()
   local retina_mode = 1
   local dpi_retval, dpi_value = reaper.ThemeLayout_GetLayout('trans', -3) -- current dpi; 256 = non retina; 512 for retina
   if tonumber(dpi_value) == 256 then retina_mode = 0 end -- if dpi~=retina, set the gfx.ext_retina to 0
   gfx.ext_retina = retina_mode -- Retina
   return retina_mode
end
I usually run this function right before my gfx.init and it works great.
Docs say:
Quote:
gfx_ext_retina - to support hidpi/retina, callers should set to 1.0 on initialization, will be updated to 2.0 if high resolution display is supported, and if so gfx_w/gfx_h/etc will be doubled.
So, I think it must be done a bit differently...


Could you try the code I posted and do a screenshot? Thanks!
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-24-2021, 03:19 PM   #25
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 790
Default

If I run your code as is, nothing happens.
lexaproductions is offline   Reply With Quote
Old 10-24-2021, 03:40 PM   #26
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

No gfx window appears? What OS?
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-25-2021, 12:31 AM   #27
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 6,517
Default

on Linux... gfx.retina seems ignored, gfx.ext_retina returns the value of ui_scale in [.swell] in the reaper.ini

but the screenshot is the same with ui_scale 1.0 or 1.50... All other elements of REAPER scale well, but scripts are not scaled. maybe a bug.
heda is offline   Reply With Quote
Old 10-26-2021, 05:05 AM   #28
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Thanks heda!

The output of the code above on my system (Win10, retina=1.00) is 150x150px with a 12px font height (18px with the spaces above and below, as requested in the code).
On your system (Linux, retina=1.5) is 149x149 (maybe you cropped a pixel out in the screenshot?) with a 12px font height (17.5px with the spaces above and below, almost as requested in the code).

So, in your retina case, there was no automatic scaling of anything.

Therefore, from what I understand, the correct way to support retina is:
  1. initialize gfx_ext_retina = 1 at the start of the script. Then, the variable will hold the exact scaling on your system. You can store it in a variable if you want (scale = gfx_ext_retina)
  2. multiply all necessary items in your script with that scale so, that they scale correctly.
Example code: (same code as above, but with that logic)
Code:
gfx.ext_retina = 1
scale = gfx.ext_retina
width, height = 150*scale, 150*scale
font_size = 18*scale

gfx.init("Retina test", width, height)
gfx.setfont( 1, "arial", font_size )
gfx.drawstr( string.format("Width: %.1f\nHeight: %.1f\nFont size: %i\nRetina: %.2f\nOS: %s", 
  gfx.w, gfx.h, gfx.texth, gfx.ext_retina, reaper.GetOS()) )
Could you try this one and check that it is scaled correctly?
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 10-26-2021 at 05:11 AM.
amagalma is online now   Reply With Quote
Old 10-26-2021, 05:16 AM   #29
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 790
Default

Ah I miss your scaling the first time. Yes that's how I do it. Everything in the script must be mult by the scaling.

This is what needs to be done in your fantastic Renamer script for example. 🙄
lexaproductions is offline   Reply With Quote
Old 10-26-2021, 05:44 AM   #30
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Regarding font sizes, these two functions may help:
Code:
-- build table of font sizes
font = {}

local function CreateTableForFont( fontface, min_size, max_size )
  fontface = string.lower(fontface)
  font[fontface] = {size = {}, min = false, max = false}
  for font_size = min_size, max_size do
    gfx.setfont( 1, fontface, font_size )
    local _, px = gfx.measurechar(65)
    font[fontface].size[px] = font_size
    if not font[fontface].min then
      font[fontface].min = px
    else
      font[fontface].max = px
    end
  end
end

local function SetFontSize( idx, fontface, requested_size )
  fontface = string.lower(fontface)
  if font[fontface] then
    if requested_size <= font[fontface].max and requested_size >= font[fontface].min then
      if font[fontface].size[requested_size] then
        return gfx.setfont( idx, fontface, requested_size )
      else
        while requested_size >= font[fontface].min do
          requested_size = requested_size - 1
          if font[fontface].size[requested_size] then
            return gfx.setfont( idx, fontface, requested_size )
          end
        end
      end
    else
      error("Size for font '"..fontface.."' out of initialized size bounds!")
    end
  else
    error( "Font '" .. fontface.. "' not initialized" )
  end
end

-- Example:
CreateTableForFont( "arial", 8, 80 )
SetFontSize( 1, "arial", 46 )
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-26-2021, 07:03 AM   #31
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 6,517
Default

on Linux.. if I change the Preferences/Advanced UI ... Scale UI elements of track /mixer etc by 1.50 and restart the script still says Retina = 1.0

now.. in order to change the retina on Linux, I have to edit the reaper.ini and set the line to

Code:
ui_scale=1.5 // scales the sizes in libSwell.colortheme
start REAPER again and the new script gives the same screenshot
Width: 150.0
Height: 150.0
Font size: 18
Retina: 1.50
OS: Other


so... if I get the scale with scale = gfx.ext_retina AFTER the gfx.init then it returns 1.5 and then we could scale the elements and maybe resize the window? Or is it a bug that we have to init the window first for the gfx.ext_retina to return the scale factor?

not sure if this is a Linux only thing. I should test it on Windows later too.
heda is offline   Reply With Quote
Old 10-26-2021, 02:25 PM   #32
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Hmm, I don't know.. What you describe on Linux is confusing.

I do not have a retina display. I went to the reaper.ini and set ui_scale = 1.25
When I restarted Reaper the UI (buttons, mixer etc) were scaled up.
I then ran this code:
Code:
scale = gfx.ext_retina -- should be 0, since it is not initialized
gfx.ext_retina = 1 -- initialization
scale2 = gfx.ext_retina -- should have the scale, in my case 1, since I do not have a retina display (it does not matter that I set ui_scale=1.25!)
gfx.init("test") -- gfx window initialized, I do not expect anything to change
scale3 = gfx.ext_retina -- should be = scale2
The values I got were:
Quote:
scale = 0
scale2 = 1
scale3 = 1
This is exactly what I was expecting. What values do you get from this code?

BTW, do you really have a retina display? What resolution?
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-26-2021, 02:59 PM   #33
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 6,517
Default

it is a mess
No I don't have a retina display.. I just force it by scaling it with the reaper.ini ui_scale value but that may be only a Linux thing since it is in the [.swell] of the ini file.
that code results

scale=0.0
scale2=1.0
scale3=1.5


Then we have windows... which doesn't have retina but HiDPI mode... I set the font sizes to 150% from the control panel and restart REAPER, but I don't know if gfx.ext_retina does something there because I always get 1.0 before and after the gfx.init. and tested all hiDPI modes in the Advanced UI settings... aware, not aware etc...

scale=0.0
scale2=1.0
scale3=1.0



and then on Mac OS I have no idea because I don't have that hardware. Someone with a Mac could test this.
heda is offline   Reply With Quote
Old 10-26-2021, 06:31 PM   #34
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 3,795
Default

Under macOS 10.14 on a monitor configured to a HiDPI resolution:

Code:
scale  = 0.0
scale2 = 1.0
scale3 = 2.0
Earlier snippet shows this:
cfillion is offline   Reply With Quote
Old 10-28-2021, 09:57 AM   #35
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Thanks cfillion for the MacOS screenshot..


So, it seems that gfx.ext_retina is indeed updated only after gfx.init has been called..


I think the best would be if one of the devs could tell us what is the proper way to support retina/hdpi in scripts..

edit. I asked Justin, hopefully he'll shed some light
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-29-2021, 04:58 AM   #36
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

The proper way to support retina/hidpi (Justin's answer):
Quote:
the proper way is to set gfx.ext_retina to 1 at script start, then after gfx.init() check it to see if is set to a value greater than 1. It will be automatically updated based on the monitor that contains your window.
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-29-2021, 05:15 AM   #37
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 12,452
Default

Something like this should work for scaling fonts:

Code:
@init
gfx_ext_retina == 0 ? gfx_ext_retina=1;

@gfx
gfx_setfont(1, "Arial", 8*(1+gfx_ext_retina));
schwa is offline   Reply With Quote
Old 10-29-2021, 12:49 PM   #38
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

Quote:
Originally Posted by schwa View Post
Something like this should work for scaling fonts:

Code:
@init
gfx_ext_retina == 0 ? gfx_ext_retina=1;

@gfx
gfx_setfont(1, "Arial", 8*(1+gfx_ext_retina));

Thanks a lot schwa!
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is online now   Reply With Quote
Old 10-29-2021, 03:28 PM   #39
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

The updated code that should scale correctly is:
Code:
-- Get the retina scale
gfx.ext_retina = 1 -- init with 1
gfx.init("", 1, 1) -- this will update the ext_retina with the correct scale
scale = gfx.ext_retina -- store the scale
gfx.quit() -- quit this window and set the correct size according to scale
width, height = 150*scale, 150*scale
font_size = 18*(1+scale)*0.5

-- Create the scaled window
gfx.init("Retina test", width, height)
gfx.setfont(1, "Arial", font_size)
gfx.drawstr( string.format("Width: %.1f\nHeight: %.1f\nFont size: %i\nRetina: %.2f\nOS: %s", 
  gfx.w, gfx.h, gfx.texth, gfx.ext_retina, reaper.GetOS()) )
local mid, p = width/2, math.pi
gfx.circle(mid,height-width/5.5-1,width/5.5, false, true)
gfx.circle(mid-width/15,height-width/4.5,width/25, false, true)
gfx.circle(mid+width/15,height-width/4.5,width/25, false, true)
gfx.arc(mid,height-width/6.7,width/12,p*1.4,p*0.6,true )

__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 11-01-2021 at 05:52 AM.
amagalma is online now   Reply With Quote
Old 11-01-2021, 05:52 AM   #40
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,188
Default

With the help of Justin, THIS is the proper way:
Code:
desired_width, desired_height = 150, 150 -- size of gfx window
font_size = 18
gfx.setfont(1, "Arial", font_size)

-- Get the retina scale
local OS = reaper.GetOS()
scale, gfx.ext_retina = 1, 1 -- init with 1

-- Open gfx window
gfx.init("Retina test", desired_width, desired_height )

function run()
  if scale ~= gfx.ext_retina then -- dpi changed (either initially or from the user moving the window or the OS changing
    scale = gfx.ext_retina
    gfx.setfont(1, "Arial", font_size * (1+scale)*0.5)
    -- Resize manually gfx window, if not MacOS
    if OS ~= "OSX64" and OS ~= "OSX32" and OS ~= "macOS-arm64" then
      gfx.init("", desired_width*scale, desired_height*scale)
    end
  end
 
  -- Draw stuff
  gfx.x, gfx.y = 0, 0
  gfx.drawstr( string.format("Width: %.1f\nHeight: %.1f\nFont size: %i\nRetina: %.2f\nOS: %s",
      gfx.w, gfx.h, gfx.texth, gfx.ext_retina, OS) )
  local mid, p = gfx.w/2, math.pi
  gfx.circle(mid,gfx.h-gfx.w/5.5-1,gfx.w/5.5, false, true)
  gfx.circle(mid-gfx.w/15,gfx.h-gfx.w/4.5,gfx.w/25, false, true)
  gfx.circle(mid+gfx.w/15,gfx.h-gfx.w/4.5,gfx.w/25, false, true)
  gfx.arc(mid,gfx.h-gfx.w/6.7,gfx.w/12,p*1.4,p*0.6,true )
  gfx.update()

  local c = gfx.getchar() -- returns <0 if the window was closed by the user, or 27 if the user hit escape
  if c >= 0 and c ~= 27 then
    reaper.defer(run)
  end
end

run()
I've put in bold the important stuff. Have in mind that on MacOS there is no need to scale the gfx window size, but only its contents.
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 11-01-2021 at 05:58 AM.
amagalma is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 08:07 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2022, vBulletin Solutions Inc.