Welcome, Guest. Please login or register.
November 23, 2014, 11:45:58 pm

Login with username, password and session length
Members
Total Members: 488
Latest: Wimmie
Stats
Total Posts: 7318
Total Topics: 1178
Online Today: 7
Online Ever: 229
(April 05, 2011, 09:10:50 am)
Users Online
Users: 0
Guests: 1
Total: 1
Permissions

A Squeakyduck Design product
Pages: [1]
Print
Author Topic: Text Wrapping  (Read 2733 times)
HoboBen
Cobra Owner
Jr. Member
*
Posts: 477


hoboben
WWW
« on: March 09, 2008, 08:23:47 am »

Hi all,

I wrote this quick function, never really expecting to get very far with it, but it works :-)

Probably not the fastest method, but it does the job:

Code:
Program
    Uses pure2d, keyset

Const
    WWRAP_LINE_PADDING = 0

Type wstrs = Record
    t: String
EndType

Var
    wstr:^wstrs
    wstrl: List of wstrs

Function TextWrap(x: Integer, y: Integer, w: Integer, e:Element, f:Integer, s:String) : Integer
{
    x: X position to start writing
    y: Y position to start writing
    w: Maximum width of text
    e: Element to write to (NULL for frontbufffer)
    f: Frame of the element to write to (0 as default)
    s: Text to write
    Returns the yoffset to continue writing from.
}
Var
    yoffset: Integer
Begin
    ClearList(wstrl)
    s = Replace(s, "\n", " \n ",FALSE)

    While Instr(s," ")>0
        wstr = NewItem(wstrl)
        wstr.t = StringField(s," ") + " "
        s = Right(s,Length(s)-Instr(s," "))
    Wend
   
    wstr = NewItem(wstrl)
    wstr.t = StringField(s," ")
    s = ""

   
    Loop wstr through wstrl
        If (wstr.t = "\n ") then
            Text(x,y+yoffset,s,e,f)
            yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING
            s = ""
        Else
            If TextWidth((s+ wstr.t),e,f) < w then
                s = s + wstr.t
            Else
                Text(x,y+yoffset,s,e,f)
                s = wstr.t
                yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING
            Endif
        Endif
        Free(wstr)
    EndLoop
    Text(x,y+yoffset,s,e,f)
    yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING
   
    Result = y + yoffset
End

Var
    y: Integer
    ms: Integer
Begin
    OpenScreen(640,480,32,FALSE,COB_SHOWBORDER+COB_SHOWCLOSE)
   
    ms = Millisecs

    y = TextWrap(10,10,630,NULL,0,"Arthur:  The Lady of the Lake, her arm clad in the purest shimmering samite, held aloft Excalibur from the bosom of the water, signifying by Divine Providence that I, Arthur, was to carry Excalibur. That is why I am your king!\nDennis:  Listen. Strange women lying in ponds distributing swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony!")
    y = TextWrap(10,y,320,NULL,0,"\nArthur: The Lady of the Lake, her arm clad in the purest shimmering samite, held aloft Excalibur from the bosom of the water, signifying by Divine Providence that I, Arthur, was to carry Excalibur. That is why I am your king!\nDennis:  Listen. Strange women lying in ponds distributing swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony!")   

    MessageBox("Took "+(Millisecs-ms)+" Millisecs")
   
    While Not ExitRequested
        Flip
        Pause(1)
        If KeyDown(VK_ESCAPE) then RequestExit
    Wend
End
Logged

nicstt
Cobra Owner
Jr. Member
*
Posts: 333


« Reply #1 on: March 09, 2008, 09:25:20 am »

It's not all about speed.Smiley

Does the job is sometimes good enough for parts of a game, and it allows for overall progression. If it does become an issue, then time can be spent later. Always nice to have something that works well. Wink

Logged

Nicholas
HoboBen
Cobra Owner
Jr. Member
*
Posts: 477


hoboben
WWW
« Reply #2 on: March 11, 2008, 04:04:54 pm »

It's not all about speed.Smiley

Does the job is sometimes good enough for parts of a game, and it allows for overall progression. If it does become an issue, then time can be spent later. Always nice to have something that works well. Wink

Very wise - programmer time is more important than CPU time, eh? :-)

I've written text-wrapping functions in a few languages before, but this time I did it in a completely different way than usual - and I even got \n style newlines in there in seconds which previously would be where I would give up! :-)
Logged

nicstt
Cobra Owner
Jr. Member
*
Posts: 333


« Reply #3 on: March 16, 2008, 05:44:42 pm »

Grr

Don't believe I just wrote some of my own text wrapping routines, even with newlines in.

There's a moral there somewhere.

Maybe it will come to me as I'm re-inventing another wheel for some reason.Smiley This one as lovely flat sides. Whip

An even wiser programmer has a better memory /nod (or a memory jogger - if I could only remember where my memory jogger is)
Logged

Nicholas
HoboBen
Cobra Owner
Jr. Member
*
Posts: 477


hoboben
WWW
« Reply #4 on: April 14, 2008, 03:39:57 am »

Whoops, rather bad bug in my original code, which I'm surprised worked at all now!

Improved version:

Code:
Function TextWrap(x: Integer, y: Integer, w: Integer, e:Element, f:Integer, s:String) : Integer ; Export
Var
    yoffset, lyoff: Integer
Begin
    ClearList(wstrl)
   
    If Instr(s," ") = 0 then
        s = s + " "
    Endif
   
    s = Replace(s, "\n", " \n ",FALSE)

    While Instr(s," ")>0
        wstr = NewItem(wstrl)
        wstr.t = StringField(s," ") + " "
        s = Right(s,Length(s)-Instr(s," "))
    Wend
   
    wstr = NewItem(wstrl)
    wstr.t = StringField(s," ")
    s = ""

   
    Loop wstr through wstrl       
        If (wstr.t = "\n ") then
            Text(x,y+yoffset,s,e,f)
            yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING
            s = ""           
        Else
            If TextWidth((s+ wstr.t),e,f) < w then
                s = s + wstr.t
            Else
                Text(x,y+yoffset,s,e,f)
                s = wstr.t
                yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING               
            Endif
        Endif
        lyoff = TextHeight((s+ wstr.t),e,f)
        Free(wstr)
    EndLoop
    Text(x,y+yoffset,s,e,f)
    yoffset = yoffset + lyoff + WWRAP_LINE_PADDING
   
    Result = y + yoffset
       
End

The problem was here:
        Free(wstr)
    EndLoop
    Text(x,y+yoffset,s,e,f)
    yoffset = yoffset + TextHeight((s+ wstr.t),e,f) + WWRAP_LINE_PADDING

I was using TextHeight on the text of a freed item.
Logged

nicstt
Cobra Owner
Jr. Member
*
Posts: 333


« Reply #5 on: April 14, 2008, 10:07:43 am »

Ewww windows protection error.

Although I usually find those easy to track down - usually. Tongue
Logged

Nicholas
LisaGray
Newbie
*
Posts: 1


« Reply #6 on: April 13, 2010, 12:25:20 am »

thank you for this one. At least I've learn something interesting in you.  Grin Grin
Logged

“The most important thing in life is to learn how to give out love, and to let it come in.”

from essays
of Morrie Schwartz
Pages: [1]
Print
Jump to: