jaytea's big text

Want to show off your scripts? Release them here and bask in the glory as the users give their opinions of your work.

Moderators: IRC Operators, Support Team, mIRC Gurus

User avatar
jaytea
mIRC Guru
mIRC Guru
Posts: 334
Joined: Sat Oct 14, 2006 1:14 am

jaytea's big text

Postby jaytea » Thu Aug 18, 2011 6:27 am

A new take on the whole 'big text' idea.

This one lets you select your own fonts as well as add control codes to format text, then generates the ASCII required to display the big text on the fly.

To use:

- Use the popup to launch the dialog.
- Enter text in the embedded window at the top.
- Click 'Go!' to generate the ASCII 'art'.

From there, you can click 'Preview' to see how it would look as an IRC message, or click '/clipboard' to copy the necessary code to your clipboard so you can then paste it wherever you like.

Note:

Some fonts use a variety of colours in order to make characters look smooth, a technique called 'anti-aliasing'. These colours are not necessarily found in the 4-bit colour palette you use in IRC messages, but this script will attempt to approximate and choose the best fitting colours in these cases.

For any questions or suggestions feel free to swing by #mSL or drop me a message.

Code: Select all

/*
{

  /bt_convert <width> <height>

  Takes data from a picwin, formats it, and adds it to a
  hidden window.

  So far, all it does is maps coloured pixels in the picwin
  onto their corresponding mIRC colour in hex format, with
  an approximation using Euclidean distance if one doesn't
  exist. In the future, this could be expanded to allow for
  more interesting designs, such as big letters composed of
  smaller versions of themselves, etc.

}
*/

alias bt_convert {
  if ($window(@bt_text)) window -c $v1
  if ($hget(bt_convert)) hfree bt_convert
  window -h @bt_text
  hmake bt_convert

  var %i, %j, %colours, %fg, %bg, %line, %dot, %approx, %tmp

  %j = 0

  ; Set %fg and %bg to the RGB integer values of the foreground (normal text) colour
  ; and window background colour

  %fg = $colour($colour(normal))
  %bg = $colour($colour(background))

  ; Fill %colours with a list of RGB integers values for all colours 0 to 15

  while (%j < 16) {
    %colours = %colours $colour(%j)
    inc %j
  }

  %j = 0

  ; $2 = height
  ; Loop through each row of pixels of the picture in @bt_pic

  while (%j < $2) {

    %i = 0
    %line =

    ; $1 = width
    ; Loop through each column of pixels

    while (%i < $1) {

      ; Get the RGB integer value of the pixel at (%i, %j)

      %dot = $getdot(@bt_pic, %i, %j)

      ; Try to determine if that pixel is normal text (fg), part of the
      ; background (bg) or otherwise try to fit it onto one of the other
      ; colours in the colour palette.

      :findDot

      ; See if the current pixel's colour is exactly equal to bg.
      ; Use 'I' (invisible) as its placeholder in %line.
      if (%dot == %bg) {
        %line = %line $+ I
      }

      ; See if the current pixel's colour is equal to fg.
      ; Use 'N' (normal) as its placeholder.
      elseif (%dot == %fg) {
        %line = %line $+ N
      }

      ; Otherwise, see if the current pixel is somewhere in our
      ; colour palette.
      ; If so, its placeholder will be a single hex digit from
      ; 0-F depending on its position in %colours (which is its
      ; position in the palette)
      elseif ($findtok(%colours, %dot, 32)) {
        %line = %line $+ $base($calc($v1 - 1), 10, 16)
      }

      ; If the current pixel is not in the colour palette, as a
      ; background/foreground colour or otherwise, then we must
      ; try to find the closest match to it in the palette.

      ; Save approximations in a hash table named 'bt_convert'

      else {

        ; Check if the approximation has been saved before

        if ($hget(bt_convert, %dot) != $null) %dot = $v1
        else {

          ; Otherwise, calculate it and save it.

          %tmp = $bt_approx(%dot, %colours)
          hadd bt_convert %dot %tmp
          %dot = %tmp
        }

        ; Now that we have our approximation in %dot, go back
        ; up and test again.

        goto findDot
      }
      inc %i

    }

    aline @bt_text $iif(%line == $null, $str(I, $1), %line)
    inc %j

  }

  ; Remove empty lines. An empty line should be detected when the
  ; whole line is the same colour whilst ignoring trailing invisible
  ; ('I') colours.

  while ($regex($line(@bt_text, 1), /^([^N])\1*I*$/)) dline @bt_text 1

  %i = 1
  %j = $line(@bt_text, 0) - 1

  ; Now remove empty lines from the end (save for one).

  while (%j) && ($regex($line(@bt_text, %j), /^([^N])\1*I*$/)) {
    dline @bt_text %j
    dec %j
  }

}

; $bt_approx(<colour>, <list of colours>)
alias -l bt_approx {
  var %i, %in, %distance, %closest, %list

  %i = 1
  %in = $rgb($1)
  %list = $2

  ; Loop through each member of %list checking calculating the distance
  ; between them and the given colour.

  while ($rgb($gettok(%list, %i, 32))) {

    ; Suppose %in = A,B,C and $v1 = X,Y,Z

    tokenize 44 %in $+ , $+ $v1

    ; The distance between %in and $v1 (given colour and current list member
    ; is then sqrt((A - X)^2 + (B - Y)^2 + (C - Z)^2)

    ; This is an equivalent calculation to determining the distance between
    ; two points in 3d.

    ; !>= %distance could be < %distance if not for the fact that %distance
    ; begins at $null, and (N < $null) is false for all numerical N.

    if ($calc(($1 - $4) ^ 2 + ($2 - $5) ^ 2 + ($3 - $6) ^ 2) !>= %distance) {
      %distance = $v1
      %closest = %i
    }
    inc %i
  }

  return $gettok(%list, %closest, 32)
}


/*
{

  /bt_prepare

  Prepares the lines added by /bt_convert for use on IRC.

  It is expected that each line of @bt_text is comprised of
  characters denoting either normal (N) or invisible (I) text
  as well as hex characters 0 to F for each of the 16 colours
  presently supported by mIRC.

  This alias is also subject to change in the future, but it is
  not worth implementing anything more abstract at this time.

}
*/

alias bt_prepare {
  if ($window(@bt_text)) {
    var %i = 1, %line, %n = $line(@bt_text, 0)

    ; Delete the last line if it's 'empty' (see /bt_convert)

    if ($regex($line(@bt_text, %n), /^([^N])\1*I*$/)) dline @bt_text %n

    while ($line(@bt_text, %i)) {

      ; With each line, replace the longest contiguous series of the same character
      ; with a block of coloured text.

      ; The nature of this block is defined by $format().

      %line = $regsubex($v1, /(?!^)I+$|((.)\2*)/g, $format(\2, $len(\1)))

      ; potential future optimizations

      rline @bt_text %i %line
      inc %i

    }
  }
}

alias -l format {

  ; R is for reverse (highlighted) text.

  if ($1 == R) return $+($chr(22), $str($chr(160), $2), $chr(22))

  ; For everything else, map the symbol ('N' = normal, etc.) onto
  ; the correct colour code.

  ; Then return a series of spaces (chr160) with foreground and background
  ; colour corresponding to the given symbol.

  if ($2) && ($map($1) >= 0) return $+($chr(3), $v1, $chr(44), $v1, $str($chr(160), $2))

}

alias -l map {
  var %n = $1 I
  goto %n

  :N
  return $colour(normal)

  :I
  return $colour(background)

  :%n
  return $base($1, 16, 10)
}

menu channel,status,menubar,query {
  jaytea's big text:{ dialog $iif($dialog(bt), -v, -m) bt bt_main }
}

dialog bt_main {
  title "jaytea's big text"
  size -1 -1 296 346

  text "Font:", 1, 42 100 35 12
  text "<font>", 2, 85 100 72 12
  text "Size:", 3, 42 120 35 12
  text "<size>", 4, 85 120 72 12
  button "Go!", 5, 128 158 84 30
  button "Choose font...", 6, 170 106 108 24
  edit "", 7, 10 200 280 100, multi read autovs
  button "Preview", 8, 10 308 58 24
  button "/clipboard", 9, 72 308 58 24
  button "Exit", 10, 236 308 50 24, ok
  check "3D text", 11, 42 146 110 12
}

on *:dialog:bt:init:*:{
  window -aoBedw0j1 +bL @bt_edit 0 0 280 75
  echo @bt_edit type here!
  ; dialog -v bt
  bt_fontdetails
  did -c bt 11
  .timerbt_checkpos -om 0 25 bt_checkpos
  .timerbt_checkpos -e
}

on *:dialog:bt:active:*:{
  if ($dialog(bt).active) {
    if ($window(@bt_edit).state == hidden) {
      bt_showEdit
    }
  }
  elseif ($active != @bt_edit) {
    bt_hideEdit
  }
}

; "Choose font"
on *:dialog:bt:sclick:6:{
  .timerfont 1 0 bt_font
}

; "Go!"
on *:dialog:bt:sclick:5:{
  bt_convert $bt_drawtext($did(2), $did(4), $$editbox(@bt_edit))
  window -c @bt_pic

  if ($did(11).state) bt_3d

  bt_prepare
  filter -cwo @bt_text bt 7
}

; "Preview"
on *:dialog:bt:sclick:8:{
  if ($window(@bt_text)) {
    window -aedCw0 @bt_preview -1 -1 $calc($window(-1).w - 100) 500

    var %i = 1, %stamp = $+(<, $me, >)

    while ($line(@bt_text, %i)) {
      echo -t @bt_preview %stamp $v1
      inc %i
    }
  }
}

; "/clipboard"
on *:dialog:bt:sclick:9:{
  clipboard $line(@bt_text, 1)

  var %i = 2

  while ($line(@bt_text, %i)) {
    clipboard -a $crlf $+ $v1
    inc %i
  }
}

; $bt_drawtext(<font>, <fontsize>, <text>)
alias bt_drawtext {
  if ($window(@bt_pic)) window -c @bt_pic

  window -Bphd @bt_pic
  drawtext -p @bt_pic $colour(normal) $qt($1) $2 0 0 $3

  return $width($3, $1, $2, 1) $height($3, $1, $2)
}

alias -l bt_font {
  window -aj1 @bt_edit
  font
  dialog -v bt
  bt_fontdetails
}

alias -l bt_fontdetails {
  did -ra bt 2 $window(@bt_edit).font
  did -ra bt 4 $window(@bt_edit).fontsize
}

on *:appactive:{
  if (!$appactive) && ($window(@bt_edit)) {
    bt_hideEdit
  }
}

alias -l bt_hideEdit {
  window -hj1 @bt_edit
  .timerbt_checkpos -p
}

alias -l bt_showEdit {
  window -ow0j1 @bt_edit
  .timerbt_checkpos -r
}

on *:dialog:bt:close:*:{
  while ($window(@bt_*, 1)) window -c $v1
  .timerbt_checkpos off
}

alias -l bt_checkpos {
  if ($$window(@bt_edit).x $window(@bt_edit).y != $calc($dialog(bt).x + 10) $calc($dialog(bt).y + 30)) {
    window -j1 @bt_edit $v2
  }
}

on *:keydown:@bt_edit:*:{
  .timer 1 0 if ($replace($editbox($active),$chr(32),$chr(160)) = $!null) dline @bt_edit 1 $(|) aline @bt_edit $!$v1
}

; --------------------------- FUN STUFF ---------------------------

/*
{

  /bt_3d

  This command should follow /bt_convert.

  It reformats the encoded picture in @bt_text
  and creates a 3d effect.

  Might optimize this in the future.

}
*/


alias bt_3d {

  if ($hget(bt_3d)) hfree bt_3d
  hmake bt_3d

  hadd bt_3d 0 F
  hadd bt_3d 1 E
  hadd bt_3d 2 C
  hadd bt_3d 3 9
  hadd bt_3d 4 5
  hadd bt_3d 5 4
  hadd bt_3d 6 D
  hadd bt_3d 7 8
  hadd bt_3d 8 7
  hadd bt_3d 9 3
  hadd bt_3d A B
  hadd bt_3d B A
  hadd bt_3d C 2
  hadd bt_3d D 6
  hadd bt_3d E F
  hadd bt_3d F E
  hadd bt_3d N E

  var %i = 1, %line, %j, %width, %coord, %n

  while ($line(@bt_text, %i)) {
    hadd bt_3d line $+ %i $v1
    inc %i
  }

  %n = %i - 1
  dec %i 2
  %width = $len($hget(bt_3d, line1)) - 2

  while (%i) {

    %j = %width

    while (%j) {
      if ($coord(%i, %j) != I) {
        %coord = $v1
        if ($coord(%i + 1, %j + 1) == I) $coord(%i + 1, %j + 1, $hget(bt_3d, %coord))

        ; Extra shadow pixel, looks better without it but you may uncomment it and
        ; decide for yourself:

        ; if ($coord(%i + 1, %j + 2) == I) $coord(%i + 1, %j + 2, $hget(bt_3d, %coord))
      }
      dec %j
    }
    dec %i
  }

  while (%n) {
    rline @bt_text %n $hget(bt_3d, line $+ %n)
    dec %n
  }

  hfree bt_3d
}

alias -l coord {
  var %1 = $calc($1), %2 = $calc($2), %line = $hget(bt_3d, line $+ %1)
  if ($0 == 2) return $mid(%line, %2, 1)
  hadd bt_3d line $+ %1 $+($mid(a %line, 2, %2), $3, $right(%line, - $+ %2))
}
Patje
mIRC Guru
mIRC Guru
Posts: 1253
Joined: Sun Dec 17, 2006 2:56 pm
Location: Netherlands

Re: jaytea's big text

Postby Patje » Fri Aug 19, 2011 10:01 am

Amazing script! I've never had so much fun trying to run a script, haha.

Using this method, wouldn't it also be possible to easily convert actual images into ASCII?
User avatar
jaytea
mIRC Guru
mIRC Guru
Posts: 334
Joined: Sat Oct 14, 2006 1:14 am

Re: jaytea's big text

Postby jaytea » Sat Aug 20, 2011 6:33 am

Patje wrote:Using this method, wouldn't it also be possible to easily convert actual images into ASCII?


indeed! this script doesn't directly provide a way to do that, but if you draw an image on a window named @bt_pic at (0,0), call /bt_convert <width> <height>, then /bt_prepare, then @bt_text will contain the ASCII art version of that image :P
User avatar
Chessnut
User
User
Posts: 1509
Joined: Thu Jun 29, 2006 5:08 pm
Location: England!

Re: jaytea's big text

Postby Chessnut » Sat Aug 20, 2011 8:30 am

screw you jaytea, i had this EXACT script in the making myself!

I did run into problems with Windows' ClearType setting, which made the font very difficult to read when converting from window > chat. Did you manage to get around this?

I did try to use some dreadful COM methods to turn it off for the duration of the font being drawn onto the window, but failed.
Ask a question and be dumb for 2 minutes...

... Never ask a question and be dumb for life

Image
Image
Patje
mIRC Guru
mIRC Guru
Posts: 1253
Joined: Sun Dec 17, 2006 2:56 pm
Location: Netherlands

Re: jaytea's big text

Postby Patje » Sat Aug 20, 2011 8:43 am

Using jaytea's script and instructions I compiled the following alias which takes an image and converts it to ASCII as well. Just load it (along with jaytea's script, of course) and type '/bt_image path to image' to run it - the output will be copied to your clipboard. Make sure not to do this to big images; a 100*100px image will already produce 50 lines of text (and it'll also throw an error because the output is too big).

Image

Code: Select all

alias bt_image {
  if ($window(@bt_pic) == @bt_pic) {
    close -@ @bt_pic
  }

  var %pic = $qt($1)

  if (!$exists($qt(%pic))) {
    echo 4 -a * /bt_image: Image $qt($1) not found.
    return
  }


  window -pfh @bt_pic 0 0 $pic($qt(%pic)).width $pic($qt(%pic)).height
  drawpic -s @bt_pic 0 0 $pic($qt(%pic)).width $calc($pic($qt(%pic)).height / 2) $qt(%pic)
  bt_convert $pic(%pic).width $calc($pic($qt(%pic)).height / 2)
  bt_prepare

  var %count = 1, %result
  while (%count <= $line(@bt_text, 0)) {
    var %result = $+(%result, $line(@bt_text, %count), $crlf)
    inc %count
  }
  clipboard %result
  echo 3 -at Image copied to clipboard
}
Arconiaprime
User
User
Posts: 1458
Joined: Fri May 18, 2007 12:29 am
Contact:

Re: jaytea's big text

Postby Arconiaprime » Sat Aug 20, 2011 6:14 pm

That nubcake Patje spammed me a bit with this the other day and told me about how cool this is, and I have to agree.

Once again, another well made piece of msl-greatness jaytea :P
(Tim) Awong, the helpops are scaring me.
--------------------------------------------------------
SwiftIRC Services Administrator - 2010 - 2012
Owner: intrepid.il.us.SwiftIRC.net
User avatar
jaytea
mIRC Guru
mIRC Guru
Posts: 334
Joined: Sat Oct 14, 2006 1:14 am

Re: jaytea's big text

Postby jaytea » Sat Sep 10, 2011 2:39 pm

added comments to a few aliases and a 3d text option
User avatar
kerst
User
User
Posts: 4514
Joined: Wed Dec 27, 2006 9:51 am
Location: #msl

Re: jaytea's big text

Postby kerst » Sun Oct 02, 2011 8:45 pm

Very nice code Jaytea, how do you keep getting the original ideas? :)
Thumbs up for the comments, you rarely see that these days.
Image
Steve's work

- Proscript -
R.I.P proscript

Return to “Scripts”

Who is online

Users browsing this forum: No registered users and 2 guests