소스 검색

Added sampling calculation to doc preview

Krzysztof Krysiński 1 주 전
부모
커밋
74fad4e191

+ 1 - 0
src/PixiEditor/Views/Dock/DocumentPreviewDockView.axaml

@@ -12,5 +12,6 @@
         <dock:DocumentPreviewDockViewModel/>
     </Design.DataContext>
     <main:DocumentPreview Document="{Binding DocumentManagerSubViewModel.ActiveDocument}"
+                          MaxBilinearSamplingSize="{Binding DocumentManagerSubViewModel.Owner.ViewportSubViewModel.MaxBilinearSampleSize}"
                      PrimaryColor="{Binding ColorsSubViewModel.PrimaryColor, Mode=TwoWay, Converter={converters:GenericColorToMediaColorConverter}}"/>
 </UserControl>

+ 1 - 0
src/PixiEditor/Views/Main/DocumentPreview.axaml

@@ -26,6 +26,7 @@
             <viewportControls:FixedViewport
                 Delayed="True"
                 x:Name="viewport"
+                MaxBilinearSampleSize="{Binding ElementName=uc, Path=MaxBilinearSamplingSize}"
                 RenderInDocSize="{Binding ElementName=highDpiButton, Path=IsChecked}"
                 Document="{Binding Document, ElementName=uc}"
                 Background="{Binding ActiveItem.Value, ElementName=backgroundButton}"/>

+ 8 - 0
src/PixiEditor/Views/Main/DocumentPreview.axaml.cs

@@ -24,6 +24,14 @@ internal partial class DocumentPreview : UserControl
     public static readonly StyledProperty<Color> PrimaryColorProperty =
         AvaloniaProperty.Register<DocumentPreview, Color>(nameof(PrimaryColor));
 
+    public static readonly StyledProperty<int> MaxBilinearSamplingSizeProperty = AvaloniaProperty.Register<DocumentPreview, int>(
+        nameof(MaxBilinearSamplingSize), 4096);
+
+    public int MaxBilinearSamplingSize
+    {
+        get => GetValue(MaxBilinearSamplingSizeProperty);
+        set => SetValue(MaxBilinearSamplingSizeProperty, value);
+    }
     public DocumentViewModel Document
     {
         get => GetValue(DocumentProperty);

+ 38 - 9
src/PixiEditor/Views/Main/ViewportControls/FixedViewport.axaml.cs

@@ -25,11 +25,22 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
     public static readonly StyledProperty<bool> DelayedProperty =
         AvaloniaProperty.Register<FixedViewport, bool>(nameof(Delayed), false);
 
-    public static readonly StyledProperty<bool> RenderInDocSizeProperty = AvaloniaProperty.Register<FixedViewport, bool>(
-        nameof(RenderInDocSize));
+    public static readonly StyledProperty<bool> RenderInDocSizeProperty =
+        AvaloniaProperty.Register<FixedViewport, bool>(
+            nameof(RenderInDocSize));
 
-    public static readonly StyledProperty<VecI> CustomRenderSizeProperty = AvaloniaProperty.Register<FixedViewport, VecI>(
-        nameof(CustomRenderSize));
+    public static readonly StyledProperty<VecI> CustomRenderSizeProperty =
+        AvaloniaProperty.Register<FixedViewport, VecI>(
+            nameof(CustomRenderSize));
+
+    public static readonly StyledProperty<int> MaxBilinearSampleSizeProperty = AvaloniaProperty.Register<FixedViewport, int>(
+        nameof(MaxBilinearSampleSize));
+
+    public int MaxBilinearSampleSize
+    {
+        get => GetValue(MaxBilinearSampleSizeProperty);
+        set => SetValue(MaxBilinearSampleSizeProperty, value);
+    }
 
     public VecI CustomRenderSize
     {
@@ -84,7 +95,7 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
             height = availableSize.Height;
             width = height * aspectRatio;
         }
-        
+
         return new Size(width, height);
     }
 
@@ -124,7 +135,8 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
         if (Document is not null)
             docSize = Document.SizeBindable;
 
-        Matrix3X3 scaling = Matrix3X3.CreateScale((float)Bounds.Width / (float)docSize.X, (float)Bounds.Height / (float)docSize.Y);
+        Matrix3X3 scaling = Matrix3X3.CreateScale((float)Bounds.Width / (float)docSize.X,
+            (float)Bounds.Height / (float)docSize.Y);
 
         return new ViewportInfo(
             0,
@@ -133,7 +145,7 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
             scaling,
             null,
             "DEFAULT",
-            SamplingOptions.Bilinear,
+            CalculateSampling(),
             docSize,
             CalculateResolution(),
             GuidValue,
@@ -141,6 +153,23 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
             ForceRefreshFinalImage);
     }
 
+    internal SamplingOptions CalculateSampling()
+    {
+        if (Document == null)
+            return SamplingOptions.Default;
+
+        if (Document.SizeBindable.LongestAxis > MaxBilinearSampleSize || SceneTexture == null)
+        {
+            return SamplingOptions.Default;
+        }
+
+        VecD densityVec = ((VecD)SceneTexture.Size).Divide(new VecD(Bounds.Width, Bounds.Height));
+        double density = Math.Min(densityVec.X, densityVec.Y);
+        return density > 1
+            ? SamplingOptions.Bilinear
+            : SamplingOptions.Default;
+    }
+
     private static void OnDocumentChange(AvaloniaPropertyChangedEventArgs<DocumentViewModel> args)
     {
         DocumentViewModel? oldDoc = args.OldValue.Value;
@@ -154,11 +183,12 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
         {
             oldDoc.SizeChanged -= viewport.DocSizeChanged;
         }
+
         if (newDoc != null)
         {
             newDoc.SizeChanged += viewport.DocSizeChanged;
         }
-        
+
         viewport.ForceRefreshFinalImage();
     }
 
@@ -181,4 +211,3 @@ internal partial class FixedViewport : UserControl, INotifyPropertyChanged
         Document?.Operations.AddOrUpdateViewport(GetLocation());
     }
 }
-