Awesomium WebControl WPF, похоже, неправильно интерпретирует масштабирование
Я пытаюсь создать простой прототип (использующий Awesomium 1.7 RC3), который позволяет приложению WPF отображать веб-страницу, позволяя увеличивать и уменьшать масштаб страницы. Я не хочу сохранять макет, но адаптирую макет так же, как вы можете изменить размер окна. Это то же самое поведение, что и функция масштабирования Internet Explorer. Область логического отображения увеличивается, а фактический рендеринг увеличивается.
Например, вот скриншот приложения со 100% увеличением:
Верхний слайдер позволяет управлять масштабированием. Когда я изменяю масштаб на 90% или 110%, вот что я получаю:
А также
Как вы можете видеть, браузер рендеринг грязный. Не только внутренний рендеринг не соответствует области управления WebBrowser, но изменение размера изображения имеет очень низкое качество.
Все это правильно работало с Awesomium 1.6.6.
Как я могу получить желаемый результат?
Пример приложения можно скачать здесь. Ключевые части:
Xaml:
<Slider Value="{Binding Path=Zoom, Mode=TwoWay}"
IsSnapToTickEnabled="True"
TickPlacement="Both"
Grid.ColumnSpan="2"
Minimum="0.1"
Maximum="2.0"
TickFrequency="0.1"
LargeChange="0.1" />
<Grid x:Name="Container"
Background="SaddleBrown"
Grid.Row="1"
utils:SizeObserver.Observe="true"
utils:SizeObserver.ObservedWidth="{Binding ContainerActualWidth, Mode=OneWayToSource}"
utils:SizeObserver.ObservedHeight="{Binding ContainerActualHeight, Mode=OneWayToSource}">
<Grid x:Name="Containee"
Background="LightBlue"
RenderTransformOrigin="0,0"
Width="{Binding ContaineeWidth, Mode=OneWay}"
Height="{Binding ContaineeHeight, Mode=OneWay}">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding Zoom, Mode=OneWay}"
ScaleY="{Binding Zoom, Mode=OneWay}" />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Grid.LayoutTransform>
<awe:WebControl Source="http://www.flickr.com/search/?q=strasbourg&z=m" />
</Grid>
</Grid>
ViewModel, который используется как DataContext:
public class ViewPortViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
Debug.WriteLine("Property changes: " + propertyName);
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private double m_Zoom = 1D;
public double Zoom
{
get { return m_Zoom; }
set
{
if (value != m_Zoom)
{
m_Zoom = value;
RaisePropertyChanged("Zoom");
RaisePropertyChanged("ContaineeWidth");
RaisePropertyChanged("ContaineeHeight");
}
}
}
private double m_ContainerActualWidth = 100D;
public double ContainerActualWidth
{
get { return m_ContainerActualWidth; }
set
{
if (value != m_ContainerActualWidth)
{
m_ContainerActualWidth = value;
RaisePropertyChanged("ContainerActualWidth");
RaisePropertyChanged("ContaineeWidth");
}
}
}
private double m_ContainerActualHeight = 100D;
public double ContainerActualHeight
{
get { return m_ContainerActualHeight; }
set
{
if (value != m_ContainerActualHeight)
{
m_ContainerActualHeight = value;
RaisePropertyChanged("ContainerActualHeight");
RaisePropertyChanged("ContaineeHeight");
}
}
}
public double ContaineeWidth
{
get { return m_ContainerActualWidth / Zoom; }
}
public double ContaineeHeight
{
get { return m_ContainerActualHeight / Zoom; }
}
2 ответа
Я нашел решение в своем вопросе на форуме поддержки awesomium от Perikles.
Два шага, чтобы решить мою проблему:
Также примените преобразование макета к веб-контролю:
<Grid x:Name="Containee" Background="LightBlue" RenderTransformOrigin="0,0" Width="{Binding ContaineeWidth, Mode=OneWay}" Height="{Binding ContaineeHeight, Mode=OneWay}"> <Grid.LayoutTransform> <TransformGroup> <ScaleTransform ScaleX="{Binding Zoom, Mode=OneWay}" ScaleY="{Binding Zoom, Mode=OneWay}" /> </TransformGroup> </Grid.LayoutTransform> <awe:WebControl Source="http://www.flickr.com/search/?q=strasbourg&z=m" LoadingFrameComplete="WebControl_LoadingFrameComplete_1"> <awe:WebControl.LayoutTransform> <ScaleTransform ScaleX="{Binding Zoom, Mode=OneWay}" ScaleY="{Binding Zoom, Mode=OneWay}" /> </awe:WebControl.LayoutTransform> </awe:WebControl> </Grid>
Подпишитесь на событие LoadingFrameComplete, чтобы применить параметры преобразования рендеринга после загрузки страницы:
private bool renderingOptionsApplied; private void WebControl_LoadingFrameComplete_1(object sender, Awesomium.Core.FrameEventArgs e) { if (renderingOptionsApplied) return; var webControl = sender as Awesomium.Windows.Controls.WebControl; if ((webControl.Surface != null) && (webControl.Surface is WebViewPresenter)) { RenderOptions.SetBitmapScalingMode(webControl.Surface as WebViewPresenter, BitmapScalingMode.Linear); renderingOptionsApplied = true; } }
Это похоже на проблему, с которой я столкнулся в предыдущей версии элемента управления, когда текст отображался нечитаемым способом. Решение (для меня) было установить RenderOptions.BitmapScalingMode
в NearestNeighbor
в моем XAML. Ответ, который я получил от Awesomium, показал, что это была известная проблема, для которой они разрабатывали несколько стратегий, хотя я с тех пор не замечал этой проблемы, возможно, она снова возникла.
Проверьте вопрос Проблема с размытым текстом и посмотрите, решит ли он вашу проблему. Вот как в итоге выглядел мой XAML:
<awe:WebControl x:Name="MyBrowser"
Grid.Row="1"
Focusable="True"
Visibility="Visible"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SnapsToDevicePixels="True"
>
<awe:WebControl.Style>
<Style>
<Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" />
</Style>
</awe:WebControl.Style>
</awe:WebControl>