I'm working on a text rendering system and I'm trying to implement a mechanism for automatically scaling down the text size to fit inside a specified box.
With word wrapping disabled, the task is nice and simple. All I have to do is check whether the width or height is proportionally larger, then scale the text down by that same ratio.
Unfortunately, with word wrapping enabled, the task gets much more complicated. If the text is larger than the box and I scale it down, the smaller text size might be able to fit more words onto each line, which might change the overall bounding box so that a different scale makes it fit the box better. Then applying that different scale might again mean there's a better way to word wrap it, and so on.
Most of the other solutions I've been able to find are basically:
while (isTooBig) { DecrementFontSize(); }
That would work, but could be very inefficient, so I was wondering if anyone knows of any lower level algorithms that deal directly with the text parsing? Failing that, do you know of any open source programs which include this feature so I can get their source code and see how they do it?
Edit: I'm doing this in Unity3D, but that doesn't really have any bearing on my problem since I'm implementing my own text rendering system.
Related
I want to develop a file viewing program for a specific read-only file format and for the most part it will just be scrollable text. The ultra-simple way is of course to use an existing text display controls, but I've come to the conclusion that I want a graphical sort of "custom colored highlighting", text coloring, and maybe other things painted in. So I was planning to handle the painting myself. I take it that attempting to line up my own graphics on top of a label or rich text box would be a bad idea, so I was planning to just paint everything except the scroll bar... unless these labels/rich text controls are a lot more extensible in some way that I don't know about?
Assuming I go the painting route, I'm not 100% sure of the specifics. Do I paint directly into a Panel? Or is there a better GUI control to paint into? Also, I think it will be better if I don't buffer the screen because I think repainting the contents on validation will be easy/efficient... but repainting from a buffer might be even faster... will it save me a lot of trouble if I just have a screen buffer... is this significantly inefficient? Is my plan of painting directly into a Panel, unbuffered, a good idea or is there a preferred method that I'm passing up?
Try to use WebBrowser control orRichTextBox (make formatted html or rtf from your text).
I need to load an image in a WPF window, an be able to read and modify individual pixels (in an efficient way), zoom the image (and scroll it), get the value RGB/grayscale of the pixel under the cursor, select areas (I guess knowing the cursor position and being able to modify pixels I could draw myself the square which represents the selected area)...
What is the best combination of WPF controls and classes to accomplish this?
I've been trying to do it loading a System.Windows.Media.Imaging.BitmapImage and putting it into a System.Windows.Controls.Image, but it's taking much longer than I expected.
Thank you very much
I once used this WPF Interactive Image Cropping Control. Go check it out, it should at the very least give you a good place to start. Oh, and welcome to Stackoverflow. :)
I have a WinForms application and a Panel Control. The panel control has a VScrollBar control for vertical scrolling. Everything works fine except right now I have my VScrollBar maximum value set to 100. The problem is, I need the Maximum property to be about 4 billion, however, since Maximum is only an Integer, I can't set it to the proper value. So, my question is, how do I get around this? I know there are text editors and file viewers that claim to view more then 4 gigs of data, so how would a scrollbar in an application like that work?
A scrollbar is a GUI control. Innately, the number of steps it can display is limited to the number of vertical pixels on your screen. Therefore, you could consider setting the maximum value to anything above that to be simply for developer convenience, to make the math easier.
How do applications deal with scrollbars? In theory, you'd want to parse the file first, to find out how many lines are in the file, and use that as your logical maximum. In reality, reading 4 GB of data when the file is opened would kill performance, so that wouldn't work.
If I were implementing this, I would set the scrollbar maximum is set to a large value, say 10,000. When the scrollbar is used, the scrollbar value is divided by 10,000 to get a percentage, and the editor shows that section of the file.
Don't think of things in terms of scrolling down so many lines. Instead, think of it as jumping to that percentage offset of the file, reading the data there, and displaying that.
Well, you could just set Maximum to int.MaxValue and scale the retrieved value to your real maximum value. This should be enough precision to avoid loading too much data.
You use a percentage. There is no need to set it to the same as the number of lines.
I'm sure this is a common problem, I don't know if there is a common solution. My problem is when the user is viewing said multi-line text box in the GUI they can just scroll down, not a problem. When I come to print however, certain text occasionally ends up going off the bottom of the given area for that text box.
We'll keep it simple and say it is not a rich text box so the user can't choose a larger font which may therefore go off the page. hmmph cross that bride if I need to =)
So I considered;
Using a character limit but then if you just return carriage a number of times, this would end up going off the bottom.
Or a 'row' limit which i'm not entirely sure how to implement but didn't seem right either
Finally I am coming to the conclusion that when you print said multi-line text box you must just expand the area on the printed document to fit whatever text has been entered. If this is the most elegant solution can anybody point me in the right direction for implementing such a feature?
Think of a notes field where the user could type as much as they wanted and the intention is to make sure all that is typed is printed.
Are you calling yourTextBox.DrawToBitMap? All that does is create a bitmap of what appears on the screen, it does not perform printer output, line layout, line breaks, printer fonts, margins, orientation, pagination, or anything else to do with printing.
If you want to send text to a printer, handling all the features mentioned above, you will have to use the System.Drawing.Printing.PrintDocument class and deal with all the things printers require that textBoxes do for you.
How and why are you printing a WinForm? I know this doesn't answer your question but printing a WinForm as a document is going to have these types of issues and I can guarantee that as you release your application to more users, more quirks will arise that will need to be fixed.
If you absolutely must print the Form and you want to limit the content in your TextBox about the best solution that I can offer is to force the font to be a fixed width font of a fixed size and the user can't modify it. Count how many characters can fit in the TextBox and set that value as a MexLength on the control.
Obviously, the user can hit the return/enter key which will use one character but will consume one entire line. To fix this, changed the TextBox's TextChange event to handle the newline character-- you can either strip it from the text or update the TextBox's MaxLength property to a smaller, appropriate value.
With possibly a few minor tweaks, obvious tweaks my recommendations should safely get you what you want. Still, I highly recommend looking for another printing mechanism for your form.
Use at your own risk.
I've searched around for an alternative way of drawing selection indicators for visual objects (like selected edges, lines etc.) without the use of ControlPaint.DrawReversibleFrame and related XOR methods. The reasons are unwanted XOR-ing "artifacts", reversibility not applying to bitmaps, no control of the actual visual look and slowness.
On the other hand I want to avoid having to repaint the whole scene (map actually) if a user decides he wants to deselect an object or two, because the repaint could be quite expensive.
So the only alternative I can see is implementing some basic drawing logic directly on a Bitmap, but with storing the previous contents of the pixels before they change. Then (in theory) I would be able to reapply old contents of, say, an selected edge rectangle if the user chooses to deselect that edge.
My question is whether you think this is a good idea or do you see some other alternatives to my problem (within the GDI+)?
Thanks in advance
If the selection indicator is just drawn on the top of the unselected object, you can use two bitmaps, draw all the unselected objects on the background one and the selection indicators on the other, and paint them both on screen.
Else, you can do the same, except that you render the selected objects instead of just indicators.
Only store the rectangles "of interest" in an off screen buffer. And repaint when the focus is lost. . . Or if you can redraw just the portion as it appears normally based on in memory data you should be fine. Otherwise it seems that you have the gist of it.