-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Potential wrong text measure with Inter Font #11804
Comments
It seems that it is dependent on which of the controls is visible initially (hence, wich of the state is set on startup. The above behavior where the 2nd control is a bit further left happens if the 2nd item is selected on startup. If the 1st item is selected on startup the behavior is the other way around. It has nothing to do with the order within Xaml (I have checked that). |
The highlight rectangle is pixel aligned and the text isn't. So the rendering might end up at different positions depending on the surrounding drawing operations. We might need to introduce pixel alignment for text as well. |
Ok. Do you see a workaround? For now without limiting myself on Font Style I would potentially remove WithInterFont() as the app is only planned for Windows. I also assumed it may be other drawing calls and I had removed a lot of things but did not find the causing other control. Gout feeling is that it is the 3 user controls within the same Grid "behind" each other where only one is visible because the problem always goes with the one control that is displayed on startup. And only for that one not for the other 2. |
Just to allow for better understanding, here some Xaml parts: The parent bottom left control that contains the 3 different (but equal) controls for each state <Grid>
<Grid IsVisible="{Binding CurrentGuidanceWorkflowState, Mode=OneWay, Converter={StaticResource guidanceWorkflowStateConverter}, ConverterParameter=Templating}" >
<v:GuidanceInfoTemplatingView DataContext="{Binding GuidanceInfoTemplatingViewModel}" />
</Grid>
<Grid IsVisible="{Binding CurrentGuidanceWorkflowState, Mode=OneWay, Converter={StaticResource guidanceWorkflowStateConverter}, ConverterParameter=PlatePreview}" >
<v:GuidanceInfoPlatePreviewView DataContext="{Binding GuidanceInfoPlatePreviewViewModel}" />
</Grid>
<Grid IsVisible="{Binding CurrentGuidanceWorkflowState, Mode=OneWay, Converter={StaticResource guidanceWorkflowStateConverter}, ConverterParameter=ArticularTargeting}" >
<v:GuidanceInfoArticularTargetingView DataContext="{Binding GuidanceInfoArticularTargetingViewModel}" />
</Grid>
</Grid> Sample of the contained user controls (all equal): <Grid Background="{StaticResource BackgroundDefault}">
<bui:StretchPanel Orientation="Vertical"
Padding="16"
ItemSpacing="16">
<bui:StretchPanel Orientation="Horizontal"
ItemSpacing="16">
<Image Source="{StaticResource GuidanceInfoPlatePreviewViewInformationIcon}"
Stretch="None" />
<TextBlock Classes="titleText"
Text="{Binding Source={StaticResource GuidanceInfoPlatePreviewViewInformation}, Converter={StaticResource I18nMand}}" />
</bui:StretchPanel>
</bui:StretchPanel>
</Grid> Note: StretchPanel is similar to StackPanel. I also tried StackPanel which does not change the problematic behavior. |
We can see that the glyph layout itself matches. The text is rendered at a different x-offset which results in a bigger bounding box. We need to compare the baseline origins of the underlying TextBlock.TextLayout's. In detail each TextLayout contains TextLines and each TextLine contains TextRuns. A ShapedTextRun holds a GlyphRun and that is rendered at the GlyphRun.BaselineOrigin Maybe you can compare the resulting values in your application. Ideally, it would be possible to extract your custom control to be able to reproduce it locally. In the end, this might be related to pixel boundaries. So measurements are the same but pixels are snapped to different edges. |
I have tried a bit more but still cannot reproduce in decently simple app. Could you let me know which values behind TextBlock I were interested? |
@llfab is any animation involved in the real world App? Idea is, that animation may not "finish" correctly causing this. |
There are animations but only in other areas of the app. This main view is currently not animated. It sits in a Grid statically whereas in the same top level Grid there are additional TransitioningContentPresenters that work with anims. The state selection that makes the relevant controls visible/invisible is non-animated. So gout feeling is it's not that. Anyhow, I find it interesting that the x-offset is always with the control that is displayed during startup. So, yes it may have to do with someting not being in its final state. |
Even more. If I choose a startup state that does not have any control on the left side, then the offset appears in the one left control that you then selected first through the top level menu and the problem stays with that first selected state. Nothing animated there. |
hm but that brings up another idea. So if in the same grid, any row or column below or above has size Auto, that can be re-calculated maybe. So in this case, can you try to hard code the columsn, rows for a test? |
The gridd is auto yes but the size of the content is set: <Grid Classes="contentView"
ColumnDefinitions="auto,*"
DragDrop.AllowDrop="{Binding DropAllowed}" >
<Grid Grid.Column="0"
RowDefinitions="*,4,*">
<v:GuidanceControlView Grid.Row="0"
DataContext="{Binding GuidanceControlViewModel}"
HorizontalAlignment="Left"
Width="{StaticResource XrayGuidanceViewControlViewWidth}"/>
<Grid Grid.Row="1" Background="{StaticResource BackgroundLow}"/>
<v:GuidanceInfoView Grid.Row="2"
DataContext="{Binding GuidanceInfoViewModel}"
HorizontalAlignment="Left"
Width="{StaticResource XrayGuidanceViewControlViewWidth}"/>
</Grid>
<v:GuidanceVisualizationView Grid.Column="1"
DataContext="{Binding GuidanceVisualizationViewModel}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</Grid> |
As I thought, I had tested that already and it seems not to change anything: <Grid Classes="contentView"
ColumnDefinitions="300,*"
DragDrop.AllowDrop="{Binding DropAllowed}" >
<v:GuidanceInfoView Grid.Column="0"
DataContext="{Binding GuidanceInfoViewModel}"
HorizontalAlignment="Left"/>
<v:GuidanceVisualizationView Grid.Column="1"
DataContext="{Binding GuidanceVisualizationViewModel}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</Grid> |
@Gillibald: I have created a sample app that shows the behavior by using my app but removing all dependencies to our libraries: https://github.com/llfab/Samples/tree/main/FontShift Hope that helps. In GuidanceModel.cs you will find: public GuidanceModel()
{
_trace = Trace.ForType<GuidanceModel>();
_currentWorkflowState = GuidanceWorkflowStateType.PlatePositioning;
_trace.Info("{0} successful.", Trace.Site());
} which defines the initial workflow state, hence, the initial views to be selected. This one does not contain any left side inner controls. Therefore, the first other state controls - that you click - will contain the font shift and the font shift will stay with that first selected one. If you restart again you can do a different first select that will again stick with that one. |
Thanks for taking the time to build a sample. Will have a look shortly. |
@Gillibald : have you been able to track this down? Or is it difficult to get to the root cause? |
I did not have time yet to investigate this further. My theory is that the Grid control is caching the first measure because both times the available space is the same. Will get back to this in late August. |
Thanks for the quick reply. No urgency here, Good to know that it is on the radar... |
Fixed in master |
Describe the bug
I have an application that shows different panels dependent on the workflow state. The app currently consists of empty panels for each state that are 100% identical. When clicking through different workflow states I noticed that one specific TextBlock text slightly moves left and right. Also Dev Tool shows that in one case the exact same TextBlock has a different width by one px.
It is worth noting that for the 3 workflow states there would be 3 user controls (one for each state) within the same grid whereas only one of which is set to IsVisible=true. Hence all exact same state specific controls exist at the same time. But only one is set to visible.
Here the differences:
In the 2nd image you can see that the blue selection starts at the same x pos but the gap to the "I" is larger.
And the image diff shows in the area of the information text:
In order to exclude potential differences in the switched user control, I have then used the very same user control for all states, sitll having different instances for each state. Same result.
If I remove the image left of the text the effect is still there.
The font is Bold, so I changed it to Normal which removes the effect also proven by the image differ. Also if I remove the .WithInterFont() from the builder (which lets Windows choose another default font, the effect goes away. Or is simply not noticable at least also not by the image differ.
Could there be a problem with the font measure?
To Reproduce
I have failed to create a minimal shareable sample so far.
Expected behavior
The text should appear at the very same position
Desktop (please complete the following information):
The text was updated successfully, but these errors were encountered: