Idea for a module (LineBreak)

Started by monkey0506, Thu 15/06/2006 22:35:52

Previous topic - Next topic

monkey0506

I've had an idea for a new module, and is one that I will use even if no one else does (and yes, it's one that I plan to complete (properlyÃ,  ;)) before release (bugs are one thing, completely broken modules are another :=)).

Its tentative name is LineBreak, and as the name may (or may not, I don't know how you might interpret it...) imply, will be designed to manage line-breaks (such as word-wrapping).Ã,  There's still a lot up in the air about the module, but some of the basic ideas I have at this point are:

- A function to add line breaks to a String (based upon strictly the width of the text, the end of the word (based upon a user-defined String of Delimiters), or a hyphenated line-ending).Ã,  The line breaks would be inserted as some type of text-based identifyer, such as "\\LineBreak: H\\" for a hyphenated line break.
- A function to remove the line breaks.
- A function to parse text containing line breaks with a separate function to retrieve a single line at a time.
- A function to test whether a String contains line breaks.

In essence the function the module would set out to perform would be a simple one, but then aren't some of the other modules out there somewhat simplistic as well?

A tentative example of how the module might be used follows:

Code: ags
String Sentence = "From what you can tell the old moth-eaten leather jacket bares little real value, however, the old man clings to it as if it were made of gold.";
Sentence = LineBreak.AddLineBreaks(Sentence, eLineBreak_Hyphenate, 2, 45); // text, line type, font, width
LineBreak.Parse(Sentence);
String Line = LineBreak.GetLine();
while (Line != null) {
  Display(Line);
  Line = LineBreak.GetLine();
  }


That would display the text as it would be broken up if displayed in font 2 with 45 pixel lines.

Anyway, the module is still under production (and it could be slow as I don't live with my parents anymore so I can't work on it everyday (probably only on the weekends) (but it will be coming)), and I just wanted to see what you guys thought.

My mom is bugging me to get off her laptop so I have to go.

SSH

I included this in one of my modules, probably Credits...
12

GarageGothic

#2
This is one of the things that I pretty much implement from scratch every time, since the core function itself is just a while-loop shortening the text until it fits and then counting back to a space or a hyphen. But the overall implementation is very different depending on what you're trying to do: For the Shadowplay Hypertext Engine (SHytE) for instance, I need a variable line width for inserting images into the text, and a check for every linebreak to see if the whole image has been drawn yet. My conversation log works in yet another way where remaining lines wrapping onto the next page must be handled differently.

One thing I can recommend though is to optimize the linebreaking function heavily. If you shorten it one character at a time and check the length every while-loop, it's slow as molasses when doing this on 300 Strings every frame (yes, some of us need that). A quick fix for this is to check how many characters you would need to fill out the line with a very slim character, say "i", and the start counting down from that number of characters.

Let me know if you need any help/advice with this module. I have lots of experience with the pitfalls of linebreaking.

Edit: I just realized that in most cases it would take less loops to add to a new string until it's too long than shortenening the full string until it's short enough. I'm off to implement this right away  ;D

Edit 2: Still, starting off from the smallest possible number of characters (how many would it take to fill up the line with "W"s) would help speeding things off.

monkey0506

Thanks for the ideas GG...but...I don't really feel safe guessing that W would be the widest character.  What I've done instead is compared the width of the original String and then divided the String in half until it was less than the specified width, and then added characters back.  That way it has some form of optimization without assuming things about the font.

And I've come up with an idea on how to handle variable-width line-breaks...using a String for the width instead of an int.  Well, the idea is to set the function up like this:

Code: ags
String LineBreak::AddLineBreaks(String Text, LineBreak_LineType Type, optional int width, optional int font, optional String Delimiters, optional String Width)


There are two different width parameters as you can see, one being an int and one being a String.  The idea is that if you default on the String parameter (not passing the parameter, passing a null or invalid String, or not specifying a width for a line) then the integer width parameter will be used (provided it is within the user-defined limits for line-widths (otherwise it defaults to the user-defined default width)).

Now this might sound a bit bunk, but I think it could work if properly implemented.  String Width parameters would be defined something like the following:

Code: ags
"LINE 1: 82; LINE 2: 115; LINE 3: 54"
"LINE 1 AND 2: 145; LINE 3: 268;"
"LINE 1 TO 3: 310;"
"LINE 1 TO 5 AND 9: 275; LINE 6 TO 8: 250;"


Granted this would require some additional parsing on my part, however I really think it could work.

Thanks for reading my thoughts and for any comments or ideas!

GarageGothic

The string based linebreaking instructions sounds like a pain in the ass for the end user, and I personally have a hard time seeing a use for them without a secondary program to provide the line length values automatically (to linebreak around an image or similar).

It's a good solution to your problem, but as a stand-alone module without rendering features it's difficult to imagine the purpose.

monkey0506

#5
Okay.  That seems fair enough.  If I do decide to implement it, it won't make the first cut (which is almost finished! (for real this time!)).

I've added functions to convert the module line-breaks into bracketed line-breaks, and vice versa (with a check to ensure that actual brackets ("[") are not converted into line-breaks).

There are also two other functions yet to be mentioned, one of which will give the user a count of the number of lines a String contains, and the other to retrieve the last parsed String of text.

It looks as though I may be staying one more night at my parents house (contrary to my prior plans), so I could (possibly) have this finished tonight.

[EDIT:]

That's right, I finished it! The official thread for the module is here. As indicated in that thread, please direct any further comments/questions to that thread.

SMF spam blocked by CleanTalk