MeasureString() pads the text on the left and the right - gdi+

I'm using GDI+ in C++. (This issue might exist in C# too).
I notice that whenever I call Graphics::MeasureString() or Graphics::DrawString(), the string is padded with blank space on the left and right.
For example, if I am using a Courier font, (not italic!) and I measure "P" I get 90, but "PP" gives me 150. I would expect a monospace font to give exactly double the width for "PP".
My question is: is this intended or documented behaviour, and how do I disable this?
RectF Rect(0,0,32767,32767);
RectF Bounds1, Bounds2;
graphics->MeasureString(L"PP", 1, font, Rect, &Bounds1);
graphics->MeasureString(L"PP", 2, font, Rect, &Bounds2);
margin = Bounds1.Width * 2 - Bounds2.Width;

It's by design, that method doesn't use the actual glyphs to measure the width and so adds a little padding in the case of overhangs.
MSDN suggests using a different method if you need more accuracy:
To obtain metrics suitable for adjacent strings in layout (for example, when implementing formatted text), use the MeasureCharacterRanges method or one of the MeasureString methods that takes a StringFormat, and pass GenericTypographic. Also, ensure the TextRenderingHint for the Graphics is AntiAlias.

It's true that is by design, however the link on the accepted answer is actually not perfect. The issue is the use of floats in all those methods when what you really want to be using is pixels (ints).
The TextRenderer class is meant for this purpose and works with the true sizes. See this link from msdn for a walkthrough of using this.

Append StringFormat.GenericTypographic will fix your issue:
graphics->MeasureString(L"PP", 1, font, width, StringFormat.GenericTypographic);
Apply the same attribute to DrawString.

Sounds like it might also be connecting to hinting, based on this kb article, Why text appears different when drawn with GDIPlus versus GDI

TextRenderer was great for getting the size of the font. But in the drawing loop, using TextRenderer.DrawText was excruciatingly slow compared to graphics.DrawString().
Since the width of a string is the problem, your much better off using a combination of TextRenderer.MeasureText and graphics.DrawString..

Related

Is there a formula to find affected square by sized-brush on a grid?

I am not sure how to put this problem in a single sentence, sorry if the title is misleading.
I am currently developing a simple terrain editor with a circle-shaped brush size. The image below shows a few cases that represent my problem.
additional info: the square size is fixed and uniform and in the current version, my concern is only to find which one is hit and which one is not (the amount of region covered is important for weighting the hit, but probably not right now)
My current solution (which is not even correct for a certain condition) is: given a hit in a position (x, y) with radius r, loop through all square from (x-radius, y-radius) to (x+radius, y+radius) and apply 2-D box to circle collision detection. But I don't think this is optimal (or even correct IMO).
Can anyone help me with this one? Thank you
Since i can't add a simple comment due to bureaucracy on this website i have to type it out here.
Anyway you're in luck since i was trying to do this recently as well! The way i did it is i iterated through the vertex array and check if the current vertex falls inside the radius of the circle. But perhaps what you want is to check it against each quad center and if that center falls inside the radius then add the whole quad as it's being collided.
Of course depending on the size of your grid the performance will vary so it's good to try to iterate through as few quads as needed. Though accessing these quads from the array is something you have to figure out yourself.

How to make qt qgraphicsview scale to not affect stipple pattern?

I draw few rectangles inside the QGraphicsView ; I use custom stipple pattern for these by creating a QBrush with my QPixmap. This gets displayed with the default zoom level as expected.
When I call view->scale(), the rectangles show up bigger or smaller as I expected. However Qt has scaled the individual bits of the stipple pattern which is not expected; I expected it to draw the larger or smaller rectangle again with the brush.
Eg.
If I had used a stipple pattern with one pixel dot and pixel space, after zooming in, I want to see a larger rectangle but I want the same stipple pattern with same pixel gaps. Is this achievable somehow? Thanks.
I ran into the same problem while developing an EDA tool companion in Qt.
After some trying, what I did (and seems to work for me) is to create a custom graphics item. On the paint method, I do:
QBrush newBrush = brush_with_pattern;
newBrush.setTransform(QTransform(painter->worldTransform().inverted()));
painter->setBrush(newBrush);
That is to apply the inverse transformation of the item to the brush (so it does not scale).
I think that the setDashOffset is only for the border of the shapes (not the fill).
You may use QPen::setDashOffset:
http://harmattan-dev.nokia.com/docs/library/html/qt4/qpen.html#setDashOffset
You'll need to set the offset based on the scenes zoom/scale level. You can grab a pointer to the scene in your item by calling scene(), don't forget to check for NULL though since it will be NULL when not added to the scene (although you shouldn't in theory get a paint() when not in a scene).
The other option is to use:
http://doc.qt.digia.com/qt/qpainter.html#scale
To undo the views scaling on your painter.
In case anyone is still looking on this, a related question here regarding scaling of standard fill patterns instead of pixmap fill patterns may help. Basically, it may not be possible to modify scaling of standard fill patterns (a few workaround ideas are listed), but, working with alpha values instead gives the desired effect if you are looking for varying colors, especially gray levels - and is much less convoluted.

Getting QGraphicsTextItem length?

Is there anyway to calculate the text's length when TextWidth = -1?.
I have a rectangle that has a QGraphicsTextItem in it, and I want to change the rectangle's width when characters exceed the rectangle.
I found this post by stopping on the same problem.
i'm using text->boundingRect().width()to get the width.
Perhaps it helps anybody
textWidth = -1 means, that
"[...] the text will not be broken into
multiple lines unless it is enforced
through an explicit line break or a
new paragraph."
(QTextDocument::textWidth())
So, if you want to get the length of your QGraphicsTextItem you can't use textWidth, but instead you need the actual length of the String within this QGraphicsTextItem. Have a look at QGraphicsTextItem::toPlainText(), which returns a QString. Call size() on that string.
int length = my_graphics_text_item.toPlainText().size()
Now you have the number of characters in this string and can implement a resize function to make your rectangle grow, when there are too many characters. It's a kind of workaround, but I hope it helps solving your problem.
You could also create a QFontMetrics([font of your QGraphicsTextItem]) instance and call its width(QString) function to obtain the width of the passed string in pixels, were it drawn in the specified fontfamily/-size/-weight.
Just obtaining the character count is only reasonable when using a monospaced font. In all other cases it's not a good idea.

How to determine the number of charecter will fit to screen in Qt

How do I determine the number of characters in a particular font will fit to the screen?
Have a look at QFontMetrics. Using this, you can determine, among other things, the width of a particular string:
QFontMetrics metrics(myFont);
int width = metrics.width(myString);
Is this what you want?
Note: It is not possible to find the number of characters of a particular font that will fit on the screen since not all fonts are monospace. So the number of characters will depend on the actual characters.
you can also use QFontMetrics::elidedText passing available space (remember to reduce it with margins/paddings. Then call length on result string

color code in X/HTML , CSS

In how many ways we can give color info in X/HTML, css?
I know some
Hex
color name
rgba
is there any other method?
and which method is preferred to use and which not? Please give explanation.
The three ways you mention are the only three.
I don't think a specific method is generally preferred, but as a developer, I like to see hex numbers.
I would avoid color names simply because if you want to know the true value of a color you have to look it up which is an annoyance in my workflow.
Also, hex numbers are the most compact way to describe a color (for most colors), so you might be saying a couple bytes of bandwidth by using hex. This doesn't really matter, but it's one of the only differences I can think of.
There is one more method: the one you're missing is old RGB. RGBa includes opacity (that's the 'a', for alpha)--it's not the same as RGB. RGB is supported by a wide array of browsers, old and new; RGBa is supported by a narrower but significant set of browsers: http://css-tricks.com/rgba-browser-support/ (IE being the main holdout, as usual).
Which method you use really doesn't matter. I prefer hex from habit, but am starting to use RGB more so that I can start getting used to extending it to RGBa.

Resources