I'd like to request $ScaleFont() as a native identifier in mIRC.


Please see the comments in the code snippet below for the usage.

mIRC has the ability to render text within a clipped region. /drawtext -c, which is quite handy, but one problem with picture windows, especially when it comes to drawing text, is there's no garuntee one users default @window font is the same, or if you specify some font with /drawtext, there's also no garuntee they have the same fonts installed on the system, so relying on font metrics for positioning text properly isn't an accurate assumption that those coordinates will apply correctly between any users potential font choices. This makes it extremely tricky to have a picture window oriented script render text properly across all users.

The problem gets even worse, fonts themselves do NOT follow any form of linear scaling so there's no logical scale from one font-point to another, even within the same font so calculating the proper font-point isn't too simple. We can greatly reduce this by using a form of estimation, and decreasing from there if it exceeds our bounds instead of having to step through all possible font-points to find the closest point to match our bound region.

This is actually more taxing than expected as a scripted solution, especially if you do something on a timed basis where text may need to be re-drawn. There may even be a better way to tackle this problem outside if mSL itself natively in C++ and win32 api like GDI+ GetTextMetrics, etc... which I'm sure $width() and $height() most likely use.

Below is my proposed identifier:

; $ScaleFont(text,font,min-size,width,height,bipt)
; width OR height (not both) can be -1 to omit testing in this direction.
; "bipt" are the same as those within $width() and $height().
; This identifier returns the largest possible fontsize point to fit in
; a given rectangle. this WILL return your original size which may or
; may not fit, if your minimum size restraint still exceeds the rectangle.
; If you do not need this option, it's recommended to just pass "1" for
; this parameter.
ScaleFont {
  var %hw = $iif($6,$width($1,$2,1638,$6),$width($1,$2,1638)) , %hh = $iif($6,$height($1,$2,1638,$6),$height($1,$2,1638))
  if ($4 == -1 && $5 == -1) { return }
  elseif ($5 == -1) { var %wr = $4 / %hw , %hr = %wr }
  elseif ($4 == -1) { var %hr = $5 / %hh , %wr = %hr } 
  else { var %wr = $4 / %hw , %hr = $5 / %hh }

  var %efs = $int($calc(1638 * $min(%wr,%hr))) , %ew = $iif($5,$width($1,$2,%efs,$5),$width($1,$2,%efs)) , %eh = $iif($5,$height($1,$2,%efs,$5),$height($1,$2,%efs))
  while (%efs >= $3) && (($4 > 0 && %ew > $4) || ($5 > 0 && %eh > $5)) { var %efs = %efs - 1 , %ew = $iif($6,$width($1,$2,%efs,$6),$width($1,$2,%efs)) , %eh = $iif($6,$height($1,$2,%efs,$6),$height($1,$2,%efs)) }
  return $iif(%efs > $3,%efs,$3)

Below is a test alias to utilize the above identifier. IMPORTANT NOTE! Some fonts only have one size, if you're still using mIRC's default "Fixedsys" for testing, you WILL NOT see this work. After @Test is open, use it's titlebar icon to select a new font to test with under "Font..." then execute the command again to see it re-drawn with the newly selected font.

Heres some examples of using:
/TestScaleFont <w> <h> <text>

Fixed rectangle bounding box (execute these one at a time to watch the size shrink-to-fit the bounding rectangle):
/testscalefont 200 30 Mooo! This is a test!
/testscalefont 200 30 Mooo! This is a test! and only a test..
/testscalefont 200 30 Mooo! This is a test! and only a test... Wow!

Fixed Height, not width:
/testscalefont -1 30 Mooo! This is a test! and only a test...

Fixed Width, not height:
/testscalefont 300 -1 Mooo! This is a test!

TestScaleFont {
  window -dp @Test -1 -1 640 480
  drawrect -nf @Test $color(background) 1 0 0 640 480
  var %FontSize = $ScaleFont($3-,$window(@Test).font,1,$1,$2) , %w = $width($3-,$window(@Test).font,%FontSize) , %h = $height($3-,$window(@Test).font,%FontSize)
  var %cw = $iif($1 > 0,$calc(($1 - %w) // 2),0) , %ch = $iif($2 > 0,$calc(($2 - %h) // 2),0)
  drawrect -n @Test 4 1 1 1 $iif($1 > 0,$1,%w) $iif($2 > 0,$2,%h)
  drawtext -nc @Test $color(normal) $qt($window(@Test).font) %FontSize %cw %ch $iif($1 > 0,$1,%w) $iif($2 > 0,$2,%h) $3-
  drawdot @Test
  echo -s *** Debug-Fontsize: %FontSize , Max/Overall Width: $+($1,/,%w) , Max/Overall Height: $+($2,/,%h) Centering: %cw %ch