WPF Bold Font - Use a different font or set Font weight? - wpf

How do I know when I should be appending "Bold" to the name of the font vs setting the font weight?
I have the following test function to demonstrate the issue:
public static bool IsBoldFont(string fontName, System.Windows.FontWeight fontWeight)
{
var typeface = new System.Windows.Media.Typeface(new System.Windows.Media.FontFamily(fontName), System.Windows.FontStyles.Normal, fontWeight, System.Windows.FontStretches.Normal);
typeface.TryGetGlyphTypeface(out System.Windows.Media.GlyphTypeface glyphTypeface);
return glyphTypeface.Weight == System.Windows.FontWeights.Bold;
}
And these are the results:
IsBoldFont("Arial Narrow", System.Windows.FontWeights.Bold); // false
IsBoldFont("Arial Narrow Bold", System.Windows.FontWeights.Regular); // true
IsBoldFont("Arial", System.Windows.FontWeights.Bold); // true
-- Update --
I think I simplified my question a bit too much. I am converting from one software package to another. The font specified is "Arial Narrow" and Bold weight (like in MS Word - select the font, then apply the Bold Weight to it, the Font "Arial Narrow Bold" does not exist in the list of fonts).
When converting the text to draw on the canvas, the font is not drawing Bold when I am asking for ("Arial Narrow", System.Windows.FontWeights.Bold), however it is correct when changing the font family name to ("Arial Narrow Bold", System.Windows.FontWeights.Regular). How am I supposed to know to append " Bold" to the end of the family name?

Related

How can I increase the size of the displayed text using a library like Allegro? C

How can I change the size of the displayed font to display the following entry:
al_draw_textf(font, al_map_rgb(204, 255, 255), WIDTH / 2, 50,\
ALLEGRO_ALIGN_CENTER, "%d : %d", pl1.scope, pl2.scope);
Created a standard ASCII font which I am trying to resize.
ALLEGRO_FONT* font = al_create_builtin_font();
Display of the players' score. (img)
This is the first game, I didn't do anything except console programs before.
As al_create_builtin_font() - liballeg points out:
ALLEGRO_FONT *al_create_builtin_font(void)
Creates a monochrome bitmap font (8x8 pixels per character).
This font is primarily intended to be used for displaying information
in environments or during early runtime states where no external font
data is available or loaded (e.g. for debugging).
In order to resize fonts load fonts from the local/system repo.
al_load_font() :
ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags)
Package your fonts with the game, it becomes easier to load them.

How to control/scale image size in Codename One?

I used the (new) GUI Builder and inserted an image (by way of adding a Label). However, it appears too big. Is there anyway I can scale and control the size? (I saw something which points to cloudinary but that seems too complicated. I just want to simply scale down the image.)
There are several ways to resize images in Codename One and I will mention few below:
1.
Use MultiImages in the GUI Builder. With this multiple sizes of images are generated from one image based on the sizes you specified. In your GUI Builder, Click Images -> Add Multi Images -> Select your image -> Check Preserve Aspect Ratio -> Increase the % that represents the percentage of the screen width you want the image to occupy. Set any DPI you don't require to 0.
2.
Use ScaledImageLabel or ScaledImageButton, it will resize the image the fill available space the component is occupying.
3.
Scale the image itself in code (This is not efficient, though):
public static Image getImageFromTheme(String name) {
try {
Resources resFile = Resources.openLayered("/theme");
Image image = resFile.getImage(name);
return image;
} catch (IOException ioe) {
//Log.p("Image " + name + " not found: " + ioe);
}
return null;
}
Image resizedImage = getImageFromTheme("myImage").scaledWidth(Math.round(Display.getInstance().getDisplayWidth() / 10)); //change value as necessary
4.
Mutate the image (Create an image from another image).

Why is the width of my placeholder not abode in URLImage (Codename One)

My app features a form with 2 images. The first one is downloaded and rounded via an ImageAdapter on the fly and the second one is from the theme. They are applied to a Button and laid next to each other as shown below :
In my Form
The placeholder in my form is defined as :
int imageWidth = (int) (Display.getInstance().getDisplayWidth() / 2.5);
EncodedImage placeholder = EncodedImage.createFromImage(Image.createImage(
imageWidth,
imageWidth,
ParametresGeneraux.accentColor), true);
The image I apply on the button is created like this :
reportImage = URLImage.createToStorage(placeholder,
Report.getFilename(chosenReport.getPhotoPath()),
chosenReport.getPhotoPath(),
ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
);
Then I do just afterwards
System.err.println("The placeholder in FORM has a width of " + placeholder.getWidth()); // 432
I get a width of 432 for the placeholder from within the FORM.
However from the ImageAdapter
public final static URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() {
#Override
public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) {
System.err.println("The placeholder in the ImageAdapter has a width of " + placeholderImage.getWidth());
// ...
}
});
The placeholder width I get from within the ImageAdapter is different with a value of 200.
Where should I look at for a mistake, since the placeholder widths should be the same in both methods, shouldn't they ?
Edit 2017-02-23 : Important note
Before showing this form, the involved image has already been downloaded a first time in another form with a different size. And actually the message from the ImageAdapter (see System.err()) is not triggered. I overflew this because many images are loaded. See my answer for the continuation.
Any hint appreciated,
Regards
Eventually it appeared that the
System.err.println("The placeholder in the ImageAdapter has a width of " + placeholderImage.getWidth());
displayed in the console was not from the ImageAdapter call in this form but from the previous form which actually downloaded and showed the same image a first time.
So the second time I call URLImage.createToStorage() with the same internal name (see Report.getFilename(chosenReport.getPhotoPath()) in my question) as the file has already been downloaded and is present in cache, it is not downloaded again as written in the doc :
Notice that the image that will be saved is the scaled image, which means you will have very little overhead in downloading images that are the wrong size although you will get some artifacts.
Finally if I changed the internal name, and then even though the Image gets downloaded it scales perfectly :

Custom heightForRowAtIndexPath (CGSize sizeWithFont) with NSAttributedString iOS

I have a table view where my cells height is defined dynamically depending on the text it is representing.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//getting my text for this cell, the row etc ...
...
//here is the part interesting us
NSAttributedString* theText = [myTextForThisCell objectAtIndex:indexPath.row];
NSInteger labelWidth = self.tableView.bounds.size.width-HORIZONTAL_CELL_PADDING;
CGSize textSize = [theText sizeWithFont:[UIFont systemFontOfSize:customFontSize] constrainedToSize:CGSizeMake(labelWidth, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
return textSize.height+VERTICAL_CELL_PADDING;
}
Ok so now my problem.
The tableview is the result of a search action which after scanning a plist file shows the lines containing a given string.
Up to now that was it. But now with iOS 6 and NSAttributedString allowing easily to bold part of strings I decided to bold the search word.
It is working, it bolds the words I want but now I am no more able to calculate the cell height as sizeWithFont ask for a NSString. And as bolding takes a wider width I cannot simply calculate the cell height with the string without attributes.
I am simply stuck here.
Anyone can help me ?
In fact I simply had to read apple documentation of NSAttributedText.
In my case I have to replace the last two lines of code by
CGRect rectSize = [theText boundingRectWithSize:CGSizeMake(labelWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin context:NULL];
return rectSize.size.height+VERTICAL_CELL_PADDING;
FOLLOW UP iOS 7
I have been struggling making this work in iOS7 with attributed text.
Apple documentation says
In iOS 7 and later, this method returns fractional sizes (in the size
component of the returned CGRect); to use a returned size to size
views, you must use raise its value to the nearest higher integer
using the ceil function.
Which way obviously not working for me ! For me the solution was to add +1 to the ceil of height. This is probably a bug from Apple, but for me now everything works as in iOS6.
CGRect rectSize = [theAttributedText boundingRectWithSize:CGSizeMake(labelWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin context:NULL];
return ceil(rectSize.size.height) + 1 + VERTICAL_CELL_PADDING;

WPF: How to filter out non-Roman fonts from Fonts.SystemFontFamilies?

I know how to create a WPF font picker with a few lines of XAML, binding to Fonts.SystemFontFamilies (thanks to Norris Cheng's excellent blog post), but I can't figure out how to filter out all the international and other non-Roman-alphabet font families. My users aren't likely to need "Mongolian Baiti", "Microsoft Uighur", or even "Webdings", and when those are in the list it makes it harder for them to find the fonts they do want.
Are there any properties on the objects reachable from SystemFontFamilies that I can use to separate the non-symbol Roman-alphabet font families from the rest?
EDIT: The information I would like to use is available in the Windows 7 Fonts control panel, in the "Designed for" field. This strings in this field contain "Latin" for fonts useful for Latin-alphabet applications, other language names for "international" fonts ('Mongolian Baiti' is 'Mongolian', for example), and "Symbol" for fonts like Wingdings. The "Category" field also looks useful for separating 'display' fonts from 'text' fonts. Unfortunately, I can't figure out any way to get this information from code, and I can't even figure out where it is in the OpenType spec. My guess is that the OpenType script tags or language tags are involved.
There is no explicit information in a font that defines unambiguously whether it is readable as "Roman" or not.
You could resort to glyph analysis to see what Unicode ranges a font covered. This could give you a clue as to what languages a font covered. However, this has problems too, e.g.:
The default Windows 7 font is "Segoe UI". In your scheme would you see this as a "Roman" font? The problem here is that even if you carry out glyph analysis it covers Latin but also other Unicode ranges e.g. Arabic and Thai. Ok fine, we can include fonts that at least cover Latin, however, what if the Latin range is not actually readable as Latin as in point 3?
The example of "Mongolian Baiti" includes glyphs that cover the basic Latin range, so it can be used to render "Roman" text.
Webdings covers the Latin range, so via analysis it could pass, but it does not actually contain readable Latin characters.
Glyph analysis could be applied to narrow things down perhaps, but you could get false positives.
Update
I have to deal with font lists in my own application, so couldn't leave this one alone! :)
It is actually possible to derive whether a font is a symbol font via the GlyphTypeface.Symbol property (which is new to me). Therefore with this and a bit of glyph analysis, the following solution should do the trick.
It will however still find "Mongolian Baiti" (and it's "Baiti" not "Balti" as in the curry style :)) as this has glyphs for Latin characters so it still is a "Roman" font depending on how you define this. As a matter of fact all non-Symbol fonts on my system have at least the Latin character range, so the Latin glyph test doesn't actually exclude any fonts.
What is your particular objection to "Mongolian Baiti", and how do you expect to automatically exclude it (without using a manually maintained exclusion list for example)?
[Test]
public void test()
{
var fonts = Fonts.SystemFontFamilies.OrderBy(x => x.ToString());
var latinFonts = fonts.Where(f =>
f.Source.StartsWith("Global") ||
(!IsSymbol(f) && HasLatinGlyphs(f)));
latinFonts.ToList().ForEach(Console.WriteLine);
}
private bool IsSymbol(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
return glyph.Symbol;
}
private bool HasLatinGlyphs(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
for (int i = 32; i < 127; i++)
{
if (!glyph.CharacterToGlyphMap.ContainsKey(i)) return false;
}
return true;
}
private GlyphTypeface GetFirstGlpyhTypeface(FontFamily fontFamily)
{
Typeface typeface = fontFamily.GetTypefaces().First();
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
return glyph;
}
Update 2
You could experiment with filtering out fonts based on what support they have for extended Latin characters by including filters for Latin Extended-A and Latin Extended-B ranges. Filtering with both Latin Extended-A and Latin Extended-B leaves very few fonts left, but just filtering on Latin Extended-A still leaves quite a lot of fonts. It also automatically removes Mongolian Baiti as this only has support for Latin-1 and Latin-1 Supplement.
Whether this sort of analysis gives desirable results is highly subjective. Something to experiment with though:
private bool HasLatinGlyphs(FontFamily fontFamily)
{
GlyphTypeface glyph = GetFirstGlpyhTypeface(fontFamily);
List<Tuple<int, int>> ranges = new List<Tuple<int, int>>
{
new Tuple<int, int>(32, 126), //Latin-1
new Tuple<int, int>(160, 255), //Latin-1 Supplement
new Tuple<int, int>(256, 383), //Latin Extended-A
new Tuple<int, int>(384, 591), //Latin Extended-B
};
foreach (Tuple<int, int> range in ranges)
{
for (int i = range.Item1; i <= range.Item2; i++)
{
if (!glyph.CharacterToGlyphMap.ContainsKey(i)) return false;
}
}
return true;
}
Again, highly subjective, but the following will give fonts that support Latin glyphs plus a sub-set of international currency characters:
List<Tuple<int, int>> ranges = new List<Tuple<int, int>>
{
new Tuple<int, int>(32, 126), //Latin-1
new Tuple<int, int>(0x20A0, 0x20B5), //Currency Symbols (Partial)
};
Update 3
Further to your question edit here is a version that will work with Windows 7. It leverages Window 7's hidden font feature (as pointed out by #Rick Sladkey) which by default hides fonts that are not considered to be useful for the current user's locale setting. It will also exclude symbol fonts:
[Test]
public void test()
{
var allFonts = Fonts.SystemFontFamilies.OrderBy(x => x.Source);
var filteredFonts = allFonts.Where(f =>
IsComposite(f) || (!IsSymbol(f) && !IsHidden(f)));
filteredFonts.ToList().ForEach(Console.WriteLine);
}
private static bool IsComposite(FontFamily fontFamily)
{
return fontFamily.Source.StartsWith("Global");
}
private static bool IsSymbol(FontFamily fontFamily)
{
Typeface typeface = fontFamily.GetTypefaces().First();
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
return glyph.Symbol;
}
private static bool IsHidden(FontFamily fontFamily)
{
const string Key = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Font Management";
const string Value = "Inactive Fonts";
RegistryKey key = Registry.CurrentUser.OpenSubKey(Key);
IEnumerable<string> hiddenFonts = (string[])key.GetValue(Value);
return hiddenFonts.Contains(fontFamily.Source);
}
I don't think that you are ever going to find that type of information without providing it yourself. Font specifications themselves don't provide this information, so I guess this means you are out of luck. Your best bet is to determine a list of fonts that you deem 'acceptable' for your end users.
I could not find an easy reliable way to do this. I think the best solution is to honor the hidden state of fonts as provided by Windows 7. This way users can hide/show fonts as they see fit but also hide all fonts inappropriate for their region. Unfortunately there is no documented API to find out if a font is hidden or not but you can use a registry setting.
Here is an article that explains how to do it:
Honoring Hidden Fonts

Resources