Home   Archive   Permalink



Displaying Anti-Aliased Fonts in Text Input Fields with REBOL 2 (a working hack)

One of the things that irks with REBOL 2 is you can't display anti-aliased fonts in text input fields, like the VID field. So I have come up with a workaround that uses DRAW to dynamically render the text as you type. It's a bit of a hack, since it only works reliably with monospaced fonts, but it does work, and it supports basic text entry and backspacing. I eventually plan to add support for copy / paste and other key combinations, but for now I thought I'd share what I have so far in case anyone is trying to achieve something similar.
    
Just make sure you download and install the 'Inconsolata Bold' font before tetsing it (or adjust the width/padding settings, as described in my comments below).
https://fonts.google.com/specimen/Inconsolata
    
    
R E B O L []
    
; the width of each character in your font
charWidth: 9
    
; the top / bottom padding used to vertically
; center the text in your input field
charPadding: 7
    
; the font for your input field
    
; Note: This works best with a monospaced font because all characters have the same width.
; If you use a variable width font then the cursor will slowly drift away as you type.
; If you change the font or size below then the width and padding above needs to be adjusted to match.
    
aaFont: make face/font [
        name: 'Inconsolata Bold'
        size: 18
]
    
; the blinking cursor
textCursor: make face [
     offset: as-pair 7 charPadding
        size: 15x40
     color: none
        edge: none
        ; hiding the textCursor face stops the timer, and so we
        ; have to draw the cursor in a pane and hide it instead
        pane: make face [
            ; indent the cursor away from the last character
            offset: 3x0
             size: 15x40
             color: none
             edge: none
            effect: [ draw [
                pen 0.0.0
                font aaFont
                text anti-aliased '|'
            ] ]
        ]
        ; blink two times a second
        rate: 2
        feel: make feel [
            engage: func [face action event] [
                if action = 'time [
                    either face/pane/show? [hide face/pane] [show face/pane]
                ]
            ]
        ]
]
    
; the typed text
textString: make face [
     offset: as-pair 7 charPadding
        size: 800x40
     color: none
        edge: none
        font: none
     ; required for focus to work
     flags: none
        data: make object! [
            text: ''
        ]
        feel: make feel [
            engage: func [face action event] [
                if action = 'key [
                    if not word? event/key [
                        ; TODO: expand this to handle copy / paste
                        ; and other special keys and combinations
                        either event/key = #'^H'
                            ; remove the last character when the backspace key is pressed
                            [remove back tail textString/data/text]
                            ; otherwise append / display all other keys
                            [append textString/data/text event/key]
                        
                        effect: [ draw [
                            pen 0.0.0
                            font aaFont
                            text anti-aliased textString/data/text
                        ] ]
                        
                        ; move the cursor ahead (or back) by 1 character
                        textCursor/offset: as-pair ((length? textString/data/text) * charWidth) charPadding
                        
                        show textCursor
                        show face
                    ]
                ]
            ]
        ]
]
    
inputField: make face [
     offset: 50x55
        size: 800x40
     color: 255.255.255
        edge: make edge [size: 1x1 color: 0.0.0 effect: 'bevel]
        pane: [textString textCursor]
]
    
window: make face [
        size: 900x150
     color: 236.236.236
        edge: none
        pane: [inputField]
]
    
center-face window
view/new window
    
; allow the textString face to receive keyboard events
; it must have a 'flags' property for this to work
focus textString
    
do-events

posted by:   Brian       22-Oct-2016/2:52:18-7:00



Liked it. Increased field y size from 40 to 80
Replaced apostrophes with quote marks, font size to 38. Does make a good input field, not everyone using a computer is under 40...so large font fields are the go! Couldn't see how to download it from Google Fonts, but other sites have it. Was already on my Windows 8.

posted by:   Norm       24-Dec-2016/5:28:03-8:00