I arrive to output a string on multiple lines inside a retangle but haven't find a way to reduce or enlarge the line spacing.
How to do that?
This MSDN should help you. Line spacing is a result of the Font you are using. You may need to break your DrawString commands up into multiple calls if you need custom line spacing.
This Microsoft forum posting may be helpful:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1507414&SiteID=1
This shows how MeasureString can be used to determine how much of your text will fit on each line, then using this to progressively render the entire rectangle's contents line by line. Unfortunately I don't think there's a built-in line spacing property, so you'll have to go for the manual approach. The post's author uses the font's Height * 1.5.
It's also worth researching StringFormatFlags - you'll need to make sure both your DrawString and MeasureString calls use the same StringFormat so the rendering and measurement are consistent:
http://msdn.microsoft.com/en-us/library/system.drawing.stringformatflags.aspx
Related
I'm trying to draw a string using either textrenderer.drawtext, graphics.drawstring or graphicspath.addstring - the main purpose is to extract all fonts to bitmaps to edit them and use them as bitmaps with shaders in a game.
With textrenderer.drawtext and graphics.drawstring, I get a padding on top of varying degrees - so I try graphicspath.addstring. I extract the font family's ascent height and descent height, but they are wildly unusable with emheight. (using ascent and descent with emheight is how microsoft suggest you do what I am trying to do - via http://msdn.microsoft.com/en-us/library/xwf9s90b%28v=vs.110%29.aspx. Has anyone successfully ever draw pixel perfect fonts using C#? Every time I ever try or look it up, textrenderer and graphics always' padding always screwed up drawing and this new graphicspath method seems to have an issue with using a specific scale.
The usual methods using TextRenderer or MeasureString will give you a SizeF, containing the bounds of the string you measure. Most formats include a little slack so you can compose text by adding strings together.
The aim of theses methods is to help create blocks of text by letting you measure when a line will be full or how many pixels to advance for the next line.
They are not really meant for maesuring single characters.
For this there is a special stringformat GenericTypographic as described here which leaves out the white space.
To get an even more precise measurement one can use GraphicsPath.AddString and then GetBounds, maybe after switching antialias off..
Now, if you wanted to draw a single character precisely, say centered on a Button this would do the job.
But you know all that and your aim is different - if I understand you correctl,y you want to create Bitmaps from each character in order to later join them to form text. This means you need them to line up correctly vertically, ie sit on the same baseline.
The sizes of the characters don't help you here; now, normally you'd need the baseline of each charcater, which you don't get, at least not for anything descending like 'f' or even just ',' etc..
But it wouldn't help you either because in GDI you don't print/draw to the baseline anyway..
What you should do, imo is either draw one long string with all characters, so that they're all lined up right and then cut out the characters one by one. Or you could draw each character on its own, but suffix all or some characters you know to have ascenders and descenders and then only pick the first columns from the result.
So the only way I figured out how to do this is is to first draw the string to a graphicpath, then measure all the empty spots in the graphic path, and get it's height only after I've measure every spot, then redraw the string (I have an attempt counter to limit attempts but increase em to pixel accuracy) taking the old size and new size into account by a modifier and then extract the final size and store it.
Only I got to get around the BS of every font having a weird top padding that isn't associated with it's ascent and internal overflow (ex: Ñ), as well as descent, in refrence to a 0,0 point, this way.
How do I set the background color of a piece of text in a PDF document using iTextSharp without taking a form field?
The answer in this post uses a FormField, which according to me is an overkill and too long-winded a way to do something really simple.
Is there a simple way of coloring the background of a piece of text?
You can use the method SetBackground that is available in the Chunk class. There are two variations of this method: one that takes default padding and one that allows you to change the padding.
If you use the onGenericTag() method on a Chunk, you can draw a custom background (and do much more). For instance: you'd use onGenericTag() if you want to draw a rectangle with rounded corners. See my answer to your duplicate question Draw a rectangle at the *current position* and then get its position coordinates
After some trying, I have come to the conclusion that there are 3 ways to do this other than using the FormField (which is the fourth way and how to do that is already linked in the question):
1) Judging from this answer to another similar question, it appears as though there is no concept of a background color for text in the PDF specification. Therefore, one has to draw a rectangle at an absolute position before drawing the text (at that position).
This is like drawing on a Win32 DeviceContext.
2) You can draw a table and set the background color of the cell in which you want a background color.
3) You can write a chunk. The Chunk class has a method named SetBackground(). This doesn't look very nice because it doesn't let you control the padding around the text and between the borders of the box. You can control how far above the baseline the bottom of the text will appear by calling the chunk.SetTextRise(float f) method but that's about it. Still, it's a fast and easy way to get things done if you don't want too much beautification.
I have an application where we replace place holding text with other text at run time.
While doing so I have to add character ellipses if the string goes beyond some predefined width.
So I do not have a DrawingContext available nor i have a Graphics.Measure available.
I used FormattedText but I was unable to extract the ellipted text.
I could never find the right way to use a formatted text like this.
Please help.
For WinForms, you can use the TextRenderer.MeasureText function,
and thanks to the comment from vcjones, using the method described at http://smellegantcode.wordpress.com/2008/07/03/glyphrun-and-so-forth/ for WPF.
I just started diving into WPF. First thing I noticed and which I really hate is the ugly rendering.
I don't know why but for example borders or lines turning ugly sometimes.
Take a look at the Screenshot. The bottom line is ugly. Not that crisp like the centered line.
Any suggestions to make that better?
See the second answer of this SO question
which suggests using UseLayoutRounding=False in preference to SnapsToDevicePixels.
As an aside if you're using bitmaps then RenderOptions.BitmapScalingMode can be useful (from this SO question
It looks like your lines don't fall on pixel boundaries. Two ways I've used to get around this are:
Use SnapsToDevicePixels. This can cause some noticeably odd spacing if you have lines sufficiently close together.
or
Increase the width of your line so that it full hits a line of pixels. (this has the drawback that the needed width is, again, device dependent).
Calling TextRenderer.MeasureText as follows:
TextRenderer.MeasureText(myControl.Text, myControl.Font);
and comparing the result to the size of the control to check if text fits. The results are sometimes incorrect. Have observed the following two issues:
Often when a Label is set to AutoSize, TextRenderer will report a width that is 1 pixel wider than the auto-sized width of the Control.
False negative where TextRenderer reports a width smaller than the control's but the text is still cut off. This occurred with "Estación de trabajo" -- not sure if the accent could somehow affect the width calculation?
Is there any way to improve the accuracy of the MeasureText method? Should I be calling one of the overrides that accepts a device context and/or format flags?
I know it's probably no actual anymore. Yet for future readers here is a simple yet accurate method of measuring text in a control:
Graphics g=Graphics.FromHwnd(YOUR CONTROL HERE.Handle);
SizeF s=g.MeasureString("YOUR STRING HERE", Font, NULL, NULL, STRING LENGTH HERE, 1)
Is there any way to improve the accuracy of the MeasureText method? Should I be calling one of the overrides that accepts a device context and/or format flags?
You have answered your question by yourself. Actually MeasureText based on Win32 DrawTextEx, and this function cannot work without valid device context. So when you call MeasureText override without hdc, it internally create desktop compatible hdc to do measurement.
Of course measurement depends on additional TextFormatFlags. Also keep in mind that Label painting (and measurement) depends on UseCompatibleTextRendering.
So general conclusion you should use MeasureText for your own code, for example when you then call DrawText with exactly same parameters, in all other cases size returned by MeasureText cannot be treated as precise.
If you need to get expected Label size, you should use GetPreferredSize method.
Check out the TextFormatFlags parameter to this function:
TextRenderer::MeasureText(String, Font, Size, TextFormatFlags)
http://msdn.microsoft.com/en-us/library/8wafk2kt.aspx
"The Size, in pixels, of text drawn on a single line with the specified font. You can manipulate how the text is drawn by using one of the DrawText overloads that takes a TextFormatFlags parameter. For example, the default behavior of the TextRenderer is to add padding to the bounding rectangle of the drawn text to accommodate overhanging glyphs. If you need to draw a line of text without these extra spaces you should use the versions of DrawText and MeasureText that take a Size and TextFormatFlags parameter. For an example, see MeasureText(IDeviceContext, String, Font, Size, TextFormatFlags)."
hth
I don't know if I have a perfect solution but I ran into this when I was doing WinForms a few years back. The way I ended up compensating was by adjusting the returned measurement by a percentage. I cannot recall what I used (maybe 5% or 105?), but I do recall that I ended up using a constant percentage across the app and always rounded up.
I haven't got enough points to comment yet, so I've had to put this as an answer:
Perhaps ClearType affects measurement accuracy, because although a character has a known width calculated from its glyph, its rendering and position are adjusted to place axial lines on whole pixels.
Just a thought.