How to keep font quality on scale transform - wpf

I want to stretch the text in a label to fill the width of the label using VB.NET code. This is in a WPF application.
I have tried numerous methods including changing only the font size like this:
scale = 0.25
lbl.FontSize = l.Width * scale
The problem with this method is I need the height to remain the same for all labels and the 0.25 was a guess that gives approximately the correct fill for a string of 4 characters
I tried a recursive method where I change the font size in small increments and compare the string width to the label width until it fits.
Transformations was also considered and it would looks like a good bet:
w = lbl.Width
scale = lbl.content.length/100
lbl.LayoutTransform = New System.Windows.Media.ScaleTransform(w * scale, 1)
This solves my problem of hight but I still need to guess the factor of transformation until it sort of works. Also the stretched text lose it quality and becomes distorted as expected.
Is there any way to reduce the distortion effect on text when its transformed. Perhaps some fonts that display better than other on after transformations?

Related

Drawing shapes on image at consistent size regardless of dimensions

I have a program where I draw a bunch of custom shapes and objects on a canvas that sits on top of an image.
The images sizes vary hugely and they are stretched proportionally to fit the view.
When I draw the shapes, I also create some editing elements (frames and handles etc) for them so they can be scaled/rotated and the like.
The problem is that due to the differing dimensions/DPI of the images, these editing elements can either be massive or tiny depending on the image.
I have tried different methods like scaling the editing elements based on a scale factor calculated from the image sizes, but I'm not terribly happy with the result.
Can anyone suggest a good way to draw these editor elements at a consistent size regardless of the size of the image below it? As in a 1px or unit line will appear exactly the same on a 100 x 100 or 10000 x 10000 image?
I dabbled with adorners hoping they might be the solution, but they scale exactly the same as my custom shapes.
Any suggestions would be awesome, thank you!

CN1: Gradient with alpha channel

I would like to have a gradient which goes from black to transparent (not white). How can I achieve this?
From my attempt below I assume the gradient style color's alpha value is not considered:
gui_Footer.allStyles.apply {
backgroundType = Style.BACKGROUND_GRADIENT_LINEAR_VERTICAL
border = RoundRectBorder.create().topOnlyMode(true).cornerRadius(1f)
backgroundGradientEndColor = ColorUtil.BLACK
backgroundGradientStartColor = ColorUtil.argb(0, 255, 255, 255)
}
Gradients in Codename One ignore the alpha byte. While we could technically add support for alpha gradients it's not something that's planned at this time. You can probably generate such an image by manipulating the RGB data but it would be more efficient to just generate an RGB image of a gradient and draw it scaled.
Notice that this is generally the most efficient approach since the GPU works by drawing textures very efficiently. If an image is a power of 2 (e.g. 256x128 pixels) it can fit perfectly in a texture and it's drawn very fast. Much faster than our builtin gradients.

What's the proper way of getting text bounding box in FreeType 2?

I wonder what's the best way of getting a text bounding box with FreeType 2?
To get the linespace bounding box width, I iterate over all the characters of the text and get it's advance and kearning:
FT_Face face = ...;
text_bbox_width = 0;
while (*p_text)
{
...
FT_Get_Kerning(...);
text_bbox_width += (face->glyph->advance.x + kerning.x) >> 6;
}
How to get linespace bounding box height? Is it necessary to iterate or can it be obtained using font face data? I.e:
text_bbox_height = (face->ascender - face->descender) >> 6
Good news: you do not need to iterate over the characters in each of your strings. You can use face->size->metrics->height, as described in 3. Global glyph metrics of http://www.freetype.org/freetype2/docs/tutorial/step2.html. Note the warnings on using ascender and descender.
Do not mistake this height for the actual pixel bounding box. Individual glyphs may stick out of this box. You can use this line height to get an even spacing over multiple lines in the same text block. To get 'larger' or 'smaller' spacing, you can multiply this value with a constant, such as 1.5 or 2.0 for "double line spacing".
I'm guessing that the value of height that Freetype calculates is the "normal" or "optimal" line spacing for a certain font.

Silverlight - Brush banding

Can someone tell me how to increase the number of "color bands" on a Silverlight gradient brush?
The question is marked as answered below, but it really isn't a solution to use bitmaps instead of gradient brushes as my users can modify their background dynamically. This is most obvious when full screen gradients are used.
how to make the brush smooth without lines in the middle
Unfortunately, I can only give you half an answer - the general principles on why this happens and how to avoid it. As to the implementation in SL, I can only give you some general ideas as I'm not an expert there.
Those bands result from the limited color depth of the display. To reduce the effect, the gradient has to be made slightly noisy. The simplest way to do is to calculate the color from the gradient as a floating number, and then round it to an integer in a weighted, random manner - like this:
correct_value = linear_gradient(x,y) // e.g 25.3
whole_part = round_down(correct_value) // 25
frac_part = correct_value - whole_part // 0.3
color_used = whole_part
if (true_with_probability(frac_part)):
color_used = color_used + 1 // color_used == 25 with 70% chance
// 26 with 30% chance
Here is an example of using this technique (on the left is the effect of simply rounding to the nearest integer, right is rounding with noise):
As to how to implement that in your case - I assume there would be some way to create a custom Brush object that would allow you to do the calculations per pixel, or alternatively some sort of shader functionality which could help. If those are not possible, you can also simply generate a bitmap using this logic, and use that bitmap as the brush (I believe this would be ImageBrush, but that's just from googling).
Perhaps somebody with more Silverlight knowledge can chime in and provide the best implementation in this case.

WPF: Textbox width guidelines

Is there a formula for textbox widths as a multiple of max. characters?
I assume that if my textbox holds 40 characters, I should be able to plug it into a formula that looks like F(40) = (40 * X + Y).
I think it really depends on the font you are using. I'm sorry for not giving you the formula, but you can find FormattedText class helpful. Especially its Width property.
In case of fixed-width fonts it's as easy as measuring any character width with FormattedText, and multiplying it by number of characters. In other cases things get trickier...
For the time being I'm using width(n) = 11n+8. This is based on the defaults for Windows 7 and the width of the M character.

Resources