It appears that my WPF app is replacing some Unicode characters with others.
With this simple example:
<Window x:Class="WPFUnicodeFail.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUnicodeFail"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" FontFamily="Segoe UI" FontSize="40">
<StackPanel Orientation="Horizontal">
<Label>◀</Label>
<Label>◀</Label>
<Label>◄</Label>
<Label>◄</Label>
<Label>▲</Label>
</StackPanel>
I get this result:
While if I switch the font to Arial, I get this:
None of this makes much sense, because the first two labels should be the BLACK LEFT-POINTING TRIANGLE (U+25C0) ◀ and the following two should be BLACK LEFT-POINTING POINTER (U+25C4) ◄. The TRIANGLE is supposed to be an equilateral triangle, while the POINTER is supposed to be flatter. With Segoe UI, the TRIANGLE is transparently replaced with the POINTER. With Arial, it's even worse, they are switched.
Trying both including the character itself in the source code and the &#x code yields the same result as seen in the images above.
In Word 2016, I try the three different characters with Segoe UI and I get the correct result (although with inconsistent scaling even though the font size is the same, but that's a different issue):
Why does this happen? How do I get consistent results with different fonts? Or at least, how do I get the TRIANGLE with Segoe UI and other fonts that seem to change it to the POINTER?
If you check the fonts you're using with the Windows Character Map (Start > Programs > Accessories > System Tools > Character Map), you'll notice that the Segoe UI font is missing the U+25C0 character, so does the Arial too. I suppose, this is implementation specific how does the system treat such a case when a character has to be displayed that is missing in the font. If you choose the Segoe UI Symbol font, you can see those characters correctly displayed by a WPF app. Maybe MS Word can do this automatically?
If you want to ensure that all your symbols will be correctly displayed in different fonts, you should probably check those fonts with the Character Map tool.
Related
If large images are displayed in a size smaller than the original, then begin to show artifacts "pixelation":
https://habrastorage.org/files/8a6/198/506/8a61985069cb4d0097540bf0d07f4a68.png
But this can be solved by specifying the attribute of the object in XAML, scaling algorithm with higher quality:
<Image Height="50" Width="50"
Source="Resources/logo.png"
RenderOptions.BitmapScalingMode="HighQuality" /><!-- Scaling Mode -->
Then, the image looks fine:
https://habrastorage.org/files/819/863/48f/81986348f9ab454a9d6b676d88321d0a.png
Question. How to change the scaling algorithm that is applied to the icon in the window? Icon set through XAML (the last line):
<Window x:Class="MyApp.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/present"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:res="clr-namespace:MyApp.Properties"
Title="{x:Static res:Resources.AboutWindowTitle}"
Height="450" Width="300"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Icon="Resources/info.png"><!-- Icon -->
Icon in the title bar looks like this:
_https://habrastorage.org/files/946/bb7/67b/946bb767b66042aba985a8e55a21b078.png (Sorry, I do not have enough reputation to post third link)
Attribute RenderOptions.BitmapScalingMode = "HighQuality" applied to the window, gives nothing.
Unlike the elements in client area, those in title bar are not under direct control of a WPF application. A png file set to a Window's Icon property will be converted to the icon image in title bar (and that in task bar) but as you see, the conversion seems to be quite limited.
So as far as I know, unfortunately, the only practical solution to set nicely shown icon in title bar is to create or find an icon file (.ico) which has multiple images inside and use it instead of merely a png file.
I was used to Windows Forms and non-resizeable windows when I posted this question, so I did not understand how to make content ajustable to the window. However, now that I understand how to use margins and other properties that allow for "responsive" windows, I highly recommend not to use this method. Use margins and alignment instead.
I've been working with WPF.NET for quite a while now, but there is a problem that has been bugging me since I first started using it in Visual Studio. It seems that when I run my program, the windows shrinks by 10 pixels, in comparison to the designer display.
Here are some pictures to better explain my problem:
Designer mode display:
Actual window when ran:
This has only been occuring in WPF. It does not happen in Windows Forms. It has been happening in VS 2012 and VS 2013.
Is there any way to solve this?
I'm pretty new to all this, and this problem was very frustrating. I worked out that on run, the whole window shrank to the panel/grid size, losing about 10px from the panel/grid (x&y).
^^above didn't help much, no disrespect.
I found this by XAML Designer(from 2010) which helped, maybe it will help you.
But basically, add:
SizeToContent="WidthAndHeight"
(instead of ^Rohit Vats "d:DesignHeight="77" d:DesignWidth="294"") ..in the Window wrapper
Make sure all margins are set to desired value for the content. Worked perfectly for me.
Design height and width might be set on your window which is completely different from actual rendered height and width of control. Remove design heigh and width:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="77" d:DesignWidth="294"> <-- HERE
<Grid>
...
</Grid>
</Window>
On a side note you should totally avoid giving hard coded height and width to your control. Play with relative width and height instead OR simply let your containing panel decide height and width. Otherwise, on window resize your control won't resize per actual window dimensions.
I have applied SmallCaps as shown below, but it doesn't seem to have any effect on in the browser or in a design window.
<TextBlock Text="Text Here !" Typography.Capitals="SmallCaps"/>
Why is Typography.Capitals parameter ignored? Are there any settings that need to be enabled for this ?
UPDATE
It seems that for these properties to work, the font used must support them. Silverlight can not perform magic with the font, it can only work with the features built into the font itself. And it seems that there are some differences between different versions of Windows, which made this even more confusing. I have tried this on Windows 7 and 8 using the following fonts:
Gabriola, Georgia, Verdana, Arial, Comic Sans MS, Calibri, Segoe UI, Portable User Interface
On both Win7 and 8 the only properties that ever worked were SmallCaps and AllSmallCaps. None of the other settings made any difference whatsoever, neither on Win7 or Win8. On Windows 8 these two properties worked for all the fonts listed above. On Windows 7 the only fonts where they did work were Calibri and Gabriola. I then started looking into the versions of the fonts installed on the two different machines. It turns out they are different. For example, on my Win7 machine both Verdana and Segoe UI is of version 5.05. On the Win8 machine Verdana is version 5.31 and Segoe UI is version 5.28.
So I think this is why we get different results on different machines. It has nothing to do with Silverlight, but with the versions of the fonts installed on the client machine. The version of Verdana installed on Win7 has no support for SmallCaps and AllSmallCaps, but the version that comes with Win8 does have that support.
END UPDATE
I am definitely seeing a difference with SmallCaps and AllSmallCaps. The rest of the values don't seem to do anything. It could depend on the FontFamily used I suppose. Any way, the following code renders like the screen shot below.
<ContentControl FontSize="18"
FontFamily="Segoe UI">
<StackPanel>
<TextBlock Text="Writing Some Text Here in the Text Block. AllPetiteCaps"
Typography.Capitals="AllPetiteCaps"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. AllSmallCaps"
Typography.Capitals="AllSmallCaps"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. Normal"
Typography.Capitals="Normal"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. PetiteCaps"
Typography.Capitals="PetiteCaps"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. SmallCaps"
Typography.Capitals="SmallCaps"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. Titling"
Typography.Capitals="Titling"></TextBlock>
<TextBlock Text="Writing Some Text Here in the Text Block. Unicase"
Typography.Capitals="Unicase"></TextBlock>
</StackPanel>
</ContentControl>
I'm not sure how much difference there is between WPF and Silverlight on this, but apparently for WPF the font has to be an OpenType font. According to wpf.2000things.com:
WPF includes a Typography class, which allows setting various attached properties for textual elements. These properties only affect text that is rendered using an OpenType font.
And in Programming WPF, 2nd Edition:
WPF supports both TrueType and OpenType fonts. OpenType fonts often contain
many alternates to the basic set of character shapes in order to support advanced
typographical functionality. If you are using a low-level text-handling feature such as
GlyphRun, you can use these alternates directly, referring to them by glyph index. But
if you are using the higher-level elements, such as TextBlock or the FlowDocument
viewers, these can locate and use the appropriate glyphs for you. You can control
which character shapes are used with the attached properties defined by the
Typography class.
I have a bit of a problem with XAML and Blend. We;ve converted the company logo from AI -> SVG -> XAML, cleaned it up a bit and its has produced a very peculiar source. In essence it is applying a "flip" transformation to a collection of paths:
<Canvas Width="640" Height="200" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas Width="640" Height="200" RenderTransform="1,0,0,-1,0,200" >
<!-- L -->
<Canvas RenderTransform="1,0,0,1,317.0645,64.3652">
<Path>
<Path.Data>
<PathGeometry FillRule="Nonzero" Figures="M0,0L0,75.065 18.743,76.83 18.743,17.066 43.553,17.066 38.564,0 0,0z" />
</Path.Data>
</Path>
</Canvas>
... etc
Note the RenderTransform="1,0,0,-1,0,200" node in the enclosing Canvas. It flips the canvas upside down and lowers it 200 down to adjust to root canvas position. Given taht Logo looks ok when rendered means that all graphic elements in the xaml are actually upside down :). Maybe its an AI thing, I don't know.
The problem is that I now use Blend to convert this canvas into a GraphicBrush. The blend omits the transform and the logo looks upiside down when brush is applied. Rather then again transforming at each brush recipient I was thinking that maybe we should just fix it at the root, e.g. convert all paths so that they render properly to begin with avoiding a need for root transform.
Question: is there a programmatic (or any other way) to do this? Meaning, can I render this canvas and then serialize a rendered (after all transforms applied) DOM into an XAML?
Or to make the question clearer: there are two transforms applied to each path (as seen above, one global flip and one local shift for each path), can I somehow apply those transforms to each path/its points so that paths render without them.
You can use the Export to XAML feature built in to Expression Design in the Microsoft Expression suite.
Or personally I normally use Mike Swanson's AI to XAML converter since I'm normally already working in Illustrator for more complex vector graphics.
Both would provide a better result than the converter you used. Not sure where that original conversion got so wacky with the RenderTransforms etc but as you've found, it helps to have a good conversion to start with then going through the trouble of fixing a bad one haha.
Cheers!
I want to seamlessly tile a bunch of different-colored Rectangles in WPF. That is, I want to put a bunch of rectangles edge-to-edge, and not have gaps between them.
If everything is aligned to pixels, this works fine. But I also want to support arbitrary zoom, and ideally, I don't want to use SnapsToDevicePixels (because it would compromise quality when the image is zoomed way out). But that means my Rectangles sometimes render with gaps. For example:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<Canvas SnapsToDevicePixels="False">
<Canvas.RenderTransform>
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
</Canvas.RenderTransform>
<Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC"/>
<Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF"/>
</Canvas>
</Page>
If the ScaleTransform's ScaleX is 1, then the Rectangles fit together seamlessly. When it's 0.5, there's a dark gray streak between them. I understand why -- the combined semi-transparent edge pixels don't combine to be 100% opaque. But I would like a way to fix it.
I could always just make the Rectangles overlap, but I won't always know in advance what patterns they'll be in (this is for a game that will eventually support a map editor). Besides, this would cause artifacts around the overlap area when things were zoomed way in (unless I did bevel-cut angles on the underlapping portion, which is an awful lot of work, and still causes problems at corners).
Is there some way I can combine these Rectangles into a single combined "shape" that does render without internal gaps? I've played around with GeometryDrawing, which does exactly that, but then I don't see a way to paint each RectangleGeometry with a different-colored brush.
Are there any other ways to get shapes to tile seamlessly under an arbitrary transform, without resorting to SnapsToDevicePixels?
You might consider using guidelines (see GuidelineSet on MSDN) and overriding the Rectangles' OnRender methods so that their boundaries line up with the pixel boundaries of the device. WPF uses guidelines to determine whether and where to snap drawings.
Internally, it's exactly what SnapsToDevicePixels is using to ensure that objects line up with the device's pixels, but by placing guidelines manually you'll be able to control when the snapping behaviour is applied and when it is not (so when your image is zoomed all of the way out, you can avoid drawing guidelines, or only draw guidelines where your shapes lie next to other shapes, and rely on WPF's anti-aliasing to take care of the rest). You might be able to do it with an attached property so that you can apply it to any element, though if it's only one type of element (e.g. Rectangle) that you need this behaviour on, it's probably not worth the extra effort.
It seems like Microsoft is aware of this problem, too - WPF 4.0 is expected to feature Layout Rounding, which, like the version in Silverlight, rounds off non-integer values at the Render pass when layout rounding has been enabled.
I guess the gaps are not actual gaps but the stroke that is painted. When you scale it down than you just make the stroke smaller to a point where it is not visible anymore. I tried to paint the stroke in the color of the rectangle wich works just fine on any scale.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<Canvas SnapsToDevicePixels="False">
<Canvas.RenderTransform>
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
</Canvas.RenderTransform>
<Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC" Stroke="#CFC"/>
<Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF" Stroke="#CCF"/>
</Canvas>
</Page>