QPrint (falcon.h simplified)
#1
There's several programs out there that make use of falcon.h by now, but I wanted to take a shot at tossing in my own personal version of a simplified wrapper for the command -- QPRINT.

Code: (Select All)
$IF FALCON = UNDEFINED THEN
    $LET FALCON = TRUE
    DECLARE LIBRARY "./falcon"
        SUB uprint_extra (BYVAL x&, BYVAL y&, BYVAL chars%&, BYVAL length%&, BYVAL kern&, BYVAL do_render&, txt_width&, BYVAL charpos%&, charcount&, BYVAL colour~&, BYVAL max_width&)
        FUNCTION uprint (BYVAL x&, BYVAL y&, chars$, BYVAL txt_len&, BYVAL colour~&, BYVAL max_width&)
        FUNCTION uprintwidth (chars$, BYVAL txt_len&, BYVAL max_width&)
        FUNCTION uheight& ()
        FUNCTION uspacing& ()
        FUNCTION uascension& ()
    END DECLARE
    DIM SHARED QPrintTextType AS STRING
    QPrintTextType = "ASCII"
$END IF


SCREEN _NEWIMAGE(1024, 720, 32)
f = _LOADFONT("cyberbit.ttf", 20, "monospace")
_FONT f


QPrintTextType = "ASCII" 'Here. we're printing using ASCII character codes

FOR y = 0 TO 15
    FOR x = 0 TO 15
        QPrintString x * 30, y * uheight, CHR$(count) 'To showcase the printstring version of Qprint
        count = count + 1
    NEXT
NEXT

SLEEP
CLS

QPrintTextType = "UTF8" 'This uses UTF8 (Unicode) character encoding to print.

OPEN "test.txt" FOR INPUT AS #1
DO UNTIL EOF(1)
    LINE INPUT #1, temp$
    QPrint temp$ 'tho show how simple Qprint itself is.
    SLEEP
LOOP


END

SUB QPrint (temp$)
    STATIC m AS _MEM: m = _MEMIMAGE(0)
    DIM BreakPoint AS STRING
    BreakPoint = ",./- ;:!" 'I consider all these to be valid breakpoints.  If you want something else, change them.
    IF QPrintTextType = "ASCII" OR QPrintTextType = "" THEN text$ = _TRIM$(AnsiTextToUtf8Text$(temp$)) ELSE text$ = temp$
    count = -1
    DO
        'first find the natural length of the line
        x = POS(0) - 1: IF _FONTWIDTH THEN x = x * _FONTWIDTH
        y = CSRLIN
        wide% = _WIDTH - x - 1
        FOR i = 1 TO LEN(text$)
            IF ASC(text$, i) = 10 OR ASC(text$, i) = 13 THEN i = i - 1: EXIT FOR
            p = uprintwidth(text$, i, 0)
            IF p > wide% THEN EXIT FOR
        NEXT
        'IF i < LEN(text$) THEN lineend = i - 1 ELSE
        lineend = i

        t$ = RTRIM$(LEFT$(text$, lineend)) 'at most, our line can't be any longer than what fits the screen.
        FOR i = lineend TO 1 STEP -1
            IF INSTR(BreakPoint, MID$(text$, i, 1)) THEN lineend = i: EXIT FOR
        NEXT
        out$ = RTRIM$(LEFT$(text$, lineend))
        text$ = LTRIM$(MID$(text$, lineend + 1))
        IF LEFT$(text$, 2) = CHR$(13) + CHR$(10) THEN text$ = MID$(text$, 3)
        IF LEFT$(text$, 2) = CHR$(10) + CHR$(13) THEN text$ = MID$(text$, 3)
        IF LEFT$(text$, 1) = CHR$(13) THEN text$ = MID$(text$, 2)
        IF LEFT$(text$, 1) = CHR$(10) THEN text$ = MID$(text$, 2)
        IF _BACKGROUNDCOLOR <> 0 THEN
            LINE (x - 1, (y - 1) * uheight)-STEP(uprintwidth(out$, LEN(out$), 0), uheight), _BACKGROUNDCOLOR, BF
        END IF
        w& = uprint(x - 1, (y - 1) * uheight, out$, LEN(out$), _DEFAULTCOLOR, 0)
        x = 1
        IF y + 1 >= _HEIGHT / uheight THEN 'scroll up
            h = uheight * _WIDTH * 4
            t$ = SPACE$(m.SIZE - h)
            _MEMGET m, m.OFFSET + h, t$
            CLS , 0
            _MEMPUT m, m.OFFSET, t$
            LOCATE y, x
        ELSE
            LOCATE y + 1, x
        END IF

    LOOP UNTIL text$ = ""
    clean_exit:
END SUB

FUNCTION QPrintWidth& (out$)
    QPrintWidth = uprintwidth(out$, LEN(out$), 0)
END FUNCTION

FUNCTION QFontHeight
    QFontHeight = uheight
END FUNCTION

SUB QPrintString (x, y, text$)
    IF QPrintTextType = "ASCII" OR QPrintTextType = "" THEN temp$ = _TRIM$(AnsiTextToUtf8Text$(text$)) ELSE temp$ = text$
    IF _BACKGROUNDCOLOR <> 0 THEN
        LINE (x, y)-STEP(uprintwidth(temp$, LEN(temp$), 0), uheight), _BACKGROUNDCOLOR, BF
    END IF
    w& = uprint(x, y, temp$, LEN(temp$), _DEFAULTCOLOR, 0)
END SUB

FUNCTION AnsiTextToUtf8Text$ (text$)
    DIM chi&, ascii%, unicode&, aci%
    FOR chi& = 1 TO LEN(text$)
        '--- get ANSI char code, reset Unicode ---
        unicode& = _MAPUNICODE(ASC(text$, chi&))
        IF unicode& = 0 THEN unicode& = 65533 'replacement character
        temp$ = temp$ + UnicodeToUtf8Char$(unicode&)
    NEXT chi&
    AnsiTextToUtf8Text$ = temp$
END FUNCTION

FUNCTION UnicodeToUtf8Char$ (unicode&)
    '--- option _explicit requirements ---
    DIM uc&, first%, remain%, conti%
    '--- UTF-8 encoding ---
    IF unicode& < 128 THEN
        '--- standard ASCII (0-127) goes as is ---
        UnicodeToUtf8Char$ = CHR$(unicode&)
        EXIT FUNCTION
    ELSE
        '--- encode the Unicode into UTF-8 notation ---
        temp$ = "": uc& = unicode& 'avoid argument side effect
        first% = &B10000000: remain% = 63
        DO
            first% = &B10000000 OR (first% \ 2): remain% = (remain% \ 2)
            conti% = &B10000000 OR (uc& AND &B00111111): uc& = uc& \ 64
            temp$ = CHR$(conti%) + temp$
            IF uc& <= remain% THEN
                first% = (first% OR uc&): uc& = 0
            END IF
        LOOP UNTIL uc& = 0
        UnicodeToUtf8Char$ = CHR$(first%) + temp$
    END IF
END FUNCTION

Instead of trying to track all sorts of parameters for uprint -- (x&, y&, chars$, txt_len&, colour~&, max_width&) -- I've written a wrapper to break it down to one little command QPrint text$.

If you want colors, simply use QB64's normal COLOR command. If you want to position your text, simply use LOCATE, like you normally would with your code. It word wraps automatically, as well as scrolls the screen for us if we end up printing down on the bottom line of the screen. Basically, use it more or less like you would a simplified PRINT statement that can only handle a single string output.

The advantage to this little command? (And to falcon.h, in general?)

No cutting off parts of your characters. Some fonts are terrible about having half the letter cut off (I was using a script font the other day that lost the whole top half of my T's and F's, and their flourishes.), and you should be able to see the difference and the problem with the example code, which relies on cyberbit.ttf.

NOTE: QPrint's LOCATE and PRINT's LOCATE are two completely different areas of your screen. Don't expect the two to match at all for you. With the example, QPRINT is printing a character 26 pixels high, whereas PRINT cuts off segments of it and only prints a character 20 pixels high... That difference is going to naturally lead to the rows being at different heights, so don't expect to LOCATE y,x and then QPRINT, and then LOCATE y,x and PRINT, and have the lines match up at all.



The first screen that pops up, you guys might recognize as our ASCII chart. It's the whole ASCII range of characters mapped over and converted from QB64's codepages over to UTF8 format, and then printed to the screen for us, by setting "ASCII" mode printing.

Now, the second screen generated above, is using QPrint to print Unicode (UTF-8) formatted text.

By default, QPrint is set to print ASCII-code pages, but it can be converted to use UTF-8 code pages with a simple variable change:

QPrintTextType = "ASCII" <-- This sets us to our default printing using the ASCII code page. (Or just leave it blank as "" does the same.)

QPrintTextType = "UTF8" or "UNICODE" and we try to print it as UTF-8 formatted text.

Change the global variable, change how you're printing...

It's now THAT simple to display UTF-8 code on to the screen.


NOTE: To use QPrint, you have to load a custom font with it. QB64's in-built fonts currently aren't working as you'd think they should with it, so be certain to load your own font.

Necessary header file, font, and test file are included in the Download.7z attachment.


Attached Files
.7z   Downloads.7z (Size: 4.65 MB / Downloads: 74)
Reply
#2
Hi Steve,

I am getting a compile error, from log:

"In file included from ..\\temp\\regsf.txt:1,
from qbx.cpp:1131:
C:/Users/marka/Downloads/Downloads/falcon.h:1:10: fatal error: internal/c/parts/video/font/ttf/src/freetypeamalgam.h: No such file or directory
#include "internal/c/parts/video/font/ttf/src/freetypeamalgam.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.""

PS the first screen falcon and cyberbit was working before I put the code file in the download folder. QB64 v2.0 still
b = b + ...
Reply
#3
@bplus make certain you extract the falcon.h file into your QB64 folder. I'm thinking the issue should go away after that, as it looks like a basic "bad path" issue. Wink
Reply
#4
Make sure you have a _LOADFONT in your program to trigger the FREETYPE dependency, otherwise the whole freetype thing is not included in the program, hence causing the c++ compilation error on the #include freetypeamalgam.h line.

RULE: Using falcon.h, put a _LOADFONT into the program (even if you don't use the loaded font).
Reply
#5
OK falcon.h has been in my QB64.exe folder since I started testing InForm way back...

And the file the compile log says it can't access does exist but I do wonder, the path is relative just starting at internal which assumes I am in QB64.exe folder which of course I am not.

Rho mentions using _LOADFONT, that is in test program right after the falcon.

OK just delete the falcon.h and all works! Tongue
b = b + ...
Reply
#6
(05-03-2022, 03:09 PM)bplus Wrote: OK falcon.h has been in my QB64.exe folder since I started testing InForm way back...

And the file the compile log says it can't access does exist but I do wonder, the path is relative just starting at internal which assumes I am in QB64.exe folder which of course I am not.

Rho mentions using _LOADFONT, that is in test program right after the falcon.

OK just delete the falcon.h and all works! Tongue

Delete the .h file and it works?   Huh Huh

As long as it works, I guess life is good, even if poor Steve is all lost and confused.  LOL!!   Heart  Huh Huh
Reply
#7
For some reason the falcon.h file in the download folder was throwing off relative path is my guess. When I deleted it from folder I guess Windows found the falcon.h in the QB64 folder and used THAT path to find whatever after that ie found the source folder and the file buried way deep in there.
b = b + ...
Reply
#8
That makes sense. We may need to look into a _QB64DIR$ type command so header files and such can always reference our home path properly. Wink
Reply




Users browsing this thread: 1 Guest(s)