Awesomium WebControl WPF, похоже, неправильно интерпретирует масштабирование

Я пытаюсь создать простой прототип (использующий Awesomium 1.7 RC3), который позволяет приложению WPF отображать веб-страницу, позволяя увеличивать и уменьшать масштаб страницы. Я не хочу сохранять макет, но адаптирую макет так же, как вы можете изменить размер окна. Это то же самое поведение, что и функция масштабирования Internet Explorer. Область логического отображения увеличивается, а фактический рендеринг увеличивается.

Например, вот скриншот приложения со 100% увеличением:

Увеличить 100Увеличить 100%

Верхний слайдер позволяет управлять масштабированием. Когда я изменяю масштаб на 90% или 110%, вот что я получаю:

Увеличить 90Увеличить 90%

А также

Увеличить 110Увеличить 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&amp;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.

Два шага, чтобы решить мою проблему:

  1. Также примените преобразование макета к веб-контролю:

    <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&amp;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>
    
  2. Подпишитесь на событие 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>
Другие вопросы по тегам