Qbasicnews.com

Full Version: Manipulating Subs
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I couldn't think of a good title for this topic but here is my problem. I'm trying to make a font that's a bit different from what's out there. I'm going to be making all the letters individually and store each in a sub. A,B,C,D and so forth. I don't remember if subs are case sensitive. If so than little A would be AA or something.

I want to make a function that will take in a string, and then break it down in order to get a sentence. What would that function look like? Or do you need more information?

Well this font is scalable, and works with lines, and curves instead of pictures. So the function would need to look something like this:

functionName "string blah blah blah", [x-coordinate],[y-coordinate], [scale],[color]
FUNCTION and SUB statements aren't case sensitive. But strings (i.e., text *data*) that you pass to or from them are. However, if I'm even close to understanding why you want to do, it appears that you're going about it the hard way. Why not just store your font patterns in an array. If you want to use the same size font as is standard for whatever video mode you're using, you can modify the fonts normally used by your video system. (It's particularly easy in a graphics video mode.)
Take a look at how I did it in HAR 13h++ (my GFX library, Pure-QB).
http://www.qbfm.cjb.net. Look at HARinstallBFont, HARinstallSFont, HARprintt, HARprint and HARsetFontTexture. Those are the routines for font-handling.
You better make just one sub which reads the letters and draws accordingly:

Code:
SUB weirdText (text$, x%, y%, colour%, whatever%)
FOR i% = 1 TO LEN(text$)
   m$=MID$(text$,i%,1)
   SELECT CASE m$
      CASE "a":
          DRAW "idfidjfijdfsiodfiosjiofsioefjioioweiof": PSET (3,3),2...
      CASE "b":
          ' ... etc
      ...
   END SELECT
NEXT i%
Nathan your a genious. Simplest answers are always the best. THat was exactly what I was looking for.
um, though you seem set, you could always just make a string array with a draw statement for each ascii value.
Here is what I got for my code.

Code:
SUB lText (text$, x%, y%, col%, scale%)

w = 5 * scale%
h = 8 * scale%

FOR i% = 1 TO LEN(text$)
    l$ = LEFT$(text$, i%)
    SELECT CASE l$
    CASE "A":
        x1 = x%
        x2 = x1 + (1 / 4) * w
        x3 = x1 + (1 / 2) * w
        x4 = x1 + (3 / 4) * w
        x5 = x1 + w

        y1 = y%
        y2 = y1 - (1 / 2) * h
        y3 = y1 - h

        LINE (x1, y1)-(x3, y3), col%
        LINE (x3, y3)-(x5, y1), col%
        LINE (x2, y2)-(x4, y2), col%
        END SELECT
NEXT i%
END SUB

While that creates a very flexible font it still looks pretty bad. Is there any way I can apply an anti-aliasing effect. To make it look thicker or something.

And what's this I hear about the DRAW command. Are you saying I can use it to Draw letters?
Anti alias is tricky, but perfectly done. The problem is that:

1. You've to have a gray palette or something like 332 if you want the background taking part of your antialias if you're in 8 bits.
2. Or maybe you need a hicolour/truecolour mode
3. Or you can plain-antialias always to the same colour (for example black), in that case you'd need a gradient palette.

Once you've solved that, just look for a SUB which draws antialiased lines, and replace your LINE statemets for SUB calls.

Here you have code and explanations of how to build an antialiased line. It is not in QB, but this kinda pascal-pseudocode-like thing is easy to translate to QB: http://freespace.virgin.net/hugo.elias/g...wuline.htm
remember logo? that little turtle you moved around to make images? or better yet, etch-a-sketch. draw works something like that.

http://qbasicnews.com/qboho/qckdraw.shtml

as for what you seem to want, though, it's vector fonts, like windows uses. it works (i think, not sure) by using a scan fill on a vector image. basically run down an image pixel by pixel, if it crosses a border change from 'do not draw' to 'draw'. to anti-alias, if it's on a border, draw the percentage of the pixel that is covered by the line using simple algebra. obviously, qb is not well suited for such a task, and even ugl's vector fonts are pretty slow. but in low resolutions, i can't see why you'd want to, just use a bitmap font.
Well, I did it myself... I took the code I gave you and made this working QB version. This takes the third assumption (everything antialiases to black):

Code:
DECLARE SUB WULine (x1%, y1%, x2%, y2%, basecolor%)
DECLARE FUNCTION invfrac! (xf!)
DECLARE FUNCTION frac! (xf!)

' WULINE.BAS adapted from pseudocode by Na Than :D

SCREEN 13

' Set up a correct gradient to test our vu line:
' we need 16 values from ZERO to a pure colour, for example YELLOW.
' We'll start in 16:

OUT &H3C8, 16
FOR i% = 0 TO 15
    OUT &H3C9, i% * 4
    OUT &H3C9, i% * 4
    OUT &H3C9, 0
NEXT i%

' And red, from 32

OUT &H3C8, 32
FOR i% = 0 TO 15
    OUT &H3C9, i% * 4
    OUT &H3C9, 0
    OUT &H3C9, 0
NEXT i%


' Draw a shiny star:

ct% = 0
FOR a! = 0 TO (8 * ATN(1)) STEP (4 * ATN(1)) / 32
    IF ct% THEN WULine 160, 100, 160 + 60 * COS(a!), 100 + 60 * SIN(a!), 31
    ct% = NOT ct%
    WULine 160 + 60 * COS(a!), 100 + 60 * SIN(a!), 160 + 60 * COS(a! + (4 * ATN(1)) / 32), 100 + 60 * SIN(a! + (4 * ATN(1)) / 32), 47
NEXT a!

FUNCTION frac! (xf!)
    frac! = xf! - INT(xf!)
END FUNCTION


FUNCTION invfrac! (xf!)
    invfrac! = 1 - frac!(xf!)
END FUNCTION

SUB WULine (x1%, y1%, x2%, y2%, basecolor%)
    ' This function uses basecolor% so basecolor%-15 is BLACK and there is
    ' a gradient to basecolor%-15 to basecolor%.

    ' Stop if vertical/horizontal line:
    IF x1% = x2% OR y1% = y2% THEN LINE (x1%, y1%)-(x2%, y2%), basecolor%: EXIT SUB

    pixelbase% = basecolor% - 15
    maxpixelvalue% = 15

    ' Width and Height of the line
    xd% = (x2% - x1%)
    yd% = (y2% - y1%)
    
    ' Now we must check whether the line is horizontal or vertical

    IF ABS(xd%) > ABS(yd%) THEN
            
        ' Horizontal line (more horizontal than vertical)

        IF x1% > x2% THEN    ' if line is back to front then swap it round
             SWAP x1%, x2%
             SWAP y1%, y2%
             xd% = (x2% - x1%)
             yd% = (y2% - y1%)
        END IF

        grad! = yd% / xd%    ' gradient of the line

        ' End Point 1
      
        xend! = INT(x1% + .5)               ' find nearest integer X-coordinate
        yend! = y1% + grad! * (xend! - x1%) ' and corresponding Y value
        
        xgap! = invfrac!(x1% + .5)          ' distance i
        
        ix1% = INT(xend!)                   ' calc screen coordinates
        iy1% = INT(yend!)
    
        brightness1! = invfrac!(yend!) * xgap!    '  calc the intensity of the other
        brightness2! = frac!(yend!) * xgap!       '  end point pixel pair.
        
        c1% = pixelbase% + brightness1! * maxpixelvalue%
        c2% = pixelbase% + brightness2! * maxpixelvalue%

        PSET (ix1%, iy1%), c1%
        PSET (ix1%, iy1% + 1), c2%
      
        yf! = yend! + grad!              ' calc first Y-intersection for main loop

        ' End Point 2
      
        xend! = INT(x2% + .5)
        yend! = y2% + grad! * (xend! - x2%)
        
        xgap! = invfrac!(x2% - .5)
        
        ix2% = INT(xend!)
        iy2% = INT(yend!)
    
        brightness1! = invfrac!(yend!) * xgap!
        brightness2! = frac!(yend!) * xgap!
        
        c1% = pixelbase% + brightness1! * maxpixelvalue%
        c2% = pixelbase% + brightness2! * maxpixelvalue%

        PSET (ix2%, iy2%), c1%
        PSET (ix2%, iy2% + 1), c2%

        ' MAIN LOOP
    
        FOR x% = (ix1% + 1) TO (ix2% - 1)
    
            brightness1! = invfrac!(yf!)
            brightness2! = frac!(yf!)

            c1% = pixelbase% + brightness1! * maxpixelvalue%
            c2% = pixelbase% + brightness2! * maxpixelvalue%

            PSET (x%, INT(yf!)), c1%
            PSET (x%, INT(yf!) + 1), c2%
          
            yf! = yf! + grad!    ' Update coordinate (bresenham style)

        NEXT x%

    ELSE

        ' Vertical line (more vertical than horizontal)
        ' NOTE that it is the same code, but with x and y swapped:

        IF y1% > y2% THEN    ' if line is back to front then swap it round
             SWAP y1%, y2%
             SWAP x1%, x2%
             yd% = (y2% - y1%)
             xd% = (x2% - x1%)
        END IF

        grad! = xd% / yd%    ' gradient of the line ***

        ' End Point 1
    
        yend! = INT(y1% + .5)               ' find nearest integer X-coordinate
        xend! = x1% + grad! * (yend! - y1%) ' and corresponding Y value
      
        ygap! = invfrac!(y1% + .5)          ' distance i
      
        iy1% = INT(yend!)                   ' calc screen coordinates
        ix1% = INT(xend!)
  
        brightness1! = invfrac!(xend!) * ygap!    '  calc the intensity of the other
        brightness2! = frac!(xend!) * ygap!       '  end point pixel pair.
      
        c1% = pixelbase% + brightness1! * maxpixelvalue%
        c2% = pixelbase% + brightness2! * maxpixelvalue%

        PSET (ix1%, iy1%), c1%
        PSET (ix1% + 1, iy1%), c2%
    
        xf! = xend! + grad!              ' calc first Y-intersection for main loop

        ' End Point 2
    
        yend! = INT(y2% + .5)
        xend! = x2% + grad! * (yend! - y2%)
      
        ygap! = invfrac!(y2% - .5)
      
        iy2% = INT(yend!)
        ix2% = INT(xend!)
  
        brightness1! = invfrac!(xend!) * ygap!
        brightness2! = frac!(xend!) * ygap!
      
        c1% = pixelbase% + brightness1! * maxpixelvalue%
        c2% = pixelbase% + brightness2! * maxpixelvalue%

        PSET (ix2%, iy2%), c1%
        PSET (ix2% + 1, iy2%), c2%

        ' MAIN LOOP
    
        FOR y% = (iy1% + 1) TO (iy2% - 1)
    
            brightness1! = invfrac!(xf!)
            brightness2! = frac!(xf!)

            c1% = pixelbase% + brightness1! * maxpixelvalue%
            c2% = pixelbase% + brightness2! * maxpixelvalue%

            PSET (INT(xf!), y%), c1%
            PSET (INT(xf!) + 1, y%), c2%

            xf! = xf! + grad!    ' Update coodinate (bresenham style)

        NEXT y%
    END IF
END SUB

Hope you like this Smile
Pages: 1 2