diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2014-09-09 16:31:31 -0700 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2014-09-09 16:39:41 -0700 |
commit | 7ea99e3a8951e265d1437a77dcfee069de0edf76 (patch) | |
tree | 8e113fea67931064e2a9338d67b26aaabab27512 /platform/windows/gsview | |
parent | 8a9519f2183b64fe220bcb1f6acedbe6acc190cd (diff) | |
download | mupdf-7ea99e3a8951e265d1437a77dcfee069de0edf76.tar.xz |
Rename of winrt to windows due to presence on gsview in this folder.
The contents of this folder will contain both winrt and gsview projects
which are shared in a common visual studio 2013 solution.
Diffstat (limited to 'platform/windows/gsview')
80 files changed, 14903 insertions, 0 deletions
diff --git a/platform/windows/gsview/About.xaml b/platform/windows/gsview/About.xaml new file mode 100644 index 00000000..13b3b142 --- /dev/null +++ b/platform/windows/gsview/About.xaml @@ -0,0 +1,96 @@ +<Window + 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" mc:Ignorable="d" x:Class="gsview.About" + Title="{Binding ProductTitle, Mode=OneTime, RelativeSource={RelativeSource Self}}" + x:Uid="idAboutBox" + Style="{DynamicResource AboutDialogStyle}" WindowStartupLocation="CenterOwner" Height="353" Width="501"> + <Window.Resources> + <XmlDataProvider x:Key="aboutProvider" XPath="ApplicationInfo" IsAsynchronous="False" IsInitialLoadEnabled="True"> + <x:XData> + <ApplicationInfo xmlns=""> + <Link Uri="http://www.gsview.com">More Info</Link> + </ApplicationInfo> + </x:XData> + </XmlDataProvider> + <Image x:Key="aboutLogo" Source="resources/banner.png" /> + <Style x:Key="AboutDialogStyle" TargetType="{x:Type Window}"> + <Setter Property="Height" Value="Auto" /> + <Setter Property="Width" Value="500" /> + <Setter Property="ShowInTaskbar" Value="False" /> + <Setter Property="ResizeMode" Value="NoResize" /> + <Setter Property="WindowStyle" Value="SingleBorderWindow" /> + <Setter Property="SizeToContent" Value="Height" /> + </Style> + <Style x:Key="DisplayAreaStyle" TargetType="{x:Type StackPanel}"> + <Setter Property="Margin" Value="10,10,10,5" /> + </Style> + <Style x:Key="BackgroundStyle" TargetType="{x:Type StackPanel}"> + <Setter Property="Background"> + <Setter.Value> + <LinearGradientBrush EndPoint="0,1"> + <GradientStop Offset="0" Color="#FF317896" /> + <GradientStop Offset="0.27" Color="White" /> + <GradientStop Offset="0.85" Color="#FF317896" /> + <GradientStop Offset="1" Color="#FF317896" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + </Style> + <Style TargetType="{x:Type Label}"> + <Setter Property="Padding" Value="0" /> + </Style> + <Style x:Key="ParagraphSeparator" TargetType="{x:Type Label}"> + <Setter Property="Padding" Value="0,10,0,0" /> + </Style> + <Style x:Key="LinkLabelStyle"> + <Setter Property="Control.Padding" Value="0" /> + <Setter Property="FrameworkElement.VerticalAlignment" Value="Center" /> + </Style> + <Style x:Key="ReadOnlyDescStyle" TargetType="{x:Type TextBox}"> + <Setter Property="MinLines" Value="6" /> + <Setter Property="MaxLines" Value="6" /> + <Setter Property="IsReadOnly" Value="True" /> + <Setter Property="TextWrapping" Value="WrapWithOverflow" /> + <Setter Property="VerticalScrollBarVisibility" Value="Visible" /> + </Style> + <Style x:Key="OkButtonStyle" TargetType="{x:Type Button}"> + <Setter Property="MinWidth" Value="75" /> + <Setter Property="Margin" Value="0,5" /> + <Setter Property="DockPanel.Dock" Value="Right" /> + <Setter Property="IsDefault" Value="True" /> + <Setter Property="IsCancel" Value="True" /> + </Style> + </Window.Resources> + <StackPanel x:Uid="clientArea" Style="{StaticResource BackgroundStyle}"> + <StaticResource ResourceKey="aboutLogo" /> + <StackPanel x:Uid="displayArea" Style="{StaticResource DisplayAreaStyle}" + DataContext="{Binding Mode=OneTime, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"> + <Label x:Name="productName" x:Uid="productName" + Content="{Binding Product, Mode=OneTime}" /> + <StackPanel x:Uid="versionArea" Orientation="Horizontal"> + <Label x:Name="versionLabel" x:Uid="VersionLabel" Content="Version - " /> + <Label x:Name="version" x:Uid="version" Content="{Binding Version, Mode=OneTime}" /> + </StackPanel> + <Label x:Name="copyright" x:Uid="copyright" Content="{Binding Copyright, Mode=OneTime}" /> + <Label x:Name="company" x:Uid="company" Content="{Binding Company, Mode=OneTime}" /> + <Label x:Name="reserved" x:Uid="reserved" Content="All Rights Reserved." /> + <Label x:Name="info" x:Uid="info" Style="{StaticResource ParagraphSeparator}" + Content="Product details:" /> + <TextBox x:Name="description" x:Uid="description" Text="" + Style="{StaticResource ReadOnlyDescStyle}" Height="140" /> + <DockPanel x:Uid="buttonArea"> + <Button x:Name="okButton" x:Uid="okButton" Style="{StaticResource OkButtonStyle}" + Content="OK" /> + <Label x:Name="productLink" x:Uid="productLink" Style="{StaticResource LinkLabelStyle}" > + <Hyperlink x:Name="hyperlink" x:Uid="hyperlink" NavigateUri="{Binding LinkUri, Mode=OneTime}" Style="{StaticResource LinkLabelStyle}" + RequestNavigate="hyperlink_RequestNavigate"> + <InlineUIContainer> + <TextBlock Text="{Binding LinkText, Mode=OneTime}" /> + </InlineUIContainer> + </Hyperlink> + </Label> + </DockPanel> + </StackPanel> + </StackPanel> +</Window>
\ No newline at end of file diff --git a/platform/windows/gsview/About.xaml.cs b/platform/windows/gsview/About.xaml.cs new file mode 100644 index 00000000..6bd50cbe --- /dev/null +++ b/platform/windows/gsview/About.xaml.cs @@ -0,0 +1,255 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Windows; +using System.Windows.Data; +using System.Xml; +using System.ComponentModel; + +namespace gsview +{ + /// <summary> + /// Interaction logic for About.xaml + /// </summary> + public partial class About : Window + { + /// <summary> + /// Default constructor is protected so callers must use one with a parent. + /// </summary> + protected About() + { + InitializeComponent(); + } + + + /// <summary> + /// Constructor that takes a parent for this About dialog. + /// </summary> + /// <param name="parent">Parent window for this dialog.</param> + public About(Window parent) + : this() + { + this.Owner = parent; + } + + /// <summary> + /// Handles click navigation on the hyperlink in the About dialog. + /// </summary> + /// <param name="sender">Object the sent the event.</param> + /// <param name="e">Navigation events arguments.</param> + private void hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) + { + if (e.Uri != null && string.IsNullOrEmpty(e.Uri.OriginalString) == false) + { + string uri = e.Uri.AbsoluteUri; + Process.Start(new ProcessStartInfo(uri)); + e.Handled = true; + } + } + + #region AboutData Provider + #region Member data + private XmlDocument xmlDoc = null; + private string variabledescription; + private const string propertyNameTitle = "Title"; + private const string propertyNameDescription = "Description"; + private const string propertyNameProduct = "Product"; + private const string propertyNameCopyright = "Copyright"; + private const string propertyNameCompany = "Company"; + private const string xPathRoot = "ApplicationInfo/"; + private const string xPathTitle = xPathRoot + propertyNameTitle; + private const string xPathVersion = xPathRoot + "Version"; + private const string xPathDescription = xPathRoot + propertyNameDescription; + private const string xPathProduct = xPathRoot + propertyNameProduct; + private const string xPathCopyright = xPathRoot + propertyNameCopyright; + private const string xPathCompany = xPathRoot + propertyNameCompany; + private const string xPathLink = xPathRoot + "Link"; + private const string xPathLinkUri = xPathRoot + "Link/@Uri"; + #endregion + + #region Properties + /// <summary> + /// Gets the title property, which is display in the About dialogs window title. + /// </summary> + public string ProductTitle + { + get + { + string result = CalculatePropertyValue<AssemblyTitleAttribute>(propertyNameTitle, xPathTitle); + if (string.IsNullOrEmpty(result)) + { + // otherwise, just get the name of the assembly itself. + result = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); + } + return result; + } + } + + /// <summary> + /// Gets the application's version information to show. + /// </summary> + public string Version + { + get + { + string result = string.Empty; + // first, try to get the version string from the assembly. + Version version = Assembly.GetExecutingAssembly().GetName().Version; + if (version != null) + { + result = version.ToString(); + } + else + { + // if that fails, try to get the version from a resource in the Application. + result = GetLogicalResourceString(xPathVersion); + } + return result; + } + } + + /// <summary> + /// Gets the description about the application. + /// </summary> + public string Description + { + get { return CalculatePropertyValue<AssemblyDescriptionAttribute>(propertyNameDescription, xPathDescription);} + } + + public string VariableDescription + { + get; + set; + } + + /// <summary> + /// Gets the product's full name. + /// </summary> + public string Product + { + get { return CalculatePropertyValue<AssemblyProductAttribute>(propertyNameProduct, xPathProduct); } + } + + /// <summary> + /// Gets the copyright information for the product. + /// </summary> + public string Copyright + { + get { return CalculatePropertyValue<AssemblyCopyrightAttribute>(propertyNameCopyright, xPathCopyright); } + } + + /// <summary> + /// Gets the product's company name. + /// </summary> + public string Company + { + get { return CalculatePropertyValue<AssemblyCompanyAttribute>(propertyNameCompany, xPathCompany); } + } + + /// <summary> + /// Gets the link text to display in the About dialog. + /// </summary> + public string LinkText + { + get { return GetLogicalResourceString(xPathLink); } + } + + /// <summary> + /// Gets the link uri that is the navigation target of the link. + /// </summary> + public string LinkUri + { + get { return GetLogicalResourceString(xPathLinkUri); } + } + #endregion + + #region Resource location methods + /// <summary> + /// Gets the specified property value either from a specific attribute, or from a resource dictionary. + /// </summary> + /// <typeparam name="T">Attribute type that we're trying to retrieve.</typeparam> + /// <param name="propertyName">Property name to use on the attribute.</param> + /// <param name="xpathQuery">XPath to the element in the XML data resource.</param> + /// <returns>The resulting string to use for a property. + /// Returns null if no data could be retrieved.</returns> + private string CalculatePropertyValue<T>(string propertyName, string xpathQuery) + { + string result = string.Empty; + // first, try to get the property value from an attribute. + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(T), false); + if (attributes.Length > 0) + { + T attrib = (T)attributes[0]; + PropertyInfo property = attrib.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property != null) + { + result = property.GetValue(attributes[0], null) as string; + } + } + + // if the attribute wasn't found or it did not have a value, then look in an xml resource. + if (result == string.Empty) + { + // if that fails, try to get it from a resource. + result = GetLogicalResourceString(xpathQuery); + } + return result; + } + + /// <summary> + /// Gets the XmlDataProvider's document from the resource dictionary. + /// </summary> + protected virtual XmlDocument ResourceXmlDocument + { + get + { + if (xmlDoc == null) + { + // if we haven't already found the resource XmlDocument, then try to find it. + XmlDataProvider provider = this.TryFindResource("aboutProvider") as XmlDataProvider; + if (provider != null) + { + // save away the XmlDocument, so we don't have to get it multiple times. + xmlDoc = provider.Document; + } + } + return xmlDoc; + } + } + + /// <summary> + /// Gets the specified data element from the XmlDataProvider in the resource dictionary. + /// </summary> + /// <param name="xpathQuery">An XPath query to the XML element to retrieve.</param> + /// <returns>The resulting string value for the specified XML element. + /// Returns empty string if resource element couldn't be found.</returns> + protected virtual string GetLogicalResourceString(string xpathQuery) + { + string result = string.Empty; + // get the About xml information from the resources. + XmlDocument doc = this.ResourceXmlDocument; + if (doc != null) + { + // if we found the XmlDocument, then look for the specified data. + XmlNode node = doc.SelectSingleNode(xpathQuery); + if (node != null) + { + if (node is XmlAttribute) + { + // only an XmlAttribute has a Value set. + result = node.Value; + } + else + { + // otherwise, need to just return the inner text. + result = node.InnerText; + } + } + } + return result; + } + #endregion + #endregion + } +} diff --git a/platform/windows/gsview/App.config b/platform/windows/gsview/App.config new file mode 100644 index 00000000..7d2f9bbc --- /dev/null +++ b/platform/windows/gsview/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <startup> + + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup> +</configuration> diff --git a/platform/windows/gsview/App.xaml b/platform/windows/gsview/App.xaml new file mode 100644 index 00000000..2b1d6cbf --- /dev/null +++ b/platform/windows/gsview/App.xaml @@ -0,0 +1,7 @@ +<Application x:Class="gsview.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + StartupUri="MainWindow.xaml"> + <Application.Resources> + </Application.Resources> +</Application> diff --git a/platform/windows/gsview/App.xaml.cs b/platform/windows/gsview/App.xaml.cs new file mode 100644 index 00000000..76d96a97 --- /dev/null +++ b/platform/windows/gsview/App.xaml.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Windows; + +namespace gsview +{ + /// <summary> + /// Interaction logic for App.xaml + /// </summary> + public partial class App : Application + { + } +} diff --git a/platform/windows/gsview/ContentEntry.cs b/platform/windows/gsview/ContentEntry.cs new file mode 100644 index 00000000..a384be16 --- /dev/null +++ b/platform/windows/gsview/ContentEntry.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace gsview +{ + public class ContentEntry + { + public String Name + { + get; + set; + } + + public int PageNum + { + get; + set; + } + + public ContentEntry(String Name, int PageNum) + { + this.Name = Name; + this.PageNum = PageNum; + } + }; +} + diff --git a/platform/windows/gsview/ContentItem.cs b/platform/windows/gsview/ContentItem.cs new file mode 100644 index 00000000..a58bdf79 --- /dev/null +++ b/platform/windows/gsview/ContentItem.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.ComponentModel; + +namespace gsview +{ + class ContentItem : INotifyPropertyChanged + { + + public int Page + { + get; + internal set; + } + + public String StringMargin + { + get; + internal set; + } + + public ContentItem() + { + StringMargin = ""; + Page = 0; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void ContentRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("StringMargin")); + PropertyChanged(this, new PropertyChangedEventArgs("Page")); + } + } + } +} diff --git a/platform/windows/gsview/Convert.xaml b/platform/windows/gsview/Convert.xaml new file mode 100644 index 00000000..120f2eec --- /dev/null +++ b/platform/windows/gsview/Convert.xaml @@ -0,0 +1,120 @@ +<Window x:Class="gsview.Convert" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Convert Pages" Height="270.96" Width="419.424"> + + <DockPanel LastChildFill="True"> + + <!-- Device viewer/selector --> + <Grid x:Name="xaml_DeviceGrid" Width="100" Background="DarkGray" DockPanel.Dock="Left" Visibility="Visible" > + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + </Grid.RowDefinitions> + <TextBlock Grid.Column="0" Grid.Row="0" Margin="15,0,0,0"> + <Bold>Devices:</Bold> + </TextBlock> + + <ListView Grid.Column="0" Grid.Row="1" x:Name="xaml_DeviceList" HorizontalAlignment="Stretch" + ScrollViewer.CanContentScroll="False" + Background="White" Margin="10,5,10,10" SelectionMode="Single"> + <ListView.ItemTemplate> + <DataTemplate> + <StackPanel Margin="5,5,0,0" HorizontalAlignment="Left"> + <TextBlock TextWrapping="Wrap" Text="{Binding DeviceName}" FontFamily="Segoe UI" FontSize="11" /> + </StackPanel> + </DataTemplate> + </ListView.ItemTemplate> + </ListView> + </Grid> + + <Grid x:Name="xaml_PageGrid" Width="100" Background="DarkGray" DockPanel.Dock="Left" Visibility="Visible"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + </Grid.RowDefinitions> + <TextBlock Grid.Column="0" Grid.Row="0" Margin="15,0,0,0"> + <Bold>Pages:</Bold> + </TextBlock> + <ListView Grid.Column="0" Grid.Row="1" x:Name="xaml_PageList" HorizontalAlignment="Stretch" + ScrollViewer.CanContentScroll="False" + Background="White" Margin="10,5,10,10"> + <ListView.ItemTemplate> + <DataTemplate> + <StackPanel Margin="5,5,0,0" HorizontalAlignment="Left"> + <TextBlock TextWrapping="Wrap" Text="{Binding PageString}" FontFamily="Segoe UI" FontSize="11" /> + </StackPanel> + </DataTemplate> + </ListView.ItemTemplate> + </ListView> + </Grid> + + <!-- Buttons and extra options --> + <Grid Background="DarkGray" DockPanel.Dock="Left"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + + <Grid Grid.Column="0" Grid.Row="0" Background="DarkGray"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + + <Grid Background="DarkGray" Grid.Row="0" Grid.Column="0" Margin="30,15,0,0"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + + <Button Grid.Column="0" Grid.Row="0" Width="50" Height="20" Name="xaml_Convert" Click="ConvertClick" Margin="0,0,0,0"> + <TextBlock>Convert</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="1" Width="50" Height="20" Name="xaml_Cancel" Click="ConvertCancel" Margin="0,5,0,0"> + <TextBlock>Cancel</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="2" Width="50" Height="20" Name="xaml_HelpConvert" Click="HelpConvert" Margin="0,5,0,0"> + <TextBlock>Help</TextBlock> + </Button> + </Grid> + + + <Grid Background="DarkGray" Grid.Row="0" Grid.Column="1" Margin="25,15,0,0"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + + <Button Grid.Column="0" Grid.Row="0" Width="70" Height="20" Name="xaml_AllPages" Click="AllPages" Margin="0,0,0,0"> + <TextBlock>All Pages</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="1" Width="70" Height="20" Name="xaml_EvenPages" Click="EvenPages" Margin="0,5,0,0"> + <TextBlock>Even Pages</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="2" Width="70" Height="20" Name="xaml_OddPages" Click="OddPages" Margin="0,5,0,0"> + <TextBlock>Odd Pages</TextBlock> + </Button> + </Grid> + </Grid> + + + <TextBlock Grid.Column="0" Grid.Row="1" Margin="5,10,0,0"> + <Bold>GhostScript Options:</Bold> + </TextBlock> + <TextBox x:Name="xaml_options" Grid.Row="2" Background="White" Height="40" Margin="5,5,5,5" Text=""></TextBox> + <TextBlock Grid.Column="0" Grid.Row="3" Margin="5,10,0,0"> + <Bold>MuPDF Resolution:</Bold> + </TextBlock> + <TextBox x:Name="xaml_resolution" Grid.Row="4" Background="White" Margin="5,5,153,19" Text="" + PreviewTextInput="PreviewInput"/> + </Grid> + + + </DockPanel> +</Window> diff --git a/platform/windows/gsview/Convert.xaml.cs b/platform/windows/gsview/Convert.xaml.cs new file mode 100644 index 00000000..c2c3ec65 --- /dev/null +++ b/platform/windows/gsview/Convert.xaml.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.ComponentModel; +using System.Collections.ObjectModel; +using System.Text.RegularExpressions; + +namespace gsview +{ + public class Device : INotifyPropertyChanged + { + public String DeviceName + { + get; + internal set; + } + + public gsDevice_t DeviceType + { + get; + internal set; + } + + public bool SupportsMultiPage + { + get; + internal set; + } + + public bool MuPDFDevice + { + get; + internal set; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void PageRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("DeviceName")); + } + } + + public Device() + { + this.DeviceName = ""; + } + }; + + public class SelectPage : INotifyPropertyChanged + { + public int Page + { + get; + internal set; + } + + public int PageString + { + get; + internal set; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void PageRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("Page")); + PropertyChanged(this, new PropertyChangedEventArgs("PageString")); + } + } + }; + + /// <summary> + /// Interaction logic for Convert.xaml + /// </summary> + public partial class Convert : Window + { + List<Device> GSDevices; + List<SelectPage> ConvertPages; + + /* Callback to Main */ + internal delegate void ConvertCallBackMain(object gsObject); + internal event ConvertCallBackMain ConvertUpdateMain; + + public Convert(int num_pages) + { + InitializeComponent(); + GSDevices = new List<Device>(); + ConvertPages = new List<SelectPage>(); + SetDeviceList(); + SetPageList(num_pages); + xaml_DeviceList.ItemsSource = GSDevices; + xaml_PageList.ItemsSource = ConvertPages; + } + + public void SetDeviceList() + { + foreach (gsDevice_t device in Enum.GetValues(typeof(gsDevice_t))) + { + Device device_t = new Device(); + device_t.DeviceName = Enum.GetName(typeof(gsDevice_t), device); + device_t.DeviceType = device; + if (device > gsDevice_t.psdrgb) + device_t.SupportsMultiPage = true; + else + device_t.SupportsMultiPage = false; + if (device < gsDevice_t.bmp16) + device_t.MuPDFDevice = true; + else + device_t.MuPDFDevice = false; + GSDevices.Add(device_t); + } + } + + public void SetPageList(int num_pages) + { + for (int k = 1; k < num_pages + 1; k++ ) + { + SelectPage Spage = new SelectPage(); + Spage.Page = k; + Spage.PageString = k; + ConvertPages.Add(Spage); + } + } + + private void ConvertClick(object sender, RoutedEventArgs e) + { + ConvertUpdateMain(this); + } + + private void ConvertCancel(object sender, RoutedEventArgs e) + { + this.Close(); + } + + private void HelpConvert(object sender, RoutedEventArgs e) + { + + } + + private void AllPages(object sender, RoutedEventArgs e) + { + xaml_PageList.SelectAll(); + } + + private void EvenPages(object sender, RoutedEventArgs e) + { + /* First check if any are selected */ + var item = xaml_PageList.SelectedItem; + + /* If none are selected then get all the evens. otherwise just get + * all the evens of the pages that have been selected */ + if (item == null) + { + /* Turn on the evens */ + for (int kk = 1; kk < ConvertPages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = true; + } + else + { + /* Turn off any odds */ + for (int kk = 0; kk < ConvertPages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = false; + } + } + + private void OddPages(object sender, RoutedEventArgs e) + { + /* First check if any are selected */ + var item = xaml_PageList.SelectedItem; + + /* If none are selected then get all the odds. otherwise just get + all the odds of the pages that have been selected */ + if (item == null) + { + /* Turn on the odds */ + for (int kk = 0; kk < ConvertPages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = true; + } + else + { + /* Turn off any evens */ + for (int kk = 1; kk < ConvertPages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = false; + } + } + + /* Allow only numbers */ + private void PreviewInput(object sender, TextCompositionEventArgs e) + { + e.Handled = !IsTextAllowed(e.Text); + } + + private static bool IsTextAllowed(string text) + { + Regex regex = new Regex("[^0-9]+"); + return !regex.IsMatch(text); + } + } +} diff --git a/platform/windows/gsview/DocPage.cs b/platform/windows/gsview/DocPage.cs new file mode 100644 index 00000000..267d99e8 --- /dev/null +++ b/platform/windows/gsview/DocPage.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.ComponentModel; +using System.Windows.Media.Imaging; +using System.Collections.ObjectModel; +using System.Windows.Media; + +namespace gsview +{ + public enum Annotate_t + { + UNKNOWN, + COMPUTING, + NO_ANNOTATE, + HAS_ANNOTATE, + ANNOTATE_VISIBLE, + ANNOTATE_HIDDEN + } + + public class DocPage : INotifyPropertyChanged + { + private LinesText m_lines; + private BlocksText m_blocks; + private int height; + private int width; + private int nativeheight; + private int nativewidth; + private double zoom; + private Annotate_t annotate; + private BitmapSource bitmap; + private IList<RectList> textbox; + private List<RectList> linkbox; + private Page_Content_t content; + private String pagename; + private int pagenum; + private double sely; + private double selx; + private double selheight; + private double selwidth; + private String selcolor; + private double sel_anchorx; + private double sel_anchory; + + public double SelAnchorX + { + get { return sel_anchorx; } + set { sel_anchorx = value; } + } + + public double SelAnchorY + { + get { return sel_anchory; } + set { sel_anchory = value; } + } + + public double SelY + { + get { return sely; } + set + { + sely = value; + OnPropertyChanged("SelY"); + } + } + + public double SelX + { + get { return selx; } + set + { + selx = value; + OnPropertyChanged("SelX"); + } + } + + public double SelHeight + { + get { return selheight; } + set + { + selheight = value; + OnPropertyChanged("SelHeight"); + } + } + + public double SelWidth + { + get { return selwidth; } + set + { + selwidth = value; + OnPropertyChanged("SelWidth"); + } + } + + public String SelColor + { + get { return selcolor; } + set + { + selcolor = value; + OnPropertyChanged("SelColor"); + } + } + + public int Height + { + get { return height; } + set + { + height = value; + OnPropertyChanged("Height"); + } + } + + public int Width + { + get { return width; } + set + { + width = value; + OnPropertyChanged("Width"); + } + } + + public int NativeHeight + { + get { return nativewidth; } + set { nativewidth = value; } + } + + public int NativeWidth + { + get { return nativeheight; } + set { nativeheight = value; } + } + + public Annotate_t Annotate + { + get { return annotate; } + set { annotate = value; } + } + + public double Zoom + { + get { return zoom; } + set { zoom = value; } + } + + public BitmapSource BitMap + { + get { return bitmap; } + set + { + bitmap = value; + OnPropertyChanged("BitMap"); + } + } + + public IList<RectList> TextBox + { + get { return textbox; } + set + { + textbox = value; + OnPropertyChanged("TextBox"); + } + } + + public List<RectList> LinkBox + { + get { return linkbox; } + set + { + linkbox = value; + OnPropertyChanged("LinkBox"); + } + } + + public BlocksText TextBlocks + { + get { return m_blocks; } + set + { + m_blocks = value; + OnPropertyChanged("TextBlocks"); + } + } + + public LinesText SelectedLines + { + get { return m_lines; } + set + { + m_lines = value; + OnPropertyChanged("SelectedLines"); + } + } + + public Page_Content_t Content + { + get { return content; } + set { content = value; } + } + + public String PageName + { + get { return pagename; } + set { pagename = value; } + } + + public int PageNum + { + get { return pagenum; } + set { pagenum = value; } + } + + public AA_t AA + { + get; + set; + } + + public event PropertyChangedEventHandler PropertyChanged; + + // Create the OnPropertyChanged method to raise the event + protected void OnPropertyChanged(string name) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + + public DocPage() + { + this.Height = 0; + this.Width = 0; + this.NativeHeight = 0; + this.NativeWidth = 0; + this.Zoom = 0; + this.BitMap = null; + this.TextBox = null; + this.LinkBox = null; + this.Content = Page_Content_t.NOTSET; + this.PageNum = -1; + this.PageName = ""; + this.TextBlocks = null; + this.AA = AA_t.HIGH; + } + + public DocPage(int Height, int Width, double Zoom, BitmapSource BitMap, + List<RectList> TextBox, List<RectList> LinkBox, + Page_Content_t Content, int PageNum, BlocksText TextBlocks, + AA_t AA) + { + this.Height = Height; + this.Width = Width; + this.Zoom = Zoom; + this.BitMap = BitMap; + this.TextBox = TextBox; + this.LinkBox = LinkBox; + this.Content = Content; + this.PageNum = PageNum; + this.PageName = ("Page " + (PageNum + 1)); + this.TextBlocks = TextBlocks; + this.AA = AA; + } + }; + public class Pages : ObservableCollection<DocPage> + { + public Pages() + : base() + { + } + } +} diff --git a/platform/windows/gsview/Info.xaml b/platform/windows/gsview/Info.xaml new file mode 100644 index 00000000..4033d2ee --- /dev/null +++ b/platform/windows/gsview/Info.xaml @@ -0,0 +1,11 @@ +<Window x:Class="gsview.Info" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Info" Height="216.304" Width="430.434" Background="WhiteSmoke"> + <DockPanel LastChildFill="True"> + <Button DockPanel.Dock="Bottom" Width="70" Height="20" Name="xaml_CloseInfo" Click="OKClose" Margin="0,0,0,20" IsDefault="True"> + <TextBlock Name="xaml_ButtonText" FontFamily="Courier" Text="OK"/> + </Button> + <TextBlock Name="xaml_TextInfo" Text="File not open" Margin="10,10,10,10" FontFamily="Courier New"></TextBlock> + </DockPanel> +</Window> diff --git a/platform/windows/gsview/Info.xaml.cs b/platform/windows/gsview/Info.xaml.cs new file mode 100644 index 00000000..8a544aa8 --- /dev/null +++ b/platform/windows/gsview/Info.xaml.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace gsview +{ + /// <summary> + /// Interaction logic for Info.xaml + /// </summary> + public partial class Info : Window + { + public Info() + { + InitializeComponent(); + } + + private void OKClose(object sender, RoutedEventArgs e) + { + this.Close(); + } + } +} diff --git a/platform/windows/gsview/Install32/Install32.vdproj b/platform/windows/gsview/Install32/Install32.vdproj new file mode 100644 index 00000000..4fecfe14 --- /dev/null +++ b/platform/windows/gsview/Install32/Install32.vdproj @@ -0,0 +1,1225 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:Install32" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_016DC0AD4FFB4399B8519ACA84400E23" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_14D6D6CD543648468701A0FE8D5A2463" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1F1881EE52A84F49A62D42DE7E4D9D24" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_200E66532F6140579FA9390D6F7CC178" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2684CEAF38794D53AF9D906A7F8D677C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_389C02C6991141428A41BC2459A55E76" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4826B6F3283A4770935083729B0777B2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_4879181DB5BD4512A8A1790BC22435A0" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_791D64A55F0847788638D3FCDD1802DD" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_87036B53E422457DBCA496540B818802" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_A62B07FE876C4ACBBE7DEF7A219A570E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B2090A11BD04495DACDA72D4E5D72B7E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_4879181DB5BD4512A8A1790BC22435A0" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Install32.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Install32.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.5" + { + "Name" = "8:Microsoft .NET Framework 4.5 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.5" + } + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_3D4E37C6DF874A34821259A8B423B24C" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "FrameworkVersion" = "8:.NETFramework,Version=v4.5" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=395269" + } + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_016DC0AD4FFB4399B8519ACA84400E23" + { + "SourcePath" = "8:..\\Resources\\pagePNG.ico" + "TargetName" = "8:pagePNG.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_14D6D6CD543648468701A0FE8D5A2463" + { + "SourcePath" = "8:..\\Resources\\pageCBZ.ico" + "TargetName" = "8:pageCBZ.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1F1881EE52A84F49A62D42DE7E4D9D24" + { + "SourcePath" = "8:..\\Resources\\pageEPS.ico" + "TargetName" = "8:pageEPS.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_200E66532F6140579FA9390D6F7CC178" + { + "SourcePath" = "8:..\\Resources\\pagePDF.ico" + "TargetName" = "8:pagePDF.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2684CEAF38794D53AF9D906A7F8D677C" + { + "SourcePath" = "8:..\\Resources\\pagePS.ico" + "TargetName" = "8:pagePS.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_389C02C6991141428A41BC2459A55E76" + { + "SourcePath" = "8:..\\Resources\\pageOXPS.ico" + "TargetName" = "8:pageOXPS.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4826B6F3283A4770935083729B0777B2" + { + "SourcePath" = "8:..\\Resources\\pageJPG.ico" + "TargetName" = "8:pageJPG.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_4879181DB5BD4512A8A1790BC22435A0" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:gsview, Version=6.0.0.0, Culture=neutral, processorArchitecture=MSIL" + "ScatterAssemblies" + { + } + "SourcePath" = "8:..\\bin\\Release\\gsview.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F115E751BD3842299C96BA6F8A5B0F40" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_791D64A55F0847788638D3FCDD1802DD" + { + "SourcePath" = "8:..\\Resources\\pageXPS.ico" + "TargetName" = "8:pageXPS.ico" + "Tag" = "8:" + "Folder" = "8:_F28BDA152FBB403EAF109B8E144140A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_87036B53E422457DBCA496540B818802" + { + "SourcePath" = "8:..\\bin\\Release\\mupdfnet32.dll" + "TargetName" = "8:mupdfnet32.dll" + "Tag" = "8:" + "Folder" = "8:_F115E751BD3842299C96BA6F8A5B0F40" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A62B07FE876C4ACBBE7DEF7A219A570E" + { + "SourcePath" = "8:..\\gsview.visualelementsmanifest.xml" + "TargetName" = "8:gsview.visualelementsmanifest.xml" + "Tag" = "8:" + "Folder" = "8:_F115E751BD3842299C96BA6F8A5B0F40" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B2090A11BD04495DACDA72D4E5D72B7E" + { + "SourcePath" = "8:..\\gslib\\gsdll32.dll" + "TargetName" = "8:gsdll32.dll" + "Tag" = "8:" + "Folder" = "8:_F115E751BD3842299C96BA6F8A5B0F40" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_12B01738B600492AA1C8D89AD0821413" + { + "Name" = "8:CDisplay ZIP Archived Comic Book file" + "Description" = "8:CDisplay ZIP Archived Comic Book file" + "Extensions" = "8:cbz" + "MIME" = "8:" + "Icon" = "8:_14D6D6CD543648468701A0FE8D5A2463" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_33B319EC439B40E38BD09902607AFE0B" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_13D929725BF0460F823C23414FB2F0A1" + { + "Name" = "8:Open XPS Document" + "Description" = "8:Open XPS Document" + "Extensions" = "8:oxps" + "MIME" = "8:" + "Icon" = "8:_389C02C6991141428A41BC2459A55E76" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_02319B3587ED4701B20BE6C84D578514" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_65F612197D8D450C8AC251D615131D21" + { + "Name" = "8:PostScript File" + "Description" = "8:PostScript File" + "Extensions" = "8:ps" + "MIME" = "8:" + "Icon" = "8:_2684CEAF38794D53AF9D906A7F8D677C" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_1CC8050B2F6146E6A1F7C71C12ACB66E" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_69F979C4C92C4C348E8001B157A92FED" + { + "Name" = "8:EPS File" + "Description" = "8:EPS File" + "Extensions" = "8:eps" + "MIME" = "8:" + "Icon" = "8:_1F1881EE52A84F49A62D42DE7E4D9D24" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_EA00D9AD05ED40BE82A6F8CF37AA21EE" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_A5691CEB907F4D66A3FE718B4FF65E8D" + { + "Name" = "8:PNG image" + "Description" = "8:PNG image" + "Extensions" = "8:png" + "MIME" = "8:" + "Icon" = "8:_016DC0AD4FFB4399B8519ACA84400E23" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_95A3859E50134298ACEA0E1EACA47513" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_CD91C7FED2C94607AC5CFB7F6571A963" + { + "Name" = "8:XPS Document" + "Description" = "8:XPS Document" + "Extensions" = "8:xps" + "MIME" = "8:" + "Icon" = "8:_791D64A55F0847788638D3FCDD1802DD" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_C39CD59228F345E48878777D30252120" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_EA8DCA7319A3441EA0A8F07F20C7EC71" + { + "Name" = "8:JPEG image" + "Description" = "8:JPEG image" + "Extensions" = "8:jpeg" + "MIME" = "8:" + "Icon" = "8:_4826B6F3283A4770935083729B0777B2" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_90799BABA05F49D6AB9D093411DD157E" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_EA91006930CC4A349642A7F0AD319AA4" + { + "Name" = "8:PDF" + "Description" = "8:PDF" + "Extensions" = "8:pdf" + "MIME" = "8:" + "Icon" = "8:_200E66532F6140579FA9390D6F7CC178" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_4879181DB5BD4512A8A1790BC22435A0" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_D9041E3AC16C43E4AF1822F9103B24D6" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_05287FF94E284ACF9E55AD5BF0AF82E6" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_8ADA7142ADE14DFFA878A5107FE5C304" + { + "Name" = "8:Artifex Software" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AF85737E4DAA4E318495768F54D7F0AF" + "Folders" + { + } + } + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_74B5607A82364A9E8F63FA435CF2C5FA" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_F115E751BD3842299C96BA6F8A5B0F40" + { + "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_F28BDA152FBB403EAF109B8E144140A8" + { + "Name" = "8:Resources" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_76594C33BABA488DBC160B0B115E0F1B" + "Folders" + { + } + } + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:GSview 6.0" + "ProductCode" = "8:{BB8C85F6-5B3C-4163-9B55-6B07E747E947}" + "PackageCode" = "8:{85959242-0814-4BFE-8891-EE46ADB397D6}" + "UpgradeCode" = "8:{00F5E049-7C22-449F-9879-A4D6A7634B7E}" + "AspNetVersion" = "8:4.0.30319.0" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:TRUE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:TRUE" + "ProductVersion" = "8:6.0.0" + "Manufacturer" = "8:Artifex Software" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://www.artifex.com" + "Title" = "8:Install GSview 6.0 x86" + "Subject" = "8:" + "ARPCONTACT" = "8:Artifex Software" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:Install GSview 6.0 for x86" + "ARPURLINFOABOUT" = "8:http://www.artifex.com" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_233AE572F5BA48D1A577D7F88DE5C94E" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_75350EE0EC77414B82CAB14EAF87F8AA" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_18E520707B824ADE8636026ABE055101" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_07D3F609B0F0416CB43A58C33358E4B5" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_027434B1EED34DEF86F7CF3635B5FD30" + { + "Name" = "8:GSView 6.0" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:32512" + "Transitive" = "11:FALSE" + "Target" = "8:_4879181DB5BD4512A8A1790BC22435A0" + "Folder" = "8:_8ADA7142ADE14DFFA878A5107FE5C304" + "WorkingFolder" = "8:_F115E751BD3842299C96BA6F8A5B0F40" + "Icon" = "8:_4879181DB5BD4512A8A1790BC22435A0" + "Feature" = "8:" + } + } + "UserInterface" + { + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_1F01AD235CE94923AAD616EC2F3B2101" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_332E71C0C4E14EB9950570071C650B0B" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_20E5387842C44457BF0F53E5E053BADA" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_50F65640B6CC47C882EDDB10C3EA355C" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_C0FA7EB2C0E949D99D49ED30340AD678" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_8B3DB474F8184537ABFC9E001FAD6796" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_90A48D00803D4600A3A0587F503DF240" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_AC19A30ACDE24F4C9F6FC61008980022" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_BF426D392BBE410FB49E79B38576061E" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_672D3C120E06497894B6A7787DB2AD1D" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_ECDD7A4101B249C88A997FF923CC7009" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_51BA1897377D4A5D98ACE0E2EB251293" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_AC4CC79CCC9E47D59B61182471DE1D40" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F1DD6CBB2F29447BB67A41DC327C2254" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_F2A4ABF584D248E7812843F3F6D91F91" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_2A85F1F786AB43EF820FA580E2689977" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E63962ADBAE3438ABDEFC6290FFF9B71" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_FD25300108814F51958E9811E0EF375D" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + } + } +} diff --git a/platform/windows/gsview/Install64/Install64.vdproj b/platform/windows/gsview/Install64/Install64.vdproj new file mode 100644 index 00000000..1d660c05 --- /dev/null +++ b/platform/windows/gsview/Install64/Install64.vdproj @@ -0,0 +1,1238 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:Install64" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_0BD3A92E2F2F40A3B601C2CF21584C48" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_157FB597E59745DFAD45AE54F232D39D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1BF4736955034DCEBB4B7C53AEFECA2A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_28423EA654C8488A8F59859D947164F4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_372F38F3347F4E0491FA521F236BA54C" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_44A71C9401B94929A3DF6828309FE684" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6724F24524E24AA1907957AF0812BD09" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9F16FF3C56C249B58F3F64B821ABBF97" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AB1B21BC24164EF4929937FE8C3ED270" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BC8D174211B84DE6968562ECF0A0443B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C11D0300BF42444AA9362921375DF910" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D300E715CB524AF1AE46CE9EB3ED67C8" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_44A71C9401B94929A3DF6828309FE684" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Install64.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.5" + { + "Name" = "8:Microsoft .NET Framework 4.5 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.5" + } + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Install64.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.5" + { + "Name" = "8:Microsoft .NET Framework 4.5 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.5" + } + } + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_D0F5C30769F1419B8C1834A6F984A56F" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "FrameworkVersion" = "8:.NETFramework,Version=v4.5" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=395269" + } + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_0BD3A92E2F2F40A3B601C2CF21584C48" + { + "SourcePath" = "8:..\\Resources\\pageEPS.ico" + "TargetName" = "8:pageEPS.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_157FB597E59745DFAD45AE54F232D39D" + { + "SourcePath" = "8:..\\Resources\\pageXPS.ico" + "TargetName" = "8:pageXPS.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1BF4736955034DCEBB4B7C53AEFECA2A" + { + "SourcePath" = "8:..\\gslib\\gsdll64.dll" + "TargetName" = "8:gsdll64.dll" + "Tag" = "8:" + "Folder" = "8:_CDB2B40979C34EBAA8A815DA144BF441" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_28423EA654C8488A8F59859D947164F4" + { + "SourcePath" = "8:..\\Resources\\pageOXPS.ico" + "TargetName" = "8:pageOXPS.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_372F38F3347F4E0491FA521F236BA54C" + { + "SourcePath" = "8:..\\bin\\Release\\mupdfnet64.dll" + "TargetName" = "8:mupdfnet64.dll" + "Tag" = "8:" + "Folder" = "8:_CDB2B40979C34EBAA8A815DA144BF441" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_44A71C9401B94929A3DF6828309FE684" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:gsview, Version=6.0.0.0, Culture=neutral, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_44A71C9401B94929A3DF6828309FE684" + { + "Name" = "8:gsview.exe" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:..\\bin\\Release\\gsview.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_CDB2B40979C34EBAA8A815DA144BF441" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6724F24524E24AA1907957AF0812BD09" + { + "SourcePath" = "8:..\\Resources\\pagePS.ico" + "TargetName" = "8:pagePS.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9F16FF3C56C249B58F3F64B821ABBF97" + { + "SourcePath" = "8:..\\Resources\\pageCBZ.ico" + "TargetName" = "8:pageCBZ.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AB1B21BC24164EF4929937FE8C3ED270" + { + "SourcePath" = "8:..\\Resources\\pagePDF.ico" + "TargetName" = "8:pagePDF.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BC8D174211B84DE6968562ECF0A0443B" + { + "SourcePath" = "8:..\\gsview.visualelementsmanifest.xml" + "TargetName" = "8:gsview.visualelementsmanifest.xml" + "Tag" = "8:" + "Folder" = "8:_CDB2B40979C34EBAA8A815DA144BF441" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C11D0300BF42444AA9362921375DF910" + { + "SourcePath" = "8:..\\Resources\\pagePNG.ico" + "TargetName" = "8:pagePNG.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D300E715CB524AF1AE46CE9EB3ED67C8" + { + "SourcePath" = "8:..\\Resources\\pageJPG.ico" + "TargetName" = "8:pageJPG.ico" + "Tag" = "8:" + "Folder" = "8:_52FA2F218E56408DA37ABFD7E103994C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_11428E8F96C54BA3900AF3407233AAC0" + { + "Name" = "8:PostScript File" + "Description" = "8:PostScript File" + "Extensions" = "8:ps" + "MIME" = "8:" + "Icon" = "8:_6724F24524E24AA1907957AF0812BD09" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_8E3935BB44F543D5B0E48ACB12FF306D" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_5C233C0E4937479FB108F39E16FABDE6" + { + "Name" = "8:CDisplay ZIP Archived Comic Book file" + "Description" = "8:CDisplay ZIP Archived Comic Book file" + "Extensions" = "8:cbz" + "MIME" = "8:" + "Icon" = "8:_9F16FF3C56C249B58F3F64B821ABBF97" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_8D3603F262824461A9EA284DBB30D575" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_61007590E6A24BA1A769A064AC2AC094" + { + "Name" = "8:JPEG image" + "Description" = "8:JPEG image" + "Extensions" = "8:jpeg" + "MIME" = "8:" + "Icon" = "8:_D300E715CB524AF1AE46CE9EB3ED67C8" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_0E6BD260F46C4A89891F1D0A7029A6EF" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_962DBD1C82974C33960B863AB9E1FC9F" + { + "Name" = "8:Open XPS Document" + "Description" = "8:Open XPS Document" + "Extensions" = "8:oxps" + "MIME" = "8:" + "Icon" = "8:_28423EA654C8488A8F59859D947164F4" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_6B19B65AF043423897A64F9129571FE9" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_A59FDC99A2564A0089516522926CE6C3" + { + "Name" = "8:PNG image" + "Description" = "8:PNG image" + "Extensions" = "8:png" + "MIME" = "8:" + "Icon" = "8:_C11D0300BF42444AA9362921375DF910" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_948A77318E904662886D34BDC0BCFE0E" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_A8D59D004BB94148B529FD692DDC5460" + { + "Name" = "8:XPS Document" + "Description" = "8:XPS Document" + "Extensions" = "8:xps" + "MIME" = "8:" + "Icon" = "8:_157FB597E59745DFAD45AE54F232D39D" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_A9ABA43924574B7A992B78537E7F2FB7" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_A8EDD49D509A4974B971BF4FBD093455" + { + "Name" = "8:PDF" + "Description" = "8:PDF" + "Extensions" = "8:pdf" + "MIME" = "8:" + "Icon" = "8:_AB1B21BC24164EF4929937FE8C3ED270" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_9396BB7A2A2841B0890D2DB6A6360F4E" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + "{5EB83D71-FA18-4901-BE56-DE22E13CC478}:_AA94DC1A560A4224A9410A3EAAB34D77" + { + "Name" = "8:EPS File" + "Description" = "8:EPS File" + "Extensions" = "8:eps" + "MIME" = "8:" + "Icon" = "8:_0BD3A92E2F2F40A3B601C2CF21584C48" + "IconIndex" = "3:0" + "Command" + { + "Command" = "8:_44A71C9401B94929A3DF6828309FE684" + } + "Verbs" + { + "{95C0C507-CBF0-42B8-B119-07219E384A4A}:_BAFA7BE3B6AF4D9283D623A69D266E9B" + { + "Command" = "8:&Open" + "Verb" = "8:open" + "Arguments" = "8:\"%1\"" + "Order" = "3:0" + } + } + } + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_A2CF2A9B6D384F768C297CC789FBB997" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_BE3A2AB1B2C04D7AB9F691ADFDCA6EE1" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:TRUE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_EAE10184B82B40399A965598BE4C92BC" + { + "Name" = "8:Artifex Software" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_6289816925F64FEEA99AF2712A31DF22" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_CDB2B40979C34EBAA8A815DA144BF441" + { + "DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_52FA2F218E56408DA37ABFD7E103994C" + { + "Name" = "8:Resources" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_0E795A41F6474AC8ACB9997020B3421A" + "Folders" + { + } + } + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:GSview 6.0" + "ProductCode" = "8:{A22596C0-BCF4-46F9-9CF2-1C66E8588C30}" + "PackageCode" = "8:{8B802149-336B-4DEB-A58A-ABDF1941600D}" + "UpgradeCode" = "8:{B494B7A2-738F-4F9D-87F4-31830A16FB76}" + "AspNetVersion" = "8:4.0.30319.0" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:TRUE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:TRUE" + "ProductVersion" = "8:6.0.0" + "Manufacturer" = "8:Artifex Software" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:http://www.artifex.com" + "Title" = "8:Install GSview 6.0 x64" + "Subject" = "8:" + "ARPCONTACT" = "8:Artifex Software" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:Install GSview 6.0 for x64" + "ARPURLINFOABOUT" = "8:http://www.artifex.com" + "ARPPRODUCTICON" = "8:_44A71C9401B94929A3DF6828309FE684" + "ARPIconIndex" = "3:32512" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:1" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_1E605C0AD6C1431799974106D953AE68" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_22F6F34C883A4B46B3D926048627ECB6" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_C1C61CD1AF1A4D718391EC0C924CCEDC" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_78C4B8465B114416A32C1313FA510012" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_DD3E47DAFCAA48ED9A8A02F3B29E888E" + { + "Name" = "8:GSView 6.0" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:32512" + "Transitive" = "11:FALSE" + "Target" = "8:_44A71C9401B94929A3DF6828309FE684" + "Folder" = "8:_EAE10184B82B40399A965598BE4C92BC" + "WorkingFolder" = "8:_CDB2B40979C34EBAA8A815DA144BF441" + "Icon" = "8:_44A71C9401B94929A3DF6828309FE684" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_84D62A451A39423FB4CBFBF0B05992AE" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_91A9D42868164E8A8F4197F300F1B9D8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8A4A575119DD460AA6774C08CB4BA465" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_44BF62E80B0E4B2DA3C75D4B8B3D11EB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_914CB62F95114045827D6FD18322AE3C" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_1A397F336F944DEAB35C08D6CEA5FE2A" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5A2C0AE1AE7D4D17B87F0474E7424544" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_FFE13B0235424B189193B4E4F400CB78" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_BC4637BE7ED7492A9359C01A9E29ACDC" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdBasicDialogs.wim" + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_C0B167A59DF14DA9A4170111D28C6057" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_C71BEB46A03841F0A26B15DC40628CE8" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E843264C683A45A5B80393D60A1EA3EB" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_DD9DE969B7A74DAC8E617049CE2C3AC1" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A7B7CDCFC5904E1D9128AA5B88FE3583" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_BC68E9D5B9714365AD5E43D2BD52B953" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D4358EB6E55E497193888CAFBDD4F2C9" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:0" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_F3C1167A3B7748BCB1C893E82BBED76A" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9313CCEC27A04A03B8010FCEC3B1BEC1" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:<VsdDialogDir>\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + } + } +} diff --git a/platform/windows/gsview/Links.cs b/platform/windows/gsview/Links.cs new file mode 100644 index 00000000..ef902381 --- /dev/null +++ b/platform/windows/gsview/Links.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Drawing; + +namespace gsview +{ + public enum link_t + { + LINK_GOTO = 0, + LINK_URI, + TEXTBOX, /* Do double duty with this class */ + NOT_SET, + }; + + class Links + { + link_t type; + Uri uri; + int page_num; + + public Links() + { + uri = new Uri(""); + page_num = -1; + type = link_t.NOT_SET; + } + } +} diff --git a/platform/windows/gsview/MainWindow.xaml b/platform/windows/gsview/MainWindow.xaml new file mode 100644 index 00000000..10d126bb --- /dev/null +++ b/platform/windows/gsview/MainWindow.xaml @@ -0,0 +1,794 @@ +<Window x:Class="gsview.MainWindow" + xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="gsview" Height="850" Width="714" UseLayoutRounding="True" + KeyDown="OnKeyDownHandler" Closing="AppClosing"> + <!-- UseLayoutRounding needed to avoid funny interpolation effects on pages --> + + <Window.Resources> + <DataTemplate x:Key="PageTemplate"> + <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="{Binding Height}" Width="{Binding Width}" Margin="0,0,0,0" + MouseLeftButtonDown="PageMouseDown" MouseMove="PageMouseMove" MouseLeftButtonUp="PageLeftClickUp" ClipToBounds="True" + MouseRightButtonDown="ShowContextMenu"> + <Image Width="{Binding Width}" Height="{Binding Height}" Stretch="Fill" HorizontalAlignment="Center" Source="{Binding BitMap}"> + <Image.BitmapEffect> + <DropShadowBitmapEffect Color="Black" Direction="-50" + ShadowDepth="40" Softness=".7" /> + </Image.BitmapEffect> + </Image> + + <!-- Single selection rectangle. Not a list --> + <Rectangle Width="{Binding Path=SelWidth}" Height="{Binding Path=SelHeight}" Stroke="{Binding Path=SelColor}"> + <Rectangle.RenderTransform> + <TranslateTransform X="{Binding Path=SelX}" Y="{Binding Path=SelY}"/> + </Rectangle.RenderTransform> + </Rectangle> + + <ItemsControl ItemsSource="{Binding Path=TextBox}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Canvas/> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}"> + <Rectangle.RenderTransform> + <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/> + </Rectangle.RenderTransform> + </Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <ItemsControl ItemsSource="{Binding Path=SelectedLines}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Canvas/> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}"> + <Rectangle.RenderTransform> + <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/> + </Rectangle.RenderTransform> + </Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <ItemsControl ItemsSource="{Binding Path=TextBlocks}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Canvas/> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}" MouseLeave="ExitTextBlock" MouseEnter="EnterTextBlock"> + <Rectangle.RenderTransform> + <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/> + </Rectangle.RenderTransform> + </Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <ItemsControl ItemsSource="{Binding Path=LinkBox}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Canvas/> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Tag="{Binding Path=Index}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Fill="{Binding Path=Color}" IsEnabled="True" MouseDown="LinkClick"> + <Rectangle.RenderTransform> + <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/> + </Rectangle.RenderTransform> + </Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + </Canvas> + </DataTemplate> + + <DataTemplate x:Key="ThumbTemplate"> + <Image Width="{Binding Width}" Height="{Binding Height}" Stretch="Fill" HorizontalAlignment="Center" Source="{Binding BitMap}" Margin="24,24,0,0"> + <Image.BitmapEffect> + <DropShadowBitmapEffect Color="Black" Direction="-50" + ShadowDepth="5" Softness=".7" /> + </Image.BitmapEffect> + </Image> + </DataTemplate> + + <Style TargetType="{x:Type Button}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type Button}"> + <ControlTemplate.Triggers> + <Trigger Property="IsPressed" Value="True"> + <Setter Property="Background" Value="Black" /> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + <!-- Customize listview to turn off selection --> + </Window.Resources> + + <!-- The following is needed to set up all the keyboard short cuts --> + <Window.CommandBindings> + <CommandBinding Command="Open" Executed="OpenFileCommand"></CommandBinding> + <CommandBinding Command="SelectAll" Executed="SelectAllCommand"></CommandBinding> + <CommandBinding Command="Copy" Executed="CopyCommand"></CommandBinding> + <CommandBinding Command="Print" Executed="PrintCommand"></CommandBinding> + <CommandBinding Command="Help" Executed="HelpCommand"></CommandBinding> + <CommandBinding Command="Close" Executed="CloseCommand"></CommandBinding> + </Window.CommandBindings> + <Window.InputBindings> + <KeyBinding Key="O" Modifiers="Control" Command="Open"></KeyBinding> + <KeyBinding Key="A" Modifiers="Control" Command="SelectAll"></KeyBinding> + <KeyBinding Key="C" Modifiers="Control" Command="Copy"></KeyBinding> + <KeyBinding Key="P" Modifiers="Control" Command="Print"></KeyBinding> + <KeyBinding Key="W" Modifiers="Control" Command="Close"></KeyBinding> + <KeyBinding Key="F1" Command="Help"></KeyBinding> + </Window.InputBindings> + + <!-- To do add in command short cuts and bindings --> + <DockPanel LastChildFill="True"> + <!-- Menu item at top --> + <Menu IsMainMenu="True" DockPanel.Dock="Top"> + <MenuItem Header="_File" x:Name="xaml_file"> + <MenuItem Header="_Open..." Command="Open" InputGestureText="Ctrl+O"> + <MenuItem.Icon> + <Image Source="Resources/OpenFile.png" /> + </MenuItem.Icon> + </MenuItem> + <MenuItem Header="Save As..." x:Name="xaml_saveas"> + <MenuItem.Icon> + <Image Source="Resources/saveHS.png" /> + </MenuItem.Icon> + <MenuItem Header="PDF" Click="SavePDF" x:Name="xaml_savepdf"/> + <MenuItem Header="Linearized PDF" Click="Linearize" x:Name="xaml_linearize_pdf"/> + <MenuItem Header="PDF-1.3" Click="SavePDF13" x:Name="xaml_savepdf13"/> + <MenuItem Header="PDF/A" x:Name="xaml_savepdfa"> + <MenuItem Header="PDF/A-1 RGB" Click="SavePDFA1_RGB" x:Name="xaml_savepdfa1_rgb"/> + <MenuItem Header="PDF/A-1 CMYK" Click="SavePDFA1_CMYK" x:Name="xaml_savepdfa1_cmyk"/> + <MenuItem Header="PDF/A-2 RGB" Click="SavePDFA2_RGB" x:Name="xaml_savepdfa2_rgb"/> + <MenuItem Header="PDF/A-2 CMYK" Click="SavePDFA2_CMYK" x:Name="xaml_savepdfa2_cmyk"/> + </MenuItem> + <MenuItem Header="PDF/X-3 Gray" Click="SavePDFX3_Gray" x:Name="xaml_savepdfx3_gray"/> + <MenuItem Header="PDF/X-3 CMYK" Click="SavePDFX3_CMYK" x:Name="xaml_savepdfx3_cmyk"/> + <MenuItem Header="PCL-XL" Click="SavePCLXL" x:Name="xaml_savepclxl"/> + <MenuItem Header="XPS" Click="SaveXPS"/> + <MenuItem Header="TEXT" Click="SaveText"/> + <MenuItem Header="HTML" Click="SaveHTML"/> + <MenuItem Header="XML" Click="SaveXML"/> + </MenuItem> + <MenuItem Header="_Close" Command="Close" InputGestureText="Ctrl+W" x:Name="xaml_closefile"> + <MenuItem.Icon> + <Image Source="Resources/Close.ico" /> + </MenuItem.Icon> + </MenuItem> + <MenuItem Header="Info" Click="ShowInfo" x:Name="xaml_showinfo"> + <MenuItem.Icon> + <Image Source="Resources/info.png" /> + </MenuItem.Icon> + </MenuItem> + <Separator /> + <MenuItem Header="Extract Selection..." x:Name="xaml_extractselection"> + <MenuItem.Icon> + <Image Source="Resources/saveHS.png" /> + </MenuItem.Icon> + <MenuItem Header="PDF" Click="ExtractPDF" x:Name="xaml_extractpdf"/> + <MenuItem Header="EPS" Click="ExtractEPS" x:Name="xaml_extracteps"/> + <MenuItem Header="PS" Click="ExtractPS" x:Name="xaml_extractps"/> + </MenuItem> + <MenuItem Header="Page Conversions..." Click="ConvertClick" x:Name="xaml_conversions"> + </MenuItem> + <Separator /> + <MenuItem Header="Print..." Command="Print" InputGestureText="Ctrl+P" x:Name="xaml_print"> + <MenuItem.Icon> + <Image Source="Resources/printer.ico" /> + </MenuItem.Icon> + </MenuItem> + <Separator /> + <MenuItem Header="Show Messages" Click="ShowGSMessage" x:Name="xaml_gsmessage"> + <MenuItem.Icon> + <Image Source="Resources/Message.png" /> + </MenuItem.Icon> + </MenuItem> + </MenuItem> + <MenuItem Header="_Edit" x:Name="xaml_edit"> + <MenuItem Header="Extract PDF Pages" Click="ExtractPages" x:Name="xaml_Extract"> + <MenuItem.Icon> + <Image Source="Resources/saveHS.png" /> + </MenuItem.Icon> + </MenuItem> + <Separator /> + <MenuItem Header="Copy Page" Click="CopyPage" x:Name="xaml_copypage"> + <MenuItem.Icon> + <Image Source="Resources/copy.ico" /> + </MenuItem.Icon> + </MenuItem> + <MenuItem Header="Paste Page To" x:Name="xaml_pastpageto"> + <MenuItem Header="BMP" Click="PastePage" Tag="BMP"/> + <MenuItem Header="GIF" Click="PastePage" Tag="GIF"/> + <MenuItem Header="JPEG" Click="PastePage" Tag="JPG"/> + <MenuItem Header="PNG" Click="PastePage" Tag="PNG"/> + <MenuItem Header="TIFF" Click="PastePage" Tag="TIF"/> + <MenuItem Header="WDP (HD Photo)" Click="PastePage" Tag="WDP"/> + </MenuItem> + <Separator /> + <MenuItem Header="Select Text All" Command="SelectAll" InputGestureText="Ctrl+A" x:Name="xaml_selectalltext" /> + <MenuItem Header="Deselect Text" x:Name="xaml_deselecttext" /> + <MenuItem Header="Copy Text" Command="Copy" InputGestureText="Ctrl+C" x:Name="xaml_copytext" /> + </MenuItem> + <MenuItem Header="_View" x:Name="xaml_view"> + <MenuItem Header="Next Page" Click="OnForwardPageClick"/> + <MenuItem Header="Previous Page" Click="OnBackPageClick"/> + <MenuItem Header="_Find" Click="Search"/> + </MenuItem> + <MenuItem Header="_Options"> + <MenuItem Header="Output Intents" Click="OutputIntents" /> + <MenuItem Header="Zoom Control" IsCheckable="true" Checked="ShowFooter" Unchecked="HideFooter"/> + <MenuItem Header="Show Annotations" IsCheckable="True" IsChecked ="True" Checked="AnnotationOn" Unchecked="AnnotationOff"/> + <MenuItem Header="AntiAlias" > + <MenuItem x:Name="xaml_AA_High" Header="High" IsCheckable="True" IsChecked="True" Checked="OnAAChecked" /> + <MenuItem x:Name="xaml_AA_MedHigh" Header="Medium High" IsCheckable="True" IsChecked="False" Checked="OnAAChecked"/> + <MenuItem x:Name="xaml_AA_Med" Header="Medium" IsCheckable="True" IsChecked="False" Checked="OnAAChecked"/> + <MenuItem x:Name="xaml_AA_Low" Header="Low" IsCheckable="True" IsChecked="False" Checked="OnAAChecked" /> + <MenuItem x:Name="xaml_AA_None" Header="None" IsCheckable="True" IsChecked="False" Checked="OnAAChecked" /> + </MenuItem> + + </MenuItem> + + <MenuItem Header="_Help"> + <MenuItem Header="GSView Help" Command="Help" InputGestureText="F1"/> + <MenuItem Header="About" Click="OnAboutClick"/> + </MenuItem> + </Menu> + + <!-- List of icons for page navigation, print, etc --> + <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Background="WhiteSmoke"> + <Button x:Name="xaml_open" Width="20" Height="20" Click="OpenFile" Background="Transparent" BorderBrush="Transparent" Margin="10,0,0,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/folder_open.ico"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button x:Name="xaml_SavePDF" Width="20" Height="20" Click="SavePDF" Background="Transparent" BorderBrush="Transparent" Margin="10,0,0,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/FloppyDisk.ico"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button x:Name="xaml_Print" Margin="10 0 0 0" Width="20" Height="20" Click="Print" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/printer.ico"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Rectangle Width="2" Height="20" Margin="10 0 0 0"> + <Rectangle.Fill> + <SolidColorBrush Color="DarkGray"> + </SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <Button Width="20" Height="20" x:Name="xaml_BackPage" Click="OnBackPageClick" Background="Transparent" BorderBrush="Transparent" Margin="10,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/Left.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Width="20" Height="20" x:Name="xaml_ForwardPage" Click="OnForwardPageClick" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/Right.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <TextBox x:Name="xaml_currPage" Grid.Row="0" Width="25" Height="20" VerticalScrollBarVisibility="Hidden" + HorizontalScrollBarVisibility="Hidden" TextAlignment="Center" Margin="10,2,0,2" PreviewKeyDown="PageEnterClicked"/> + <TextBlock Margin="5,0,0,0" Height="20" Text="/ 0" x:Name="xaml_TotalPages"> + <TextBlock.FontSize>12</TextBlock.FontSize> + </TextBlock> + <Rectangle Width="2" Height="20" Margin="10 0 0 0"> + <Rectangle.Fill> + <SolidColorBrush Color="DarkGray"> + </SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ZoomIn" Background="Transparent" BorderBrush="Transparent" x:Name="xaml_zoomIn"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/zoom_in.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Margin="10 0 0 0" x:Name="xaml_zoomOut" Width="20" Height="20" Click="ZoomOut" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/zoom_out.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <TextBox Grid.Row="0" Grid.Column="2" Width="30" Height="20" VerticalScrollBarVisibility="Hidden" + HorizontalScrollBarVisibility="Hidden" TextAlignment="Left" x:Name="xaml_Zoomsize" + Text="{Binding Mode=TwoWay, ElementName=xaml_ZoomSlider,Path=Value, UpdateSourceTrigger=PropertyChanged}" Margin="10 0 0 0" + PreviewKeyDown="ZoomEnterClicked"/> + <TextBlock Margin="5,0,0,0" Height="20" Text="%"> + <TextBlock.FontSize>12</TextBlock.FontSize> + </TextBlock> + + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ActualSize" Background="Transparent" BorderBrush="Transparent" x:Name="xaml_ActualSize"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/ActualSize48.png"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ContScrollFill" Background="Transparent" BorderBrush="Transparent" x:Name="xaml_ContScrollFill"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/ContScrollFill48.png"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ExpandFill" Background="Transparent" BorderBrush="Transparent" x:Name="xaml_ExpandFill"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/ExpandFill48.png"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + + + <Rectangle Width="2" Height="20" Margin="10 0 0 0"> + <Rectangle.Fill> + <SolidColorBrush Color="DarkGray"> + </SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <Button Margin="10 0 0 0" x:Name="xaml_Thumbs" Width="20" Height="20" Click="ToggleThumbs" Background="Transparent" BorderBrush="Transparent"> + <Button.ToolTip> + <TextBlock Text="Thumbnails"/> + </Button.ToolTip> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/thumbnail.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Margin="10 0 0 0" x:Name="xaml_Contents" Width="20" Height="20" Click="ToggleContents" Background="Transparent" BorderBrush="Transparent"> + <Button.ToolTip> + <TextBlock Text="Contents"/> + </Button.ToolTip> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/contents.ico"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Margin="10 0 0 0" x:Name="xaml_Search" Width="20" Height="20" Click="Search" Background="Transparent" BorderBrush="Transparent"> + <Button.ToolTip> + <TextBlock Text="Search"/> + </Button.ToolTip> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Width="20" Height="20"> + <Rectangle.Fill> + <ImageBrush ImageSource="Resources/search.png"/> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Margin="10 0 0 0" x:Name="xaml_Links" Width="20" Height="20" Click="LinksToggle" Background="Transparent" BorderBrush="Transparent"> + <Button.ToolTip> + <TextBlock Text="Hyperlinks"/> + </Button.ToolTip> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/hyperlink.png"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + </StackPanel> + + <!-- Search control --> + <Grid x:Name="xaml_SearchControl" Background="WhiteSmoke" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Margin="5,5,0,5"><Bold>Search:</Bold></TextBlock> + <TextBox x:Name="xaml_SearchText" Grid.Row="0" Grid.Column="1" Width="100" Height="20" VerticalScrollBarVisibility="Hidden" + HorizontalScrollBarVisibility="Hidden" TextAlignment="Center" Margin="5,5,0,5"/> + <Button Grid.Row="0" Grid.Column="2" Width="20" Height="20" Click="OnSearchBackClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/Left.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Grid.Row="0" Grid.Column="3" Width="20" Height="20" Click="OnSearchForwardClick" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/Right.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + </Grid> + + <!-- Footer control Currently just zoom slider in here but we may add more --> + <Grid x:Name="xaml_FooterControl" Background="WhiteSmoke" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Margin="5,0,0,0"><Bold>Zoom:</Bold></TextBlock> + <Slider x:Name="xaml_ZoomSlider" Grid.Row="0" Grid.Column="1" Margin="10, 0, 0, 0" + Width="150" Orientation="Horizontal" HorizontalAlignment="Center" + Value="100" Minimum="25" Maximum="400" + SmallChange="1" LargeChange="1" + TickPlacement="None" TickFrequency="1" IsSnapToTickEnabled="True"/> + </Grid> + + <!-- The progress bar that runs while the thumbnails are rendered --> + <Grid x:Name="xaml_ProgressGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_ThumbProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch" /> + <TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>Creating Thumbs</Bold></TextBlock> + <!-- <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelThumb" Click="CancelLoadClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> --> + </Grid> + + <!-- The progress bar that runs during text search --> + <Grid x:Name="xaml_SearchGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_SearchProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch" /> + <TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>Searching</Bold></TextBlock> + <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelSearch" Click="CancelSearchClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> + </Grid> + + <!-- The progress bar that runs during copy all text to clipboard --> + <Grid x:Name="xaml_CopyTextGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_CopyTextProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch" /> + <TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>Printing</Bold></TextBlock> + <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelCopyText" Click="CancelCopyText" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> + </Grid> + + <!-- The progress bar that runs during printing --> + <Grid x:Name="xaml_PrintGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_PrintProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch" /> + <TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>Printing</Bold></TextBlock> + <!-- Asyc Cancel crashes in windows 8 for this xps creation --> + <!-- <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelPrint" Click="CancelPrintClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> --> + </Grid> + + <!-- The progress bar that runs during MuPDF page by page conversion to file--> + <Grid x:Name="xaml_MuPDFGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_MuPDFProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch"/> + <TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>MuPDF Converting Document</Bold></TextBlock> + <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelMuPDF" Click="CancelMuPDFClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> + </Grid> + + <!-- The progress bar that runs during GS distilling --> + <Grid x:Name="xaml_DistillGrid" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <ProgressBar x:Name="xaml_DistillProgress" Grid.Row="0" Grid.Column="0" Margin="3" Minimum="0" + Maximum="100" Height="20" HorizontalAlignment="Stretch"/> + <TextBlock x:Name="xaml_DistillName" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="5, 0, 5, 0"><Bold>Distilling</Bold></TextBlock> + <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Name="xaml_CancelDistill" Click="CancelDistillClick" Background="Transparent" BorderBrush="Transparent" Margin="5,0,5,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Cancel</Bold></TextBlock> + </Button> + </Grid> + + <!-- Thumb viewer/selector --> + <Grid x:Name="xaml_ThumbGrid" Width="100" Background="DarkGray" DockPanel.Dock="Left" Visibility="Collapsed"> + <ListView x:Name="xaml_ThumbList" HorizontalAlignment="Stretch" + ItemTemplate="{StaticResource ThumbTemplate}" + ScrollViewer.CanContentScroll="False" + Background="DarkGray" + PreviewMouseLeftButtonUp="ThumbSelected"> + </ListView> + </Grid> + + <!-- Contents viewer/selector. --> + <Grid x:Name="xaml_ContentGrid" Width="250" Background="DarkGray" DockPanel.Dock="Left" Visibility="Collapsed"> + <ListView x:Name="xaml_ContentList" HorizontalAlignment="Stretch" + ScrollViewer.CanContentScroll="False" PreviewMouseLeftButtonUp="ContentSelected" + Background="DarkGray" > + <ListView.ItemTemplate> + <DataTemplate> + <StackPanel Margin="5,5,0,0" HorizontalAlignment="Left"> + <TextBlock TextWrapping="Wrap" Text="{Binding StringMargin}" FontFamily="Segoe UI" FontSize="11" /> + </StackPanel> + </DataTemplate> + </ListView.ItemTemplate> + </ListView> + </Grid> + + <Grid x:Name="xaml_OpenProgressGrid" HorizontalAlignment="Stretch" Background="DarkGray" DockPanel.Dock="Bottom" Visibility="Collapsed"> + <Grid.RowDefinitions> + <RowDefinition Height="*" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + <TextBlock x:Name ="xaml_openfilestatus" Text="Opening File" Grid.Row="0" Grid.Column="0" Margin="0,0,0,10" HorizontalAlignment="Center"></TextBlock> + <ProgressBar Grid.Row="1" Grid.Column="0" x:Name="xaml_OpenProgress" Minimum="0" + Maximum="100" Height="20" Margin="100,0,100,200" HorizontalAlignment="Stretch" IsIndeterminate="True" /> + </Grid> + + <!-- The stock scroll bar that comes with the ListView scrollviewer does is not well behaved when + the page sizes change. So we have our own here that we will set up --> + <ScrollBar x:Name="xaml_VerticalScroll" Orientation="Vertical" Grid.Row="0" Grid.Column="1" DockPanel.Dock="Right" + Width ="5" Height="Auto" Margin="0,0,0,0" Background="WhiteSmoke" Visibility="Collapsed" + Scroll="VerticalScroll"/> + + <!-- Pages are last child fill. This goes in the center of our dock panel ScrollViewer.CanContentScroll False allows continuous scrolling--> + <!-- <Grid x:Name="xaml_PageGrid" HorizontalAlignment="Stretch" Background="DarkGray" DockPanel.Dock="Left" AllowDrop="True"> --> + <ListView x:Name="xaml_PageList" HorizontalAlignment="Stretch" + ItemTemplate="{StaticResource PageTemplate}" + ScrollViewer.CanContentScroll="False" + Background="DarkGray" + ScrollViewer.ScrollChanged="ListViewScrollChanged" + MouseDoubleClick="PageDoubleClick" IsHitTestVisible="True" + SelectionMode="Single" + PreviewMouseLeftButtonDown="ListPreviewMouseLeftButtonDown" + PreviewMouseLeftButtonUp="ListPreviewLeftButtonUp" + MouseLeave="ListMouseLeave" + PreviewMouseMove="ListPreviewMouseMove" + ScrollViewer.HorizontalScrollBarVisibility="Auto" + ScrollViewer.VerticalScrollBarVisibility="Hidden" + ScrollViewer.IsDeferredScrollingEnabled ="False" DockPanel.Dock="Left" AllowDrop="True" + > + <!-- This keeps the pages in the center of the panel --> + + <ListView.ItemContainerStyle> + + <Style TargetType="ListViewItem"> + <Setter Property="HorizontalContentAlignment" Value="Stretch"/> + <EventSetter Event="RequestBringIntoView" Handler="AvoidScrollIntoView"/> + </Style> + </ListView.ItemContainerStyle> + </ListView> + <!-- </Grid> --> + </DockPanel> +</Window> diff --git a/platform/windows/gsview/MainWindow.xaml.cs b/platform/windows/gsview/MainWindow.xaml.cs new file mode 100644 index 00000000..6e6ee855 --- /dev/null +++ b/platform/windows/gsview/MainWindow.xaml.cs @@ -0,0 +1,4906 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Windows.Forms; +using System.ComponentModel; +using System.IO; +using System.Windows.Xps.Packaging; +using System.Printing; +using System.Windows.Markup; +using System.Runtime.InteropServices; +using Microsoft.Win32; /* For registry */ + +public enum AA_t +{ + HIGH = 8, + MEDHIGH = 6, + MED = 4, + LOW = 2, + NONE = 0 +} + +enum PDFType_t +{ + PDFX, + PDFA +} + +enum AppBar_t +{ + TEXT_SEARCH, + STANDARD +} + +enum NotifyType_t +{ + MESS_STATUS, + MESS_ERROR +}; + +enum RenderingStatus_t +{ + REN_AVAILABLE, + REN_THUMBS, + REN_UPDATE_THUMB_CANVAS, + REN_PAGE /* Used to ignore value when source based setting */ +}; + +public enum status_t +{ + S_ISOK, + E_FAILURE, + E_OUTOFMEM, + E_NEEDPASSWORD +}; + +public enum textout_t +{ + HTML = 0, + XML, + TEXT +} + +enum zoom_t +{ + NO_ZOOM, + ZOOM_IN, + ZOOM_OUT +} + +enum view_t +{ + VIEW_WEB, + VIEW_CONTENT, + VIEW_PAGE, + VIEW_PASSWORD, + VIEW_TEXTSEARCH +}; + +public enum Page_Content_t +{ + FULL_RESOLUTION = 0, + THUMBNAIL, + OLD_RESOLUTION, + NOTSET +}; + +/* Put all the PDF types first to make the switch statment shorter + Save_Type_t.PDF is the test */ +public enum Save_Type_t +{ + PDF13, + LINEAR_PDF, + PDFA1_RGB, + PDFA1_CMYK, + PDFA2_RGB, + PDFA2_CMYK, + PDFX3_GRAY, + PDFX3_CMYK, + PDF, + PCLXL, + XPS, + SVG, + TEXT, + HTML, + XML +} + +public enum Extract_Type_t +{ + PDF, + EPS, + PS, + SVG +} + +/* C# has no defines.... */ +static class Constants +{ + public const int SCROLL_STEPSIZE = 48; + public const int INIT_LOOK_AHEAD = 2; /* A + count on the pages to pre-render */ + public const int THUMB_PREADD = 10; + public const double MIN_SCALE = 0.5; + public const double SCALE_THUMB = 0.05; + public const int BLANK_WIDTH = 17; + public const int BLANK_HEIGHT = 22; + public const double ZOOM_STEP = 0.25; + public const int ZOOM_MAX = 4; + public const double ZOOM_MIN = 0.25; + public const int KEY_PLUS = 0xbb; + public const int KEY_MINUS = 0xbd; + public const int ZOOM_IN = 0; + public const int ZOOM_OUT = 1; + public const double SCREEN_SCALE = 1; + public const int HEADER_SIZE = 54; + public const int SEARCH_FORWARD = 1; + public const int SEARCH_BACKWARD = -1; + public const int TEXT_NOT_FOUND = -1; + public const int DEFAULT_GS_RES = 300; + public const int DISPATCH_TIME = 50; + public const int SCROLL_STEP = 10; + public const int SCROLL_EDGE_BUFFER = 90; + public const int VERT_SCROLL_STEP = 48; + public const int PAGE_MARGIN = 1; +} + +public static class DocumentTypes +{ + public const string PDF = "Portable Document Format"; + public const string PS = "PostScript"; + public const string XPS = "XPS"; + public const string EPS = "Encapsulated PostScript"; + public const string CBZ = "Comic Book Archive"; + public const string PNG = "Portable Network Graphics Image"; + public const string JPG = "Joint Photographic Experts Group Image"; + public const string UNKNOWN = "Unknown"; +} + +namespace gsview +{ + /// <summary> + /// Interaction logic for MainWindow.xaml + /// </summary> + /// + + public struct pageprogress_t + { + public Byte[] bitmap; + public BlocksText charlist; + public int pagenum; + public Point size; + public Annotate_t annot; + } + + public struct ContextMenu_t + { + public int page_num; + public Point mouse_position; + } + + public struct thumb_t + { + public int page_num; + public Byte[] bitmap; + public Point size; + } + + public struct searchResults_t + { + public String needle; + public bool done; + public int page_found; + public List<Rect> rectangles; + public int num_rects; + } + + public struct textSelectInfo_t + { + public int pagenum; + public bool first_line_full; + public bool last_line_full; + } + + public static class ScrollBarExtensions + { + public static double GetThumbCenter(this System.Windows.Controls.Primitives.ScrollBar s) + { + double thumbLength = GetThumbLength(s); + double trackLength = s.Maximum - s.Minimum; + + return thumbLength / 2 + s.Minimum + (s.Value - s.Minimum) * + (trackLength - thumbLength) / trackLength; + } + + public static void SetThumbCenter(this System.Windows.Controls.Primitives.ScrollBar s, double thumbCenter) + { + double thumbLength = GetThumbLength(s); + double trackLength = s.Maximum - s.Minimum; + + if (thumbCenter >= s.Maximum - thumbLength / 2) + { + s.Value = s.Maximum; + } + else if (thumbCenter <= s.Minimum + thumbLength / 2) + { + s.Value = s.Minimum; + } + else if (thumbLength >= trackLength) + { + s.Value = s.Minimum; + } + else + { + s.Value = (int)(s.Minimum + trackLength * + ((thumbCenter - s.Minimum - thumbLength / 2) + / (trackLength - thumbLength))); + } + } + + public static double GetThumbLength(this System.Windows.Controls.Primitives.ScrollBar s) + { + double trackLength = s.Maximum - s.Minimum; + return trackLength * s.ViewportSize / + (trackLength + s.ViewportSize); + } + + public static void SetThumbLength(this System.Windows.Controls.Primitives.ScrollBar s, double thumbLength) + { + double trackLength = s.Maximum - s.Minimum; + + if (thumbLength < 0) + { + s.ViewportSize = 0; + } + else if (thumbLength < trackLength) + { + s.ViewportSize = trackLength * thumbLength / (trackLength - thumbLength); + } + else + { + s.ViewportSize = double.MaxValue; + } + } + } + + public partial class MainWindow : Window + { + mudocument mu_doc = null; + public Pages m_docPages; + List<textSelectInfo_t> m_textSelect; + List<DocPage> m_thumbnails; + List<List<RectList>> m_page_link_list = null; + IList<RectList> m_text_list; + public List<LinesText> m_lineptrs = null; + public List<BlocksText> m_textptrs = null; + List<Boolean> m_textset = null; + private bool m_file_open; + private int m_currpage; + private int m_searchpage; + private int m_num_pages; + private bool m_init_done; + private bool m_links_on; + String m_textsearchcolor = "#4072AC25"; + String m_textselectcolor = "#402572AC"; + String m_regionselect = "#00FFFFFF"; + String m_blockcolor = "#00FFFFFF"; + //String m_regionselect = "#FFFF0000"; /* Debug */ + String m_linkcolor = "#40AC7225"; + private bool m_have_thumbs; + double m_doczoom; + ghostsharp m_ghostscript; + String m_currfile; + String m_origfile; + private gsprint m_ghostprint = null; + bool m_isXPS; + gsOutput m_gsoutput; + Convert m_convertwin; + PageExtractSave m_extractwin; + Password m_password = null; + String m_currpassword = null; + BackgroundWorker m_thumbworker = null; + BackgroundWorker m_textsearch = null; + BackgroundWorker m_linksearch = null; + BackgroundWorker m_openfile = null; + BackgroundWorker m_initrender = null; + BackgroundWorker m_copytext = null; + String m_document_type; + Info m_infowindow; + OutputIntent m_outputintents; + Selection m_selection; + String m_prevsearch = null; + bool m_clipboardset; + bool m_doscroll; + bool m_intxtselect; + bool m_textselected; + System.Windows.Threading.DispatcherTimer m_dispatcherTimer = null; + double m_lastY; + double m_maxY; + bool m_ignorescrollchange; + double m_totalpageheight; + AA_t m_AA; + bool m_regstartup; + int m_initpage; + bool m_selectall; + bool m_showannot; + bool m_ScrolledChanged; + + public MainWindow() + { + InitializeComponent(); + this.Closing += new System.ComponentModel.CancelEventHandler(Window_Closing); + m_file_open = false; + m_regstartup = true; + m_showannot = true; + + /* Allocations and set up */ + try + { + m_docPages = new Pages(); + m_thumbnails = new List<DocPage>(); + m_lineptrs = new List<LinesText>(); + m_textptrs = new List<BlocksText>(); + m_textset = new List<Boolean>(); + m_ghostscript = new ghostsharp(); + m_ghostscript.gsUpdateMain += new ghostsharp.gsCallBackMain(gsProgress); + m_gsoutput = new gsOutput(); + m_gsoutput.Activate(); + m_outputintents = new OutputIntent(); + m_outputintents.Activate(); + m_ghostscript.gsIOUpdateMain += new ghostsharp.gsIOCallBackMain(gsIO); + m_ghostscript.gsDLLProblemMain += new ghostsharp.gsDLLProblem(gsDLL); + m_convertwin = null; + m_extractwin = null; + m_selection = null; + xaml_ZoomSlider.AddHandler(MouseLeftButtonUpEvent, new MouseButtonEventHandler(ZoomReleased), true); + xaml_PageList.AddHandler(Grid.DragOverEvent, new System.Windows.DragEventHandler(Grid_DragOver), true); + xaml_PageList.AddHandler(Grid.DropEvent, new System.Windows.DragEventHandler(Grid_Drop), true); + DimSelections(); + status_t result = CleanUp(); + + string[] arguments = Environment.GetCommandLineArgs(); + if (arguments.Length > 1) + { + string filePath = arguments[1]; + ProcessFile(filePath); + } + else + { + if (m_regstartup) + InitFromRegistry(); + } + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed at initialization\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + + private void Grid_DragOver(object sender, System.Windows.DragEventArgs e) + { + if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop)) + { + e.Effects = System.Windows.DragDropEffects.All; + } + else + { + e.Effects = System.Windows.DragDropEffects.None; + } + e.Handled = false; + } + + private void Grid_Drop(object sender, System.Windows.DragEventArgs e) + { + if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop)) + { + string[] docPath = (string[]) e.Data.GetData(System.Windows.DataFormats.FileDrop); + ProcessFile(String.Join("",docPath)); + } + } + + void CloseExtraWindows(bool shutdown) + { + if (m_selection != null) + m_selection.Close(); + if (m_convertwin != null) + m_convertwin.Close(); + if (m_extractwin != null) + m_extractwin.Close(); + if (m_infowindow != null) + m_infowindow.Close(); + if (shutdown) + { + if (m_gsoutput != null) + m_gsoutput.RealWindowClosing(); + if (m_outputintents != null) + m_outputintents.RealWindowClosing(); + } + else + { + if (m_gsoutput != null) + m_gsoutput.Hide(); + if (m_outputintents != null) + m_outputintents.Hide(); + } + } + + void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + CloseExtraWindows(true); + } + + /* Stuff not enabled when source is XPS */ + void EnabletoPDF() + { + xaml_savepdf.IsEnabled = true; + xaml_linearize_pdf.IsEnabled = true; + xaml_saveas.IsEnabled = true; + xaml_Extract.IsEnabled = true; + xaml_conversions.IsEnabled = true; + xaml_extractselection.IsEnabled = true; + } + + void DisabletoPDF() + { + xaml_savepdf.IsEnabled = false; + xaml_linearize_pdf.IsEnabled = false; + xaml_saveas.IsEnabled = false; + xaml_Extract.IsEnabled = false; + xaml_conversions.IsEnabled = false; + xaml_extractselection.IsEnabled = false; + } + + private void DimSelections() + { + xaml_currPage.Text = ""; + xaml_TotalPages.Text = "/ 0"; + xaml_Zoomsize.Text = "100"; + xaml_BackPage.Opacity = 0.5; + xaml_Contents.Opacity = 0.5; + xaml_currPage.Opacity = 0.5; + xaml_currPage.IsEnabled = false; + xaml_ForwardPage.Opacity = 0.5; + xaml_Links.Opacity = 0.5; + xaml_Print.Opacity = 0.5; + xaml_SavePDF.Opacity = 0.5; + xaml_Search.Opacity = 0.5; + xaml_Thumbs.Opacity = 0.5; + xaml_TotalPages.Opacity = 0.5; + xaml_zoomIn.Opacity = 0.5; + xaml_zoomOut.Opacity = 0.5; + xaml_Zoomsize.Opacity = 0.5; + xaml_ExpandFill.Opacity = 0.5; + xaml_ContScrollFill.Opacity = 0.5; + xaml_ActualSize.Opacity = 0.5; + xaml_Zoomsize.IsEnabled = false; + xaml_ZoomSlider.Opacity = 0.5; + xaml_ZoomSlider.IsEnabled = false; + xaml_saveas.IsEnabled = false; + xaml_closefile.IsEnabled = false; + xaml_showinfo.IsEnabled = false; + xaml_extractselection.IsEnabled = false; + xaml_conversions.IsEnabled = false; + xaml_gsmessage.IsEnabled = false; + xaml_print.IsEnabled = false; + xaml_view.IsEnabled = false; + xaml_edit.IsEnabled = false; + } + + private status_t CleanUp() + { + m_init_done = false; + this.Cursor = System.Windows.Input.Cursors.Arrow; + /* Collapse this stuff since it is going to be released */ + xaml_ThumbGrid.Visibility = System.Windows.Visibility.Collapsed; + xaml_ContentGrid.Visibility = System.Windows.Visibility.Collapsed; + xaml_VerticalScroll.Visibility = System.Windows.Visibility.Collapsed; + + /* Clear out everything */ + if (m_docPages != null && m_docPages.Count > 0) + m_docPages.Clear(); + if (m_textSelect != null) + m_textSelect.Clear(); + if (m_textset != null) + m_textset.Clear(); + if (m_lineptrs != null && m_lineptrs.Count > 0) + m_lineptrs.Clear(); + if (m_thumbnails != null && m_thumbnails.Count > 0) + m_thumbnails.Clear(); + if (m_textptrs != null && m_textptrs.Count > 0) + m_textptrs.Clear(); + if (m_page_link_list != null && m_page_link_list.Count > 0) + { + m_page_link_list.Clear(); + m_page_link_list = null; + } + if (m_text_list != null && m_text_list.Count > 0) + { + m_text_list.Clear(); + m_text_list = null; + } + if (mu_doc != null) + mu_doc.CleanUp(); + try + { + mu_doc = new mudocument(); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during clean up\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + mu_doc.mupdfDLLProblemMain += new mudocument.mupdfDLLProblem(muDLL); + status_t result = mu_doc.Initialize(); + mu_doc.mupdfUpdateMain += new mudocument.mupdfCallBackMain(mupdfUpdate); + + if (result != status_t.S_ISOK) + { + Console.WriteLine("Library allocation failed during clean up\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Library allocation failed!"); + return result; + } + + m_have_thumbs = false; + m_file_open = false; + m_num_pages = -1; + m_links_on = false; + m_doczoom = 1.0; + m_isXPS = false; + //xaml_CancelThumb.IsEnabled = true; + m_currpage = 0; + m_ignorescrollchange = false; + m_document_type = DocumentTypes.UNKNOWN; + EnabletoPDF(); + m_clipboardset = false; + m_doscroll = false; + m_intxtselect = false; + m_textselected = false; + m_currpassword = null; + CloseExtraWindows(false); + ResetScroll(); + m_totalpageheight = 0; + m_AA = GetAA(); + m_origfile = null; + m_initpage = 0; + xaml_Zoomsize.Text = "100"; + m_selectall = false; + return result; + } + + /* Initialize from registry */ + private void InitFromRegistry() + { + RegistryKey key = Registry.CurrentUser.CreateSubKey("Software"); + RegistryKey keyA = key.CreateSubKey("Artifex Software"); + RegistryKey keygs = keyA.CreateSubKey("GSview 6.0"); + String filepath = null; + Int32 page; + AA_t aa = AA_t.HIGH; + + try + { + filepath = (String)keygs.GetValue("File", null); + aa = (AA_t)keygs.GetValue("AA"); + page = (Int32)keygs.GetValue("Page"); + } + catch + { + return; + } + keygs.Close(); + keyA.Close(); + key.Close(); + + SetAA(aa); + m_AA = aa; + + if (filepath != null && File.Exists(filepath)) + { + m_initpage = page; + ProcessFile(filepath); + } + else + m_initpage = 0; + } + + private void SetRegistry() + { + if (m_currfile == null) + return; + + RegistryKey key = Registry.CurrentUser.CreateSubKey("Software"); + RegistryKey keyA = key.CreateSubKey("Artifex Software"); + RegistryKey keygs = keyA.CreateSubKey("GSview 6.0"); + + if (m_origfile != null && (m_document_type == DocumentTypes.PS || + m_document_type == DocumentTypes.EPS)) + { + keygs.SetValue("File", m_origfile, RegistryValueKind.String); + } + else + { + keygs.SetValue("File", m_currfile, RegistryValueKind.String); + } + keygs.SetValue("Page", m_currpage, RegistryValueKind.DWord); + Int32 aa_int = (Int32)m_AA; + keygs.SetValue("AA", aa_int, RegistryValueKind.DWord); + keygs.Close(); + keyA.Close(); + key.Close(); + } + + private void AppClosing(object sender, CancelEventArgs e) + { + if (m_init_done) + SetRegistry(); + } + + private void ShowMessage(NotifyType_t type, String Message) + { + if (type == NotifyType_t.MESS_ERROR) + { + System.Windows.Forms.MessageBox.Show(Message, "Error", + MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + else + { + System.Windows.Forms.MessageBox.Show(Message, "Notice", + MessageBoxButtons.OK); + } + } + + private void CloseCommand(object sender, ExecutedRoutedEventArgs e) + { + if (m_init_done) + CloseDoc(); + } + + private void CloseDoc() + { + CleanUp(); + } + + /* Set the page with the new raster information */ + private void UpdatePage(int page_num, Byte[] bitmap, Point ras_size, + Page_Content_t content, double zoom_in, AA_t AA) + { + DocPage doc_page = this.m_docPages[page_num]; + + doc_page.Width = (int)ras_size.X; + doc_page.Height = (int)ras_size.Y; + + doc_page.Content = content; + doc_page.Zoom = zoom_in; + + int stride = doc_page.Width * 4; + doc_page.BitMap = BitmapSource.Create(doc_page.Width, doc_page.Height, + 72, 72, PixelFormats.Pbgra32, BitmapPalettes.Halftone256, bitmap, stride); + doc_page.PageNum = page_num; + doc_page.AA = AA; + + if (content == Page_Content_t.THUMBNAIL) + { + doc_page.Width = (int)(ras_size.X / Constants.SCALE_THUMB); + doc_page.Height = (int)(ras_size.Y / Constants.SCALE_THUMB); + } + } + + private void OpenFileCommand(object sender, ExecutedRoutedEventArgs e) + { + OpenFile(sender, e); + } + + private void OpenFile(object sender, RoutedEventArgs e) + { + if (m_password != null && m_password.IsActive) + m_password.Close(); + + if (m_infowindow != null && m_infowindow.IsActive) + m_infowindow.Close(); + + /* Check if gs is currently busy. If it is then don't allow a new + * file to be opened. They can cancel gs with the cancel button if + * they want */ + if (m_ghostscript.GetStatus() != gsStatus.GS_READY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy. Cancel to open new file."); + return; + } + + if (m_ghostprint != null && m_ghostprint.IsBusy()) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Let printing complete"); + return; + } + + System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog(); + dlg.Filter = "Document Files(*.ps;*.eps;*.pdf;*.xps;*.oxps;*.cbz;*.png;*.jpg;*.jpeg)|*.ps;*.eps;*.pdf;*.xps;*.oxps;*.cbz;*.png;*.jpg;*.jpeg|All files (*.*)|*.*"; + dlg.FilterIndex = 1; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + ProcessFile(dlg.FileName); + } + + private void ProcessFile(String FileName) + { + if (m_file_open) + { + CloseDoc(); + } + /* If we have a ps or eps file then launch the distiller first + * and then we will get a temp pdf file which will be opened by + * mupdf */ + string extension = System.IO.Path.GetExtension(FileName); + /* We are doing this based on the extension but like should do + * it based upon the content */ + switch (extension.ToUpper()) + { + case ".PS": + m_document_type = DocumentTypes.PS; + break; + case ".EPS": + m_document_type = DocumentTypes.EPS; + break; + case ".XPS": + case ".OXPS": + m_document_type = DocumentTypes.XPS; + break; + case ".PDF": + m_document_type = DocumentTypes.PDF; + break; + case ".CBZ": + m_document_type = DocumentTypes.CBZ; + break; + case ".PNG": + m_document_type = DocumentTypes.PNG; + break; + case ".JPG": + m_document_type = DocumentTypes.JPG; + break; + case ".JPEG": + m_document_type = DocumentTypes.JPG; + break; + default: + { + ShowMessage(NotifyType_t.MESS_STATUS, "Unknown File Type"); + return; + } + } + if (extension.ToUpper() == ".PS" || extension.ToUpper() == ".EPS") + { + xaml_DistillProgress.Value = 0; + if (m_ghostscript.DistillPS(FileName, Constants.DEFAULT_GS_RES) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS currently busy"); + return; + } + xaml_DistillName.Text = "Distilling"; + xaml_CancelDistill.Visibility = System.Windows.Visibility.Visible; + xaml_DistillName.FontWeight = FontWeights.Bold; + xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; + return; + } + /* Set if this is already xps for printing */ + if (extension.ToUpper() == ".XPS" || extension.ToUpper() == ".OXPS") + m_isXPS = true; + OpenFile2(FileName); + } + + private void OpenFile2(String File) + { + m_currfile = File; + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Visible; + xaml_openfilestatus.Text = "Opening File"; + /* The file open can take a fair amount of time. So that we can show + * an indeterminate progress bar while opening, go ahead an do this + * on a separate thread */ + OpenFileBG(); + } + + private void OpenWork(object sender, DoWorkEventArgs e) + { + BackgroundWorker worker = sender as BackgroundWorker; + + status_t code = mu_doc.OpenFile(m_currfile); + worker.ReportProgress(100, code); + } + + private void OpenProgress(object sender, ProgressChangedEventArgs e) + { + status_t result = (status_t)(e.UserState); + + if (result == status_t.S_ISOK) + { + /* Check if we need a password */ + if (mu_doc.RequiresPassword()) + { + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Collapsed; + GetPassword(); + } + else + StartViewer(); + } + else + { + m_currfile = null; + } + } + + private void OpenFileBG() + { + try + { + m_openfile = new BackgroundWorker(); + m_openfile.WorkerReportsProgress = true; + m_openfile.WorkerSupportsCancellation = false; + m_openfile.DoWork += new DoWorkEventHandler(OpenWork); + m_openfile.ProgressChanged += new ProgressChangedEventHandler(OpenProgress); + m_openfile.RunWorkerAsync(); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during opening\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + + private void SetPageAnnot(int page_num, Annotate_t render_result) + { + if (m_docPages[page_num].Annotate == Annotate_t.UNKNOWN || + m_docPages[page_num].Annotate == Annotate_t.COMPUTING) + { + if (render_result == Annotate_t.NO_ANNOTATE) + m_docPages[page_num].Annotate = Annotate_t.NO_ANNOTATE; + else + { + if (m_showannot) + m_docPages[page_num].Annotate = Annotate_t.ANNOTATE_VISIBLE; + else + m_docPages[page_num].Annotate = Annotate_t.ANNOTATE_HIDDEN; + } + } + else + { + if (m_docPages[page_num].Annotate != Annotate_t.NO_ANNOTATE) + { + if (m_showannot) + m_docPages[page_num].Annotate = Annotate_t.ANNOTATE_VISIBLE; + else + m_docPages[page_num].Annotate = Annotate_t.ANNOTATE_HIDDEN; + } + } + } + + private void InitialRenderWork(object sender, DoWorkEventArgs e) + { + BackgroundWorker worker = sender as BackgroundWorker; + int look_ahead = Math.Min(m_num_pages, Constants.INIT_LOOK_AHEAD); + + /* Do the first few full res pages */ + for (int k = 0; k < look_ahead; k++) + { + if (m_num_pages > k) + { + Point ras_size; + double scale_factor = 1.0; + Byte[] bitmap; + BlocksText charlist; + status_t code; + Annotate_t annot; + + if (ComputePageSize(k, scale_factor, out ras_size) == status_t.S_ISOK) + { + try + { + bitmap = new byte[(int)ras_size.X * (int)ras_size.Y * 4]; + + /* Synchronous call on our background thread */ + code = (status_t)mu_doc.RenderPage(k, bitmap, (int)ras_size.X, + (int)ras_size.Y, scale_factor, false, true, + !(m_textset[k]), out charlist, m_showannot, out annot); + } + catch (OutOfMemoryException em) + { + Console.WriteLine("Memory allocation failed init page " + k + em.Message + "\n"); + break; + } + /* create new page if we rendered ok. set ui value with + * progress call back, pass page number, charlist and bitmap */ + if (code == status_t.S_ISOK) + { + pageprogress_t page_prog = new pageprogress_t(); + page_prog.bitmap = bitmap; + page_prog.charlist = charlist; + page_prog.pagenum = k; + page_prog.size = ras_size; + page_prog.annot = annot; + worker.ReportProgress(100, page_prog); + } + } + } + } + } + + private void InitialRenderProgressChanged(object sender, ProgressChangedEventArgs e) + { + pageprogress_t result = (pageprogress_t)(e.UserState); + int k = result.pagenum; + + m_textset[k] = true; + m_textptrs[k] = result.charlist; + m_docPages[k].TextBlocks = result.charlist; + UpdatePage(k, result.bitmap, result.size, Page_Content_t.FULL_RESOLUTION, 1.0, m_AA); + m_docPages[k].NativeHeight = (int) result.size.Y; + m_docPages[k].NativeWidth = (int)result.size.X; + SetPageAnnot(k, result.annot); + } + + private void InitialRenderCompleted(object sender, RunWorkerCompletedEventArgs e) + { + m_init_done = true; + m_currpage = 0; + RenderThumbs(); + m_file_open = true; + xaml_BackPage.Opacity = 1; + xaml_Contents.Opacity = 1; + xaml_currPage.Opacity = 1; + xaml_ForwardPage.Opacity = 1; + xaml_Links.Opacity = 1; + xaml_Print.Opacity = 1; + xaml_SavePDF.Opacity = 1; + xaml_Search.Opacity = 1; + xaml_Thumbs.Opacity = 1; + xaml_TotalPages.Opacity = 1; + xaml_zoomIn.Opacity = 1; + xaml_zoomOut.Opacity = 1; + xaml_Zoomsize.Opacity = 1; + xaml_ExpandFill.Opacity = 1; + xaml_ContScrollFill.Opacity = 1; + xaml_ActualSize.Opacity = 1; + xaml_Zoomsize.IsEnabled = true; + xaml_currPage.IsEnabled = true; + xaml_TotalPages.Text = "/ " + m_num_pages.ToString(); + xaml_currPage.Text = "1"; + xaml_ZoomSlider.Opacity = 1.0; + xaml_ZoomSlider.IsEnabled = true; + xaml_closefile.IsEnabled = true; + xaml_saveas.IsEnabled = true; + xaml_showinfo.IsEnabled = true; + xaml_extractselection.IsEnabled = true; + xaml_conversions.IsEnabled = true; + xaml_gsmessage.IsEnabled = true; + xaml_print.IsEnabled = true; + xaml_view.IsEnabled = true; + xaml_edit.IsEnabled = true; + if (m_isXPS) + DisabletoPDF(); + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Collapsed; + xaml_VerticalScroll.Visibility = System.Windows.Visibility.Visible; + xaml_VerticalScroll.Value = 0; + } + + private void InitialRenderBG() + { + int look_ahead = Math.Min(Constants.INIT_LOOK_AHEAD, m_num_pages); + m_currpage = 0; + m_thumbnails.Capacity = m_num_pages; + + for (int k = 0; k < Constants.INIT_LOOK_AHEAD; k++) + { + m_docPages.Add(InitDocPage()); + m_docPages[k].PageNum = k; + m_textptrs.Add(new BlocksText()); + m_lineptrs.Add(new LinesText()); + m_textset.Add(false); + } + var dummy = InitDocPage(); + for (int k = Constants.INIT_LOOK_AHEAD; k < m_num_pages; k++) + { + m_docPages.Add(dummy); + m_textptrs.Add(new BlocksText()); + m_lineptrs.Add(new LinesText()); + m_textset.Add(false); + } + + xaml_PageList.ItemsSource = m_docPages; + + try + { + m_initrender = new BackgroundWorker(); + m_initrender.WorkerReportsProgress = true; + m_initrender.WorkerSupportsCancellation = false; + m_initrender.DoWork += new DoWorkEventHandler(InitialRenderWork); + m_initrender.RunWorkerCompleted += new RunWorkerCompletedEventHandler(InitialRenderCompleted); + m_initrender.ProgressChanged += new ProgressChangedEventHandler(InitialRenderProgressChanged); + m_initrender.RunWorkerAsync(); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during initial render\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + private void StartViewer() + { + m_num_pages = mu_doc.GetPageCount(); + + if (m_num_pages == 0) + { + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Collapsed; + CleanUp(); + ShowMessage(NotifyType_t.MESS_ERROR, m_currfile + " is corrupted"); + } + else + { + xaml_openfilestatus.Text = "Initial Page Rendering"; + xaml_openfilestatus.UpdateLayout(); + InitialRenderBG(); + } + } + + private status_t ComputePageSize(int page_num, double scale_factor, + out Point render_size) + { + Point renpageSize = new Point(); + + status_t code = (status_t)mu_doc.GetPageSize(page_num, out render_size); + if (code != status_t.S_ISOK) + return code; + + renpageSize.X = (render_size.X * scale_factor); + renpageSize.Y = (render_size.Y * scale_factor); + + render_size = renpageSize; + + return status_t.S_ISOK; + } + + private DocPage InitDocPage() + { + DocPage doc_page = new DocPage(); + + doc_page.BitMap = null; + doc_page.Height = Constants.BLANK_HEIGHT; + doc_page.Width = Constants.BLANK_WIDTH; + doc_page.NativeHeight = Constants.BLANK_HEIGHT; + doc_page.NativeWidth = Constants.BLANK_WIDTH; + doc_page.Content = Page_Content_t.NOTSET; + doc_page.TextBox = null; + doc_page.LinkBox = null; + doc_page.SelHeight = 0; + doc_page.SelWidth = 0; + doc_page.SelX = 0; + doc_page.SelY = 0; + return doc_page; + } + + #region Navigation + private void OnBackPageClick(object sender, RoutedEventArgs e) + { + if (m_currpage == 0 || !m_init_done) return; + m_ignorescrollchange = true; + RenderRange(m_currpage - 1, true, zoom_t.NO_ZOOM, 0); + } + + private void OnForwardPageClick(object sender, RoutedEventArgs e) + { + if (m_currpage == m_num_pages - 1 || !m_init_done) return; + m_ignorescrollchange = true; + RenderRange(m_currpage + 1, true, zoom_t.NO_ZOOM, 0); + } + + private void PageEnterClicked(object sender, System.Windows.Input.KeyEventArgs e) + { + if (e.Key == Key.Return) + { + e.Handled = true; + var desired_page = xaml_currPage.Text; + try + { + int page = System.Convert.ToInt32(desired_page); + if (page > 0 && page < (m_num_pages + 1)) + { + m_ignorescrollchange = true; + RenderRange(page - 1, true, zoom_t.NO_ZOOM, 0); + } + } + catch (FormatException e1) + { + Console.WriteLine("String is not a sequence of digits."); + } + catch (OverflowException e2) + { + Console.WriteLine("The number cannot fit in an Int32."); + } + } + } + + private void OnKeyDownHandler(object sender, System.Windows.Input.KeyEventArgs e) + { + switch (e.Key) + { + case Key.Left: + case Key.PageUp: + if (m_currpage == 0 || !m_init_done) + return; + m_ignorescrollchange = true; + RenderRange(m_currpage - 1, true, zoom_t.NO_ZOOM, 0); + e.Handled = true; + break; + + case Key.Right: + case Key.PageDown: + if (m_currpage == m_num_pages - 1 || !m_init_done) + return; + m_ignorescrollchange = true; + RenderRange(m_currpage + 1, true, zoom_t.NO_ZOOM, 0); + e.Handled = true; + break; + + case Key.Up: + if (!m_init_done) + return; + e.Handled = true; + OffsetScroll(-Constants.VERT_SCROLL_STEP * m_doczoom); + break; + + case Key.Down: + if (!m_init_done) + return; + e.Handled = true; + OffsetScroll(Constants.VERT_SCROLL_STEP * m_doczoom); + break; + } + } + #endregion Navigation + + private void CancelLoadClick(object sender, RoutedEventArgs e) + { + /* Cancel during thumbnail loading. Deactivate the button + * and cancel the thumbnail rendering */ + if (m_thumbworker != null) + m_thumbworker.CancelAsync(); + //xaml_CancelThumb.IsEnabled = false; + } + + private void ToggleThumbs(object sender, RoutedEventArgs e) + { + if (m_have_thumbs) + { + if (xaml_ThumbGrid.Visibility == System.Windows.Visibility.Collapsed) + { + xaml_ThumbGrid.Visibility = System.Windows.Visibility.Visible; + } + else + { + xaml_ThumbGrid.Visibility = System.Windows.Visibility.Collapsed; + } + } + } + + private void ToggleContents(object sender, RoutedEventArgs e) + { + if (xaml_ContentGrid.Visibility == System.Windows.Visibility.Visible) + { + xaml_ContentGrid.Visibility = System.Windows.Visibility.Collapsed; + return; + } + + if (m_num_pages < 0) + return; + + if (xaml_ContentList.Items.IsEmpty) + { + int size_content = mu_doc.ComputeContents(); + if (size_content == 0) + return; + xaml_ContentList.ItemsSource = mu_doc.contents; + } + xaml_ContentGrid.Visibility = System.Windows.Visibility.Visible; + } + + private void ThumbSelected(object sender, MouseButtonEventArgs e) + { + var item = ((FrameworkElement)e.OriginalSource).DataContext as DocPage; + + if (item != null) + { + if (item.PageNum < 0) + return; + RenderRange(item.PageNum, true, zoom_t.NO_ZOOM, 0); + } + } + + private void ContentSelected(object sender, MouseButtonEventArgs e) + { + var item = ((FrameworkElement)e.OriginalSource).DataContext as ContentItem; + if (item != null && item.Page < m_num_pages) + { + int page = m_docPages[item.Page].PageNum; + if (page >= 0 && page < m_num_pages) + RenderRange(page, true, zoom_t.NO_ZOOM, 0); + } + } + + /* We need to avoid rendering due to size changes */ + private void ListViewScrollChanged(object sender, ScrollChangedEventArgs e) + { + /* This makes sure we dont call render range a second time due to + * page advances */ + int first_item = -1; + int second_item = -1; + //Console.WriteLine("***************************************/n"); + //Console.WriteLine("VerticalChange = " + e.VerticalChange + "/n"); + //Console.WriteLine("ExtentHeightChange = " + e.ExtentHeightChange + "/n"); + //Console.WriteLine("ExtentWidthChange = " + e.ExtentWidthChange + "/n"); + //Console.WriteLine("HorizontalChange = " + e.HorizontalChange + "/n"); + //Console.WriteLine("ViewportHeightChange = " + e.ViewportHeightChange + "/n"); + //Console.WriteLine("ViewportWidthChange = " + e.ViewportWidthChange + "/n"); + //Console.WriteLine("ExtentHeight = " + e.ExtentHeight + "/n"); + //Console.WriteLine("ViewportHeight = " + e.ViewportHeight + "/n"); + //Console.WriteLine("VerticalOffset = " + e.VerticalOffset + "/n"); + //Console.WriteLine("***************************************/n"); + if (m_ignorescrollchange == true) + { + m_ignorescrollchange = false; + return; + } + if (!m_init_done) + return; + if (e.VerticalChange == 0) + return; + if (m_num_pages == 1) + return; + + /* From current page go forward and backward checking if pages are + * visible */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + double bottom = this.ActualHeight; + /* first going forward */ + for (int kk = m_currpage + 1; kk < m_num_pages; kk++) + { + UIElement uiElement = (UIElement)xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk); + double y_top = uiElement.TranslatePoint(new System.Windows.Point(0, 0), xaml_PageList).Y; + double y_bottom = uiElement.TranslatePoint(new System.Windows.Point(0, m_docPages[kk].Height), xaml_PageList).Y; + /* Test if this and all further pages are outside window */ + if (y_top > bottom) + break; + /* Test if page is not even yet in window */ + if (y_bottom > 0) + { + if (!(m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled == true)) + { + /* In this case grab the first one that we find */ + if (second_item == -1) + second_item = kk; + } + } + } + + /* and now going backward */ + for (int kk = m_currpage; kk > -1; kk--) + { + UIElement uiElement = (UIElement)xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk); + double y_top = uiElement.TranslatePoint(new System.Windows.Point(0, 0), xaml_PageList).Y; + double y_bottom = uiElement.TranslatePoint(new System.Windows.Point(0, m_docPages[kk].Height), xaml_PageList).Y; + /* Test if this and all further pages are outside window */ + if (y_bottom < 0) + break; + if (y_top < bottom) + if (!(m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled == true)) + first_item = kk; + } + e.Handled = true; + if (first_item != -1) + second_item = first_item; + /* Finish */ + if (m_ScrolledChanged) + { + m_ScrolledChanged = false; + } + else + { + /* We have to update the vertical scroll position */ + double perc = (e.VerticalOffset) / (e.ExtentHeight - e.ViewportHeight); + xaml_VerticalScroll.Value = perc * xaml_VerticalScroll.Maximum; + } + if (second_item < 0) + second_item = 0; + RenderRange(second_item, false, zoom_t.NO_ZOOM, 0); + } + } + + /* ScrollIntoView will not scroll to top on its own. If item is already + * in view it just sits there */ + private void ScrollPageToTop(int k, double offset, bool from_scroller) + { + if (m_num_pages == 1) + return; + /* Get access to the scrollviewer */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + UIElement uiElement = (UIElement) xaml_PageList.ItemContainerGenerator.ContainerFromIndex(k); + double y = uiElement.TranslatePoint(new System.Windows.Point(0, offset), xaml_PageList).Y; + double curr_value = viewer.VerticalOffset; + viewer.ScrollToVerticalOffset(curr_value + y); + + if (!from_scroller) + { + double perc = (double) k / (double) ( m_num_pages - 1); + xaml_VerticalScroll.Value = perc * xaml_VerticalScroll.Maximum; + } + } + } + + /* Scroll to offset */ + private void OffsetScroll(double offset) + { + if (m_num_pages == 1) + return; + /* Get access to the scrollviewer */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + double curr_value = viewer.VerticalOffset; + AdjustScrollPercent(offset / viewer.ScrollableHeight); + viewer.ScrollToVerticalOffset(curr_value + offset); + } + } + + /* Scroll to offset */ + private void OffsetScrollPercent(double percent) + { + /* Get access to the scrollviewer */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + double curr_value = viewer.VerticalOffset; + if (curr_value < 0 || curr_value > viewer.MaxHeight) + return; + var extentheight = viewer.ExtentHeight - viewer.ViewportHeight; + + var pos = extentheight * percent; + viewer.ScrollToVerticalOffset(pos); + } + } + + /* Render +/- the look ahead from where we are if blank page is present */ + async private void RenderRange(int new_page, bool scrollto, zoom_t newzoom, double zoom_offset) + { + /* Need to figure out what pages are going to be visible */ + double bottom = this.ActualHeight; + bool done = false; + int final_page = new_page; + double count = -zoom_offset; + int offset = -1; + bool scrollbottom = false; + + if (newzoom != zoom_t.NO_ZOOM) + offset = 0; + + if (m_thumbnails.Count < m_num_pages) + final_page = final_page + 1; + else + { + while (!done && final_page >= 0 && final_page < m_num_pages) + { + count = count + m_thumbnails[final_page].NativeHeight * m_doczoom; + final_page = final_page + 1; + if (final_page == m_num_pages || count > bottom) + done = true; + } + /* We have zoomed out to a point where the offset will not stay + * in its current spot. Figure out where we need to be */ + final_page = final_page - 1; + if (newzoom == zoom_t.ZOOM_OUT && count < bottom) + { + int curr_page = new_page - 1; + while (true) + { + if (curr_page < 0) + break; + count = count + m_thumbnails[curr_page].NativeHeight * m_doczoom; + if (count > bottom) + break; + curr_page = curr_page - 1; + } + new_page = curr_page; + if (new_page < 0) + new_page = 0; + scrollbottom = true; + } + } + + for (int k = new_page + offset; k <= final_page + 1; k++) + { + if (k >= 0 && k < m_num_pages) + { + /* Check if page is already rendered */ + var doc = m_docPages[k]; + if (doc.Content != Page_Content_t.FULL_RESOLUTION || + doc.Zoom != m_doczoom || m_AA != doc.AA || + (doc.Annotate == Annotate_t.UNKNOWN && m_showannot) || + (doc.Annotate == Annotate_t.ANNOTATE_VISIBLE && !m_showannot) || + (doc.Annotate == Annotate_t.ANNOTATE_HIDDEN && m_showannot)) + { + Point ras_size; + double scale_factor = m_doczoom; + /* To avoid multiple page renderings on top of one + * another with scroll changes mark this as being + * full resolution */ + m_docPages[k].Content = Page_Content_t.FULL_RESOLUTION; + /* Avoid launching another thread just because we don't + * know the annotation condition for this page */ + m_docPages[k].Annotate = Annotate_t.COMPUTING; + if (ComputePageSize(k, scale_factor, out ras_size) == status_t.S_ISOK) + { + try + { + Byte[] bitmap = new byte[(int)ras_size.X * (int)ras_size.Y * 4]; + BlocksText charlist = null; + Annotate_t annot = Annotate_t.UNKNOWN; + m_docPages[k].NativeWidth = (int)(ras_size.X / scale_factor); + m_docPages[k].NativeHeight = (int)(ras_size.Y / scale_factor); + + Task<int> ren_task = + new Task<int>(() => mu_doc.RenderPage(k, bitmap, + (int)ras_size.X, (int)ras_size.Y, scale_factor, + false, true, !(m_textset[k]), out charlist, m_showannot, + out annot)); + ren_task.Start(); + await ren_task.ContinueWith((antecedent) => + { + status_t code = (status_t)ren_task.Result; + if (code == status_t.S_ISOK) + { + SetPageAnnot(k, annot); + if (m_docPages[k].TextBox != null) + ScaleTextBox(k); + if (m_links_on && m_page_link_list != null) + { + m_docPages[k].LinkBox = m_page_link_list[k]; + if (m_docPages[k].LinkBox != null) + ScaleLinkBox(k); + } + else + { + m_docPages[k].LinkBox = null; + } + if (!(m_textset[k]) && charlist != null) + { + m_textptrs[k] = charlist; + if (scale_factor != 1.0) + ScaleTextBlocks(k, scale_factor); + m_docPages[k].TextBlocks = m_textptrs[k]; + m_textset[k] = true; + if (m_selectall) + { + int num_blocks = m_docPages[k].TextBlocks.Count; + for (int jj = 0; jj < num_blocks; jj++) + { + m_docPages[k].TextBlocks[jj].Color = m_textselectcolor; + } + } + } + else + { + /* We had to rerender due to scale */ + if (m_textptrs[k] != null) + { + ScaleTextBlocks(k, scale_factor); + m_docPages[k].TextBlocks = m_textptrs[k]; + } + if (m_lineptrs[k] != null) + { + ScaleTextLines(k, scale_factor); + m_docPages[k].SelectedLines = m_lineptrs[k]; + } + } + /* This needs to be handled here to reduce + * flashing effects */ + if (newzoom != zoom_t.NO_ZOOM && k == new_page) + { + m_ignorescrollchange = true; + UpdatePageSizes(); + xaml_VerticalScroll.Maximum = m_totalpageheight * m_doczoom + 4 * m_num_pages; + if (!scrollbottom) + ScrollPageToTop(new_page, zoom_offset, false); + } + UpdatePage(k, bitmap, ras_size, + Page_Content_t.FULL_RESOLUTION, m_doczoom, m_AA); + if (k == new_page && scrollto && new_page != m_currpage) + { + m_doscroll = true; + ScrollPageToTop(k, 0, false); + } + } + }, TaskScheduler.FromCurrentSynchronizationContext()); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed page " + k + "\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + } + else + { + /* We did not have to render the page but we may need to + * scroll to it */ + if (k == new_page && scrollto && new_page != m_currpage) + { + m_ignorescrollchange = true; + ScrollPageToTop(k, 0, false); + } + } + } + } + /* Release old range and set new page */ + //ReleasePages(m_currpage, new_page - 1, final_page + 1); + m_currpage = new_page; + xaml_currPage.Text = (m_currpage + 1).ToString(); + } + + /* Avoids the next page jumping into view when touched by mouse. See xaml code */ + private void AvoidScrollIntoView(object sender, RequestBringIntoViewEventArgs e) + { + if (!m_doscroll) + e.Handled = true; + else + m_doscroll = false; + } + + private void ReleasePages(int old_page, int new_page, int final_page) + { + if (old_page == new_page) return; + /* To keep from having memory issue reset the page back to + the thumb if we are done rendering the thumbnails */ + for (int k = 0; k < m_num_pages; k++) + { + if (k < new_page || k > final_page) + { + if (k >= 0 && k < m_num_pages) + { + SetThumb(k); + } + } + } + } + + /* Return this page from a full res image to the thumb image */ + private void SetThumb(int page_num) + { + /* See what is there now */ + var doc_page = m_docPages[page_num]; + if (doc_page.Content == Page_Content_t.THUMBNAIL && + doc_page.Zoom == m_doczoom) return; + + if (m_thumbnails.Count > page_num) + { + doc_page.Content = Page_Content_t.THUMBNAIL; + doc_page.Zoom = m_doczoom; + + doc_page.BitMap = m_thumbnails[page_num].BitMap; + doc_page.Width = (int)(m_doczoom * doc_page.BitMap.PixelWidth / Constants.SCALE_THUMB); + doc_page.Height = (int)(m_doczoom * doc_page.BitMap.PixelHeight / Constants.SCALE_THUMB); + doc_page.PageNum = page_num; + doc_page.LinkBox = null; + doc_page.TextBox = null; + /* No need to refresh unless it just occurs during other stuff + * we just want to make sure we can release the bitmaps */ + //doc_page.PageRefresh(); + } + } + + private void gsDLL(object gsObject, String mess) + { + ShowMessage(NotifyType_t.MESS_STATUS, mess); + } + + /* Catastrophic */ + private void muDLL(object gsObject, String mess) + { + ShowMessage(NotifyType_t.MESS_ERROR, mess); + /* Disable even the ability to open a file */ + xaml_open.Opacity = 0.5; + xaml_open.IsEnabled = false; + xaml_file.Opacity = 0.5; + xaml_file.IsEnabled = false; + /* And to drag - drop or registry start up */ + xaml_PageList.RemoveHandler(Grid.DragOverEvent, new System.Windows.DragEventHandler(Grid_DragOver)); + xaml_PageList.RemoveHandler(Grid.DropEvent, new System.Windows.DragEventHandler(Grid_Drop)); + m_regstartup = false; + } + + private void gsIO(object gsObject, String mess, int len) + { + m_gsoutput.Update(mess, len); + } + + private void mupdfUpdate(object muObject, muPDFEventArgs asyncInformation) + { + if (asyncInformation.Completed) + { + xaml_MuPDFProgress.Value = 100; + xaml_MuPDFGrid.Visibility = System.Windows.Visibility.Collapsed; + if (asyncInformation.Params.result == GS_Result_t.gsFAILED) + { + ShowMessage(NotifyType_t.MESS_STATUS, "MuPDF failed to convert document"); + } + MuPDFResult(asyncInformation.Params); + } + else + { + this.xaml_MuPDFProgress.Value = asyncInformation.Progress; + } + } + + /* MuPDF Result*/ + public void MuPDFResult(ConvertParams_t gs_result) + { + if (gs_result.result == GS_Result_t.gsCANCELLED) + { + xaml_MuPDFGrid.Visibility = System.Windows.Visibility.Collapsed; + return; + } + if (gs_result.result == GS_Result_t.gsFAILED) + { + xaml_MuPDFGrid.Visibility = System.Windows.Visibility.Collapsed; + ShowMessage(NotifyType_t.MESS_STATUS, "MuPDF Failed Conversion"); + return; + } + ShowMessage(NotifyType_t.MESS_STATUS, "MuPDF Completed Conversion"); + } + + private void gsProgress(object gsObject, gsEventArgs asyncInformation) + { + if (asyncInformation.Completed) + { + xaml_DistillProgress.Value = 100; + xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + if (asyncInformation.Params.result == GS_Result_t.gsFAILED) + { + switch (asyncInformation.Params.task) + { + case GS_Task_t.CREATE_XPS: + ShowMessage(NotifyType_t.MESS_STATUS, "Ghostscript failed to create XPS"); + break; + + case GS_Task_t.PS_DISTILL: + ShowMessage(NotifyType_t.MESS_STATUS, "Ghostscript failed to distill PS"); + break; + + case GS_Task_t.SAVE_RESULT: + ShowMessage(NotifyType_t.MESS_STATUS, "Ghostscript failed to convert document"); + break; + } + return; + } + GSResult(asyncInformation.Params); + } + else + { + this.xaml_DistillProgress.Value = asyncInformation.Progress; + } + } + + /* GS Result*/ + public void GSResult(gsParams_t gs_result) + { + if (gs_result.result == GS_Result_t.gsCANCELLED) + { + xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + return; + } + if (gs_result.result == GS_Result_t.gsFAILED) + { + xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + ShowMessage(NotifyType_t.MESS_STATUS, "GS Failed Conversion"); + return; + } + switch (gs_result.task) + { + case GS_Task_t.CREATE_XPS: + xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + PrintXPS(gs_result.outputfile); + break; + + case GS_Task_t.PS_DISTILL: + xaml_DistillGrid.Visibility = System.Windows.Visibility.Collapsed; + m_origfile = gs_result.inputfile; + OpenFile2(gs_result.outputfile); + break; + + case GS_Task_t.SAVE_RESULT: + ShowMessage(NotifyType_t.MESS_STATUS, "GS Completed Conversion"); + break; + } + } + + private void PrintCommand(object sender, ExecutedRoutedEventArgs e) + { + Print(sender, e); + } + + /* Printing is achieved using xpswrite device in ghostscript and + * pushing that file through the XPS print queue */ + private void Print(object sender, RoutedEventArgs e) + { + if (!m_file_open) + return; + + /* If file is already xps then gs need not do this */ + if (!m_isXPS) + { + xaml_DistillProgress.Value = 0; + if (m_ghostscript.CreateXPS(m_currfile, Constants.DEFAULT_GS_RES, m_num_pages) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS currently busy"); + return; + } + else + { + /* Right now this is not possible to cancel due to the way + * that gs is run for xpswrite from pdf */ + xaml_CancelDistill.Visibility = System.Windows.Visibility.Collapsed; + xaml_DistillName.Text = "Convert to XPS"; + xaml_DistillName.FontWeight = FontWeights.Bold; + xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; + } + } + else + PrintXPS(m_currfile); + } + + private void PrintXPS(String file) + { + gsprint ghostprint = new gsprint(); + System.Windows.Controls.PrintDialog pDialog = ghostprint.GetPrintDialog(); + + if (pDialog == null) + return; + /* We have to create the XPS document on a different thread */ + XpsDocument xpsDocument = new XpsDocument(file, FileAccess.Read); + FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence(); + PrintQueue printQueue = pDialog.PrintQueue; + + m_ghostprint = ghostprint; + xaml_PrintGrid.Visibility = System.Windows.Visibility.Visible; + + xaml_PrintProgress.Value = 0; + + ghostprint.Print(printQueue, fixedDocSeq); + } + + private void PrintProgress(object printHelper, gsPrintEventArgs Information) + { + if (Information.Status != PrintStatus_t.PRINT_BUSY) + { + xaml_PrintProgress.Value = 100; + xaml_PrintGrid.Visibility = System.Windows.Visibility.Collapsed; + } + else + { + xaml_PrintProgress.Value = + 100.0 * (double)Information.Page / (double)m_num_pages; + } + } + + private void CancelMuPDFClick(object sender, RoutedEventArgs e) + { + xaml_CancelMuPDF.IsEnabled = false; + mu_doc.Cancel(); + } + + private void CancelDistillClick(object sender, RoutedEventArgs e) + { + xaml_CancelDistill.IsEnabled = false; + if (m_ghostscript != null) + m_ghostscript.Cancel(); + } + + private void CancelPrintClick(object sender, RoutedEventArgs e) + { + m_ghostprint.CancelAsync(); + } + + private void ShowGSMessage(object sender, RoutedEventArgs e) + { + m_gsoutput.Show(); + } + + private void ConvertClick(object sender, RoutedEventArgs e) + { + if (m_ghostscript.GetStatus() != gsStatus.GS_READY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + + if (m_convertwin == null || !m_convertwin.IsActive) + { + m_convertwin = new Convert(m_num_pages); + m_convertwin.ConvertUpdateMain += new Convert.ConvertCallBackMain(ConvertReturn); + m_convertwin.Activate(); + m_convertwin.Show(); + } + } + + private void ConvertReturn(object sender) + { + Device device = (Device)m_convertwin.xaml_DeviceList.SelectedItem; + if (device == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "No Device Selected"); + return; + } + + if (m_ghostscript.GetStatus() != gsStatus.GS_READY && + !device.MuPDFDevice) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + + System.Collections.IList pages = m_convertwin.xaml_PageList.SelectedItems; + System.Collections.IList pages_selected = null; + String options = m_convertwin.xaml_options.Text; + int resolution = 72; + bool multi_page_needed = false; + int first_page = -1; + int last_page = -1; + + if (pages.Count == 0) + { + ShowMessage(NotifyType_t.MESS_STATUS, "No Pages Selected"); + return; + } + + /* Get a filename */ + System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog(); + dlg.Filter = "All files (*.*)|*.*"; + dlg.FilterIndex = 1; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (device.MuPDFDevice) + { + /* Allow only one of these as a time */ + pages_selected = pages; + var val = m_convertwin.xaml_resolution.Text; + if (val.Length > 0) + { + bool isok = true; + int num = resolution; + try + { + num = System.Convert.ToInt32(val); + } + catch (FormatException e) + { + isok = false; + Console.WriteLine("Input string is not a sequence of digits."); + } + catch (OverflowException e) + { + isok = false; + Console.WriteLine("The number cannot fit in an Int32."); + } + if (isok && num > 0) + resolution = num; + } + + if (mu_doc.ConvertSave(device.DeviceType, dlg.FileName, + pages.Count, pages_selected, resolution) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "MuPDF conversion busy"); + return; + } + xaml_CancelMuPDF.Visibility = System.Windows.Visibility.Visible; + xaml_MuPDFGrid.Visibility = System.Windows.Visibility.Visible; + } + else + { + if (!device.SupportsMultiPage && m_num_pages > 1) + multi_page_needed = true; + + if (pages.Count != m_num_pages) + { + /* We may need to go through page by page. Determine if + * selection of pages is continuous. This is done by + * looking at the first one in the list and the last one + * in the list and checking the length */ + SelectPage lastpage = (SelectPage)pages[pages.Count - 1]; + SelectPage firstpage = (SelectPage)pages[0]; + int temp = lastpage.Page - firstpage.Page + 1; + if (temp == pages.Count) + { + /* Pages are contiguous. Add first and last page + * as command line option */ + options = options + " -dFirstPage=" + firstpage.Page + " -dLastPage=" + lastpage.Page; + first_page = firstpage.Page; + last_page = lastpage.Page; + } + else + { + /* Pages are not continguous. We will do this page + * by page.*/ + pages_selected = pages; + multi_page_needed = true; /* need to put in separate outputs */ + } + } + xaml_DistillProgress.Value = 0; + if (m_ghostscript.Convert(m_currfile, options, + device.DeviceName, dlg.FileName, pages.Count, resolution, + multi_page_needed, pages_selected, first_page, last_page, + null, null) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + xaml_DistillName.Text = "GS Converting Document"; + xaml_CancelDistill.Visibility = System.Windows.Visibility.Collapsed; + xaml_DistillName.FontWeight = FontWeights.Bold; + xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; + } + m_convertwin.Close(); + } + return; + } + + private void ExtractPages(object sender, RoutedEventArgs e) + { + if (!m_init_done || m_isXPS) + return; + + if (m_extractwin == null || !m_extractwin.IsActive) + { + m_extractwin = new PageExtractSave(m_num_pages); + m_extractwin.ExtractMain += new PageExtractSave.ExtractCallBackMain(ExtractReturn); + m_extractwin.Activate(); + m_extractwin.Show(); + } + } + + private void ExtractReturn(object sender) + { + if (m_extractwin.xaml_PageList.SelectedItems.Count == 0) + { + ShowMessage(NotifyType_t.MESS_STATUS, "No Pages Selected"); + return; + } + + /* Go through the actual list not the selected items list. The + * selected items list contains them in the order that the were + * selected not the order graphically shown */ + List<SelectPage> pages = new List<SelectPage>(m_extractwin.xaml_PageList.SelectedItems.Count); + + for (int kk = 0; kk < m_extractwin.xaml_PageList.Items.Count; kk++) + { + var item = (m_extractwin.xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk)) as System.Windows.Controls.ListViewItem; + if (item.IsSelected == true) + { + pages.Add((SelectPage) m_extractwin.Pages[kk]); + } + } + + /* Get a filename */ + System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog(); + dlg.Filter = "All files (*.pdf)|*.pdf"; + dlg.FilterIndex = 1; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + mu_doc.PDFExtract(m_currfile, dlg.FileName, m_currpassword, m_currpassword != null, + false, pages.Count, pages); + m_extractwin.Close(); + } + return; + } + + private void GetPassword() + { + if (m_password == null) + { + m_password = new Password(); + m_password.PassUpdateMain += new Password.PassCallBackMain(PasswordReturn); + m_password.Activate(); + m_password.Show(); + } + } + + private void PasswordReturn(object sender) + { + if (mu_doc.ApplyPassword(m_password.xaml_Password.Password)) + { + m_currpassword = m_password.xaml_Password.Password; + m_password.Close(); + m_password = null; + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Visible; + xaml_openfilestatus.Text = "Opening File"; + StartViewer(); + } + else + { + xaml_OpenProgressGrid.Visibility = System.Windows.Visibility.Collapsed; + ShowMessage(NotifyType_t.MESS_STATUS, "Password Incorrect"); + } + } + + private void ShowInfo(object sender, RoutedEventArgs e) + { + String Message; + + if (m_file_open) + { + String filename; + + if (m_origfile != null && (m_document_type == DocumentTypes.PS || + m_document_type == DocumentTypes.EPS)) + filename = m_origfile; + else + filename = m_currfile; + + Message = + " File: " + filename + "\n" + + "Document Type: " + m_document_type + "\n" + + " Pages: " + m_num_pages + "\n" + + " Current Page: " + (m_currpage + 1) + "\n"; + if (m_infowindow == null || !(m_infowindow.IsActive)) + m_infowindow = new Info(); + m_infowindow.xaml_TextInfo.Text = Message; + m_infowindow.FontFamily = new FontFamily("Courier New"); + m_infowindow.Show(); + } + } + + #region Zoom Control + + /* Find out where the current page is */ + private double ComputeOffsetZoomOut(double old_zoom) + { + double y = 0; + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + /* Look at the offset and where it falls relative to the top of our current page */ + UIElement uiElement = (UIElement)xaml_PageList.ItemContainerGenerator.ContainerFromIndex(m_currpage); + y = viewer.TranslatePoint(new System.Windows.Point(0, 0), uiElement).Y; + } + return y * m_doczoom / old_zoom; + } + + private double ComputeOffsetZoomIn(double old_zoom, out int new_page) + { + double y = 0; + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + new_page = m_currpage; + if (viewer != null) + { + /* Look at the offset and where it falls relative to the top of our current page */ + UIElement uiElement = (UIElement)xaml_PageList.ItemContainerGenerator.ContainerFromIndex(m_currpage); + y = viewer.TranslatePoint(new System.Windows.Point(0, 0), uiElement).Y; + + /* If we are zoomed out, we can be on a page that is not on the top boundry. See if we can find one + * that is */ + if (y < 0) + { + new_page = m_currpage - 1; + while (true) + { + if (new_page < 0) + { + new_page = 0; + return 0; + } + uiElement = (UIElement)xaml_PageList.ItemContainerGenerator.ContainerFromIndex(new_page); + y = viewer.TranslatePoint(new System.Windows.Point(0, 0), uiElement).Y; + if (y >= 0) + { + return y * m_doczoom / old_zoom; + } + new_page = new_page - 1; + } + } + } + return y * m_doczoom / old_zoom; + } + + private void ZoomOut(object sender, RoutedEventArgs e) + { + if (!m_init_done || m_doczoom <= Constants.ZOOM_MIN) + return; + double old_zoom = m_doczoom; + m_doczoom = m_doczoom - Constants.ZOOM_STEP; + if (m_doczoom < Constants.ZOOM_MIN) + m_doczoom = Constants.ZOOM_MIN; + xaml_ZoomSlider.Value = m_doczoom * 100.0; + double offset = ComputeOffsetZoomOut(old_zoom); + RenderRange(m_currpage, false, zoom_t.ZOOM_OUT, offset); + } + + private void ZoomIn(object sender, RoutedEventArgs e) + { + if (!m_init_done || m_doczoom >= Constants.ZOOM_MAX) + return; + double old_zoom = m_doczoom; + m_doczoom = m_doczoom + Constants.ZOOM_STEP; + if (m_doczoom > Constants.ZOOM_MAX) + m_doczoom = Constants.ZOOM_MAX; + xaml_ZoomSlider.Value = m_doczoom * 100.0; + int newpage; + double offset = ComputeOffsetZoomIn(old_zoom, out newpage); + RenderRange(newpage, false, zoom_t.ZOOM_IN, offset); + } + + private void ActualSize(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + double old_zoom = m_doczoom; + m_doczoom = 1.0; + xaml_ZoomSlider.Value = m_doczoom * 100.0; + if (old_zoom < 1.0) + { + int new_page; + double offset = ComputeOffsetZoomIn(old_zoom, out new_page); + RenderRange(new_page, false, zoom_t.ZOOM_IN, offset); + } + else if (old_zoom > 1.0) + { + double offset = ComputeOffsetZoomOut(old_zoom); + RenderRange(m_currpage, false, zoom_t.ZOOM_OUT, offset); + } + } + + private void ContScrollFill(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + /* Scale our pages based upon the size of scrollviewer */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer == null) + return; + double width = viewer.ViewportWidth; + double page_width = m_thumbnails[m_currpage].NativeWidth; + double scale = width / page_width; + if (scale < Constants.ZOOM_MIN) + scale = Constants.ZOOM_MIN; + if (scale > Constants.ZOOM_MAX) + scale = Constants.ZOOM_MAX; + if (m_doczoom == scale) + return; + double old_zoom = m_doczoom; + m_doczoom = scale; + xaml_ZoomSlider.Value = m_doczoom * 100.0; + if (old_zoom > m_doczoom) + RenderRange(m_currpage, true, zoom_t.ZOOM_OUT, 0); + else + RenderRange(m_currpage, true, zoom_t.ZOOM_IN, 0); + } + + private void ExpandFill(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + /* Scale our pages based upon the size of scrollviewer */ + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer == null) + return; + double height = viewer.ViewportHeight; + double width = viewer.ViewportWidth; + double page_height = m_thumbnails[m_currpage].NativeHeight; + double page_width = m_thumbnails[m_currpage].NativeWidth; + double height_scale = height / page_height; + double width_scale = width / page_width; + double scale = Math.Min(height_scale, width_scale); + if (scale < Constants.ZOOM_MIN) + scale = Constants.ZOOM_MIN; + if (scale > Constants.ZOOM_MAX) + scale = Constants.ZOOM_MAX; + if (m_doczoom == scale) + return; + double old_zoom = m_doczoom; + m_doczoom = scale; + xaml_ZoomSlider.Value = m_doczoom * 100.0; + if (old_zoom > m_doczoom) + RenderRange(m_currpage, true, zoom_t.ZOOM_OUT, 0); + else + RenderRange(m_currpage, true, zoom_t.ZOOM_IN, 0); + } + + private void ShowFooter(object sender, RoutedEventArgs e) + { + xaml_FooterControl.Visibility = System.Windows.Visibility.Visible; + } + + private void HideFooter(object sender, RoutedEventArgs e) + { + xaml_FooterControl.Visibility = System.Windows.Visibility.Collapsed; + } + + private void ZoomReleased(object sender, MouseButtonEventArgs e) + { + if (m_init_done) + { + double zoom = xaml_ZoomSlider.Value / 100.0; + if (zoom > Constants.ZOOM_MAX) + zoom = Constants.ZOOM_MAX; + if (zoom < Constants.ZOOM_MIN) + zoom = Constants.ZOOM_MIN; + double old_zoom = zoom; + m_doczoom = zoom; + if (old_zoom > m_doczoom) + { + double offset = ComputeOffsetZoomOut(old_zoom); + RenderRange(m_currpage, false, zoom_t.ZOOM_OUT, offset); + } + else + { + int new_page; + double offset = ComputeOffsetZoomIn(old_zoom, out new_page); + RenderRange(new_page, false, zoom_t.ZOOM_IN, offset); + } + } + } + + /* If the zoom is not equalto 1 then set the zoom to 1 and scoll to this page */ + private void PageDoubleClick(object sender, MouseButtonEventArgs e) + { + return; /* Disable this for now */ + if (m_doczoom != 1.0) + { + double old_zoom = m_doczoom; + m_doczoom = 1.0; + xaml_Zoomsize.Text = "100"; + var item = ((FrameworkElement)e.OriginalSource).DataContext as DocPage; + if (item != null) + { + if (old_zoom > m_doczoom) + { + double offset = ComputeOffsetZoomOut(old_zoom); + RenderRange(m_currpage, false, zoom_t.ZOOM_OUT, offset); + } + else + { + int new_page; + double offset = ComputeOffsetZoomIn(old_zoom, out new_page); + RenderRange(new_page, false, zoom_t.ZOOM_IN, offset); + } + } + } + } + + private void ZoomEnterClicked(object sender, System.Windows.Input.KeyEventArgs e) + { + if (e.Key == Key.Return) + { + e.Handled = true; + var desired_zoom = xaml_Zoomsize.Text; + try + { + double zoom = (double)System.Convert.ToInt32(desired_zoom) / 100.0; + if (zoom > Constants.ZOOM_MAX) + zoom = Constants.ZOOM_MAX; + if (zoom < Constants.ZOOM_MIN) + zoom = Constants.ZOOM_MIN; + double old_zoom = m_doczoom; + m_doczoom = zoom; + if (old_zoom > m_doczoom) + { + double offset = ComputeOffsetZoomOut(old_zoom); + RenderRange(m_currpage, false, zoom_t.ZOOM_OUT, offset); + } + else + { + int new_page; + double offset = ComputeOffsetZoomIn(old_zoom, out new_page); + RenderRange(new_page, false, zoom_t.ZOOM_IN, offset); + } + } + catch (FormatException e1) + { + Console.WriteLine("String is not a sequence of digits."); + } + catch (OverflowException e2) + { + Console.WriteLine("The number cannot fit in an Int32."); + } + } + } + + /* Rescale the pages based upon the zoom value and the native size */ + private void UpdatePageSizes() + { + SetThumbwidth(); + for (int k = 0; k > m_num_pages; k++) + { + var thumbpage = m_thumbnails[k]; + var page = m_docPages[k]; + + if (page.Zoom == m_doczoom) + continue; + int scale_zoom = (int)Math.Round((double)page.Height / (double)thumbpage.NativeHeight); + if (scale_zoom != m_doczoom) + { + page.Height = (int)Math.Round(thumbpage.NativeHeight * m_doczoom); + page.Width = (int)Math.Round(thumbpage.NativeWidth * m_doczoom); + } + } + } + #endregion Zoom Control + + #region Thumb Rendering + void SetThumbInit(int page_num, Byte[] bitmap, Point ras_size, double zoom_in) + { + /* Three jobs. Store the thumb and possibly update the full page. Also + add to collection of pages. Set up page geometry info (scale of + 100 percent ) */ + + DocPage doc_page = new DocPage(); + m_thumbnails.Add(doc_page); + + doc_page.Width = (int)ras_size.X; + + doc_page.Height = (int)ras_size.Y; + doc_page.NativeWidth = (int)(ras_size.X / Constants.SCALE_THUMB); + doc_page.NativeHeight = (int)(ras_size.Y / Constants.SCALE_THUMB); + m_totalpageheight = m_totalpageheight + doc_page.NativeHeight; + + doc_page.Content = Page_Content_t.THUMBNAIL; + doc_page.Zoom = zoom_in; + int stride = doc_page.Width * 4; + doc_page.BitMap = BitmapSource.Create(doc_page.Width, doc_page.Height, + 72, 72, PixelFormats.Pbgra32, BitmapPalettes.Halftone256, bitmap, stride); + doc_page.PageNum = page_num; + + /* Lets see if we need to set the main page */ + var doc = m_docPages[page_num]; + switch (doc.Content) + { + case Page_Content_t.FULL_RESOLUTION: + case Page_Content_t.THUMBNAIL: + return; + + case Page_Content_t.NOTSET: + doc_page = InitDocPage(); + doc_page.Content = Page_Content_t.THUMBNAIL; + doc_page.Zoom = zoom_in; + doc_page.BitMap = m_thumbnails[page_num].BitMap; + doc_page.Width = (int)(ras_size.X / Constants.SCALE_THUMB); + doc_page.Height = (int)(ras_size.Y / Constants.SCALE_THUMB); + doc_page.PageNum = page_num; + this.m_docPages[page_num] = doc_page; + break; + + case Page_Content_t.OLD_RESOLUTION: + return; + } + } + + private void ThumbsWork(object sender, DoWorkEventArgs e) + { + Point ras_size; + status_t code; + double scale_factor = Constants.SCALE_THUMB; + BackgroundWorker worker = sender as BackgroundWorker; + + Byte[] bitmap; + + for (int k = 0; k < m_num_pages; k++) + { + if (ComputePageSize(k, scale_factor, out ras_size) == status_t.S_ISOK) + { + try + { + bitmap = new byte[(int)ras_size.X * (int)ras_size.Y * 4]; + BlocksText charlist; + Annotate_t annot; + /* Synchronous call on our background thread */ + code = (status_t)mu_doc.RenderPage(k, bitmap, (int)ras_size.X, + (int)ras_size.Y, scale_factor, false, false, false, + out charlist, false, out annot); + } + catch (OutOfMemoryException em) + { + Console.WriteLine("Memory allocation failed thumb page " + k + em.Message + "\n"); + break; + } + /* Use thumb if we rendered ok */ + if (code == status_t.S_ISOK) + { + double percent = 100 * (double)(k + 1) / (double)m_num_pages; + thumb_t curr_thumb = new thumb_t(); + curr_thumb.page_num = k; + curr_thumb.bitmap = bitmap; + curr_thumb.size = ras_size; + worker.ReportProgress((int)percent, curr_thumb); + } + } + if (worker.CancellationPending == true) + { + e.Cancel = true; + break; + } + } + } + + private void ThumbsCompleted(object sender, RunWorkerCompletedEventArgs e) + { + xaml_ProgressGrid.Visibility = System.Windows.Visibility.Collapsed; + xaml_ThumbProgress.Value = 0; + xaml_ThumbList.ItemsSource = m_thumbnails; + m_have_thumbs = true; + m_thumbworker = null; + //xaml_CancelThumb.IsEnabled = true; + xaml_ThumbList.Items.Refresh(); + xaml_VerticalScroll.Minimum = 0; + xaml_VerticalScroll.Maximum = m_totalpageheight + 4 * m_num_pages; + //thumbSize = (viewportSize/(maximum–minimum+viewportSize))×trackLength + SetThumbwidth(); + //ScrollBarExtensions.SetThumbLength(xaml_VerticalScroll, 1); + } + + private void ThumbsProgressChanged(object sender, ProgressChangedEventArgs e) + { + thumb_t thumb = (thumb_t)(e.UserState); + + xaml_ThumbProgress.Value = e.ProgressPercentage; + SetThumbInit(thumb.page_num, thumb.bitmap, thumb.size, 1.0); + } + + private void RenderThumbs() + { + /* Create background task for rendering the thumbnails. Allow + this to be cancelled if we open a new doc while we are in loop + rendering. Put the UI updates in the progress changed which will + run on the main thread */ + try + { + m_thumbworker = new BackgroundWorker(); + m_thumbworker.WorkerReportsProgress = true; + m_thumbworker.WorkerSupportsCancellation = true; + m_thumbworker.DoWork += new DoWorkEventHandler(ThumbsWork); + m_thumbworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ThumbsCompleted); + m_thumbworker.ProgressChanged += new ProgressChangedEventHandler(ThumbsProgressChanged); + xaml_ProgressGrid.Visibility = System.Windows.Visibility.Visible; + m_thumbworker.RunWorkerAsync(); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during thumb rendering\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + #endregion Thumb Rendering + + #region Copy Paste + /* Copy the current page as a bmp to the clipboard this is done at the + * current resolution */ + private void CopyPage(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + var curr_page = m_docPages[m_currpage]; + System.Windows.Clipboard.SetImage(curr_page.BitMap); + m_clipboardset = true; + } + + /* Paste the page to various types supported by the windows encoder class */ + private void PastePage(object sender, RoutedEventArgs e) + { + var menu = (System.Windows.Controls.MenuItem)sender; + + String tag = (String)menu.Tag; + + if (!m_clipboardset || !System.Windows.Clipboard.ContainsImage() || + !m_init_done) + return; + var bitmap = System.Windows.Clipboard.GetImage(); + + BitmapEncoder encoder; + System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog(); + dlg.FilterIndex = 1; + + switch (tag) + { + case "PNG": + dlg.Filter = "PNG Files(*.png)|*.png"; + encoder = new PngBitmapEncoder(); + + break; + case "JPG": + dlg.Filter = "JPEG Files(*.jpg)|*.jpg"; + encoder = new JpegBitmapEncoder(); + break; + + case "WDP": + dlg.Filter = "HDP Files(*.wdp)|*.wdp"; + encoder = new WmpBitmapEncoder(); + break; + + case "TIF": + dlg.Filter = "TIFF Files(*.tif)|*.tif"; + encoder = new TiffBitmapEncoder(); + break; + + case "BMP": + dlg.Filter = "BMP Files(*.bmp)|*.bmp"; + encoder = new BmpBitmapEncoder(); + break; + + case "GIF": + dlg.Filter = "GIF Files(*.gif)|*.gif"; + encoder = new GifBitmapEncoder(); + break; + + default: + return; + } + + encoder.Frames.Add(BitmapFrame.Create(bitmap)); + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + using (var stream = dlg.OpenFile()) + encoder.Save(stream); + } + } + #endregion Copy Paste + + #region SaveAs + String CreatePDFXA(Save_Type_t type) + { + Byte[] Resource; + String Profile; + + switch (type) + { + case Save_Type_t.PDFA1_CMYK: + case Save_Type_t.PDFA2_CMYK: + Resource = Properties.Resources.PDFA_def; + Profile = m_outputintents.cmyk_icc; + break; + + case Save_Type_t.PDFA1_RGB: + case Save_Type_t.PDFA2_RGB: + Resource = Properties.Resources.PDFA_def; + Profile = m_outputintents.rgb_icc; + break; + + case Save_Type_t.PDFX3_CMYK: + Resource = Properties.Resources.PDFX_def; + Profile = m_outputintents.cmyk_icc; + break; + + case Save_Type_t.PDFX3_GRAY: + Resource = Properties.Resources.PDFX_def; + Profile = m_outputintents.gray_icc; + break; + + default: + return null; + } + + String Profile_new = Profile.Replace("\\", "/"); + String result = System.Text.Encoding.UTF8.GetString(Resource); + String pdfx_cust = result.Replace("ICCPROFILE", Profile_new); + var out_file = System.IO.Path.GetTempFileName(); + System.IO.File.WriteAllText(out_file, pdfx_cust); + return out_file; + } + + private void SaveFile(Save_Type_t type) + { + if (!m_file_open) + return; + + System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog(); + dlg.FilterIndex = 1; + + /* PDF output types */ + if (type <= Save_Type_t.PDF) + { + dlg.Filter = "PDF Files(*.pdf)|*.pdf"; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + String options = null; + bool use_gs = true; + String init_file = CreatePDFXA(type); + + switch (type) + { + case Save_Type_t.PDF: + /* All done. No need to use gs or mupdf */ + System.IO.File.Copy(m_currfile, dlg.FileName, true); + use_gs = false; + break; + case Save_Type_t.LINEAR_PDF: + mu_doc.PDFExtract(m_currfile, dlg.FileName, m_currpassword, + m_currpassword != null, true, -1, null); + use_gs = false; + break; + case Save_Type_t.PDF13: + options = "-dCompatibilityLevel=1.3"; + break; + case Save_Type_t.PDFA1_CMYK: + options = "-dPDFA=1 -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceCMYK -dColorConversionStrategy=/CMYK -sOutputICCProfile=" + m_outputintents.cmyk_icc; + break; + case Save_Type_t.PDFA1_RGB: + options = "-dPDFA=1 -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceRGB -dColorConversionStrategy=/RGB -sOutputICCProfile=" + m_outputintents.rgb_icc; + break; + case Save_Type_t.PDFA2_CMYK: + options = "-dPDFA=2 -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceCMYK -dColorConversionStrategy=/CMYK -sOutputICCProfile=" + m_outputintents.cmyk_icc; + break; + case Save_Type_t.PDFA2_RGB: + options = "-dPDFA=2 -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceRGB -dColorConversionStrategy=/RGB -sOutputICCProfile=" + m_outputintents.rgb_icc; + break; + case Save_Type_t.PDFX3_CMYK: + options = "-dPDFX -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceCMYK -dColorConversionStrategy=/CMYK -sOutputICCProfile=" + m_outputintents.cmyk_icc; + break; + case Save_Type_t.PDFX3_GRAY: + options = "-dPDFX -dNOOUTERSAVE -dPDFACompatibilityPolicy=1 -sProcessColorModel=DeviceGray -dColorConversionStrategy=/Gray -sOutputICCProfile=" + m_outputintents.cmyk_icc; + break; + + } + if (use_gs) + { + xaml_DistillProgress.Value = 0; + if (m_ghostscript.Convert(m_currfile, options, + Enum.GetName(typeof(gsDevice_t), gsDevice_t.pdfwrite), + dlg.FileName, m_num_pages, 300, false, null, -1, -1, + init_file, null) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + xaml_DistillName.Text = "Creating PDF"; + xaml_CancelDistill.Visibility = System.Windows.Visibility.Collapsed; + xaml_DistillName.FontWeight = FontWeights.Bold; + xaml_DistillGrid.Visibility = System.Windows.Visibility.Visible; + } + } + } + else + { + /* Non PDF output */ + gsDevice_t Device = gsDevice_t.xpswrite; + bool use_mupdf = true; + String Message = ""; + textout_t textout = textout_t.HTML; + switch (type) + { + case Save_Type_t.HTML: + dlg.Filter = "HTML (*.html)|*.html"; + Message = "HTML content written"; + break; + case Save_Type_t.XML: + dlg.Filter = "XML (*.xml)|*.xml"; + Message = "XML content written"; + textout = textout_t.XML; + break; + case Save_Type_t.TEXT: + dlg.Filter = "Text (*.txt)|*.txt"; + Message = "Text content written"; + textout = textout_t.TEXT; + break; + case Save_Type_t.PCLXL: + use_mupdf = false; + dlg.Filter = "PCL-XL (*.bin)|*.bin"; + Device = gsDevice_t.pxlcolor; + break; + case Save_Type_t.XPS: + use_mupdf = false; + dlg.Filter = "XPS Files(*.xps)|*.xps"; + break; + } + if (!use_mupdf) + { + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (m_ghostscript.Convert(m_currfile, "", + Enum.GetName(typeof(gsDevice_t), Device), + dlg.FileName, 1, 300, false, null, -1, -1, + null, null) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + } + } + else + { + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + /* Write out first non null page then append the rest */ + int curr_page = 0; + bool done = false; + + while (!done) + { + String output = null; + output = mu_doc.GetText(curr_page, textout); + if (output == null) + { + curr_page = curr_page + 1; + if (curr_page == m_num_pages) + { + ShowMessage(NotifyType_t.MESS_STATUS, "No text found in file"); + return; + } + } + else + { + System.IO.File.WriteAllText(dlg.FileName, output); + done = true; + } + } + curr_page = curr_page + 1; + + if (curr_page == m_num_pages) + { + ShowMessage(NotifyType_t.MESS_STATUS, Message); + return; + } + done = false; + while (!done) + { + String output = null; + output = mu_doc.GetText(curr_page, textout); + if (output != null) + { + System.IO.File.AppendAllText(dlg.FileName, output); + } + curr_page = curr_page + 1; + if (curr_page == m_num_pages) + { + ShowMessage(NotifyType_t.MESS_STATUS, Message); + return; + } + } + } + } + } + } + + private void SaveSVG(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.SVG); + } + + private void SavePDF(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.PDF); + } + + private void SaveText(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.TEXT); + } + + private void SaveXML(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.XML); + } + + private void SaveHTML(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.HTML); + } + + private void Linearize(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.LINEAR_PDF); + } + + private void SavePDF13(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.PDF13); + } + + private void SavePDFX3_Gray(object sender, RoutedEventArgs e) + { + if (m_outputintents.gray_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set Gray Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFX3_GRAY); + } + + private void SavePDFX3_CMYK(object sender, RoutedEventArgs e) + { + if (m_outputintents.cmyk_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set CMYK Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFX3_CMYK); + } + + private void SavePDFA1_RGB(object sender, RoutedEventArgs e) + { + if (m_outputintents.rgb_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set RGB Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFA1_RGB); + } + + private void SavePDFA1_CMYK(object sender, RoutedEventArgs e) + { + if (m_outputintents.cmyk_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set CMYK Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFA1_CMYK); + } + + private void SavePDFA2_RGB(object sender, RoutedEventArgs e) + { + if (m_outputintents.rgb_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set RGB Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFA2_RGB); + } + + private void SavePDFA2_CMYK(object sender, RoutedEventArgs e) + { + if (m_outputintents.cmyk_icc == null) + { + ShowMessage(NotifyType_t.MESS_STATUS, "Set CMYK Output Intent ICC Profile"); + return; + } + SaveFile(Save_Type_t.PDFA2_CMYK); + } + + private void SavePCLXL(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.PCLXL); + } + private void SaveXPS(object sender, RoutedEventArgs e) + { + SaveFile(Save_Type_t.XPS); + } + #endregion SaveAs + + #region Extract + private void Extract(Extract_Type_t type) + { + if (m_selection != null || !m_init_done) + return; + + m_selection = new Selection(m_currpage + 1, m_doczoom, type); + m_selection.UpdateMain += new Selection.CallBackMain(SelectionMade); + m_selection.Show(); + m_selection.xaml_Image.Source = m_docPages[m_currpage].BitMap; + m_selection.xaml_Image.Height = m_docPages[m_currpage].Height; + m_selection.xaml_Image.Width = m_docPages[m_currpage].Width; + } + + async private void SelectionZoom(int page_num, double zoom) + { + Point ras_size; + if (ComputePageSize(page_num, zoom, out ras_size) == status_t.S_ISOK) + { + try + { + Byte[] bitmap = new byte[(int)ras_size.X * (int)ras_size.Y * 4]; + BlocksText charlist; + Annotate_t annot; + + Task<int> ren_task = + new Task<int>(() => mu_doc.RenderPage(page_num, bitmap, + (int)ras_size.X, (int)ras_size.Y, zoom, false, true, + false, out charlist, true, out annot)); + ren_task.Start(); + await ren_task.ContinueWith((antecedent) => + { + status_t code = (status_t)ren_task.Result; + if (code == status_t.S_ISOK) + { + if (m_selection != null) + { + int stride = (int)ras_size.X * 4; + m_selection.xaml_Image.Source = BitmapSource.Create((int)ras_size.X, (int)ras_size.Y, 72, 72, PixelFormats.Pbgra32, BitmapPalettes.Halftone256, bitmap, stride); + m_selection.xaml_Image.Height = (int)ras_size.Y; + m_selection.xaml_Image.Width = (int)ras_size.X; + m_selection.UpdateRect(); + m_selection.m_curr_state = SelectStatus_t.OK; + } + } + }, TaskScheduler.FromCurrentSynchronizationContext()); + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed page " + page_num + "\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + } + + private void SelectionMade(object gsObject, SelectEventArgs results) + { + switch (results.State) + { + case SelectStatus_t.CANCEL: + case SelectStatus_t.CLOSE: + m_selection = null; + return; + case SelectStatus_t.SELECT: + /* Get the information we need */ + double zoom = results.ZoomFactor; + Point start = results.TopLeft; + Point size = results.Size; + int page = results.PageNum; + gsDevice_t Device = gsDevice_t.pdfwrite; + + start.X = start.X / zoom; + start.Y = start.Y / zoom; + size.X = size.X / zoom; + size.Y = size.Y / zoom; + + /* Do the actual extraction */ + String options; + System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog(); + dlg.FilterIndex = 1; + + /* Get us set up to do a fixed size */ + options = "-dFirstPage=" + page + " -dLastPage=" + page + + " -dDEVICEWIDTHPOINTS=" + size.X + " -dDEVICEHEIGHTPOINTS=" + + size.Y + " -dFIXEDMEDIA"; + + /* Set up the translation */ + String init_string = "<</Install {-" + start.X + " -" + + start.Y + " translate (testing) == flush}>> setpagedevice"; + + switch (results.Type) + { + case Extract_Type_t.PDF: + dlg.Filter = "PDF Files(*.pdf)|*.pdf"; + break; + case Extract_Type_t.EPS: + dlg.Filter = "EPS Files(*.eps)|*.eps"; + Device = gsDevice_t.eps2write; + break; + case Extract_Type_t.PS: + dlg.Filter = "PostScript Files(*.ps)|*.ps"; + Device = gsDevice_t.ps2write; + break; + case Extract_Type_t.SVG: + dlg.Filter = "SVG Files(*.svg)|*.svg"; + break; + } + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + if (m_ghostscript.Convert(m_currfile, options, + Enum.GetName(typeof(gsDevice_t), Device), + dlg.FileName, 1, 300, false, null, page, page, + null, init_string) == gsStatus.GS_BUSY) + { + ShowMessage(NotifyType_t.MESS_STATUS, "GS busy"); + return; + } + } + m_selection.Close(); + break; + case SelectStatus_t.ZOOMIN: + /* Render new page at this resolution and hand it off */ + SelectionZoom(results.PageNum - 1, results.ZoomFactor); + break; + case SelectStatus_t.ZOOMOUT: + /* Render new page at this resolution and hand it off */ + SelectionZoom(results.PageNum - 1, results.ZoomFactor); + break; + } + } + + private void ExtractPDF(object sender, RoutedEventArgs e) + { + Extract(Extract_Type_t.PDF); + } + private void ExtractEPS(object sender, RoutedEventArgs e) + { + Extract(Extract_Type_t.EPS); + } + private void ExtractPS(object sender, RoutedEventArgs e) + { + Extract(Extract_Type_t.PS); + } + private void OutputIntents(object sender, RoutedEventArgs e) + { + m_outputintents.Show(); + } + #endregion Extract + + #region Search + /* Search related code */ + private void Search(object sender, RoutedEventArgs e) + { + if (!m_init_done || (m_textsearch != null && m_textsearch.IsBusy)) + return; + + m_textsearch = null; /* Start out fresh */ + if (xaml_SearchControl.Visibility == System.Windows.Visibility.Collapsed) + xaml_SearchControl.Visibility = System.Windows.Visibility.Visible; + else + { + xaml_SearchControl.Visibility = System.Windows.Visibility.Collapsed; + xaml_SearchGrid.Visibility = System.Windows.Visibility.Collapsed; + ClearTextSearch(); + } + } + + private void OnSearchBackClick(object sender, RoutedEventArgs e) + { + String textToFind = xaml_SearchText.Text; + TextSearchSetUp(-1, textToFind); + } + + private void OnSearchForwardClick(object sender, RoutedEventArgs e) + { + String textToFind = xaml_SearchText.Text; + TextSearchSetUp(1, textToFind); + } + + /* The thread that is actually doing the search work */ + void SearchWork(object sender, DoWorkEventArgs e) + { + BackgroundWorker worker = sender as BackgroundWorker; + List<object> genericlist = e.Argument as List<object>; + int direction = (int)genericlist[0]; + String needle = (String)genericlist[1]; + /* To make sure we get the next page or current page during search */ + int in_search = (int)genericlist[2]; + m_searchpage = m_currpage + direction * in_search; + searchResults_t results = new searchResults_t(); + + /* Break if we find something, get to the end (or start of doc) + * or if we have a cancel occur */ + while (true) + { + int box_count = mu_doc.TextSearchPage(m_searchpage, needle); + int percent; + + if (direction == 1) + percent = (int)(100.0 * ((double)m_searchpage + 1) / (double)m_num_pages); + else + percent = 100 - (int)(100.0 * ((double)m_searchpage) / (double)m_num_pages); + + if (box_count > 0) + { + /* This page has something lets go ahead and extract and + * signal to the UI thread and end this thread */ + results.done = false; + results.num_rects = box_count; + results.page_found = m_searchpage; + results.rectangles = new List<Rect>(); + + for (int kk = 0; kk < box_count; kk++) + { + Point top_left; + Size size; + mu_doc.GetTextSearchItem(kk, out top_left, out size); + var rect = new Rect(top_left, size); + results.rectangles.Add(rect); + } + /* Reset global smart pointer once we have everything */ + mu_doc.ReleaseTextSearch(); + worker.ReportProgress(percent, results); + break; + } + else + { + /* This page has nothing. Lets go ahead and just update + * the progress bar */ + worker.ReportProgress(percent, null); + if (percent >= 100) + { + results.done = true; + results.needle = needle; + break; + } + m_searchpage = m_searchpage + direction; + } + if (worker.CancellationPending == true) + { + e.Cancel = true; + break; + } + } + e.Result = results; + } + + private void SearchProgressChanged(object sender, ProgressChangedEventArgs e) + { + if (e.UserState == null) + { + /* Nothing found */ + xaml_SearchProgress.Value = e.ProgressPercentage; + } + else + { + m_text_list = new List<RectList>(); + /* found something go to page and show results */ + searchResults_t results = (searchResults_t)e.UserState; + xaml_SearchProgress.Value = e.ProgressPercentage; + m_currpage = results.page_found; + /* Add in the rectangles */ + for (int kk = 0; kk < results.num_rects; kk++) + { + var rect_item = new RectList(); + rect_item.Scale = m_doczoom; + rect_item.Color = m_textsearchcolor; + rect_item.Height = results.rectangles[kk].Height * m_doczoom; + rect_item.Width = results.rectangles[kk].Width * m_doczoom; + rect_item.X = results.rectangles[kk].X * m_doczoom; + rect_item.Y = results.rectangles[kk].Y * m_doczoom; + rect_item.Index = kk.ToString(); + m_text_list.Add(rect_item); + } + m_docPages[results.page_found].TextBox = m_text_list; + m_doscroll = true; + xaml_PageList.ScrollIntoView(m_docPages[results.page_found]); + } + } + + private void SearchCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (e.Cancelled == true) + { + xaml_SearchGrid.Visibility = System.Windows.Visibility.Collapsed; + m_textsearch = null; + } + else + { + searchResults_t results = (searchResults_t)e.Result; + if (results.done == true) + { + xaml_SearchGrid.Visibility = System.Windows.Visibility.Collapsed; + m_textsearch = null; + ShowMessage(NotifyType_t.MESS_STATUS, "End of document search for \"" + results.needle + "\""); + } + } + } + + private void CancelSearchClick(object sender, RoutedEventArgs e) + { + if (m_textsearch != null && m_textsearch.IsBusy) + m_textsearch.CancelAsync(); + xaml_SearchGrid.Visibility = System.Windows.Visibility.Collapsed; + m_textsearch = null; + ClearTextSearch(); + } + + private void ClearTextSearch() + { + for (int kk = 0; kk < m_num_pages; kk++) + { + var temp = m_docPages[kk].TextBox; + if (temp != null) + { + m_docPages[kk].TextBox = null; + } + } + } + + private void ScaleTextBox(int pagenum) + { + var temp = m_docPages[pagenum].TextBox; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = m_doczoom / temp[kk].Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = m_doczoom; + temp[kk].PageRefresh(); + } + m_docPages[pagenum].TextBox = temp; + } + + private void TextSearchSetUp(int direction, String needle) + { + /* Create background task for performing text search. */ + try + { + int in_text_search = 0; + + if (m_textsearch != null && m_textsearch.IsBusy) + return; + + if (m_textsearch != null) + { + in_text_search = 1; + m_textsearch = null; + } + if (m_prevsearch != null && needle != m_prevsearch) + { + in_text_search = 0; + ClearTextSearch(); + } + + if (m_textsearch == null) + { + m_prevsearch = needle; + m_textsearch = new BackgroundWorker(); + m_textsearch.WorkerReportsProgress = true; + m_textsearch.WorkerSupportsCancellation = true; + var arguments = new List<object>(); + arguments.Add(direction); + arguments.Add(needle); + arguments.Add(in_text_search); + m_textsearch.DoWork += new DoWorkEventHandler(SearchWork); + m_textsearch.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SearchCompleted); + m_textsearch.ProgressChanged += new ProgressChangedEventHandler(SearchProgressChanged); + xaml_SearchGrid.Visibility = System.Windows.Visibility.Visible; + m_textsearch.RunWorkerAsync(arguments); + } + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during text search\n"); + ShowMessage(NotifyType_t.MESS_ERROR, "Out of memory: " + e.Message); + } + } + #endregion Search + + #region Link + private void LinksToggle(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + + m_links_on = !m_links_on; + + if (m_page_link_list == null) + { + if (m_linksearch != null && m_linksearch.IsBusy) + return; + + m_page_link_list = new List<List<RectList>>(); + m_linksearch = new BackgroundWorker(); + m_linksearch.WorkerReportsProgress = false; + m_linksearch.WorkerSupportsCancellation = true; + m_linksearch.DoWork += new DoWorkEventHandler(LinkWork); + m_linksearch.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LinkCompleted); + m_linksearch.RunWorkerAsync(); + } + else + { + if (m_links_on) + LinksOn(); + else + LinksOff(); + } + } + + private void LinkWork(object sender, DoWorkEventArgs e) + { + BackgroundWorker worker = sender as BackgroundWorker; + + for (int k = 0; k < m_num_pages; k++) + { + int box_count = mu_doc.GetLinksPage(k); + List<RectList> links = new List<RectList>(); + if (box_count > 0) + { + for (int j = 0; j < box_count; j++) + { + Point top_left; + Size size; + String uri; + int type; + int topage; + + mu_doc.GetLinkItem(j, out top_left, out size, out uri, + out topage, out type); + var rectlist = new RectList(); + rectlist.Height = size.Height * m_doczoom; + rectlist.Width = size.Width * m_doczoom; + rectlist.X = top_left.X * m_doczoom; + rectlist.Y = top_left.Y * m_doczoom; + rectlist.Color = m_linkcolor; + rectlist.Index = k.ToString() + "." + j.ToString(); + rectlist.PageNum = topage; + rectlist.Scale = m_doczoom; + if (uri != null) + rectlist.Urilink = new Uri(uri); + rectlist.Type = (Link_t)type; + links.Add(rectlist); + } + } + mu_doc.ReleaseLink(); + m_page_link_list.Add(links); + + if (worker.CancellationPending == true) + { + e.Cancel = true; + break; + } + } + } + + private void LinkCompleted(object sender, RunWorkerCompletedEventArgs e) + { + LinksOn(); + } + + private void ScaleLinkBox(int pagenum) + { + var temp = m_docPages[pagenum].LinkBox; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = m_doczoom / temp[kk].Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = m_doczoom; + temp[kk].PageRefresh(); + } + m_docPages[pagenum].LinkBox = temp; + } + /* Merge these */ + private void ScaleTextLines(int pagenum, double scale_factor) + { + var temp = m_lineptrs[pagenum]; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = scale_factor / temp[kk].Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = scale_factor; + } + m_lineptrs[pagenum] = temp; + } + + private void ScaleTextBlocks(int pagenum, double scale_factor) + { + var temp = m_textptrs[pagenum]; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = scale_factor / temp[kk].Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = scale_factor; + } + m_textptrs[pagenum] = temp; + } + + private int GetVisibleRange() + { + /* Need to figure out what pages are going to be visible */ + double bottom = this.ActualHeight; + bool done = false; + int final_page = m_currpage; + double count = 0; + + while (!done) + { + count = count + m_thumbnails[final_page].NativeHeight * m_doczoom; + final_page = final_page + 1; + if (final_page == m_num_pages || count > bottom) + done = true; + } + return final_page; + } + + /* Only visible pages */ + private void LinksOff() + { + int final_page = GetVisibleRange(); + for (int kk = m_currpage - 1; kk <= final_page + 1; kk++) + { + var temp = m_docPages[kk].LinkBox; + if (temp != null) + { + m_docPages[kk].LinkBox = null; + } + } + } + + /* Only visible pages */ + private void LinksOn() + { + int final_page = GetVisibleRange(); + for (int kk = m_currpage - 1; kk <= final_page + 1; kk++) + { + if (!(kk < 0 || kk > m_num_pages - 1)) + { + var temp = m_docPages[kk].LinkBox; + if (temp == null) + { + m_docPages[kk].LinkBox = m_page_link_list[kk]; + } + } + } + } + + private void LinkClick(object sender, MouseButtonEventArgs e) + { + var item = (Rectangle)sender; + + if (item == null) + return; + + String tag = (String)item.Tag; + int page = 0; + int index = 0; + + if (tag == null || tag.Length < 3 || !(tag.Contains('.'))) + return; + + String[] parts = tag.Split('.'); + try + { + page = System.Convert.ToInt32(parts[0]); + index = System.Convert.ToInt32(parts[1]); + + } + catch (FormatException e1) + { + Console.WriteLine("String is not a sequence of digits."); + } + catch (OverflowException e2) + { + Console.WriteLine("The number cannot fit in an Int32."); + } + + if (index >= 0 && index < m_num_pages && page >= 0 && page < m_num_pages) + { + var link_list = m_page_link_list[page]; + var link = link_list[index]; + + if (link.Type == Link_t.LINK_GOTO) + { + if (m_currpage != link.PageNum && link.PageNum >= 0 && + link.PageNum < m_num_pages) + RenderRange(link.PageNum, true, zoom_t.NO_ZOOM, 0); + } + else if (link.Type == Link_t.LINK_URI) + System.Diagnostics.Process.Start(link.Urilink.AbsoluteUri); + } + } + #endregion Link + + #region TextSelection + + /* Change cursor if we are over text block */ + private void ExitTextBlock(object sender, System.Windows.Input.MouseEventArgs e) + { + this.Cursor = System.Windows.Input.Cursors.Arrow; + } + + private void EnterTextBlock(object sender, System.Windows.Input.MouseEventArgs e) + { + this.Cursor = System.Windows.Input.Cursors.IBeam; + } + + private void ClearSelections() + { + for (int kk = 0; kk < m_textSelect.Count; kk++) + { + m_lineptrs[m_textSelect[kk].pagenum].Clear(); + if (m_docPages[m_textSelect[kk].pagenum].SelectedLines != null) + m_docPages[m_textSelect[kk].pagenum].SelectedLines.Clear(); + } + m_textSelect.Clear(); + m_textselected = false; + m_selectall = false; + SetSelectAll(m_blockcolor); + } + + private void InitTextSelection(DocPage page) + { + if (m_textSelect != null) + ClearSelections(); + else + m_textSelect = new List<textSelectInfo_t>(); + + m_intxtselect = true; + + textSelectInfo_t selinfo = new textSelectInfo_t(); + selinfo.pagenum = page.PageNum; + selinfo.first_line_full = false; + selinfo.last_line_full = false; + m_textSelect.Add(selinfo); + } + + private void PageMouseDown(object sender, MouseButtonEventArgs e) + { + if (this.Cursor != System.Windows.Input.Cursors.IBeam) + return; + + var page = ((FrameworkElement)e.Source).DataContext as DocPage; + Canvas can = ((FrameworkElement)e.Source).Parent as Canvas; + if (page == null || can == null) + return; + + InitTextSelection(page); + var posit = e.GetPosition(can); + + page.SelX = posit.X; + page.SelY = posit.Y; + page.SelAnchorX = posit.X; + page.SelAnchorY = posit.Y; + page.SelColor = m_regionselect; + + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + } + + private void PageMouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + if (e.LeftButton == MouseButtonState.Released || m_intxtselect == false) + return; + + var page = ((FrameworkElement)e.Source).DataContext as DocPage; + Canvas can = ((FrameworkElement)e.Source).Parent as Canvas; + if (page == null || can == null) + return; + if (page.PageNum < 0) + return; + /* Store the location of our most recent page in case we exit window */ + var pos = e.GetPosition(can); + m_lastY = pos.Y; + m_maxY = can.Height; + /* Don't allow the listview to maintain control of the mouse, we need + * to detect if we leave the window */ + /* Make sure page is rendered */ + if (page.Content != Page_Content_t.FULL_RESOLUTION || + page.Zoom != m_doczoom) + { + RenderRange(page.PageNum, false, zoom_t.NO_ZOOM, 0); + } + + UpdateSelection(pos, page); + } + + /* Resize selection rect */ + private void UpdateSelection(System.Windows.Point pos, DocPage page) + { + bool new_page = true; + TextLine start_line, end_line; + double x = 0, y, w = 0, h; + bool found_first = false; + bool above_anchor = true; + bool first_line_full = false; + bool last_line_full = false; + + for (int kk = 0; kk < m_textSelect.Count; kk++) + if (m_textSelect[kk].pagenum == page.PageNum) + new_page = false; + + /* See if we have gone back to a previous page */ + if (!new_page && page.PageNum != m_textSelect[m_textSelect.Count - 1].pagenum) + { + DocPage curr_page = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum]; + curr_page.SelHeight = 0; + curr_page.SelWidth = 0; + m_textSelect.RemoveAt(m_textSelect.Count - 1); + m_lineptrs[curr_page.PageNum].Clear(); + curr_page.SelectedLines.Clear(); + } + if (new_page) + { + /* New page */ + page.SelX = pos.X; + page.SelY = pos.Y; + page.SelAnchorX = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum].SelAnchorX; + if (m_textSelect[m_textSelect.Count - 1].pagenum > page.PageNum) + { + page.SelAnchorY = page.Height; + } + else + { + page.SelAnchorY = 0; + } + page.SelColor = m_regionselect; + textSelectInfo_t info = new textSelectInfo_t(); + info.pagenum = page.PageNum; + info.first_line_full = false; + info.last_line_full = false; + m_textSelect.Add(info); + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + } + + if (page.TextBlocks == null || page.TextBlocks.Count == 0) + return; + + /* Width changes translate across the pages */ + for (int jj = 0; jj < m_textSelect.Count; jj++) + { + DocPage curr_page = m_docPages[m_textSelect[jj].pagenum]; + x = Math.Min(pos.X, curr_page.SelAnchorX); + w = Math.Max(pos.X, curr_page.SelAnchorX) - x; + curr_page.SelX = x; + curr_page.SelWidth = w; + } + /* Height is just the current page */ + y = Math.Min(pos.Y, page.SelAnchorY); + h = Math.Max(pos.Y, page.SelAnchorY) - y; + + /* Determine if we are going up or down */ + if (pos.Y > page.SelAnchorY) + above_anchor = false; + page.SelY = y; + page.SelHeight = h; + + /* Clear out what we currently have */ + m_lineptrs[page.PageNum].Clear(); + + /* Stuff already selected above us */ + if (m_textSelect.Count > 1) + found_first = true; + /* Moving backwards through pages */ + if (m_textSelect.Count > 1 && m_textSelect[m_textSelect.Count - 2].pagenum > page.PageNum) + found_first = false; + + for (int jj = 0; jj < page.TextBlocks.Count; jj++) + { + /* Text blocks are already scaled. Lines are not */ + var intersect_blk = page.TextBlocks[jj].CheckIntersection(x, y, w, h); + var lines = page.TextBlocks[jj].TextLines; + + if (intersect_blk == Intersection_t.FULL) + { + /* Just add all the lines for this block */ + for (int kk = 0; kk < lines.Count; kk++) + m_lineptrs[page.PageNum].Add(lines[kk]); + if (jj == 0) + { + first_line_full = true; + found_first = true; + } + if (jj == page.TextBlocks.Count - 1) + last_line_full = true; + } + else if (intersect_blk != Intersection_t.NONE) + { + /* Now go through the lines */ + for (int kk = 0; kk < lines.Count; kk++) + { + double scale = m_doczoom / lines[kk].Scale; + //var intersect_line = lines[kk].CheckIntersection(x * scale, y * scale, w * scale, h * scale); + var intersect_line = lines[kk].CheckIntersection(x / scale , y / scale , w / scale , h / scale); + if (intersect_line == Intersection_t.FULL) + { + m_lineptrs[page.PageNum].Add(lines[kk]); + found_first = true; + if (jj == 0 && kk == 0) + first_line_full = true; + if (jj == page.TextBlocks.Count - 1 && + kk == lines.Count - 1) + last_line_full = true; + + } + else if (intersect_line == Intersection_t.PARTIAL) + { + double val; + var lett = lines[kk].TextCharacters; + + /* Now go through the width. */ + if (found_first) + { + if (above_anchor) + val = page.SelAnchorX; + else + val = pos.X; + + /* our second partial line */ + if (val > lines[kk].X * scale + lines[kk].Width * scale) + m_lineptrs[page.PageNum].Add(lines[kk]); + else + { + /* Use either anchor point or mouse pos */ + end_line = new TextLine(); + end_line.TextCharacters = new List<TextCharacter>(); + end_line.Height = 0; + end_line.Scale = m_doczoom; + for (int mm = 0; mm < lett.Count; mm++) + { + double letscale = m_doczoom / lett[mm].Scale; + if (lett[mm].X * letscale < val) + { + /* Can set to special color for debug */ + end_line.Color = m_textselectcolor; + /* special color for debug */ + //end_line.Color = "#4000FF00"; + end_line.Height = lines[kk].Height * scale; + end_line.Width = lett[mm].X * letscale + lett[mm].Width * letscale - lines[kk].X * scale; + end_line.Y = lines[kk].Y * scale; + end_line.X = lines[kk].X * scale; + end_line.TextCharacters.Add(lett[mm]); + } + else + break; + } + if (end_line.Height != 0) + m_lineptrs[page.PageNum].Add(end_line); + } + } + else + { + if (!above_anchor) + val = page.SelAnchorX; + else + val = pos.X; + + /* our first partial line */ + found_first = true; + if (val < lines[kk].X * scale) + m_lineptrs[page.PageNum].Add(lines[kk]); + else + { + start_line = new TextLine(); + start_line.TextCharacters = new List<TextCharacter>(); + start_line.Height = 0; + start_line.Scale = m_doczoom; + /* Use either anchor point or mouse pos */ + bool highlight_done = false; + for (int mm = 0; mm < lett.Count; mm++) + { + double letscale = m_doczoom / lett[mm].Scale; + if (lett[mm].X * letscale + lett[mm].Width * letscale >= val) + { + /* In this case, we are done with the + * highlight section as it only + * depends upon the first character + * we encounter and the line end. + * But we must continue to add in + * the selected characters */ + if (!highlight_done) + { + start_line.Color = m_textselectcolor; + /* special color for debug */ + /* start_line.Color = "#40FF0000"; */ + start_line.Height = lines[kk].Height * scale; + start_line.Width = lines[kk].X * scale + lines[kk].Width * scale - lett[mm].X * letscale; + start_line.X = lett[mm].X * letscale; + start_line.Y = lines[kk].Y * scale; + highlight_done = true; + } + start_line.TextCharacters.Add(lett[mm]); + } + } + if (start_line.Height > 0) + m_lineptrs[page.PageNum].Add(start_line); + } + } + } + } + } + } + var txtsel = m_textSelect[m_textSelect.Count - 1]; + txtsel.first_line_full = first_line_full; + txtsel.last_line_full = last_line_full; + m_textSelect[m_textSelect.Count - 1] = txtsel; + + /* Adjust for scale before assigning */ + var temp = m_lineptrs[page.PageNum]; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = m_doczoom / rect_item.Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = m_doczoom; + } + page.SelectedLines = m_lineptrs[page.PageNum]; + } + + /* A fix for handling column cases TODO FIXME */ + private void UpdateSelectionCol(System.Windows.Point pos, DocPage page) + { + bool new_page = true; + TextLine start_line, end_line; + double x = 0, y, w = 0, h; + bool found_first = false; + bool above_anchor = true; + bool first_line_full = false; + bool last_line_full = false; + + for (int kk = 0; kk < m_textSelect.Count; kk++) + if (m_textSelect[kk].pagenum == page.PageNum) + new_page = false; + + /* See if we have gone back to a previous page */ + if (!new_page && page.PageNum != m_textSelect[m_textSelect.Count - 1].pagenum) + { + DocPage curr_page = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum]; + curr_page.SelHeight = 0; + curr_page.SelWidth = 0; + m_textSelect.RemoveAt(m_textSelect.Count - 1); + m_lineptrs[curr_page.PageNum].Clear(); + curr_page.SelectedLines.Clear(); + } + if (new_page) + { + /* New page */ + page.SelX = pos.X; + page.SelY = pos.Y; + page.SelAnchorX = m_docPages[m_textSelect[m_textSelect.Count - 1].pagenum].SelAnchorX; + if (m_textSelect[m_textSelect.Count - 1].pagenum > page.PageNum) + { + page.SelAnchorY = page.Height; + } + else + { + page.SelAnchorY = 0; + } + page.SelColor = m_regionselect; + textSelectInfo_t info = new textSelectInfo_t(); + info.pagenum = page.PageNum; + info.first_line_full = false; + info.last_line_full = false; + m_textSelect.Add(info); + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + } + + if (page.TextBlocks == null || page.TextBlocks.Count == 0) + return; + + /* Width changes translate across the pages */ + for (int jj = 0; jj < m_textSelect.Count; jj++) + { + DocPage curr_page = m_docPages[m_textSelect[jj].pagenum]; + x = Math.Min(pos.X, curr_page.SelAnchorX); + w = Math.Max(pos.X, curr_page.SelAnchorX) - x; + curr_page.SelX = x; + curr_page.SelWidth = w; + } + /* Height is just the current page */ + y = Math.Min(pos.Y, page.SelAnchorY); + h = Math.Max(pos.Y, page.SelAnchorY) - y; + + /* Determine if we are going up or down */ + if (pos.Y > page.SelAnchorY) + above_anchor = false; + page.SelY = y; + page.SelHeight = h; + + /* Clear out what we currently have */ + m_lineptrs[page.PageNum].Clear(); + + /* Stuff already selected above us */ + if (m_textSelect.Count > 1) + found_first = true; + /* Moving backwards through pages */ + if (m_textSelect.Count > 1 && m_textSelect[m_textSelect.Count - 2].pagenum > page.PageNum) + found_first = false; + + /* To properly handle the multiple columns we have to find the last + * line and make sure that all blocks between our first and last + * line are included. To do this we do an initial step through the + * blocks looking at our intersections */ + int first_block = -1; + int last_block = -1; + for (int jj = 0; jj < page.TextBlocks.Count; jj++ ) + { + var intersect_blk = page.TextBlocks[jj].CheckIntersection(x, y, w, h); + if (intersect_blk == Intersection_t.NONE && first_block != -1) + { + last_block = jj; /* NB: this is just past last block */ + break; + } + else if (intersect_blk != Intersection_t.NONE && first_block == -1) + first_block = jj; /* NB: this is the first block */ + } + if (first_block == -1) + return; + if (last_block == -1) + { + /* Only 1 block */ + last_block = first_block + 1; + } + + for (int jj = first_block; jj < last_block; jj++) + { + /* Text blocks are already scaled. Lines are not */ + var intersect_blk = page.TextBlocks[jj].CheckIntersection(x, y, w, h); + var lines = page.TextBlocks[jj].TextLines; + + if (jj == first_block || jj == last_block - 1) + { + /* Partial cases */ + if (intersect_blk == Intersection_t.FULL) + { + for (int kk = 0; kk < lines.Count; kk++) + m_lineptrs[page.PageNum].Add(lines[kk]); + if (jj == first_block) + { + first_line_full = true; + found_first = true; + } + if (jj == last_block - 1) + { + last_line_full = true; + } + } + else if (intersect_blk == Intersection_t.PARTIAL) + { + for (int kk = 0; kk < lines.Count; kk++) + { + double scale = m_doczoom / lines[kk].Scale; + var intersect_line = lines[kk].CheckIntersection(x * scale, y * scale, w * scale, h * scale); + if (intersect_line == Intersection_t.FULL) + { + m_lineptrs[page.PageNum].Add(lines[kk]); + found_first = true; + if (jj == 0 && kk == 0) + first_line_full = true; + if (jj == page.TextBlocks.Count - 1 && + kk == lines.Count - 1) + last_line_full = true; + + } + else if (intersect_line == Intersection_t.PARTIAL) + { + double val; + var lett = lines[kk].TextCharacters; + + /* Now go through the width. */ + if (found_first) + { + if (above_anchor) + val = page.SelAnchorX; + else + val = pos.X; + + /* our second partial line */ + if (val > lines[kk].X * scale + lines[kk].Width * scale) + m_lineptrs[page.PageNum].Add(lines[kk]); + else + { + /* Use either anchor point or mouse pos */ + end_line = new TextLine(); + end_line.TextCharacters = new List<TextCharacter>(); + end_line.Height = 0; + end_line.Scale = m_doczoom; + for (int mm = 0; mm < lett.Count; mm++) + { + double letscale = m_doczoom / lett[mm].Scale; + if (lett[mm].X * letscale < val) + { + /* Can set to special color for debug */ + end_line.Color = m_textselectcolor; + /* special color for debug */ + //end_line.Color = "#4000FF00"; + end_line.Height = lines[kk].Height * scale; + end_line.Width = lett[mm].X * letscale + lett[mm].Width * letscale - lines[kk].X * scale; + end_line.Y = lines[kk].Y * scale; + end_line.X = lines[kk].X * scale; + end_line.TextCharacters.Add(lett[mm]); + } + else + break; + } + if (end_line.Height != 0) + m_lineptrs[page.PageNum].Add(end_line); + } + } + else + { + if (!above_anchor) + val = page.SelAnchorX; + else + val = pos.X; + + /* our first partial line */ + found_first = true; + if (val < lines[kk].X * scale) + m_lineptrs[page.PageNum].Add(lines[kk]); + else + { + start_line = new TextLine(); + start_line.TextCharacters = new List<TextCharacter>(); + start_line.Height = 0; + start_line.Scale = m_doczoom; + /* Use either anchor point or mouse pos */ + for (int mm = 0; mm < lett.Count; mm++) + { + double letscale = m_doczoom / lett[mm].Scale; + if (lett[mm].X * letscale + lett[mm].Width * letscale >= val) + { + start_line.Color = m_textselectcolor; + /* special color for debug */ + //start_line.Color = "#40FF0000"; + start_line.Height = lines[kk].Height * scale; + start_line.Width = lines[kk].X * scale + lines[kk].Width * scale - lett[mm].X * letscale; + start_line.X = lett[mm].X * letscale; + start_line.Y = lines[kk].Y * scale; + start_line.TextCharacters.Add(lett[mm]); + break; + } + } + if (start_line.Height > 0) + m_lineptrs[page.PageNum].Add(start_line); + } + } + } + } + } + } + else + { + /* Add all the lines for the blocks between the first and last */ + for (int kk = 0; kk < lines.Count; kk++) + m_lineptrs[page.PageNum].Add(lines[kk]); + } + } + + var txtsel = m_textSelect[m_textSelect.Count - 1]; + txtsel.first_line_full = first_line_full; + txtsel.last_line_full = last_line_full; + m_textSelect[m_textSelect.Count - 1] = txtsel; + + /* Adjust for scale before assigning */ + var temp = m_lineptrs[page.PageNum]; + for (int kk = 0; kk < temp.Count; kk++) + { + var rect_item = temp[kk]; + double factor = m_doczoom / rect_item.Scale; + + temp[kk].Height = temp[kk].Height * factor; + temp[kk].Width = temp[kk].Width * factor; + temp[kk].X = temp[kk].X * factor; + temp[kk].Y = temp[kk].Y * factor; + + temp[kk].Scale = m_doczoom; + } + page.SelectedLines = m_lineptrs[page.PageNum]; + } + + private void CheckIfSelected() + { + m_textselected = false; + + if (m_selectall) + { + SetSelectAll(m_blockcolor); + m_selectall = false; + } + /* Check if anything was selected */ + for (int kk = 0; kk < m_lineptrs.Count; kk++) + { + if (m_lineptrs[kk].Count > 0) + { + m_textselected = true; + break; + } + } + } + + /* Rect should be removed */ + private void PageLeftClickUp(object sender, MouseButtonEventArgs e) + { + m_intxtselect = false; + CheckIfSelected(); + } + + private void StepScroll(int stepsize) + { + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + { + var scrollpos = viewer.VerticalOffset; + viewer.ScrollToVerticalOffset(scrollpos + stepsize); + } + } + + private void ResetScroll() + { + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer != null) + viewer.ScrollToVerticalOffset(0); + } + + /* Recursive call to find the scroll viewer */ + private ScrollViewer FindScrollViewer(DependencyObject d) + { + if (d is ScrollViewer) + return d as ScrollViewer; + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++) + { + var sw = FindScrollViewer(VisualTreeHelper.GetChild(d, i)); + if (sw != null) return sw; + } + return null; + } + + /* Only worry about cases where we are moving and left button is down */ + private void ListPreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + var relPoint = e.GetPosition(xaml_PageList); + var absPoint = this.PointToScreen(relPoint); + /* Console.Write("abs Y position = " + absPoint.Y + "\n"); + Console.Write("rel Y position = " + relPoint.Y + "\n"); + Console.Write("Height is = " + (this.Top + this.Height) + "\n"); */ + + if (xaml_PageList.IsMouseCaptured == true) + { + if (!m_intxtselect) + { + xaml_PageList.ReleaseMouseCapture(); + e.Handled = true; + return; + } + + if (relPoint.Y < Constants.SCROLL_EDGE_BUFFER || + absPoint.Y > (this.Top + this.Height - Constants.SCROLL_EDGE_BUFFER)) + { + if (m_dispatcherTimer == null) + { + m_dispatcherTimer = new System.Windows.Threading.DispatcherTimer(); + m_dispatcherTimer.Tick += new EventHandler(dispatcherTimerTick); + m_dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, Constants.DISPATCH_TIME); + } + if (m_dispatcherTimer.IsEnabled == false) + m_dispatcherTimer.Start(); + e.Handled = true; + } + + /* This is not desirable, but the scrollviewer behaves badly + * when it has captured the mouse and we move beyond the + * range. So we wont allow it */ + if (relPoint.Y < 0 || + absPoint.Y > (this.Top + this.Height) - Constants.SCROLL_EDGE_BUFFER / 2.0) + { + xaml_PageList.ReleaseMouseCapture(); + e.Handled = true; + if (m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled == true) + m_dispatcherTimer.Stop(); + return; + } + } + } + + private void ListPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled) + { + m_dispatcherTimer.Stop(); + } + } + + private void ListMouseLeave(object sender, System.Windows.Input.MouseEventArgs e) + { + if (m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled) + { + m_dispatcherTimer.Stop(); + } + if (xaml_PageList.IsMouseCaptured == true) + xaml_PageList.ReleaseMouseCapture(); + } + + /* Get mouse position, update selection accordingly */ + private void dispatcherTimerTick(object sender, EventArgs e) + { + var position = this.PointToScreen(Mouse.GetPosition(xaml_PageList)); + /* Console.Write("Y position = " + position.Y + "\n"); + Console.Write("Top position = " + this.Top + "\n"); + Console.Write("Bottom position = " + (this.Top + this.Height) + "\n"); */ + DocPage page; + int page_num; + + if (!xaml_PageList.IsMouseCaptured) + { + //Console.Write("Lost capture\n"); + return; + } + /*else + { + Console.Write("Have capture\n"); + } */ + /* Get our most recent page */ + var pageinfo = m_textSelect[m_textSelect.Count - 1]; + page_num = pageinfo.pagenum; + + /* Scrolling up */ + if (position.Y > this.Top + this.Height - Constants.SCROLL_EDGE_BUFFER) + { + /* See if we have the last line for this page */ + if (pageinfo.last_line_full) + { + page_num = page_num + 1; + m_lastY = 0; + if (page_num >= m_num_pages) + return; + } + page = m_docPages[page_num]; + StepScroll(Constants.SCROLL_STEP); + /* Set position for proper selection update */ + m_lastY = m_lastY + Constants.SCROLL_STEP; + if (m_lastY > m_maxY) + m_lastY = m_maxY; + position.Y = m_lastY; + UpdateSelection(position, page); + } + else if (position.Y < this.Top + Constants.SCROLL_EDGE_BUFFER) + { + /* See if we have the first line for this page */ + if (pageinfo.first_line_full) + { + if (page_num <= 0) + return; + page_num = page_num - 1; + m_lastY = m_docPages[page_num].Height; + } + page = m_docPages[page_num]; + StepScroll(-Constants.SCROLL_STEP); + /* Set position for proper selection update */ + m_lastY = m_lastY - Constants.SCROLL_STEP; + if (m_lastY < 0) + m_lastY = 0; + position.Y = m_lastY; + UpdateSelection(position, page); + } + } + + private void ListPreviewLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (m_dispatcherTimer != null && m_dispatcherTimer.IsEnabled) + { + m_dispatcherTimer.Stop(); + } + } + + private void ShowContextMenu(object sender, MouseButtonEventArgs e) + { + if (this.Cursor != System.Windows.Input.Cursors.IBeam) + return; + + var contextmenu = new System.Windows.Controls.ContextMenu(); + Canvas can = ((FrameworkElement)e.Source).Parent as Canvas; + var page = ((FrameworkElement)e.Source).DataContext as DocPage; + if (can == null || page == null) + return; + + var posit = e.GetPosition(can); + ContextMenu_t info = new ContextMenu_t(); + info.mouse_position = posit; + info.page_num = page.PageNum; + can.ContextMenu = contextmenu; + + if (m_textselected || m_selectall) + { + var m1 = new System.Windows.Controls.MenuItem(); + m1.Header = "Copy"; + + /* amazing what I have to do here to get the icon out of the + * resources into something that wpf can use */ + var iconres = Properties.Resources.copy; + var bitmap = iconres.ToBitmap(); + using (MemoryStream memory = new MemoryStream()) + { + bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png); + memory.Position = 0; + BitmapImage bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memory; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + Image iconImage = new Image(); + iconImage.Source = bitmapImage; + m1.Icon = iconImage; + m1.Click += cntxMenuCopy; + contextmenu.Items.Add(m1); + } + + var m6 = new System.Windows.Controls.MenuItem(); + m6.Header = "Deselect All"; + m6.Click += cntxMenuDeselectAll; + contextmenu.Items.Add(m6); + + /* Below to be enabled when we add annotations */ + /* + var ma1 = new System.Windows.Controls.MenuItem(); + ma1.Header = "Highlight"; + ma1.Click += cntxMenuHighlight; + contextmenu.Items.Add(ma1); + + var ma2 = new System.Windows.Controls.MenuItem(); + ma2.Header = "Underline"; + ma2.Click += cntxMenuUnderline; + contextmenu.Items.Add(ma2); + + var ma3 = new System.Windows.Controls.MenuItem(); + ma3.Header = "Strikeout"; + ma3.Click += cntxMenuStrike; + contextmenu.Items.Add(ma3);*/ + + } + var m2 = new System.Windows.Controls.MenuItem(); + m2.Header = "Select Line"; + m2.Click += cntxMenuSelectLine; + m2.Tag = info; + contextmenu.Items.Add(m2); + + var m3 = new System.Windows.Controls.MenuItem(); + m3.Header = "Select Block"; + m3.Click += cntxMenuSelectBlock; + m3.Tag = info; + contextmenu.Items.Add(m3); + + var m4 = new System.Windows.Controls.MenuItem(); + m4.Header = "Select Page"; + m4.Click += cntxMenuSelectPage; + m4.Tag = info; + contextmenu.Items.Add(m4); + + var m5 = new System.Windows.Controls.MenuItem(); + m5.Header = "Select All"; + m5.Click += cntxMenuSelectAll; + contextmenu.Items.Add(m5); + } + + private void CopyTextDone(object sender, RunWorkerCompletedEventArgs e) + { + String result = (String) e.Result; + xaml_CopyTextProgress.Visibility = System.Windows.Visibility.Collapsed; + xaml_CopyTextProgress.Value = 0; + + try + { + System.Windows.Clipboard.SetText(result); + } + catch + { + return; + } + } + + private void CopyTextWork(object sender, DoWorkEventArgs e) + { + String output = null; + String fullstring = null; + BackgroundWorker worker = sender as BackgroundWorker; + + for (int k = 0; k < m_num_pages; k++) + { + output = mu_doc.GetText(k, textout_t.TEXT); + if (output != null) + fullstring = fullstring + output; + + double percent = 100 * (double)(k + 1) / (double)m_num_pages; + worker.ReportProgress((int)percent, output); + + if (worker.CancellationPending == true) + { + e.Cancel = true; + break; + } + } + e.Result = fullstring; + } + + private void CopyTextProgress(object sender, ProgressChangedEventArgs e) + { + String output = (String)(e.UserState); + xaml_CopyTextProgress.Value = e.ProgressPercentage; + } + + private void cntxMenuCopy(object sender, RoutedEventArgs e) + { + if (m_selectall) + { + /* Start a thread to go through and copy the pages to the + * clipboard */ + m_copytext = new BackgroundWorker(); + m_copytext.WorkerReportsProgress = true; + m_copytext.WorkerSupportsCancellation = true; + m_copytext.DoWork += new DoWorkEventHandler(CopyTextWork); + m_copytext.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CopyTextDone); + m_copytext.ProgressChanged += new ProgressChangedEventHandler(CopyTextProgress); + xaml_CopyTextProgress.Visibility = System.Windows.Visibility.Visible; + m_copytext.RunWorkerAsync(); + return; + } + + /* Go through and get each line of text */ + String result = null; + + for (int kk = 0; kk < m_textSelect.Count; kk++) + { + var lines = m_lineptrs[m_textSelect[kk].pagenum]; + for (int jj = 0; jj < lines.Count; jj++) + { + var text = lines[jj].TextCharacters; + for (int mm = 0; mm < text.Count; mm++) + { + result += text[mm].character; + } + result += "\r\n"; + } + } + System.Windows.Clipboard.SetText(result); + } + + private void cntxMenuSelectLine(object sender, RoutedEventArgs e) + { + var mi = sender as System.Windows.Controls.MenuItem; + ContextMenu_t info = (ContextMenu_t)mi.Tag; + var page = m_docPages[info.page_num]; + + InitTextSelection(page); + + page.SelX = 0; + page.SelY = info.mouse_position.Y - 1; + page.SelAnchorX = 0; + page.SelAnchorY = info.mouse_position.Y - 1; + page.SelColor = m_regionselect; + + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + + Point pos = new Point(); + pos.X = page.Width; + pos.Y += info.mouse_position.Y + 1; + + UpdateSelection(pos, page); + CheckIfSelected(); + } + + /* This one requires its own special handling TODO FIXME */ + private void cntxMenuSelectBlock(object sender, RoutedEventArgs e) + { + var mi = sender as System.Windows.Controls.MenuItem; + ContextMenu_t info = (ContextMenu_t)mi.Tag; + var page = m_docPages[info.page_num]; + bool found = false; + int jj; + + InitTextSelection(page); + + /* Find the block that we are in */ + for (jj = 0; jj < page.TextBlocks.Count; jj++) + { + var intersect_blk = page.TextBlocks[jj].CheckIntersection(info.mouse_position.X, info.mouse_position.Y, 1, 1); + if (intersect_blk != Intersection_t.NONE) + { + found = true; + break; + } + } + if (found) + { + page.SelX = page.TextBlocks[jj].X; + page.SelY = page.TextBlocks[jj].Y; + page.SelAnchorX = page.TextBlocks[jj].X; + page.SelAnchorY = page.TextBlocks[jj].Y; + page.SelColor = m_regionselect; + + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + + Point pos = new Point(); + pos.X = page.TextBlocks[jj].X + page.TextBlocks[jj].Width; + pos.Y = page.TextBlocks[jj].Y + page.TextBlocks[jj].Height; + + UpdateSelection(pos, page); + CheckIfSelected(); + } + else + m_textselected = false; + } + + private void SelectFullPage(int page_num) + { + var page = m_docPages[page_num]; + + InitTextSelection(page); + + page.SelX = 0; + page.SelY = 0; + page.SelAnchorX = 0; + page.SelAnchorY = 0; + page.SelColor = m_regionselect; + + /* Create new holder for lines highlighted */ + m_lineptrs[page.PageNum] = new LinesText(); + + Point pos = new Point(); + pos.X = page.Width; + pos.Y = page.Height; + + UpdateSelection(pos, page); + } + + private void cntxMenuSelectPage(object sender, RoutedEventArgs e) + { + var mi = sender as System.Windows.Controls.MenuItem; + ContextMenu_t info = (ContextMenu_t)mi.Tag; + + SelectFullPage(info.page_num); + CheckIfSelected(); + } + + private void cntxMenuSelectAll(object sender, RoutedEventArgs e) + { + var mi = sender as System.Windows.Controls.MenuItem; + if (m_textSelect != null) + ClearSelections(); + else + m_textSelect = new List<textSelectInfo_t>(); + + m_selectall = true; + SetSelectAll(m_textselectcolor); + } + + private void SetSelectAll(String color) + { + if (!m_init_done) + return; + + for (int kk = 0; kk < m_num_pages; kk++) + { + if (m_docPages[kk] != null && m_docPages[kk].TextBlocks != null) + { + int num_blocks = m_docPages[kk].TextBlocks.Count; + for (int jj = 0; jj < num_blocks; jj++) + m_docPages[kk].TextBlocks[jj].Color = color; + } + } + } + + private void cntxMenuDeselectAll(object sender, RoutedEventArgs e) + { + ClearSelections(); + } + + private void SelectAllCommand(object sender, ExecutedRoutedEventArgs e) + { + if (m_init_done) + cntxMenuSelectAll(sender, e); + } + + private void CopyCommand(object sender, ExecutedRoutedEventArgs e) + { + if (m_init_done) + cntxMenuCopy(sender, e); + } + + private void CancelCopyText(object sender, RoutedEventArgs e) + { + if (m_copytext != null && m_copytext.IsBusy) + m_copytext.CancelAsync(); + } + + /* To add with annotation support */ + /* + private void cntxMenuHighlight(object sender, RoutedEventArgs e) + { + + } + + private void cntxMenuUnderline(object sender, RoutedEventArgs e) + { + + } + + private void cntxMenuStrike(object sender, RoutedEventArgs e) + { + + } + */ + #endregion TextSelection + + private void OnAboutClick(object sender, RoutedEventArgs e) + { + String muversion; + About about = new About(this); + var desc_static = about.Description; + String desc; + + /* Get our gs and mupdf version numbers to add to the description */ + mu_doc.GetVersion(out muversion); + if (muversion == null) + desc = desc_static + "\nMuPDF DLL: Not Found"; + else + { + if (mu_doc.is64bit) + { + desc = desc_static + "\nUsing MuPDF Version " + muversion + " 64 bit\n"; + } + else + { + desc = desc_static + "\nUsing MuPDF Version " + muversion + " 32 bit\n"; + } + } + String gs_vers = m_ghostscript.GetVersion(); + if (gs_vers == null) + desc = desc + "\nGhostscript DLL: Not Found"; + else + if (mu_doc.is64bit) + { + desc = desc + "\nGhostscript DLL: " + gs_vers + " 64 bit\n"; + } + else + { + desc = desc + "\nGhostscript DLL: " + gs_vers + " 64 bit\n"; + } + about.description.Text = desc; + about.ShowDialog(); + } + + private void HelpCommand(object sender, ExecutedRoutedEventArgs e) + { + OnHelpClick(sender, e); + } + + private void OnHelpClick(object sender, RoutedEventArgs e) + { + + } + + private void CloseFile(object sender, RoutedEventArgs e) + { + CleanUp(); + DimSelections(); + } + + private double GetTotalHeightZoom() + { + return m_totalpageheight * m_doczoom + (m_num_pages - 1) * Constants.PAGE_MARGIN; + } + + private double GetTotalHeightNoZoom() + { + return m_totalpageheight + (m_num_pages - 1) * Constants.PAGE_MARGIN; + } + + private double GetViewPortSize() + { + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + return viewer.ViewportHeight; + } + + private void SetThumbwidth() + { + double percent = GetViewPortSize() / GetTotalHeightZoom(); + double range = xaml_VerticalScroll.Maximum - xaml_VerticalScroll.Minimum; + xaml_VerticalScroll.SetThumbLength(percent * range); + } + + private void AdjustScrollPercent(double percent) + { + double curr_value = xaml_VerticalScroll.Value; + double range = xaml_VerticalScroll.Maximum; + double step = range * percent; + + xaml_VerticalScroll.Value = curr_value + step; + } + + /* Due to the scroll bar on the scroll viewer being wonky on its updating during zooming + * we have to do this ourselves */ + private void VerticalScroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e) + { + var mi = sender as System.Windows.Controls.Primitives.ScrollBar; + ScrollViewer viewer = FindScrollViewer(xaml_PageList); + if (viewer == null || mi == null) + return; + + m_ScrolledChanged = true; + + if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.ThumbTrack) + { + OffsetScrollPercent(mi.Value / mi.Maximum); + e.Handled = true; + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.First) + { + mi.Value = 0; + viewer.ScrollToTop(); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.Last) + { + mi.Value = mi.Maximum; + viewer.ScrollToBottom(); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.SmallDecrement) + { + OffsetScroll(-Constants.VERT_SCROLL_STEP * m_doczoom); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.SmallIncrement) + { + OffsetScroll(Constants.VERT_SCROLL_STEP * m_doczoom); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.LargeDecrement) + { + if (m_currpage == 0) + { + mi.Value = 0; + viewer.ScrollToTop(); + } + else + OnBackPageClick(null, null); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.LargeIncrement) + { + if (m_currpage == m_num_pages - 1) + { + mi.Value = mi.Maximum; + viewer.ScrollToBottom(); + } + else + OnForwardPageClick(null, null); + } + else if (e.ScrollEventType == System.Windows.Controls.Primitives.ScrollEventType.ThumbPosition) + { + OffsetScrollPercent(e.NewValue / mi.Maximum); + } + } + + private void OnAAChecked(object sender, RoutedEventArgs e) + { + var control = sender as System.Windows.Controls.Control; + string Name = control.Name; + + /* It would be nice to uncheck all and then recheck the one + * that we want to avoid the repeated code below, but that puts + * us in a infinite recursion with the call from the xaml Checked + * call */ + + switch (Name) + { + case "xaml_AA_High": + m_AA = AA_t.HIGH; + if (xaml_AA_MedHigh != null) + xaml_AA_MedHigh.IsChecked = false; + if (xaml_AA_Med != null) + xaml_AA_Med.IsChecked = false; + if (xaml_AA_Low != null) + xaml_AA_Low.IsChecked = false; + if (xaml_AA_None != null) + xaml_AA_None.IsChecked = false; + break; + case "xaml_AA_MedHigh": + m_AA = AA_t.MEDHIGH; + if (xaml_AA_High != null) + xaml_AA_High.IsChecked = false; + if (xaml_AA_Med != null) + xaml_AA_Med.IsChecked = false; + if (xaml_AA_Low != null) + xaml_AA_Low.IsChecked = false; + if (xaml_AA_None != null) + xaml_AA_None.IsChecked = false; + break; + case "xaml_AA_Med": + m_AA = AA_t.MED; + if (xaml_AA_High != null) + xaml_AA_High.IsChecked = false; + if (xaml_AA_MedHigh != null) + xaml_AA_MedHigh.IsChecked = false; + if (xaml_AA_Low != null) + xaml_AA_Low.IsChecked = false; + if (xaml_AA_None != null) + xaml_AA_None.IsChecked = false; + break; + case "xaml_AA_Low": + m_AA = AA_t.LOW; + if (xaml_AA_High != null) + xaml_AA_High.IsChecked = false; + if (xaml_AA_MedHigh != null) + xaml_AA_MedHigh.IsChecked = false; + if (xaml_AA_Med != null) + xaml_AA_Med.IsChecked = false; + if (xaml_AA_None != null) + xaml_AA_None.IsChecked = false; + break; + case "xaml_AA_None": + m_AA = AA_t.NONE; + if (xaml_AA_High != null) + xaml_AA_High.IsChecked = false; + if (xaml_AA_MedHigh != null) + xaml_AA_MedHigh.IsChecked = false; + if (xaml_AA_Med != null) + xaml_AA_Med.IsChecked = false; + if (xaml_AA_Low != null) + xaml_AA_Low.IsChecked = false; + break; + } + if (mu_doc != null) + mu_doc.SetAA(m_AA); + if (m_init_done) + RenderRange(m_currpage, false, zoom_t.NO_ZOOM, 0); + } + + private AA_t GetAA() + { + if (xaml_AA_High.IsChecked) + return AA_t.HIGH; + else if (xaml_AA_MedHigh.IsChecked) + return AA_t.MEDHIGH; + else if (xaml_AA_Med.IsChecked) + return AA_t.MED; + else if (xaml_AA_Low.IsChecked) + return AA_t.LOW; + else + return AA_t.NONE; + } + + private void SetAA(AA_t aa) + { + xaml_AA_High.IsChecked = false; + xaml_AA_MedHigh.IsChecked = false; + xaml_AA_Med.IsChecked = false; + xaml_AA_Low.IsChecked = false; + xaml_AA_None.IsChecked = false; + + switch (aa) + { + case AA_t.HIGH: + xaml_AA_High.IsChecked = true; + break; + case AA_t.MEDHIGH: + xaml_AA_MedHigh.IsChecked = true; + break; + case AA_t.MED: + xaml_AA_High.IsChecked = true; + break; + case AA_t.LOW: + xaml_AA_High.IsChecked = true; + break; + case AA_t.NONE: + xaml_AA_High.IsChecked = true; + break; + } + } + + private void AnnotationOn(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + m_showannot = true; + RenderRange(m_currpage, false, zoom_t.NO_ZOOM, 0); + } + + private void AnnotationOff(object sender, RoutedEventArgs e) + { + if (!m_init_done) + return; + m_showannot = false; + RenderRange(m_currpage, false, zoom_t.NO_ZOOM, 0); + } + } +}
\ No newline at end of file diff --git a/platform/windows/gsview/OutputIntent.xaml b/platform/windows/gsview/OutputIntent.xaml new file mode 100644 index 00000000..fdfb7e3c --- /dev/null +++ b/platform/windows/gsview/OutputIntent.xaml @@ -0,0 +1,50 @@ +<Window x:Class="gsview.OutputIntent" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="OutputIntent" Height="176" Width="338" + SizeToContent="Width"> + + <DockPanel LastChildFill="True" Margin="0,0,0,0"> + + <Grid Background="DarkGray" DockPanel.Dock="Bottom" > + <Button Width="50" Height="20" Click="ClickOK" Margin="0,5,0,5"> + <TextBlock>OK</TextBlock> + </Button> + </Grid> + + <Grid Background="DarkGray" DockPanel.Dock="Top" > + <Grid Background="DarkGray" Grid.Row="0" Grid.Column="0" Margin="25,15,25,0"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + + <Button Grid.Column="0" Grid.Row="0" Width="50" Height="20" Click="SelectGray" Margin="0,0,0,0"> + <TextBlock>Gray</TextBlock> + </Button> + <TextBox x:Name="xaml_gray" Grid.Column="1" Grid.Row="0" Background="DarkGray" Height="20" Margin="5,5,5,5" IsReadOnly="True" Text="Not Set" BorderBrush="Red"></TextBox> + + <Button Grid.Column="0" Grid.Row="1" Width="50" Height="20" Click="SelectRGB" Margin="0,0,0,0"> + <TextBlock>RGB</TextBlock> + </Button> + <TextBox x:Name="xaml_rgb" Grid.Column="1" Grid.Row="1" Background="DarkGray" Height="20" Margin="5,5,5,5" IsReadOnly="True" Text="Not Set" BorderBrush="Red"></TextBox> + + <Button Grid.Column="0" Grid.Row="2" Width="50" Height="20" Click="SelectCMYK" Margin="0,0,0,0"> + <TextBlock>CMYK</TextBlock> + </Button> + <TextBox x:Name="xaml_cmyk" Grid.Column="1" Grid.Row="2" Background="DarkGray" Height="20" Margin="5,5,5,5" IsReadOnly="True" Text="Not Set" BorderBrush="Red"></TextBox> + + + + + </Grid> + </Grid> + + + </DockPanel> +</Window> diff --git a/platform/windows/gsview/OutputIntent.xaml.cs b/platform/windows/gsview/OutputIntent.xaml.cs new file mode 100644 index 00000000..eb11f0f6 --- /dev/null +++ b/platform/windows/gsview/OutputIntent.xaml.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.Windows.Forms; + +namespace gsview +{ + public enum OutputIntent_t + { + GRAY, + RGB, + CMYK + } + + /// <summary> + /// Interaction logic for OutputIntent.xaml + /// </summary> + public partial class OutputIntent : Window + { + public String gray_icc; + public String rgb_icc; + public String cmyk_icc; + + public OutputIntent() + { + InitializeComponent(); + this.Closing += new System.ComponentModel.CancelEventHandler(FakeWindowClosing); + gray_icc = null; + rgb_icc = null; + cmyk_icc = null; + } + + void FakeWindowClosing(object sender, System.ComponentModel.CancelEventArgs e) + { + e.Cancel = true; + this.Hide(); + } + + public void RealWindowClosing() + { + this.Closing -= new System.ComponentModel.CancelEventHandler(FakeWindowClosing); + this.Close(); + } + + /* No error checking in here yet for making sure the profiles are of + * the right type and are valid */ + private void SelectGray(object sender, RoutedEventArgs e) + { + SetIntent(OutputIntent_t.GRAY); + } + + private void SelectRGB(object sender, RoutedEventArgs e) + { + SetIntent(OutputIntent_t.RGB); + } + + private void SelectCMYK(object sender, RoutedEventArgs e) + { + SetIntent(OutputIntent_t.CMYK); + } + + private void SetIntent(OutputIntent_t intent) + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "ICC Profile Files(*.icc;*.icm)|*.icc;*.icm"; + dlg.FilterIndex = 1; + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + switch(intent) + { + case OutputIntent_t.GRAY: + gray_icc = dlg.FileName; + this.xaml_gray.Text = gray_icc; + this.xaml_gray.BorderBrush = new SolidColorBrush(Colors.Green); + break; + case OutputIntent_t.RGB: + rgb_icc = dlg.FileName; + this.xaml_rgb.Text = rgb_icc; + this.xaml_rgb.BorderBrush = new SolidColorBrush(Colors.Green); + break; + case OutputIntent_t.CMYK: + cmyk_icc = dlg.FileName; + this.xaml_cmyk.Text = cmyk_icc; + this.xaml_cmyk.BorderBrush = new SolidColorBrush(Colors.Green); + break; + } + } + } + + private void ClickOK(object sender, RoutedEventArgs e) + { + this.Hide(); + } + } +} diff --git a/platform/windows/gsview/PageExtractSave.xaml b/platform/windows/gsview/PageExtractSave.xaml new file mode 100644 index 00000000..36f30324 --- /dev/null +++ b/platform/windows/gsview/PageExtractSave.xaml @@ -0,0 +1,59 @@ +<Window x:Class="gsview.PageExtractSave" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Extract/Rearrange Pages" Height="306" Width="282"> + + <DockPanel LastChildFill="True"> + <Grid x:Name="xaml_PageGrid" Width="100" Background="DarkGray" DockPanel.Dock="Left" Visibility="Visible"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + </Grid.RowDefinitions> + <TextBlock Grid.Column="0" Grid.Row="0" Margin="15,0,0,0"> + <Bold>Pages:</Bold> + </TextBlock> + <ListView Grid.Column="0" Grid.Row="1" x:Name="xaml_PageList" HorizontalAlignment="Stretch" + ScrollViewer.CanContentScroll="False" + Background="White" Margin="10,5,10,10" + PreviewMouseLeftButtonDown="ExtractLeftButtonDown" PreviewMouseLeftButtonUp="ExtractLeftButtonUp" + PreviewMouseMove="ExtractMouseMove" MouseLeave="ExtractMouseLeave" PreviewMouseRightButtonDown="RightButtonDown"> + <ListView.ItemTemplate> + <DataTemplate> + <StackPanel Margin="5,5,0,0" HorizontalAlignment="Left"> + <TextBlock TextWrapping="Wrap" Text="{Binding PageString}" FontFamily="Segoe UI" FontSize="11" /> + </StackPanel> + </DataTemplate> + </ListView.ItemTemplate> + </ListView> + </Grid> + + <Grid Background="DarkGray" Grid.Row="0" Grid.Column="1" Margin="0,0,0,0"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + <RowDefinition Height="Auto" /> + </Grid.RowDefinitions> + + <Button Grid.Column="0" Grid.Row="0" Width="70" Height="20" Name="xaml_AllPages" Click="AllPages" Margin="0,40,0,0"> + <TextBlock>All Pages</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="1" Width="70" Height="20" Name="xaml_EvenPages" Click="EvenPages" Margin="0,5,0,0"> + <TextBlock>Even Pages</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="2" Width="70" Height="20" Name="xaml_OddPages" Click="OddPages" Margin="0,5,0,0"> + <TextBlock>Odd Pages</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="3" Width="70" Height="20" Name="xaml_ReversePages" Click="Reverse" Margin="0,5,0,0"> + <TextBlock>Reverse</TextBlock> + </Button> + <Button Grid.Column="0" Grid.Row="4" Width="70" Height="20" Name="xaml_Extract" Click="ExtractPages" Margin="0,20,0,0"> + <TextBlock>Extract</TextBlock> + </Button> + <TextBlock Grid.Column="0" Grid.Row="5" Margin="0,20,0,0"> Use drag/drop to rearrange. <LineBreak /> Right click to delete from list. + <LineBreak /> Only selected pages extracted. </TextBlock> + </Grid> + </DockPanel> +</Window> diff --git a/platform/windows/gsview/PageExtractSave.xaml.cs b/platform/windows/gsview/PageExtractSave.xaml.cs new file mode 100644 index 00000000..e3985d17 --- /dev/null +++ b/platform/windows/gsview/PageExtractSave.xaml.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.ComponentModel; +using System.Collections.ObjectModel; + +namespace gsview +{ + public partial class PageExtractSave : Window + { + public List<SelectPage> Pages; + SelectPage selectedpage = null; + int dropafterposition; + bool putattop = false; + + /* Callback to Main */ + internal delegate void ExtractCallBackMain(object gsObject); + internal event ExtractCallBackMain ExtractMain; + + public PageExtractSave(int num_pages) + { + InitializeComponent(); + Pages = new List<SelectPage>(); + SetPageList(num_pages); + xaml_PageList.ItemsSource = Pages; + } + + private void AllPages(object sender, RoutedEventArgs e) + { + xaml_PageList.SelectAll(); + } + + public void SetPageList(int num_pages) + { + for (int k = 1; k < num_pages + 1; k++) + { + SelectPage Spage = new SelectPage(); + Spage.Page = k; + Spage.PageString = k; + Pages.Add(Spage); + } + } + + private void EvenPages(object sender, RoutedEventArgs e) + { + /* First check if any are selected */ + var item = xaml_PageList.SelectedItem; + + /* If none are selected then get all the evens. otherwise just get + * all the evens of the pages that have been selected */ + if (item == null) + { + /* Turn on the evens */ + for (int kk = 1; kk < Pages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = true; + } + else + { + /* Turn off any odds */ + for (int kk = 0; kk < Pages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = false; + } + } + + private void OddPages(object sender, RoutedEventArgs e) + { + /* First check if any are selected */ + var item = xaml_PageList.SelectedItem; + + /* If none are selected then get all the odds. otherwise just get + all the odds of the pages that have been selected */ + if (item == null) + { + /* Turn on the odds */ + for (int kk = 0; kk < Pages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = true; + } + else + { + /* Turn off any evens */ + for (int kk = 1; kk < Pages.Count; kk = kk + 2) + (xaml_PageList.ItemContainerGenerator.ContainerFromIndex(kk) as ListViewItem).IsSelected = false; + } + } + + private void ExtractPages(object sender, RoutedEventArgs e) + { + ExtractMain(this); + } + + private void ExtractLeftButtonDown(object sender, MouseButtonEventArgs e) + { + int index = GetCurrentIndex(); + if (index > -1 && index < Pages.Count) + selectedpage = Pages[index]; + } + + private void ExtractLeftButtonUp(object sender, MouseButtonEventArgs e) + { + /* Check if we have something selected */ + if (selectedpage == null) + { + Cursor = Cursors.Arrow; + return; + } + + Point posit = e.GetPosition(xaml_PageList); + dropafterposition = GetCurrentIndex(); + putattop = false; + + if (dropafterposition < 0) + { + /* Check if we are above or below */ + if (posit.Y < 0) + putattop = true; + else + dropafterposition = xaml_PageList.Items.Count - 1; + } + Cursor = Cursors.Arrow; + MoveItem(); + selectedpage = null; + } + + private void MoveItem() + { + if (putattop) + { + Pages.Remove(selectedpage); + Pages.Insert(0, selectedpage); + } + else + { + Pages.Remove(selectedpage); + Pages.Insert(dropafterposition, selectedpage); + } + xaml_PageList.Items.Refresh(); + } + + private void ExtractMouseMove(object sender, MouseEventArgs e) + { + if (Mouse.LeftButton == MouseButtonState.Pressed) + Cursor = Cursors.Hand; + } + + private void ExtractMouseLeave(object sender, MouseEventArgs e) + { + Cursor = Cursors.Arrow; + } + + private void RightButtonDown(object sender, MouseButtonEventArgs e) + { + var contextmenu = new System.Windows.Controls.ContextMenu(); + this.ContextMenu = contextmenu; + + var m1 = new System.Windows.Controls.MenuItem(); + m1.Header = "Delete"; + m1.Click += cntxDeleteItem; + contextmenu.Items.Add(m1); + } + + /* Delete all selected items */ + private void cntxDeleteItem(object sender, RoutedEventArgs e) + { + /* Go backwards */ + var temp = xaml_PageList.SelectedItems; + int max = temp.Count; ; + for (int i = 0; i < max; i++) + { + var item = temp[i]; + Pages.Remove((SelectPage)item); + } + xaml_PageList.Items.Refresh(); + } + + int GetCurrentIndex() + { + int index = -1; + for (int i = 0; i < this.xaml_PageList.Items.Count; ++i) + { + ListViewItem item = GetListViewItem(i); + if (item.IsMouseOver) + { + index = i; + break; + } + } + return index; + } + + ListViewItem GetListViewItem(int index) + { + if (this.xaml_PageList.ItemContainerGenerator.Status != + System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) + return null; + return this.xaml_PageList.ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem; + } + + private void Reverse(object sender, RoutedEventArgs e) + { + Pages.Reverse(); + xaml_PageList.Items.Refresh(); + } + } +} diff --git a/platform/windows/gsview/Password.xaml b/platform/windows/gsview/Password.xaml new file mode 100644 index 00000000..8692244f --- /dev/null +++ b/platform/windows/gsview/Password.xaml @@ -0,0 +1,15 @@ +<Window x:Class="gsview.Password" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Height="110" Width="306"> + <Grid Background="WhiteSmoke"> + + <StackPanel> + <Label Content="Password:" /> + <PasswordBox x:Name="xaml_Password" Width="150" /> + <Button Width="50" Height="20" Name="xaml_PasswordClick" Click="PasswordCheck" Margin="0,5,0,0" IsDefault="True"> + <TextBlock>OK</TextBlock> + </Button> + </StackPanel> + </Grid> +</Window> diff --git a/platform/windows/gsview/Password.xaml.cs b/platform/windows/gsview/Password.xaml.cs new file mode 100644 index 00000000..5c45200e --- /dev/null +++ b/platform/windows/gsview/Password.xaml.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace gsview +{ + /// <summary> + /// Interaction logic for Password.xaml + /// </summary> + public partial class Password : Window + { + /* Callback to Main */ + internal delegate void PassCallBackMain(object gsObject); + internal event PassCallBackMain PassUpdateMain; + + public Password() + { + InitializeComponent(); + } + + private void PasswordCheck(object sender, RoutedEventArgs e) + { + PassUpdateMain(this); + } + } +} diff --git a/platform/windows/gsview/Properties/AssemblyInfo.cs b/platform/windows/gsview/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..8bd14cda --- /dev/null +++ b/platform/windows/gsview/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GSview")] +[assembly: AssemblyDescription("GSview is a PDF, XPS, PS, and CBZ document viewer. It makes use of the MuPDF and Ghostscript rendering libraries to provide a number of features including conversion to other file formats. GSview was created and is maintained by Artifex Software Incorporated.\n")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Artifex Software Incorporated")] +[assembly: AssemblyProduct("GSview")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file +//inside a <PropertyGroup>. For example, if you are using US english +//in your source files, set the <UICulture> to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("6.0.0.0")] +[assembly: AssemblyFileVersion("6.0.0.0")] diff --git a/platform/windows/gsview/Properties/Resources.Designer.cs b/platform/windows/gsview/Properties/Resources.Designer.cs new file mode 100644 index 00000000..4fdb3c91 --- /dev/null +++ b/platform/windows/gsview/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace gsview.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("gsview.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// </summary> + public static System.Drawing.Icon Close { + get { + object obj = ResourceManager.GetObject("Close", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// </summary> + public static System.Drawing.Icon copy { + get { + object obj = ResourceManager.GetObject("copy", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + public static System.Drawing.Bitmap info { + get { + object obj = ResourceManager.GetObject("info", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + public static System.Drawing.Bitmap Message { + get { + object obj = ResourceManager.GetObject("Message", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + public static System.Drawing.Bitmap OpenFile { + get { + object obj = ResourceManager.GetObject("OpenFile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Byte[]. + /// </summary> + public static byte[] PDFA_def { + get { + object obj = ResourceManager.GetObject("PDFA_def", resourceCulture); + return ((byte[])(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Byte[]. + /// </summary> + public static byte[] PDFX_def { + get { + object obj = ResourceManager.GetObject("PDFX_def", resourceCulture); + return ((byte[])(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// </summary> + public static System.Drawing.Icon printer { + get { + object obj = ResourceManager.GetObject("printer", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + public static System.Drawing.Bitmap saveHS { + get { + object obj = ResourceManager.GetObject("saveHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/platform/windows/gsview/Properties/Resources.resx b/platform/windows/gsview/Properties/Resources.resx new file mode 100644 index 00000000..b87e9f79 --- /dev/null +++ b/platform/windows/gsview/Properties/Resources.resx @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> + <data name="Close" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\close.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="info" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\info.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="Message" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\message.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="OpenFile" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\openfile.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="printer" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\printer.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="saveHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\resources\savehs.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="PDFA_def" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>pdfa_def.ps;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </data> + <data name="PDFX_def" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>pdfx_def.ps;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </data> + <data name="copy" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\copy.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> +</root>
\ No newline at end of file diff --git a/platform/windows/gsview/Properties/Settings.Designer.cs b/platform/windows/gsview/Properties/Settings.Designer.cs new file mode 100644 index 00000000..aec7d913 --- /dev/null +++ b/platform/windows/gsview/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace gsview.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/platform/windows/gsview/Properties/Settings.settings b/platform/windows/gsview/Properties/Settings.settings new file mode 100644 index 00000000..033d7a5e --- /dev/null +++ b/platform/windows/gsview/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file diff --git a/platform/windows/gsview/Properties/pdfa_def.ps b/platform/windows/gsview/Properties/pdfa_def.ps new file mode 100644 index 00000000..5d242d56 --- /dev/null +++ b/platform/windows/gsview/Properties/pdfa_def.ps @@ -0,0 +1,40 @@ +%! +% This is a sample prefix file for creating a PDF/A document. +% Feel free to modify entries marked with "Customize". +% This assumes an ICC profile to reside in the file (ICCPROFILE), +% unless the user modifies the corresponding line below. + +% Define entries in the document Info dictionary : +/ICCProfile (ICCPROFILE) % Customize +def + +[ /Title (TITLE) % Customize + /DOCINFO pdfmark + +% Define an ICC profile : + +[/_objdef {icc_PDFA} /type /stream /OBJ pdfmark +[{icc_PDFA} +<< + /N currentpagedevice /ProcessColorModel known { + currentpagedevice /ProcessColorModel get dup /DeviceGray eq + {pop 1} { + /DeviceRGB eq + {3}{4} ifelse + } ifelse + } { + (ERROR, unable to determine ProcessColorModel) == flush + } ifelse +>> /PUT pdfmark +[{icc_PDFA} ICCProfile (r) file /PUT pdfmark + +% Define the output intent dictionary : + +[/_objdef {OutputIntent_PDFA} /type /dict /OBJ pdfmark +[{OutputIntent_PDFA} << + /Type /OutputIntent % Must be so (the standard requires). + /S /GTS_PDFA1 % Must be so (the standard requires). + /DestOutputProfile {icc_PDFA} % Must be so (see above). + /OutputConditionIdentifier (ICC Profile) % A string describing output intent +>> /PUT pdfmark +[{Catalog} <</OutputIntents [ {OutputIntent_PDFA} ]>> /PUT pdfmark diff --git a/platform/windows/gsview/Properties/pdfx_def.ps b/platform/windows/gsview/Properties/pdfx_def.ps new file mode 100644 index 00000000..a2bd0108 --- /dev/null +++ b/platform/windows/gsview/Properties/pdfx_def.ps @@ -0,0 +1,48 @@ +%! +% This is a sample prefix file for creating a PDF/X-3 document. +% Feel free to modify entries marked with "Customize". + +% This assumes an ICC profile to reside in the file (ICCPROFILE), +% unless the user modifies the corresponding line below. + +systemdict /ProcessColorModel known { + systemdict /ProcessColorModel get dup /DeviceGray ne exch /DeviceCMYK ne and +} { + true +} ifelse +{ (ERROR: ProcessColorModel must be /DeviceGray or DeviceCMYK.)= + /ProcessColorModel cvx /rangecheck signalerror +} if + +% Define entries to the document Info dictionary : + +/ICCProfile (ICCPROFILE) def % Customize or remove. + +[ /GTS_PDFXVersion (PDF/X-3:2002) % Must be so (the standard requires). + /Title (TITLE) % Customize. + /Trapped /False % Must be so (Ghostscript doesn't provide other). + /DOCINFO pdfmark + +% Define an ICC profile : + +currentdict /ICCProfile known { + [/_objdef {icc_PDFX} /type /stream /OBJ pdfmark + [{icc_PDFX} <</N systemdict /ProcessColorModel get /DeviceGray eq {1} {4} ifelse >> /PUT pdfmark + [{icc_PDFX} ICCProfile (r) file /PUT pdfmark +} if + +% Define the output intent dictionary : + +[/_objdef {OutputIntent_PDFX} /type /dict /OBJ pdfmark +[{OutputIntent_PDFX} << + /Type /OutputIntent % Must be so (the standard requires). + /S /GTS_PDFX % Must be so (the standard requires). + /OutputCondition (Created using ghostscript) % Customize + /Info (Through gsview) % Customize + /OutputConditionIdentifier (ICC Profile) % Customize + /RegistryName (http://www.color.org) % Must be so (the standard requires). + currentdict /ICCProfile known { + /DestOutputProfile {icc_PDFX} % Must be so (see above). + } if +>> /PUT pdfmark +[{Catalog} <</OutputIntents [ {OutputIntent_PDFX} ]>> /PUT pdfmark diff --git a/platform/windows/gsview/README.txt b/platform/windows/gsview/README.txt new file mode 100644 index 00000000..35593bce --- /dev/null +++ b/platform/windows/gsview/README.txt @@ -0,0 +1,8 @@ +Note building the projects in this solution requires VS 2013 +To build the installer projects you will need the extension: + +Microsoft Visual Studio Installer Projects + +located at + +http://visualstudiogallery.msdn.microsoft.com/9abe329c-9bba-44a1-be59-0fbf6151054d
\ No newline at end of file diff --git a/platform/windows/gsview/RectList.cs b/platform/windows/gsview/RectList.cs new file mode 100644 index 00000000..ecbc013a --- /dev/null +++ b/platform/windows/gsview/RectList.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; + +namespace gsview +{ + public enum Link_t + { + LINK_GOTO, + LINK_URI, + TEXTBOX, + NOT_SET + }; + + public class RectList : INotifyPropertyChanged + { + public String Character + { + get; + set; + } + + public String Index + { + get; + set; + } + + public String Color + { + get; + set; + } + + public double Height + { + get; + set; + } + + public double Width + { + get; + set; + } + + public double X + { + get; + set; + } + + public double Y + { + get; + set; + } + + public double Scale + { + get; + set; + } + + public Link_t Type + { + get; + set; + } + + public int PageNum + { + get; + set; + } + + public Uri Urilink + { + get; + set; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void PageRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("X")); + PropertyChanged(this, new PropertyChangedEventArgs("Height")); + PropertyChanged(this, new PropertyChangedEventArgs("Width")); + PropertyChanged(this, new PropertyChangedEventArgs("Y")); + PropertyChanged(this, new PropertyChangedEventArgs("Color")); + } + } + } +} diff --git a/platform/windows/gsview/Resources/ActualSize48.png b/platform/windows/gsview/Resources/ActualSize48.png Binary files differnew file mode 100644 index 00000000..4c6e990f --- /dev/null +++ b/platform/windows/gsview/Resources/ActualSize48.png diff --git a/platform/windows/gsview/Resources/Close.ico b/platform/windows/gsview/Resources/Close.ico Binary files differnew file mode 100644 index 00000000..131dcf0c --- /dev/null +++ b/platform/windows/gsview/Resources/Close.ico diff --git a/platform/windows/gsview/Resources/ContScrollFill48.png b/platform/windows/gsview/Resources/ContScrollFill48.png Binary files differnew file mode 100644 index 00000000..2ebf672f --- /dev/null +++ b/platform/windows/gsview/Resources/ContScrollFill48.png diff --git a/platform/windows/gsview/Resources/ExpandFill48.png b/platform/windows/gsview/Resources/ExpandFill48.png Binary files differnew file mode 100644 index 00000000..9df8e512 --- /dev/null +++ b/platform/windows/gsview/Resources/ExpandFill48.png diff --git a/platform/windows/gsview/Resources/FloppyDisk.ico b/platform/windows/gsview/Resources/FloppyDisk.ico Binary files differnew file mode 100644 index 00000000..c50273e2 --- /dev/null +++ b/platform/windows/gsview/Resources/FloppyDisk.ico diff --git a/platform/windows/gsview/Resources/Left.ico b/platform/windows/gsview/Resources/Left.ico Binary files differnew file mode 100644 index 00000000..b2507e31 --- /dev/null +++ b/platform/windows/gsview/Resources/Left.ico diff --git a/platform/windows/gsview/Resources/Message.png b/platform/windows/gsview/Resources/Message.png Binary files differnew file mode 100644 index 00000000..7746354e --- /dev/null +++ b/platform/windows/gsview/Resources/Message.png diff --git a/platform/windows/gsview/Resources/OpenFile.png b/platform/windows/gsview/Resources/OpenFile.png Binary files differnew file mode 100644 index 00000000..99262d52 --- /dev/null +++ b/platform/windows/gsview/Resources/OpenFile.png diff --git a/platform/windows/gsview/Resources/Right.ico b/platform/windows/gsview/Resources/Right.ico Binary files differnew file mode 100644 index 00000000..c2f9238f --- /dev/null +++ b/platform/windows/gsview/Resources/Right.ico diff --git a/platform/windows/gsview/Resources/banner.png b/platform/windows/gsview/Resources/banner.png Binary files differnew file mode 100644 index 00000000..60ec5ea0 --- /dev/null +++ b/platform/windows/gsview/Resources/banner.png diff --git a/platform/windows/gsview/Resources/contents.ico b/platform/windows/gsview/Resources/contents.ico Binary files differnew file mode 100644 index 00000000..97a12dd8 --- /dev/null +++ b/platform/windows/gsview/Resources/contents.ico diff --git a/platform/windows/gsview/Resources/copy.ico b/platform/windows/gsview/Resources/copy.ico Binary files differnew file mode 100644 index 00000000..7c8600f9 --- /dev/null +++ b/platform/windows/gsview/Resources/copy.ico diff --git a/platform/windows/gsview/Resources/folder_open.ico b/platform/windows/gsview/Resources/folder_open.ico Binary files differnew file mode 100644 index 00000000..ef6ac424 --- /dev/null +++ b/platform/windows/gsview/Resources/folder_open.ico diff --git a/platform/windows/gsview/Resources/gsview_app.ico b/platform/windows/gsview/Resources/gsview_app.ico Binary files differnew file mode 100644 index 00000000..29c5ca50 --- /dev/null +++ b/platform/windows/gsview/Resources/gsview_app.ico diff --git a/platform/windows/gsview/Resources/hyperlink.png b/platform/windows/gsview/Resources/hyperlink.png Binary files differnew file mode 100644 index 00000000..6ea0d798 --- /dev/null +++ b/platform/windows/gsview/Resources/hyperlink.png diff --git a/platform/windows/gsview/Resources/info.png b/platform/windows/gsview/Resources/info.png Binary files differnew file mode 100644 index 00000000..172d23c3 --- /dev/null +++ b/platform/windows/gsview/Resources/info.png diff --git a/platform/windows/gsview/Resources/pageCBZ.ico b/platform/windows/gsview/Resources/pageCBZ.ico Binary files differnew file mode 100644 index 00000000..42a0f829 --- /dev/null +++ b/platform/windows/gsview/Resources/pageCBZ.ico diff --git a/platform/windows/gsview/Resources/pageEPS.ico b/platform/windows/gsview/Resources/pageEPS.ico Binary files differnew file mode 100644 index 00000000..3acc64d3 --- /dev/null +++ b/platform/windows/gsview/Resources/pageEPS.ico diff --git a/platform/windows/gsview/Resources/pageJPG.ico b/platform/windows/gsview/Resources/pageJPG.ico Binary files differnew file mode 100644 index 00000000..d1b6b885 --- /dev/null +++ b/platform/windows/gsview/Resources/pageJPG.ico diff --git a/platform/windows/gsview/Resources/pageOXPS.ico b/platform/windows/gsview/Resources/pageOXPS.ico Binary files differnew file mode 100644 index 00000000..8a79ffa9 --- /dev/null +++ b/platform/windows/gsview/Resources/pageOXPS.ico diff --git a/platform/windows/gsview/Resources/pagePDF.ico b/platform/windows/gsview/Resources/pagePDF.ico Binary files differnew file mode 100644 index 00000000..74423969 --- /dev/null +++ b/platform/windows/gsview/Resources/pagePDF.ico diff --git a/platform/windows/gsview/Resources/pagePNG.ico b/platform/windows/gsview/Resources/pagePNG.ico Binary files differnew file mode 100644 index 00000000..dad4bb15 --- /dev/null +++ b/platform/windows/gsview/Resources/pagePNG.ico diff --git a/platform/windows/gsview/Resources/pagePS.ico b/platform/windows/gsview/Resources/pagePS.ico Binary files differnew file mode 100644 index 00000000..2ddcfe05 --- /dev/null +++ b/platform/windows/gsview/Resources/pagePS.ico diff --git a/platform/windows/gsview/Resources/pageXPS.ico b/platform/windows/gsview/Resources/pageXPS.ico Binary files differnew file mode 100644 index 00000000..e30ec2a7 --- /dev/null +++ b/platform/windows/gsview/Resources/pageXPS.ico diff --git a/platform/windows/gsview/Resources/printer.ico b/platform/windows/gsview/Resources/printer.ico Binary files differnew file mode 100644 index 00000000..c03d9853 --- /dev/null +++ b/platform/windows/gsview/Resources/printer.ico diff --git a/platform/windows/gsview/Resources/saveHS.png b/platform/windows/gsview/Resources/saveHS.png Binary files differnew file mode 100644 index 00000000..5ca4d106 --- /dev/null +++ b/platform/windows/gsview/Resources/saveHS.png diff --git a/platform/windows/gsview/Resources/search.ico b/platform/windows/gsview/Resources/search.ico Binary files differnew file mode 100644 index 00000000..2841a637 --- /dev/null +++ b/platform/windows/gsview/Resources/search.ico diff --git a/platform/windows/gsview/Resources/search.png b/platform/windows/gsview/Resources/search.png Binary files differnew file mode 100644 index 00000000..9bbb2255 --- /dev/null +++ b/platform/windows/gsview/Resources/search.png diff --git a/platform/windows/gsview/Resources/thumbnail.ico b/platform/windows/gsview/Resources/thumbnail.ico Binary files differnew file mode 100644 index 00000000..71d38e97 --- /dev/null +++ b/platform/windows/gsview/Resources/thumbnail.ico diff --git a/platform/windows/gsview/Resources/zoom_in.ico b/platform/windows/gsview/Resources/zoom_in.ico Binary files differnew file mode 100644 index 00000000..b0ca2ead --- /dev/null +++ b/platform/windows/gsview/Resources/zoom_in.ico diff --git a/platform/windows/gsview/Resources/zoom_out.ico b/platform/windows/gsview/Resources/zoom_out.ico Binary files differnew file mode 100644 index 00000000..a31d6c8b --- /dev/null +++ b/platform/windows/gsview/Resources/zoom_out.ico diff --git a/platform/windows/gsview/Selection.xaml b/platform/windows/gsview/Selection.xaml new file mode 100644 index 00000000..af67b2d5 --- /dev/null +++ b/platform/windows/gsview/Selection.xaml @@ -0,0 +1,49 @@ +<Window x:Class="gsview.Selection" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Selection" Height="524" Width="452"> + + <DockPanel LastChildFill="True"> + <Menu IsMainMenu="True" DockPanel.Dock="Top"> + <MenuItem Header="OK" Click="ClickOK"/> + <MenuItem Header="Exit" Click="ClickExit"/> + <MenuItem Header="Clear" Click="ClickClear"/> + </Menu> + + <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Background="WhiteSmoke"> + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ZoomIn" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/zoom_in.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + <Button Margin="10 0 0 0" Width="20" Height="20" Click="ZoomOut" Background="Transparent" BorderBrush="Transparent"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Ellipse> + <Ellipse.Fill > + <ImageBrush ImageSource="Resources/zoom_out.ico"/> + </Ellipse.Fill> + </Ellipse> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + </Button> + </StackPanel> + <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Stretch" Background="DarkGray" DockPanel.Dock="Left"> + <Canvas x:Name="xaml_Canvas" MouseDown="Canvas_MouseDown" MouseMove="Canvas_MouseMove" Background="Transparent" Width="{Binding ActualWidth, ElementName=xaml_Image}" Height="{Binding ActualHeight, ElementName=xaml_Image}"> + <Image x:Name="xaml_Image" Width="{Binding Width}" Height="{Binding Height}" Stretch="Fill" HorizontalAlignment="Center" Source="{Binding BitMap}"/> + </Canvas> + </ScrollViewer> + </DockPanel> +</Window> diff --git a/platform/windows/gsview/Selection.xaml.cs b/platform/windows/gsview/Selection.xaml.cs new file mode 100644 index 00000000..1fe76fd1 --- /dev/null +++ b/platform/windows/gsview/Selection.xaml.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace gsview +{ + /// <summary> + /// Interaction logic for Selection.xaml + /// </summary> + /// + + public enum SelectStatus_t + { + OK, + CANCEL, + SELECT, + CLOSE, + ZOOMIN, + ZOOMOUT + } + + public class SelectEventArgs : EventArgs + { + Point m_topleft, m_size; + double m_zoomFactor; + SelectStatus_t m_state; + int m_page_num; + Extract_Type_t m_type; + + public Point TopLeft + { + get { return m_topleft; } + } + + public Point Size + { + get { return m_size; } + } + + public double ZoomFactor + { + get { return m_zoomFactor; } + } + + public int PageNum + { + get { return m_page_num; } + } + + public SelectStatus_t State + { + get { return m_state; } + } + + public Extract_Type_t Type + { + get { return m_type; } + } + + public SelectEventArgs(Point start, Point size, double zoom, + SelectStatus_t state, int page, Extract_Type_t type) + { + m_topleft = start; + m_size = size; + m_zoomFactor = zoom; + m_state = state; + m_page_num = page; + m_type = type; + } + } + + public partial class Selection : Window + { + private Point m_startPoint, m_topleft; + private Point m_size; + public SelectStatus_t m_curr_state; + double m_zoom; + double m_old_zoom; + int m_page_num; + private Rectangle m_rect; + Extract_Type_t m_type; + internal delegate void CallBackMain(object gsObject, SelectEventArgs info); + internal event CallBackMain UpdateMain; + + public Selection(int page, double init_zoom, Extract_Type_t type) + { + InitializeComponent(); + this.Closing += new System.ComponentModel.CancelEventHandler(WindowClosing); + m_page_num = page; + m_zoom = init_zoom; + m_curr_state = SelectStatus_t.OK; + m_type = type; + m_rect = null; + } + + void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e) + { + var result = new SelectEventArgs(m_topleft, m_size, m_zoom, + SelectStatus_t.CANCEL, m_page_num, m_type); + UpdateMain(this, result); + } + + private void ClickOK(object sender, RoutedEventArgs e) + { + if (m_curr_state != SelectStatus_t.OK) + return; + if (m_rect == null) + Close(); + else + { + m_size.X = m_rect.Width; + m_size.Y = m_rect.Height; + m_topleft.Y = xaml_Image.Height - m_topleft.Y - m_size.Y; + var result = new SelectEventArgs(m_topleft, m_size, m_zoom, + SelectStatus_t.SELECT, m_page_num, m_type); + UpdateMain(this, result); + } + } + + private void ClickExit(object sender, RoutedEventArgs e) + { + var result = new SelectEventArgs(m_topleft, m_size, m_zoom, + SelectStatus_t.CANCEL, m_page_num, m_type); + UpdateMain(this, result); + Close(); + } + + private void ClickClear(object sender, RoutedEventArgs e) + { + if (m_rect != null) + { + xaml_Canvas.Children.Remove(m_rect); + m_rect = null; + } + } + + private void ZoomIn(object sender, RoutedEventArgs e) + { + if (m_curr_state != SelectStatus_t.OK || m_zoom >= Constants.ZOOM_MAX) + return; + m_old_zoom = m_zoom; + m_zoom = m_zoom + Constants.ZOOM_STEP; + if (m_zoom > Constants.ZOOM_MAX) + { + m_zoom = Constants.ZOOM_MAX; + return; + } + m_curr_state = SelectStatus_t.ZOOMIN; + var result = new SelectEventArgs(m_startPoint, m_size, m_zoom, + SelectStatus_t.ZOOMIN, m_page_num, m_type); + UpdateMain(this, result); + } + + private void ZoomOut(object sender, RoutedEventArgs e) + { + if (m_curr_state != SelectStatus_t.OK || m_zoom <= Constants.ZOOM_MIN) + return; + m_old_zoom = m_zoom; + m_zoom = m_zoom - Constants.ZOOM_STEP; + if (m_zoom < Constants.ZOOM_MIN) + { + m_zoom = Constants.ZOOM_MIN; + return; + } + m_curr_state = SelectStatus_t.ZOOMOUT; + var result = new SelectEventArgs(m_startPoint, m_size, m_zoom, + SelectStatus_t.ZOOMOUT, m_page_num, m_type); + UpdateMain(this, result); + } + + /* Called when we have had a zoom change */ + public void UpdateRect() + { + if (m_rect != null) + { + double left = Canvas.GetLeft(m_rect); + double top = Canvas.GetTop(m_rect); + Canvas.SetLeft(m_rect, left * m_zoom / m_old_zoom); + Canvas.SetTop(m_rect, top * m_zoom / m_old_zoom); + m_rect.Width = m_rect.Width * m_zoom / m_old_zoom; + m_rect.Height = m_rect.Height * m_zoom / m_old_zoom; + } + } + + private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) + { + if (m_rect != null) + { + xaml_Canvas.Children.Remove(m_rect); + } + + m_startPoint = e.GetPosition(xaml_Canvas); + + m_rect = new Rectangle + { + Stroke = Brushes.Red, + StrokeThickness = 2 + }; + Canvas.SetLeft(m_rect, m_startPoint.X); + Canvas.SetTop(m_rect, m_startPoint.X); + xaml_Canvas.Children.Add(m_rect); + } + + private void Canvas_MouseMove(object sender, MouseEventArgs e) + { + if (e.LeftButton == MouseButtonState.Released || m_rect == null) + return; + + var pos = e.GetPosition(xaml_Canvas); + + var x = Math.Min(pos.X, m_startPoint.X); + var y = Math.Min(pos.Y, m_startPoint.Y); + + var w = Math.Max(pos.X, m_startPoint.X) - x; + var h = Math.Max(pos.Y, m_startPoint.Y) - y; + + m_rect.Width = w; + m_rect.Height = h; + + m_topleft.X = x; + m_topleft.Y = y; + Canvas.SetLeft(m_rect, x); + Canvas.SetTop(m_rect, y); + } + } +} diff --git a/platform/windows/gsview/Strings/en-US/Messages.Designer.cs b/platform/windows/gsview/Strings/en-US/Messages.Designer.cs new file mode 100644 index 00000000..1c34b901 --- /dev/null +++ b/platform/windows/gsview/Strings/en-US/Messages.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace gsview.Strings.en_US { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Messages { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Messages() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("gsview.Strings.en_US.Messages", typeof(Messages).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/platform/windows/gsview/Strings/en-US/Messages.resx b/platform/windows/gsview/Strings/en-US/Messages.resx new file mode 100644 index 00000000..4fdb1b6a --- /dev/null +++ b/platform/windows/gsview/Strings/en-US/Messages.resx @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 1.3 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">1.3</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1">this is my long string</data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + [base64 mime encoded serialized .NET Framework object] + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + [base64 mime encoded string representing a byte array form of the .NET Framework object] + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>1.3</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/platform/windows/gsview/TextBlock.cs b/platform/windows/gsview/TextBlock.cs new file mode 100644 index 00000000..55d3e744 --- /dev/null +++ b/platform/windows/gsview/TextBlock.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Collections.ObjectModel; + +namespace gsview +{ + public class TextBlock : INotifyPropertyChanged + { + double height; + double width; + double x; + double y; + double scale; + String color; + int page_number; + + public List<TextLine> TextLines; + + /* Determine intersection case of block with selection rectangle */ + public Intersection_t CheckIntersection(double rect_x, double rect_y, double rect_w, double rect_h) + { + if (rect_h == 0 || rect_y > y + height || rect_y + rect_h < y || + rect_x + rect_w < x || rect_x > x + width) + return Intersection_t.NONE; + + if (rect_y < y && y + height < rect_y + rect_h) + return Intersection_t.FULL; + + return Intersection_t.PARTIAL; + } + + public double Height + { + get { return height; } + set + { + height = value; + OnPropertyChanged("Height"); + } + } + + public double Width + { + get { return width; } + set + { + width = value; + OnPropertyChanged("Width"); + } + } + + public double X + { + get { return x; } + set + { + x = value; + OnPropertyChanged("X"); + } + } + + public double Y + { + get { return y; } + set + { + y = value; + OnPropertyChanged("Y"); + } + } + public double Scale + { + get { return scale; } + set { scale = value;} + } + + public int PageNumber + { + get { return page_number; } + set { page_number = value; } + } + + public String Color + { + get { return color; } + set + { + color = value; + OnPropertyChanged("Color"); + } + } + + public int GetNumberLines() + { + return TextLines.Count; + } + + public event PropertyChangedEventHandler PropertyChanged; + + // Create the OnPropertyChanged method to raise the event + protected void OnPropertyChanged(string name) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + } + + public class BlocksText : ObservableCollection<TextBlock> + { + public BlocksText() + : base() + { + } + } +} diff --git a/platform/windows/gsview/TextCharacter.cs b/platform/windows/gsview/TextCharacter.cs new file mode 100644 index 00000000..b69cfbff --- /dev/null +++ b/platform/windows/gsview/TextCharacter.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.ComponentModel; + +namespace gsview +{ + public class TextCharacter + { + public String character; + + public double Height + { + get; + set; + } + + public double Width + { + get; + set; + } + + public double X + { + get; + set; + } + + public double Y + { + get; + set; + } + + public double Scale + { + get; + set; + } + + public String Color + { + get; + set; + } + + /* Here we only worry about intersection in the x direction TODO */ + public Intersection_t CheckIntersection(double rect_x, double rect_y, double rect_w, double rect_h) + { + if (rect_w == 0 || rect_x > X + Width || rect_x + rect_w < X) + return Intersection_t.NONE; + + if (rect_x <= X && X + Width <= rect_x + rect_w) + return Intersection_t.FULL; + + return Intersection_t.PARTIAL; + } + + + //public event PropertyChangedEventHandler PropertyChanged; + + /* + public void CharRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("X")); + PropertyChanged(this, new PropertyChangedEventArgs("Height")); + PropertyChanged(this, new PropertyChangedEventArgs("Width")); + PropertyChanged(this, new PropertyChangedEventArgs("Y")); + PropertyChanged(this, new PropertyChangedEventArgs("Color")); + } + } + * */ + } +} diff --git a/platform/windows/gsview/TextLine.cs b/platform/windows/gsview/TextLine.cs new file mode 100644 index 00000000..c37f604b --- /dev/null +++ b/platform/windows/gsview/TextLine.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.ComponentModel; +using System.Collections.ObjectModel; + +namespace gsview +{ + public enum Intersection_t + { + NONE, + PARTIAL, + FULL + }; + + public class TextLine : INotifyPropertyChanged + { + public List<TextCharacter> TextCharacters; + double height; + double width; + double x; + double y; + double scale; + String color; + int page_number; + + /* Determine intersection case of line with selection rectangle */ + public Intersection_t CheckIntersection(double rect_x, double rect_y, double rect_w, double rect_h) + { + if (rect_h == 0 || rect_y > y + height || rect_y + rect_h < y) + return Intersection_t.NONE; + + if (rect_y <= y && y + height <= rect_y + rect_h) + return Intersection_t.FULL; + + return Intersection_t.PARTIAL; + } + + public double Height + { + get { return height; } + set + { + height = value; + OnPropertyChanged("Height"); + } + } + + public double Width + { + get { return width; } + set + { + width = value; + OnPropertyChanged("Width"); + } + } + + public double X + { + get { return x; } + set + { + x = value; + OnPropertyChanged("X"); + } + } + + public double Y + { + get { return y; } + set + { + y = value; + OnPropertyChanged("Y"); + } + } + public double Scale + { + get { return scale; } + set { scale = value;} + } + + public int PageNumber + { + get { return page_number; } + set { page_number = value; } + } + + public String Color + { + get { return color; } + set + { + color = value; + //OnPropertyChanged("Color"); + } + } + public event PropertyChangedEventHandler PropertyChanged; + + // Create the OnPropertyChanged method to raise the event + protected void OnPropertyChanged(string name) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(name)); + } + } + } + + public class LinesText : ObservableCollection<TextLine> + { + public LinesText() + : base() + { + } + } +} diff --git a/platform/windows/gsview/ghostsharp.cs b/platform/windows/gsview/ghostsharp.cs new file mode 100644 index 00000000..168ce476 --- /dev/null +++ b/platform/windows/gsview/ghostsharp.cs @@ -0,0 +1,1165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +//using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.IO; +using System.Security; +using System.ComponentModel; + +namespace gsview +{ + /* Warning. This list is in a particular order. The devices before + * psdrgb do not support multiple pages. Those including psdrgb do + * support multiple pages. This is used in the conversion process. + * Also note that mupdf devices go at the beginning of the list */ + public enum gsDevice_t + { + svg, + pnm, + pclbitmap, + pwg, + bmp16, /* Add mupdf devices before this one */ + bmp16m, + bmp256, + bmp32b, + bmpgray, + bmpmono, + eps2write, + jpeg, + jpegcmyk, + jpeggray, + pamcmyk32, + pamcmyk4, + pbm, + pgm, + png16, + png16m, + png256, + pngalpha, + pnggray, + pngmono, + psdcmyk, + psdrgb, /* Add single page gs devices before this device */ + pdfwrite, + ps2write, + pxlcolor, + pxlmono, + tiff12nc, + tiff24nc, + tiff32nc, + tiff64nc, + tiffcrle, + tiffg3, + tiffg32d, + tiffg4, + tiffgray, + tifflzw, + tiffpack, + tiffsep, + txtwrite, + xpswrite + }; + + public enum GS_Task_t + { + PS_DISTILL, + CREATE_XPS, + SAVE_RESULT + } + + public enum GS_Result_t + { + gsOK, + gsFAILED, + gsCANCELLED + } + + /* Parameters */ + public struct gsParams_t + { + public String init_string; + public String init_file; + public int resolution; + public gsDevice_t device; + public String devicename; + public String outputfile; + public String inputfile; + public GS_Task_t task; + public GS_Result_t result; + public int num_pages; + public String options; + public bool need_multi_page; + public System.Collections.IList pages; + public int firstpage; + public int lastpage; + public int currpage; /* valid only when pages != null */ + }; + + public class gsEventArgs : EventArgs + { + private bool m_completed; + private int m_progress; + private gsParams_t m_param; + + public bool Completed + { + get { return m_completed; } + } + + public gsParams_t Params + { + get { return m_param; } + } + + public int Progress + { + get { return m_progress; } + } + + public gsEventArgs(bool completed, int progress, gsParams_t param) + { + m_completed = completed; + m_progress = progress; + m_param = param; + } + } + + /* from gs */ + public struct gsapi_revision_t + { + public IntPtr product; + public IntPtr copyright; + public int revision; + public int revisiondate; + } + + public enum gsEncoding { + GS_ARG_ENCODING_LOCAL = 0, + GS_ARG_ENCODING_UTF8 = 1, + GS_ARG_ENCODING_UTF16LE = 2 + }; + + public enum gsStatus + { + GS_READY, + GS_BUSY, + GS_ERROR + }; + + static class gsConstants + { + public const int E_QUIT = -101; + public const int GS_READ_BUFFER = 32768; + } + + [SuppressUnmanagedCodeSecurity] + class ghostsharp + { + /* Callback proto for stdio */ + public delegate int gsStdIOHandler(IntPtr caller_handle, IntPtr buffer, + int len); + + #region DLLInterface + /* Ghostscript API */ + [DllImport("gsdll64.dll", EntryPoint = "gsapi_revision", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_revision64(ref gsapi_revision_t vers, int size); + + [DllImport("gsdll64.dll", EntryPoint="gsapi_new_instance", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_new_instance64(out IntPtr pinstance, + IntPtr caller_handle); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_delete_instance", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_delete_instance64(IntPtr instance); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_init_with_args", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_init_with_args64(IntPtr instance, int argc, + IntPtr argv); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_exit", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_exit64(IntPtr instance); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_set_arg_encoding", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_set_arg_encoding64(IntPtr instance, + int encoding); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_set_stdio", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_set_stdio64(IntPtr instance, + gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_run_string_begin", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_begin64(IntPtr instance, + int usererr, ref int exitcode); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_run_string_continue", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_continue64(IntPtr instance, + IntPtr command, int count, int usererr, ref int exitcode); + + [DllImport("gsdll64.dll", EntryPoint = "gsapi_run_string_end", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_end64(IntPtr instance, + int usererr, ref int exitcode); + + /* 32 Bit DLL */ + [DllImport("gsdll32.dll", EntryPoint = "gsapi_revision", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_revision32(ref gsapi_revision_t vers, int size); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_new_instance32(out IntPtr pinstance, + IntPtr caller_handle); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_delete_instance32(IntPtr instance); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_init_with_args32(IntPtr instance, int argc, + IntPtr argv); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_exit", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_exit32(IntPtr instance); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_set_arg_encoding", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_set_arg_encoding32(IntPtr instance, + int encoding); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_set_stdio", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern int gsapi_set_stdio32(IntPtr instance, + gsStdIOHandler stdin, gsStdIOHandler stdout, gsStdIOHandler stderr); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_run_string_begin", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_begin32(IntPtr instance, + int usererr, ref int exitcode); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_run_string_continue", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_continue32(IntPtr instance, + IntPtr command, int count, int usererr, ref int exitcode); + + [DllImport("gsdll32.dll", EntryPoint = "gsapi_run_string_end", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + private static extern void gsapi_run_string_end32(IntPtr instance, + int usererr, ref int exitcode); + #endregion DLLInterface + + #region DLLErrorCatch + /* In case the DLL is not found we need to wrap the methods up with + * a try/catch. Also select 32 or 64 bit DLL at this time. This + * C# code is compiled as ANYCPU type */ + private int tc_gsapi_revision(ref gsapi_revision_t vers, int size) + { + int code = 0; + try + { + if (is64bit) + code = gsapi_revision64(ref vers, size); + else + code = gsapi_revision32(ref vers, size); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return code; + } + + private int tc_gsapi_new_instance(out IntPtr pinstance, IntPtr caller_handle) + { + int code = 0; + pinstance = IntPtr.Zero; + try + { + if (is64bit) + code = gsapi_new_instance64(out pinstance, caller_handle); + else + code = gsapi_new_instance32(out pinstance, caller_handle); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return code; + } + + private int tc_gsapi_delete_instance(IntPtr instance) + { + try + { + if (is64bit) + gsapi_delete_instance64(instance); + else + gsapi_delete_instance32(instance); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return 0; + } + + private int tc_gsapi_init_with_args(IntPtr instance, int argc, IntPtr argv) + { + int code; + + try + { + if (is64bit) + code = gsapi_init_with_args64(instance, argc, argv); + else + code = gsapi_init_with_args32(instance, argc, argv); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + catch(System.Reflection.TargetInvocationException ee) + { + String output = "TargetInvocationException"; + gsDLLProblemMain(this, output); + return -1; + } + + return code; + } + + private int tc_gsapi_exit(IntPtr instance) + { + int code; + try + { + if (is64bit) + code = gsapi_exit64(instance); + else + code = gsapi_exit32(instance); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return code; + } + + private int tc_gsapi_set_arg_encoding(IntPtr instance, int encoding) + { + int code; + try + { + if (is64bit) + code = gsapi_set_arg_encoding64(instance, encoding); + else + code = gsapi_set_arg_encoding32(instance, encoding); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return code; + } + + private int tc_gsapi_set_stdio(IntPtr instance, gsStdIOHandler stdin, + gsStdIOHandler stdout, gsStdIOHandler stderr) + { + int code; + try + { + if (is64bit) + code = gsapi_set_stdio64(instance, stdin, stdout, stderr); + else + code = gsapi_set_stdio32(instance, stdin, stdout, stderr); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return code; + } + + private int tc_gsapi_run_string_begin(IntPtr instance, int usererr, + ref int exitcode) + { + try + { + if (is64bit) + gsapi_run_string_begin64(instance, usererr, ref exitcode); + else + gsapi_run_string_begin32(instance, usererr, ref exitcode); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return 0; + } + + private int tc_gsapi_run_string_continue(IntPtr instance, IntPtr command, + int count, int usererr, ref int exitcode) + { + try + { + if (is64bit) + gsapi_run_string_continue64(instance, command, count, usererr, + ref exitcode); + else + gsapi_run_string_continue32(instance, command, count, usererr, + ref exitcode); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return 0; + } + + private int tc_gsapi_run_string_end(IntPtr instance, int usererr, + ref int exitcode) + { + try + { + if (is64bit) + gsapi_run_string_end64(instance, usererr, ref exitcode); + else + gsapi_run_string_end32(instance, usererr, ref exitcode); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String output = "DllNotFoundException: Ghostscript DLL not found"; + gsDLLProblemMain(this, output); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String output = "BadImageFormatException: Incorrect Ghostscript DLL"; + gsDLLProblemMain(this, output); + return -1; + } + return 0; + } + #endregion DLLErrorCatch + + private int StdInCallback(IntPtr handle, IntPtr pointer, int count) + { + String output = Marshal.PtrToStringAnsi(pointer); + return count; + } + + private int StdOutCallback(IntPtr handle, IntPtr pointer, int count) + { + String output = Marshal.PtrToStringAnsi(pointer); + gsIOUpdateMain(this, output, count); + if (m_params.task != GS_Task_t.PS_DISTILL) + { + /* See if we have a page number */ + if (count >= 7 && output.Substring(0, 4) == "Page") + { + String page = output.Substring(5, count - 6); + int numVal; + try + { + double perc = 0.0; + numVal = System.Convert.ToInt32(page); + if (m_params.firstpage == -1 && m_params.lastpage == -1 && + m_params.pages == null) + { + /* Doing full document */ + perc = 100.0 * (double)numVal / (double)m_params.num_pages; + } + else + { + if (m_params.pages != null) + { + perc = 100.0 * ((double)numVal - m_params.currpage) / (double)m_params.num_pages; + m_params.currpage = m_params.currpage + 1; + } + else + { + /* continugous set of pages */ + perc = 100.0 * ((double)numVal - m_params.firstpage + 1) / (double)m_params.num_pages; + } + } + m_worker.ReportProgress((int)perc); + } + catch (FormatException e) + { + Console.WriteLine("XPSPrint Error: Input string is not a sequence of digits."); + } + catch (OverflowException e) + { + Console.WriteLine("XPSPrint Error: The number cannot fit in an Int32."); + } + + } + } + return count; + } + + private int StdErrCallback(IntPtr handle, IntPtr pointer, int count) + { + String output = Marshal.PtrToStringAnsi(pointer); + gsIOUpdateMain(this, output, count); + return count; + } + + IntPtr gsInstance; + BackgroundWorker m_worker; + bool is64bit; + gsParams_t m_params; + /* Callbacks to Main */ + internal delegate void gsDLLProblem(object gsObject, String mess); + internal event gsDLLProblem gsDLLProblemMain; + internal delegate void gsIOCallBackMain(object gsObject, String mess, int len); + internal event gsIOCallBackMain gsIOUpdateMain; + internal delegate void gsCallBackMain(object gsObject, gsEventArgs info); + internal event gsCallBackMain gsUpdateMain; + /* These need to be declared as members, to keep a reference and avoid GC + * You do not pin delegates */ + gsStdIOHandler RaiseStdInCallback; + gsStdIOHandler RaiseStdOutCallback; + gsStdIOHandler RaiseStdErrCallback; + + public ghostsharp() + { + /* Determine now if we are 64 or 32 bit */ + is64bit = Environment.Is64BitOperatingSystem && + Environment.Is64BitProcess; + m_worker = null; + gsInstance = IntPtr.Zero; + + /* Go ahead and do the assignment here */ + RaiseStdInCallback = StdInCallback; + RaiseStdOutCallback = StdOutCallback; + RaiseStdErrCallback = StdErrCallback; + } + + private List<String> GetOptions(String options) + { + List<String> optionlist = new List<String>(); + + if (options != "") + { + string[] words = options.Split(' '); + for (int k = 0; k < words.Length; k++) + { + if (words[k].Length > 0) + { + optionlist.Add(words[k]); + } + } + } + return optionlist; + } + + /* A standard command line approach to using gs API */ + private void gsWork1(object sender, DoWorkEventArgs e) + { + gsParams_t gsparams = (gsParams_t) e.Argument; + String out_file = gsparams.outputfile; + String in_file = gsparams.inputfile; + int num_params = 8; /* base number */ + int rend_count = 1; + String options; + int count; + List<String> optionlist; + + optionlist = GetOptions(gsparams.options); + num_params = num_params + optionlist.Count; + if (gsparams.pages != null) + { + rend_count = gsparams.pages.Count; + num_params = num_params + 2; + } + if (gsparams.init_file != null) + num_params = num_params + 1; + if (gsparams.init_string != null) + num_params = num_params + 2; + + var argParam = new GCHandle[num_params]; + var argPtrs = new IntPtr[num_params]; + String[] strParams = new String[num_params]; + List<byte[]> CharacterArray = new List<byte[]>(num_params); + GCHandle argPtrsStable; + + /* New instance */ + int code = tc_gsapi_new_instance(out gsInstance, IntPtr.Zero); + if (code < 0) + { + gsparams.result = GS_Result_t.gsFAILED; + e.Result = gsparams; + return; + } + + code = tc_gsapi_set_stdio(gsInstance, RaiseStdInCallback, + RaiseStdOutCallback, RaiseStdErrCallback); + code = tc_gsapi_set_arg_encoding(gsInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); + + if (code == 0) + { + for (int jj = 0; jj < rend_count; jj++) + { + strParams[0] = "gs"; /* This does not matter */ + strParams[1] = "-dNOPAUSE"; + strParams[2] = "-dBATCH"; + if (gsparams.devicename != null) + { + strParams[3] = "-sDEVICE=" + gsparams.devicename; + } + else + { + strParams[3] = "-sDEVICE=" + Enum.GetName(typeof(gsDevice_t), gsparams.device); + } + strParams[4] = "-r" + gsparams.resolution; + /* Create temp file if file not specified */ + if (out_file == null) + { + out_file = Path.GetTempFileName(); + gsparams.outputfile = out_file; + } + count = 5; + /* Add in the options */ + for (int kk = 0; kk < optionlist.Count; kk++) + { + strParams[count] = optionlist[kk]; + count++; + } + /* We have discontinuous page selection */ + if (gsparams.pages != null) + { + String firstpage, lastpage; + options = gsparams.options; + SelectPage curr_page = (SelectPage)(gsparams.pages[jj]); + firstpage = "-dFirstPage=" + curr_page.Page; + lastpage = "-dLastPage=" + curr_page.Page; + strParams[count] = firstpage; + count++; + strParams[count] = lastpage; + count++; + /* Look for file extension. */ + string extension = System.IO.Path.GetExtension(out_file); + int len = extension.Length; + String new_out_file = out_file.Substring(0, out_file.Length - len); + strParams[count] = "-o" + new_out_file + "_page" + curr_page.Page + extension; + } + else + { + if (gsparams.need_multi_page) + { + /* Look for file extension. */ + string extension = System.IO.Path.GetExtension(out_file); + int len = extension.Length; + String new_out_file = out_file.Substring(0, out_file.Length - len); + strParams[count] = "-o" + new_out_file + "_page%d" + extension; + } + else + strParams[count] = "-o" + out_file; + } + if (gsparams.init_string != null) + { + count++; + strParams[count] = "-c"; + count++; + strParams[count] = gsparams.init_string; + } + count++; + strParams[count] = "-f"; + if (gsparams.init_file != null) + { + count++; + strParams[count] = gsparams.init_file; + } + count++; + strParams[count] = in_file; + + /* Now convert our Strings to char* and get pinned handles to these. + * This keeps the c# GC from moving stuff around on us */ + for (int k = 0; k < num_params; k++) + { + CharacterArray.Add(System.Text.Encoding.UTF8.GetBytes(strParams[k].ToCharArray())); + argParam[k] = GCHandle.Alloc(CharacterArray[k], GCHandleType.Pinned); + argPtrs[k] = argParam[k].AddrOfPinnedObject(); + } + /* Also stick the array of pointers into memory that will not be GCd */ + argPtrsStable = GCHandle.Alloc(argPtrs, GCHandleType.Pinned); + + code = tc_gsapi_init_with_args(gsInstance, num_params, argPtrsStable.AddrOfPinnedObject()); + /* All the pinned items need to be freed so the GC can do its job */ + for (int k = 0; k < num_params; k++) + { + argParam[k].Free(); + } + argPtrsStable.Free(); + /* Free the character array list in case we have multiple runs */ + CharacterArray.Clear(); + + if (code < 0) + break; + } + } + + int code1 = tc_gsapi_exit(gsInstance); + if ((code == 0) || (code == gsConstants.E_QUIT)) + code = code1; + + tc_gsapi_delete_instance(gsInstance); + if ((code == 0) || (code == gsConstants.E_QUIT)) + { + gsparams.result = GS_Result_t.gsOK; + e.Result = gsparams; + return; + } + + gsparams.result = GS_Result_t.gsFAILED; + e.Result = gsparams; + return; + } + + /* Feeding gs piecemeal so that we can have some progress callback */ + /* Used only for PS Distill */ + private void gsWork2(object sender, DoWorkEventArgs e) + { + gsParams_t Params = (gsParams_t)e.Argument; + String out_file = Params.outputfile; + String in_file = Params.inputfile; + int num_params = 6; + if (Params.options.Length > 0) + num_params = num_params + 1; + + int exitcode = 0; + var argParam = new GCHandle[num_params]; + var argPtrs = new IntPtr[num_params]; + var Feed = new GCHandle(); + var FeedPtr = new IntPtr(); + String[] strParams = new String[num_params]; + List<byte[]> CharacterArray = new List<byte[]>(num_params); + GCHandle argPtrsStable; + Byte[] Buffer = new Byte[gsConstants.GS_READ_BUFFER]; + BackgroundWorker worker = sender as BackgroundWorker; + + /* Open the file */ + var fs = new FileStream(in_file, FileMode.Open); + var len = (int) fs.Length; + /* New instance */ + int code = tc_gsapi_new_instance(out gsInstance, IntPtr.Zero); + if (code < 0) + { + Params.result = GS_Result_t.gsFAILED; + e.Result = Params; + return; + } + + code = tc_gsapi_set_stdio(gsInstance, RaiseStdInCallback, + RaiseStdOutCallback, RaiseStdErrCallback); + code = tc_gsapi_set_arg_encoding(gsInstance, (int)gsEncoding.GS_ARG_ENCODING_UTF8); + + if (code == 0) + { + strParams[0] = "gs"; /* This does not matter */ + strParams[1] = "-dNOPAUSE"; + strParams[2] = "-dBATCH"; + if (Params.devicename != null) + { + strParams[3] = "-sDEVICE=" + Params.devicename; + } + else + { + strParams[3] = "-sDEVICE=" + Enum.GetName(typeof(gsDevice_t), Params.device); + } + strParams[4] = "-r" + Params.resolution; + /* Create temp file if file not specified */ + if (out_file == null) + { + out_file = Path.GetTempFileName(); + Params.outputfile = out_file; + } + if (Params.options.Length > 0) + { + strParams[5] = Params.options; + strParams[6] = "-o" + out_file; + } else + strParams[5] = "-o" + out_file; + + /* Now convert our Strings to char* and get pinned handles to these. + * This keeps the c# GC from moving stuff around on us */ + for (int k = 0; k < num_params; k++) + { + CharacterArray.Add(System.Text.Encoding.UTF8.GetBytes(strParams[k].ToCharArray())); + argParam[k] = GCHandle.Alloc(CharacterArray[k], GCHandleType.Pinned); + argPtrs[k] = argParam[k].AddrOfPinnedObject(); + } + /* Also stick the array of pointers into memory that will not be GCd */ + argPtrsStable = GCHandle.Alloc(argPtrs, GCHandleType.Pinned); + + code = tc_gsapi_init_with_args(gsInstance, num_params, argPtrsStable.AddrOfPinnedObject()); + + /* First pin the data buffer */ + Feed = GCHandle.Alloc(Buffer, GCHandleType.Pinned); + FeedPtr = Feed.AddrOfPinnedObject(); + + /* Now start feeding the input piece meal and do a call back + * with our progress */ + if (code == 0) + { + int count; + double perc; + int total = 0; + + tc_gsapi_run_string_begin(gsInstance, 0, ref exitcode); + while ((count = fs.Read(Buffer, 0, gsConstants.GS_READ_BUFFER)) > 0) + { + tc_gsapi_run_string_continue(gsInstance, FeedPtr, count, 0, ref exitcode); + if (exitcode < 0) + { + code = exitcode; + break; + } + total = total + count; + perc = 100.0 * (double) total / (double) len; + worker.ReportProgress((int)perc); + if (worker.CancellationPending == true) + { + e.Cancel = true; + break; + } + } + tc_gsapi_run_string_end(gsInstance, 0, ref exitcode); + if (code == 0) + code = exitcode; + } + + /* All the pinned items need to be freed so the GC can do its job */ + for (int k = 0; k < num_params; k++) + { + argParam[k].Free(); + } + argPtrsStable.Free(); + Feed.Free(); + } + + int code1 = tc_gsapi_exit(gsInstance); + if ((code == 0) || (code == gsConstants.E_QUIT)) + code = code1; + + tc_gsapi_delete_instance(gsInstance); + if ((code == 0) || (code == gsConstants.E_QUIT)) + { + Params.result = GS_Result_t.gsOK; + e.Result = Params; + return; + } + Params.result = GS_Result_t.gsFAILED; + e.Result = Params; + return; + } + + /* Callback */ + private void gsCompleted(object sender, RunWorkerCompletedEventArgs e) + { + gsParams_t Value; + gsEventArgs info; + gsParams_t Params; + + try + { + Params = (gsParams_t)e.Result; + } + catch(System.Reflection.TargetInvocationException ee) + { + /* Something went VERY wrong with GS */ + /* Following is to help debug these issues */ + /* var inner = ee.InnerException; + var message = ee.Message; + var inner_message = inner.Message; + String bound = "\n************\n"; + gsIOUpdateMain(this, bound, bound.Length); + gsIOUpdateMain(this, message, message.Length); + gsIOUpdateMain(this, bound, bound.Length); + gsIOUpdateMain(this, inner_message, inner_message.Length); + gsIOUpdateMain(this, bound, bound.Length); + var temp = inner.Source; + gsIOUpdateMain(this, bound, bound.Length); + gsIOUpdateMain(this, temp, temp.Length); + var method = inner.TargetSite; + gsIOUpdateMain(this, bound, bound.Length); + var method_name = method.Name; + gsIOUpdateMain(this, method_name, method_name.Length); + var stack = inner.StackTrace; + gsIOUpdateMain(this, bound, bound.Length); + gsIOUpdateMain(this, stack, stack.Length); */ + String output = "Ghostscript DLL Invalid Access."; + gsDLLProblemMain(this, output); + return; + } + + if (Params.task == GS_Task_t.PS_DISTILL) + m_worker.DoWork -= new DoWorkEventHandler(gsWork2); + else + m_worker.DoWork -= new DoWorkEventHandler(gsWork1); + + if (e.Cancelled) + { + Value = new gsParams_t(); + Value.result = GS_Result_t.gsCANCELLED; + info = new gsEventArgs(true, 100, Value); + } + else + { + Value = (gsParams_t)e.Result; + info = new gsEventArgs(true, 100, Value); + } + gsUpdateMain(this, info); + } + + private void gsProgressChanged(object sender, ProgressChangedEventArgs e) + { + /* Callback with progress */ + gsParams_t Value = new gsParams_t(); + gsEventArgs info = new gsEventArgs(false, e.ProgressPercentage, Value); + gsUpdateMain(this, info); + } + + public gsStatus DistillPS(String fileName, int resolution) + { + gsParams_t gsparams = new gsParams_t(); ; + + gsparams.init_file = null; + gsparams.init_string = null; + gsparams.device = gsDevice_t.pdfwrite; + gsparams.devicename = null; + gsparams.outputfile = null; + gsparams.resolution = resolution; + gsparams.inputfile = fileName; + gsparams.num_pages = -1; + gsparams.task = GS_Task_t.PS_DISTILL; + gsparams.options = ""; + gsparams.need_multi_page = false; + gsparams.pages = null; + gsparams.firstpage = -1; + gsparams.lastpage = -1; + gsparams.currpage = -1; + return RunGhostscript(gsparams); + } + + public gsStatus CreateXPS(String fileName, int resolution, int num_pages) + { + gsParams_t gsparams = new gsParams_t(); + + gsparams.init_file = null; + gsparams.init_string = null; + gsparams.device = gsDevice_t.xpswrite; + gsparams.outputfile = null; + gsparams.resolution = resolution; + gsparams.inputfile = fileName; + gsparams.task = GS_Task_t.CREATE_XPS; + gsparams.num_pages = num_pages; + gsparams.options = "-dNOCACHE"; + gsparams.need_multi_page = false; + gsparams.pages = null; + gsparams.firstpage = -1; + gsparams.lastpage = -1; + gsparams.currpage = -1; + return RunGhostscript(gsparams); + } + + public gsStatus Convert(String fileName, String options, String device, + String outputFile, int num_pages, int resolution, + bool multi_page_needed, System.Collections.IList pages, + int firstpage, int lastpage, String init_file, String init_string) + { + gsParams_t gsparams = new gsParams_t(); + + gsparams.init_file = init_file; + gsparams.init_string = init_string; + gsparams.devicename = device; + gsparams.outputfile = outputFile; + gsparams.inputfile = fileName; + gsparams.task = GS_Task_t.SAVE_RESULT; + gsparams.num_pages = num_pages; + gsparams.options = options; + gsparams.resolution = resolution; + gsparams.need_multi_page = multi_page_needed; + gsparams.pages = pages; + gsparams.firstpage = firstpage; + gsparams.lastpage = lastpage; + gsparams.currpage = 1; + return RunGhostscript(gsparams); + } + + public gsStatus GetStatus() + { + if (m_worker != null && m_worker.IsBusy) + return gsStatus.GS_BUSY; + else + return gsStatus.GS_READY; + } + + public String GetVersion() + { + gsapi_revision_t vers; + vers.copyright = IntPtr.Zero; + vers.product = IntPtr.Zero; + vers.revision = 0; + vers.revisiondate = 0; + int size = System.Runtime.InteropServices.Marshal.SizeOf(vers); + + if (tc_gsapi_revision(ref vers, size) == 0) + { + String product = Marshal.PtrToStringAnsi(vers.product); + String output; + int major = vers.revision / 100; + int minor = vers.revision - major * 100; + String versnum = major + "." + minor; + output = product + " " + versnum; + return output; + } + else + return null; + } + + private gsStatus RunGhostscript(gsParams_t Params) + { + try + { + if (m_worker != null && m_worker.IsBusy) + { + m_worker.CancelAsync(); + return gsStatus.GS_BUSY; + } + if (m_worker == null) + { + m_worker = new BackgroundWorker(); + m_worker.WorkerReportsProgress = true; + m_worker.WorkerSupportsCancellation = true; + m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(gsCompleted); + m_worker.ProgressChanged += new ProgressChangedEventHandler(gsProgressChanged); + } + + if (Params.task == GS_Task_t.PS_DISTILL) + m_worker.DoWork += new DoWorkEventHandler(gsWork2); + else + m_worker.DoWork += new DoWorkEventHandler(gsWork1); + + m_params = Params; + m_worker.RunWorkerAsync(Params); + return gsStatus.GS_READY; + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during gs rendering\n"); + return gsStatus.GS_ERROR; + } + } + + public void Cancel() + { + m_worker.CancelAsync(); + } + } +} diff --git a/platform/windows/gsview/gsIO.cs b/platform/windows/gsview/gsIO.cs new file mode 100644 index 00000000..82e47be6 --- /dev/null +++ b/platform/windows/gsview/gsIO.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; + +namespace gsview +{ + class gsIO : INotifyPropertyChanged + { + public String gsIOString + { + get; + set; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void PageRefresh() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("gsIOString")); + } + } + + public gsIO() + { + this.gsIOString = ""; + } + } +} diff --git a/platform/windows/gsview/gsOutput.xaml b/platform/windows/gsview/gsOutput.xaml new file mode 100644 index 00000000..0c69461c --- /dev/null +++ b/platform/windows/gsview/gsOutput.xaml @@ -0,0 +1,51 @@ +<Window x:Class="gsview.gsOutput" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Ghostscript Messages" Height="500" Width="500"> + + <DockPanel LastChildFill="True"> + <Grid DockPanel.Dock="Bottom" Visibility="Visible" Background="WhiteSmoke"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <Button Grid.Row="0" Grid.Column="1" Width="50" Height="20" Click="ClearContents" Background="Transparent" BorderBrush="Transparent" Margin="5,0,15,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>Clear</Bold></TextBlock> + </Button> + <Button Grid.Row="0" Grid.Column="2" Width="50" Height="20" Click="HideWindow" Background="Transparent" BorderBrush="Transparent" Margin="5,0,15,0"> + <Button.Template> + <ControlTemplate TargetType="{x:Type Button}"> + <Grid> + <Rectangle Height="Auto" RadiusX="5" RadiusY="5"> + <Rectangle.Fill > + <SolidColorBrush Color="LightSlateGray"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/> + </Grid> + </ControlTemplate> + </Button.Template> + <TextBlock><Bold>OK</Bold></TextBlock> + </Button> + </Grid> + + <!-- Pages are last child fill. This goes in the center of our dock panel --> + <Grid HorizontalAlignment="Stretch" Background="DarkGray"> + <TextBox x:Name="xaml_gsText" Margin="1, 1, 1, 1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Text="{Binding gsIOString}" IsReadOnly="True"/> + </Grid> + + </DockPanel> +</Window> diff --git a/platform/windows/gsview/gsOutput.xaml.cs b/platform/windows/gsview/gsOutput.xaml.cs new file mode 100644 index 00000000..c2aa9375 --- /dev/null +++ b/platform/windows/gsview/gsOutput.xaml.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace gsview +{ + /// <summary> + /// Interaction logic for gsOutput.xaml + /// </summary> + public partial class gsOutput : Window + { + gsIO m_gsIO; + public gsOutput() + { + InitializeComponent(); + this.Closing += new System.ComponentModel.CancelEventHandler(FakeWindowClosing); + m_gsIO = new gsIO(); + xaml_gsText.DataContext = m_gsIO; + } + + void FakeWindowClosing(object sender, System.ComponentModel.CancelEventArgs e) + { + e.Cancel = true; + this.Hide(); + } + + private void HideWindow(object sender, RoutedEventArgs e) + { + this.Hide(); + } + + public void RealWindowClosing() + { + this.Closing -= new System.ComponentModel.CancelEventHandler(FakeWindowClosing); + this.Close(); + } + + public void Update(String newstring, int len) + { + m_gsIO.gsIOString += newstring.Substring(0, len); + m_gsIO.PageRefresh(); + } + + private void ClearContents(object sender, RoutedEventArgs e) + { + m_gsIO.gsIOString = null; + m_gsIO.PageRefresh(); + } + } +} diff --git a/platform/windows/gsview/gsprint.cs b/platform/windows/gsview/gsprint.cs new file mode 100644 index 00000000..27976bc0 --- /dev/null +++ b/platform/windows/gsview/gsprint.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; +using System.Printing; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Documents.Serialization; +using System.Windows.Media; +using System.Windows.Xps; +using System.Windows.Xps.Packaging; +using System.Windows.Xps.Serialization; + +namespace gsview +{ + public enum PrintStatus_t + { + PRINT_READY, + PRINT_BUSY, + PRINT_ERROR, + PRINT_CANCELLED + }; + + /* Class for handling async print progress callback */ + public class gsPrintEventArgs : EventArgs + { + private PrintStatus_t m_status; + private bool m_completed; + private int m_page; + + public PrintStatus_t Status + { + get { return m_status; } + } + + public bool Completed + { + get { return m_completed; } + } + + public int Page + { + get { return m_page; } + } + + public gsPrintEventArgs(PrintStatus_t status, bool completed, int page) + { + m_completed = completed; + m_status = status; + m_page = page; + } + } + + public class gsprint + { + private XpsDocumentWriter m_docWriter = null; + internal delegate void AsyncPrintCallBack(object printObject, gsPrintEventArgs info); + internal event AsyncPrintCallBack PrintUpdate; + private bool m_busy; + + public bool IsBusy() + { + return m_busy; + } + + public gsprint() + { + m_busy = false; + } + + /* Show std. print dialog */ + public PrintDialog GetPrintDialog() + { + PrintDialog dlg = new PrintDialog(); + /* Current page and page ranges is going to require a little work */ + dlg.PageRangeSelection = PageRangeSelection.AllPages; + //dlg.UserPageRangeEnabled = true; + //dlg.CurrentPageEnabled = true; + dlg.SelectedPagesEnabled = false; + m_busy = false; + if (dlg.ShowDialog() == true) + return dlg; + return null; + } + + /* Main print entry point */ + public void Print(PrintQueue queu, FixedDocumentSequence fixdoc) + { + XpsDocumentWriter docwrite = GetDocWriter(queu); + + m_busy = true; + docwrite.WritingPrintTicketRequired += + new WritingPrintTicketRequiredEventHandler(PrintTicket); + PrintPages(docwrite, fixdoc); + } + + /* Send it */ + private void PrintPages(XpsDocumentWriter xpsdw, FixedDocumentSequence fixdoc) + { + m_docWriter = xpsdw; + xpsdw.WritingCompleted += + new WritingCompletedEventHandler(AsyncCompleted); + xpsdw.WritingProgressChanged += + new WritingProgressChangedEventHandler(AsyncProgress); + xpsdw.WriteAsync(fixdoc); + } + + public void CancelAsync() + { + /* ick. This does not work in windows 8. causes crash */ + /* https://connect.microsoft.com/VisualStudio/feedback/details/778145/xpsdocumentwriter-cancelasync-cause-crash-in-win8 */ + m_docWriter.CancelAsync(); + } + + /* Done */ + private void AsyncCompleted(object sender, WritingCompletedEventArgs e) + { + PrintStatus_t status; + + if (e.Cancelled) + status = PrintStatus_t.PRINT_CANCELLED; + else if (e.Error != null) + status = PrintStatus_t.PRINT_ERROR; + else + status = PrintStatus_t.PRINT_READY; + + if (PrintUpdate != null) + { + gsPrintEventArgs info = new gsPrintEventArgs(status, true, 0); + PrintUpdate(this, info); + } + m_busy = false; + } + + /* Do this update with each fixed document (page) that is handled */ + private void AsyncProgress(object sender, WritingProgressChangedEventArgs e) + { + if (PrintUpdate != null) + { + gsPrintEventArgs info = new gsPrintEventArgs(PrintStatus_t.PRINT_BUSY, + false, e.Number); + PrintUpdate(this, info); + } + } + + /* Print ticket handling. You can customize for PrintTicketLevel at + FixedDocumentSequencePrintTicket, FixedDocumentPrintTicket, + or FixedPagePrintTicket. We may want to play around with this some */ + private void PrintTicket(Object sender, WritingPrintTicketRequiredEventArgs e) + { + if (e.CurrentPrintTicketLevel == + PrintTicketLevel.FixedDocumentSequencePrintTicket) + { + PrintTicket pts = new PrintTicket(); + pts.PageOrientation = PageOrientation.Portrait; + e.CurrentPrintTicket = pts; + } + } + + /* Create the document write */ + private XpsDocumentWriter GetDocWriter(PrintQueue pq) + { + XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq); + return xpsdw; + } + } +} diff --git a/platform/windows/gsview/gsprintbg.cs b/platform/windows/gsview/gsprintbg.cs new file mode 100644 index 00000000..199258e3 --- /dev/null +++ b/platform/windows/gsview/gsprintbg.cs @@ -0,0 +1,261 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel; +using System.IO; +using System.IO.Packaging; +using System.Printing; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Documents.Serialization; +using System.Windows.Media; +using System.Windows.Xps; +using System.Windows.Xps.Packaging; +using System.Windows.Xps.Serialization; +using System.Threading; + +namespace gsview +{ + public enum PrintStatus_t + { + PRINT_READY, + PRINT_BUSY, + PRINT_ERROR + }; + + public enum PrintResult_t + { + PrintOK, + PrintFAILED, + PrintCANCELLED, + PrintCOMPLETED + } + + public struct PrintParams_t + { + public int num_pages; + public int start_page; + public int end_page; + public PrintQueue queu; + public FixedDocumentSequence fixdoc; + public PrintResult_t result; + public PrintStatus_t status; + + }; + + public class PrintEventArgs : EventArgs + { + private PrintStatus_t m_status; + private PrintResult_t m_result; + private int m_percentdone; + + public PrintStatus_t Status + { + get { return m_status; } + } + + public PrintResult_t Result + { + get { return m_result; } + } + + public int Percent + { + get { return m_percentdone; } + } + + public PrintEventArgs(PrintStatus_t status, PrintResult_t completed, int percent) + { + m_status = status; + m_result = completed; + m_percentdone = percent; + } + } + + public class gsprintbg + { + BackgroundWorker m_worker; + private XpsDocumentWriter m_docWriter = null; + PrintParams_t m_pparams; + + internal delegate void PrintCallBackMain(object gsObject, PrintEventArgs info); + internal event PrintCallBackMain PrintUpdateMain; + + private void PrintProgressChanged(object sender, ProgressChangedEventArgs e) + { + /* Callback with progress */ + PrintEventArgs info = new PrintEventArgs(m_pparams.status, m_pparams.result, e.ProgressPercentage); + if (PrintUpdateMain != null) + PrintUpdateMain(this, info); + } + + /* Callback */ + private void PrintCompleted(object sender, RunWorkerCompletedEventArgs e) + { + PrintParams_t Value; + PrintEventArgs info; + PrintParams_t Params = (PrintParams_t)e.Result; + + if (e.Cancelled) + { + info = new PrintEventArgs(PrintStatus_t.PRINT_READY, PrintResult_t.PrintCANCELLED, 100); + } + else + { + Value = (PrintParams_t)e.Result; + info = new PrintEventArgs(PrintStatus_t.PRINT_READY, PrintResult_t.PrintCOMPLETED, 100); + } + PrintUpdateMain(this, info); + } + + + /* Show std. print dialog */ + public PrintDialog GetPrintDialog() + { + PrintDialog dlg = new PrintDialog(); + /* Current page and page ranges is going to require a little work */ + dlg.PageRangeSelection = PageRangeSelection.AllPages; + //dlg.UserPageRangeEnabled = true; + //dlg.CurrentPageEnabled = true; + dlg.SelectedPagesEnabled = false; + if (dlg.ShowDialog() == true) + return dlg; + return null; + } + + /* Main print entry point */ + private void Print(PrintParams_t pparams) + { + XpsDocumentWriter docwrite = GetDocWriter(pparams.queu); + docwrite.WritingPrintTicketRequired += + new WritingPrintTicketRequiredEventHandler(PrintTicket); + PrintPages(docwrite, pparams.fixdoc); + } + + /* Send it */ + private void PrintPages(XpsDocumentWriter xpsdw, FixedDocumentSequence fixdoc) + { + m_docWriter = xpsdw; + xpsdw.WritingCompleted += + new WritingCompletedEventHandler(AsyncCompleted); + xpsdw.WritingProgressChanged += + new WritingProgressChangedEventHandler(AsyncProgress); + xpsdw.WriteAsync(fixdoc); + } + + private void CancelAsync() + { + /* ick. This does not work in windows 8. causes crash */ + /* https://connect.microsoft.com/VisualStudio/feedback/details/778145/xpsdocumentwriter-cancelasync-cause-crash-in-win8 */ + m_docWriter.CancelAsync(); + } + + /* Done */ + private void AsyncCompleted(object sender, WritingCompletedEventArgs e) + { + if (e.Cancelled) + m_pparams.result = PrintResult_t.PrintCANCELLED; + else if (e.Error != null) + m_pparams.result = PrintResult_t.PrintFAILED; + else + m_pparams.result = PrintResult_t.PrintCOMPLETED; + m_worker.ReportProgress(100); + } + + /* Do this update with each fixed document (page) that is handled */ + private void AsyncProgress(object sender, WritingProgressChangedEventArgs e) + { + double perc = 100.0 * (double) e.Number / (double) m_pparams.num_pages; + m_worker.ReportProgress((int) perc); + } + + /* Print ticket handling. You can customize for PrintTicketLevel at + FixedDocumentSequencePrintTicket, FixedDocumentPrintTicket, + or FixedPagePrintTicket. We may want to play around with this some */ + private void PrintTicket(Object sender, WritingPrintTicketRequiredEventArgs e) + { + if (e.CurrentPrintTicketLevel == + PrintTicketLevel.FixedDocumentSequencePrintTicket) + { + PrintTicket pts = new PrintTicket(); + pts.PageOrientation = PageOrientation.Portrait; + e.CurrentPrintTicket = pts; + } + } + + /* Create the document write */ + private XpsDocumentWriter GetDocWriter(PrintQueue pq) + { + XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq); + return xpsdw; + } + + + private void PrintWork(object sender, DoWorkEventArgs e) + { + PrintParams_t PParams = (PrintParams_t)e.Argument; + BackgroundWorker worker = sender as BackgroundWorker; + + Print(PParams); + } + + public bool IsBusy() + { + if (m_worker != null) + return m_worker.IsBusy; + else + return false; + } + + public void PrintWorkThread(object data) + { + PrintParams_t PParams = (PrintParams_t) data; + Print(PParams); + } + + public PrintStatus_t StartPrint(PrintParams_t pparams) + { + try + { + if (m_worker != null && m_worker.IsBusy) + { + m_worker.CancelAsync(); + return PrintStatus_t.PRINT_BUSY; + } + + if (m_worker == null) + { + + Thread asyncThread = new Thread(PrintWorkThread); + asyncThread.SetApartmentState(ApartmentState.STA); + asyncThread.Start(pparams); + + /* m_worker = new BackgroundWorker(); + m_worker.WorkerReportsProgress = true; + m_worker.WorkerSupportsCancellation = true; + m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(PrintCompleted); + m_worker.ProgressChanged += new ProgressChangedEventHandler(PrintProgressChanged); + m_worker.DoWork += new DoWorkEventHandler(PrintWork);*/ + } + + ////m_pparams = pparams; + //m_worker.RunWorkerAsync(pparams); + pparams.status = PrintStatus_t.PRINT_BUSY; + return PrintStatus_t.PRINT_READY; + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during printing\n"); + return PrintStatus_t.PRINT_ERROR; + } + } + + + public void Cancel() + { + m_worker.CancelAsync(); + } + } +} diff --git a/platform/windows/gsview/gsview.csproj b/platform/windows/gsview/gsview.csproj new file mode 100644 index 00000000..31f40f51 --- /dev/null +++ b/platform/windows/gsview/gsview.csproj @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{5DA0ECC9-4026-4427-862F-E3226EFEFEB1}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>gsview</RootNamespace> + <AssemblyName>gsview</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + <IsWebBootstrapper>false</IsWebBootstrapper> + <TargetFrameworkProfile /> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>6.0.0.%2a</ApplicationVersion> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>TRACE;DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup> + <StartupObject /> + </PropertyGroup> + <PropertyGroup> + <ApplicationIcon>gsview_app.ico</ApplicationIcon> + </PropertyGroup> + <ItemGroup> + <Reference Include="ReachFramework" /> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Printing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Xaml"> + <RequiredTargetFramework>4.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Xml.Linq" /> + <Reference Include="UIAutomationProvider" /> + <Reference Include="UIAutomationTypes" /> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <ApplicationDefinition Include="App.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </ApplicationDefinition> + <Compile Include="About.xaml.cs"> + <DependentUpon>About.xaml</DependentUpon> + </Compile> + <Compile Include="ContentEntry.cs" /> + <Compile Include="ContentItem.cs" /> + <Compile Include="Convert.xaml.cs"> + <DependentUpon>Convert.xaml</DependentUpon> + </Compile> + <Compile Include="DocPage.cs" /> + <Compile Include="ghostsharp.cs" /> + <Compile Include="gsIO.cs" /> + <Compile Include="gsOutput.xaml.cs"> + <DependentUpon>gsOutput.xaml</DependentUpon> + </Compile> + <Compile Include="gsprint.cs" /> + <Compile Include="Info.xaml.cs"> + <DependentUpon>Info.xaml</DependentUpon> + </Compile> + <Compile Include="Links.cs" /> + <Compile Include="mudocument.cs" /> + <Compile Include="OutputIntent.xaml.cs"> + <DependentUpon>OutputIntent.xaml</DependentUpon> + </Compile> + <Compile Include="PageExtractSave.xaml.cs"> + <DependentUpon>PageExtractSave.xaml</DependentUpon> + </Compile> + <Compile Include="Password.xaml.cs"> + <DependentUpon>Password.xaml</DependentUpon> + </Compile> + <Compile Include="RectList.cs" /> + <Compile Include="Selection.xaml.cs"> + <DependentUpon>Selection.xaml</DependentUpon> + </Compile> + <Compile Include="Strings\en-US\Messages.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Messages.resx</DependentUpon> + </Compile> + <Compile Include="TextBlock.cs" /> + <Compile Include="TextCharacter.cs" /> + <Compile Include="TextLine.cs" /> + <Page Include="About.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Convert.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="gsOutput.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Info.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="MainWindow.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Compile Include="App.xaml.cs"> + <DependentUpon>App.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + <Compile Include="MainWindow.xaml.cs"> + <DependentUpon>MainWindow.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + <Page Include="OutputIntent.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="PageExtractSave.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Password.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Selection.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>PublicResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <EmbeddedResource Include="Strings\en-US\Messages.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Messages.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + <AppDesigner Include="Properties\" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\ActualSize48.png" /> + <Resource Include="Resources\Close.ico" /> + <Resource Include="Resources\ContScrollFill48.png" /> + <Resource Include="Resources\ExpandFill48.png" /> + <Resource Include="Resources\info.png" /> + <Resource Include="Resources\Message.png" /> + <Resource Include="Resources\OpenFile.png" /> + <Resource Include="Resources\printer.ico" /> + <Resource Include="Resources\saveHS.png" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include=".NETFramework,Version=v4.5"> + <Visible>False</Visible> + <ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>false</Install> + </BootstrapperPackage> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\Left.ico" /> + <Resource Include="Resources\Right.ico" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\thumbnail.ico" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\hyperlink.png" /> + <Resource Include="Resources\search.ico" /> + <Resource Include="Resources\zoom_in.ico" /> + <Resource Include="Resources\zoom_out.ico" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\search.png" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\contents.ico" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\folder_open.ico" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\FloppyDisk.ico" /> + </ItemGroup> + <ItemGroup> + <None Include="Resources\copy.ico" /> + </ItemGroup> + <ItemGroup> + <WCFMetadata Include="Service References\" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\banner.png" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Resources\gsview_app.ico" /> + </ItemGroup> + <ItemGroup> + <None Include="Resources\PDF.bmp" /> + </ItemGroup> + <ItemGroup> + <Resource Include="gsview_app.ico" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/platform/windows/gsview/gsview.visualelementsmanifest.xml b/platform/windows/gsview/gsview.visualelementsmanifest.xml new file mode 100644 index 00000000..865a37fc --- /dev/null +++ b/platform/windows/gsview/gsview.visualelementsmanifest.xml @@ -0,0 +1,7 @@ +<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <VisualElements + BackgroundColor="#FFFFFF" + ShowNameOnSquare150x150Logo="on" + ForegroundText="dark" + /> +</Application>
\ No newline at end of file diff --git a/platform/windows/gsview/gsview_app.ico b/platform/windows/gsview/gsview_app.ico Binary files differnew file mode 100644 index 00000000..29c5ca50 --- /dev/null +++ b/platform/windows/gsview/gsview_app.ico diff --git a/platform/windows/gsview/mudocument.cs b/platform/windows/gsview/mudocument.cs new file mode 100644 index 00000000..291a424e --- /dev/null +++ b/platform/windows/gsview/mudocument.cs @@ -0,0 +1,1747 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +//using System.Threading.Tasks; +using System.Threading; +using System.Runtime.InteropServices; +using System.Security; +using System.Windows; +using System.ComponentModel; +using System.Windows.Forms; + +/* This file contains the interface between the muctx cpp class, which + implements the mupdf calls and the .net managed code */ + +namespace gsview +{ + /* Parameters for conversion */ + public struct ConvertParams_t + { + public int resolution; + public gsDevice_t device; + public String outputfile; + public int num_pages; + public System.Collections.IList pages; + public int currpage; + public GS_Result_t result; + }; + + /* Must match enum in muctx.h */ + enum mudevice_t + { + SVG_OUT, + PNM_OUT, + PCL_OUT, + PWG_OUT, + }; + + public class muPDFEventArgs : EventArgs + { + private bool m_completed; + private int m_progress; + private ConvertParams_t m_param; + + public bool Completed + { + get { return m_completed; } + } + + public ConvertParams_t Params + { + get { return m_param; } + } + + public int Progress + { + get { return m_progress; } + } + + public muPDFEventArgs(bool completed, int progress, ConvertParams_t param) + { + m_completed = completed; + m_progress = progress; + m_param = param; + } + } + + public struct content_s + { + public int page; + public IntPtr string_margin; + } + + [SuppressUnmanagedCodeSecurity] + class mudocument + { + public bool is64bit; + IntPtr mu_object; + BackgroundWorker m_worker; + ConvertParams_t m_params; + /* Callbacks to Main */ + internal delegate void mupdfDLLProblem(object muObject, String mess); + internal event mupdfDLLProblem mupdfDLLProblemMain; + internal delegate void mupdfCallBackMain(object muObject, muPDFEventArgs info); + internal event mupdfCallBackMain mupdfUpdateMain; + + private System.Object m_lock = new System.Object(); + public List<ContentItem> contents; + + #region DLLInterface + /* The list of functions that we use to call into C interface of muctx. + * Calling into C++ code from managed code is complex. Since CLR + * compiling is needed and that does not support mutex. Hence the C + * interface */ + [DllImport("mupdfnet64.dll", EntryPoint = "mInitialize", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mInitialize64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mOpenDocument", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern status_t mOpenDocument64(IntPtr ctx, string filename); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCleanUp", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mCleanUp64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetPageCount", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetPageCount64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRequiresPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mRequiresPassword64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mApplyPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mApplyPassword64(IntPtr ctx, string password); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRenderPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPage64(IntPtr ctx, int page_num, + Byte[] bmp_data, int bmp_width, int bmp_height, double scale, + bool flipy); + + [DllImport("mupdfnet64.dll", EntryPoint = "mMeasurePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mMeasurePage64(IntPtr ctx, int page_num, + ref double width, ref double height); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetContents64(IntPtr ctx); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseContents64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mSetAA", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mSetAA64(IntPtr ctx, int level); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetContentsItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetContentsItem64(int k, ref int len, ref int page); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayList", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayList64(IntPtr ctx, int page_num, + ref int page_width, ref int page_height); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayListAnnot", + CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListAnnot64(IntPtr ctx, int page_num); + + [DllImport("mupdfnet64.dll", EntryPoint = "mCreateDisplayListText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListText64(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length); + + [DllImport("mupdfnet64.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPageMT64(IntPtr ctx, IntPtr dlist, + IntPtr annot_dlist, int page_width, int page_height, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy); + + [DllImport("mupdfnet64.dll", EntryPoint = "mTextSearchPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mTextSearchPage64(IntPtr ctx, int page_num, + string needle); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextSearchItem", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mGetTextSearchItem64(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseTextSearch", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseTextSearch64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetLinksPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetLinksPage64(IntPtr ctx, int page_num); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetLinkItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetLinkItem64(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseLink", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseLink64(); + + [DllImport("mupdfnet64.dll", EntryPoint = "mReleaseText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseText64(IntPtr ctx, IntPtr textpage); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextBlock", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextBlock64(IntPtr textpage, int block_num, + ref double top_x,ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextLine", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextLine64(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mGetTextCharacter", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextCharacter64(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet64.dll", EntryPoint = "mExtractPages", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mExtractPages64(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages); + + [DllImport("mupdfnet64.dll", EntryPoint = "mSavePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mSavePage64(IntPtr ctx, String outfile, + int page_num, int res, int type, bool append); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetVers", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetVers64(); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet64.dll", EntryPoint = "mGetText", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetText64(IntPtr ctx, int pagenum, int type); + + /* And the 32bit version */ + [DllImport("mupdfnet32.dll", EntryPoint = "mInitialize", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mInitialize32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mOpenDocument", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern status_t mOpenDocument32(IntPtr ctx, string filename); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCleanUp", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mCleanUp32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetPageCount", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetPageCount32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRequiresPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mRequiresPassword32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mApplyPassword", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mApplyPassword32(IntPtr ctx, string password); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRenderPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPage32(IntPtr ctx, int page_num, + Byte[] bmp_data, int bmp_width, int bmp_height, double scale, + bool flipy); + + [DllImport("mupdfnet32.dll", EntryPoint = "mMeasurePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mMeasurePage32(IntPtr ctx, int page_num, + ref double width, ref double height); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetContents32(IntPtr ctx); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseContents", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseContents32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mSetAA", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mSetAA32(IntPtr ctx, int level); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetContentsItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetContentsItem32(int k, ref int len, ref int page); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayList", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayList32(IntPtr ctx, int page_num, + ref int page_width, ref int page_height); + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayListAnnot", + CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListAnnot32(IntPtr ctx, int page_num); + + + [DllImport("mupdfnet32.dll", EntryPoint = "mCreateDisplayListText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr mCreateDisplayListText32(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length); + + [DllImport("mupdfnet32.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mRenderPageMT32(IntPtr ctx, IntPtr dlist, + IntPtr annot_dlist, int page_width, int page_height, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy); + + [DllImport("mupdfnet32.dll", EntryPoint = "mTextSearchPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mTextSearchPage32(IntPtr ctx, int page_num, + string needle); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextSearchItem", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern bool mGetTextSearchItem32(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseTextSearch", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseTextSearch32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetLinksPage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetLinksPage32(IntPtr ctx, int page_num); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetLinkItem", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetLinkItem32(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseLink", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseLink32(); + + [DllImport("mupdfnet32.dll", EntryPoint = "mReleaseText", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern void mReleaseText32(IntPtr ctx, IntPtr textpage); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextBlock", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextBlock32(IntPtr textpage, int block_num, + ref double top_x, ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextLine", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextLine32(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mGetTextCharacter", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mGetTextCharacter32(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width); + + [DllImport("mupdfnet32.dll", EntryPoint = "mExtractPages", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mExtractPages32(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages); + + [DllImport("mupdfnet32.dll", EntryPoint = "mSavePage", CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + private static extern int mSavePage32(IntPtr ctx, String outfile, + int page_num, int res, int type, bool append); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetVers", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetVers32(); + + /* The managed code Marshal actually releases the allocated string from C */ + [DllImport("mupdfnet32.dll", EntryPoint = "mGetText", CharSet = CharSet.Ansi, + CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.LPStr)] + private static extern string mGetText32(IntPtr ctx, int pagenum, int type); + + #endregion DLLInterface + + #region DLLErrorTrap + /* And make sure we can catch any issues in finding the DLL or if we have + * a 32bit 64bit issue */ + private IntPtr tc_mInitialize() + { + IntPtr output; + try + { + if (is64bit) + output = mInitialize64(); + else + output = mInitialize32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 1"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private status_t tc_mOpenDocument(IntPtr ctx, string filename) + { + status_t output; + try + { + if (is64bit) + output = mOpenDocument64(ctx, filename); + else + output = mOpenDocument32(ctx, filename); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 2"; + mupdfDLLProblemMain(this, err); + return status_t.E_FAILURE; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return status_t.E_FAILURE; + } + return output; + } + + private int tc_mCleanUp(IntPtr ctx) + { + try + { + if (is64bit) + mCleanUp64(ctx); + else + mCleanUp32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 3"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetPageCount(IntPtr ctx) + { + int output; + try + { + if (is64bit) + output = mGetPageCount64(ctx); + else + output = mGetPageCount32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 4"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private bool tc_mRequiresPassword(IntPtr ctx) + { + bool output; + try + { + if (is64bit) + output = mRequiresPassword64(ctx); + else + output = mRequiresPassword32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 5"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private bool tc_mApplyPassword(IntPtr ctx, string password) + { + bool output; + try + { + if (is64bit) + output = mApplyPassword64(ctx, password); + else + output = mApplyPassword32(ctx, password); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 6"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private int tc_mRenderPage(IntPtr ctx, int page_num, Byte[] bmp_data, + int bmp_width, int bmp_height, double scale, bool flipy) + { + int output; + try + { + if (is64bit) + output = mRenderPage64(ctx, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + else + output = mRenderPage32(ctx, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 7"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mMeasurePage(IntPtr ctx, int page_num, ref double width, + ref double height) + { + int output; + try + { + if (is64bit) + output = mMeasurePage64(ctx, page_num, ref width, ref height); + else + output = mMeasurePage32(ctx, page_num, ref width, ref height); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 8"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetContents(IntPtr ctx) + { + int output; + try + { + if (is64bit) + output = mGetContents64(ctx); + else + output = mGetContents32(ctx); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 9"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mReleaseContents() + { + try + { + if (is64bit) + mReleaseContents64(); + else + mReleaseContents32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 10"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private string tc_mGetContentsItem(int k, ref int len, ref int page) + { + String output; + try + { + if (is64bit) + output = mGetContentsItem64(k, ref len, ref page); + else + output = mGetContentsItem32(k, ref len, ref page); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 11"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private IntPtr tc_mCreateDisplayListAnnot(IntPtr ctx, int page_num) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayListAnnot64(ctx, page_num); + else + output = mCreateDisplayListAnnot32(ctx, page_num); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 12"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private IntPtr tc_mCreateDisplayList(IntPtr ctx, int page_num, + ref int page_width, ref int page_height) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayList64(ctx, page_num, ref page_width, + ref page_height); + else + output = mCreateDisplayList32(ctx, page_num, ref page_width, + ref page_height); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 13"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private int tc_mSetAA(IntPtr ctx, int level) + { + try + { + if (is64bit) + mSetAA64(ctx, level); + else + mSetAA32(ctx, level); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 14"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private IntPtr tc_mCreateDisplayListText(IntPtr ctx, int page_num, + ref int page_width, ref int page_height, ref IntPtr text, ref int length) + { + IntPtr output; + try + { + if (is64bit) + output = mCreateDisplayListText64(ctx, page_num, ref page_width, + ref page_height, ref text, ref length); + else + output = mCreateDisplayListText32(ctx, page_num, ref page_width, + ref page_height, ref text, ref length); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 15"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return IntPtr.Zero; + } + return output; + } + + private int tc_mRenderPageMT(IntPtr ctx, IntPtr dlist, IntPtr annot_dlist, + int page_width, int page_height, Byte[] bmp_data, int bmp_width, + int bmp_height, double scale, bool flipy) + { + int output; + try + { + if (is64bit) + output = mRenderPageMT64(ctx, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + else + output = mRenderPageMT32(ctx, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 16"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mTextSearchPage(IntPtr ctx, int page_num, string needle) + { + int output; + try + { + if (is64bit) + output = mTextSearchPage64(ctx, page_num, needle); + else + output = mTextSearchPage32(ctx, page_num, needle); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 17"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private bool tc_mGetTextSearchItem(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width) + { + bool output; + try + { + if (is64bit) + output = mGetTextSearchItem64(item_num, ref top_x, ref top_y, + ref height, ref width); + else + output = mGetTextSearchItem32(item_num, ref top_x, ref top_y, + ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 18"; + mupdfDLLProblemMain(this, err); + return false; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return false; + } + return output; + } + + private int tc_mReleaseTextSearch() + { + try + { + if (is64bit) + mReleaseTextSearch64(); + else + mReleaseTextSearch32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 18"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetLinksPage(IntPtr ctx, int page_num) + { + int output; + try + { + if (is64bit) + output = mGetLinksPage64(ctx, page_num); + else + output = mGetLinksPage32(ctx, page_num); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 19"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private string tc_mGetLinkItem(int item_num, ref double top_x, + ref double top_y, ref double height, ref double width, ref int topage, + ref int type) + { + String output; + try + { + if (is64bit) + output = mGetLinkItem64(item_num, ref top_x, ref top_y, ref height, + ref width, ref topage, ref type); + else + output = mGetLinkItem32(item_num, ref top_x, ref top_y, ref height, + ref width, ref topage, ref type); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 20"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private int tc_mReleaseLink() + { + try + { + if (is64bit) + mReleaseLink64(); + else + mReleaseLink32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 21"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mReleaseText(IntPtr ctx, IntPtr textpage) + { + try + { + if (is64bit) + mReleaseText64(ctx, textpage); + else + mReleaseText32(ctx, textpage); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 22"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return 0; + } + + private int tc_mGetTextBlock(IntPtr textpage, int block_num, + ref double top_x, ref double top_y, ref double height, ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextBlock64(textpage, block_num, ref top_x, + ref top_y, ref height, ref width); + else + output = mGetTextBlock32(textpage, block_num, ref top_x, + ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 23"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetTextLine(IntPtr textpage, int block_num, + int line_num, ref double top_x, ref double top_y, ref double height, + ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextLine64(textpage, block_num, line_num, + ref top_x, ref top_y, ref height, ref width); + else + output = mGetTextLine32(textpage, block_num, line_num, + ref top_x, ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 24"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mGetTextCharacter(IntPtr textpage, int block_num, + int line_num, int item_num, ref double top_x, + ref double top_y, ref double height, ref double width) + { + int output; + try + { + if (is64bit) + output = mGetTextCharacter64(textpage, block_num, line_num, + item_num, ref top_x, ref top_y, ref height, ref width); + else + output = mGetTextCharacter32(textpage, block_num, line_num, + item_num, ref top_x, ref top_y, ref height, ref width); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 25"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private int tc_mExtractPages(String infile, String outfile, + String password, bool has_password, bool linearize, int num_pages, + IntPtr pages) + { + int output; + try + { + if (is64bit) + output = mExtractPages64(infile, outfile, password, has_password, + linearize, num_pages, pages); + else + output = mExtractPages32(infile, outfile, password, has_password, + linearize, num_pages, pages); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 26"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + + private string tc_mGetVers() + { + String output; + try + { + if (is64bit) + output = mGetVers64(); + else + output = mGetVers32(); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 27"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private string tc_mGetText(IntPtr ctx, int pagenum, textout_t type) + { + String output; + try + { + if (is64bit) + output = mGetText64(ctx, pagenum, (int) type); + else + output = mGetText32(ctx, pagenum, (int) type); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 28"; + mupdfDLLProblemMain(this, err); + return null; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return null; + } + return output; + } + + private int tc_mSavePage(IntPtr ctx, String outfile, int page_num, + int res, int type, bool append) + { + int output; + try + { + if (is64bit) + output = mSavePage64(ctx, outfile, page_num, res, type, append); + else + output = mSavePage32(ctx, outfile, page_num, res, type, append); + } + catch (DllNotFoundException) + { + /* DLL not found */ + String err = "DllNotFoundException: MuPDF DLL not found 29"; + mupdfDLLProblemMain(this, err); + return -1; + } + catch (BadImageFormatException) + { + /* Using 32 bit with 64 or vice versa */ + String err = "BadImageFormatException: Incorrect MuPDF DLL"; + mupdfDLLProblemMain(this, err); + return -1; + } + return output; + } + #endregion DLLErrorTrap + + /* Now the actual code that does some work */ + public status_t Initialize() + { + is64bit = Environment.Is64BitOperatingSystem && + Environment.Is64BitProcess; + + mu_object = tc_mInitialize(); + if (mu_object == null) + return status_t.E_FAILURE; + else + return status_t.S_ISOK; + } + + public void CleanUp() + { + if (mu_object != null) + { + lock(m_lock) + tc_mCleanUp(mu_object); + } + } + + public String GetText(int page_num, textout_t type) + { + return tc_mGetText(mu_object, page_num, type); + } + + public void GetVersion(out String vers) + { + vers = tc_mGetVers(); + } + + public int GetPageCount() + { + return tc_mGetPageCount(mu_object); + } + + public bool RequiresPassword() + { + return tc_mRequiresPassword(mu_object); + } + + public bool ApplyPassword(String password) + { + return tc_mApplyPassword(mu_object, password); + } + + public void SetAA(AA_t AAlevel) + { + lock (m_lock) + { + tc_mSetAA(mu_object, (int)AAlevel); + } + } + + public int RenderPage(int page_num, Byte[] bmp_data, int bmp_width, + int bmp_height, double scale, bool flipy, bool use_dlist, bool + get_text, out BlocksText blocks, bool annotation, + out Annotate_t annot_type) + { + int code; + blocks = null; + String blockcolor = "#00FFFFFF"; + String linecolor = "#402572AC"; + /* Debug */ + //blockcolor = "#20FFFF00"; + + annot_type = Annotate_t.UNKNOWN; + if (use_dlist) + { + IntPtr dlist = IntPtr.Zero; + IntPtr annot_dlist = IntPtr.Zero; + IntPtr text = IntPtr.Zero; + int num_blocks = 0; + + int page_height = 0; + int page_width = 0; + + if (get_text) + { + lock (m_lock) + { + dlist = tc_mCreateDisplayListText(mu_object, page_num, + ref page_width, ref page_height, ref text, ref num_blocks); + } + /* If we have some text go ahead and get the bounding boxes + * now. There is likely a better way to do this with passing + * a structure across the boundary in a single call. ToDO */ + /* Length here is the number of blocks. mupdf splits block + * into lines (spans) and then these into text characters + * Our goal here is to get them into a structure that we + * can rapidly use in our ui display. Maintaining the block + * and span stucture so that we can minimize the number of + * rects that are introduced */ + if (num_blocks > 0) + { + blocks = new BlocksText(); + for (int kk = 0; kk < num_blocks; kk++) + { + double top_x = 0, top_y = 0, height = 0, width = 0; + var block = new TextBlock(); + + int num_lines = tc_mGetTextBlock(text, kk, ref top_x, + ref top_y, ref height, ref width); + + block.X = top_x; + block.Y = top_y; + block.Width = width; + block.Height = height; + block.Color = blockcolor; + block.Scale = 1.0; + block.PageNumber = page_num; + blocks.Add(block); + + blocks[kk].TextLines = new List<TextLine>(); + for (int jj = 0; jj < num_lines; jj++) + { + var line = new TextLine(); + int num_chars = tc_mGetTextLine(text, kk, jj, ref top_x, + ref top_y, ref height, ref width); + line.X = top_x; + line.Y = top_y; + line.Width = width; + line.Height = height; + line.Scale = 1.0; + line.Color = linecolor; + blocks[kk].TextLines.Add(line); + + blocks[kk].TextLines[jj].TextCharacters = new List<TextCharacter>(); + for (int mm = 0; mm < num_chars; mm++) + { + var textchars = new TextCharacter(); + int character = tc_mGetTextCharacter(text, kk, jj, mm, ref top_x, + ref top_y, ref height, ref width); + textchars.X = top_x; + textchars.Y = top_y; + textchars.Width = width; + textchars.Height = height; + textchars.Scale = 1.0; + textchars.Color = linecolor; + textchars.character = System.Convert.ToChar(character).ToString(); + blocks[kk].TextLines[jj].TextCharacters.Add(textchars); + } + } + } + /* We are done with the text object */ + tc_mReleaseText(mu_object, text); + } + } + else + lock (m_lock) + { + dlist = tc_mCreateDisplayList(mu_object, page_num, + ref page_width, ref page_height); + } + if (annotation) + { + lock (m_lock) + { + annot_dlist = tc_mCreateDisplayListAnnot(mu_object, page_num); + if (annot_dlist == IntPtr.Zero) + annot_type = Annotate_t.NO_ANNOTATE; + else + annot_type = Annotate_t.HAS_ANNOTATE; + } + } + + /* Rendering of display list can occur with other threads so unlock */ + if (dlist == null) + { + return (int) status_t.E_FAILURE; + } + code = tc_mRenderPageMT(mu_object, dlist, annot_dlist, page_width, + page_height, bmp_data, bmp_width, bmp_height, scale, flipy); + } + else + { + lock(m_lock) + { + code = tc_mRenderPage(mu_object, page_num, bmp_data, bmp_width, + bmp_height, scale, flipy); + } + } + return code; + } + + public status_t OpenFile(string filename) + { + return tc_mOpenDocument(mu_object, filename); + } + + public int GetPageSize(int page_num, out Point size_out) + { + int code; + double height = 0, width = 0; + + size_out = new Point(); + + lock(m_lock) + { + code = tc_mMeasurePage(mu_object, page_num, ref width, ref height); + } + + size_out.X = width; + size_out.Y = height; + return code; + } + + public int ComputeContents() + { + int num_items; + int len = 0, page = 0; + + lock(m_lock) + { + num_items = tc_mGetContents(mu_object); + } + + if (contents == null) + contents = new List<ContentItem>(); + + for (int k = 0; k < num_items; k++) + { + ContentItem item = new ContentItem(); + item.StringMargin = tc_mGetContentsItem(k, ref len, ref page); + item.Page = page; + contents.Add(item); + } + return num_items; + } + + public void ReleaseContents() + { + tc_mReleaseContents(); + } + + public int TextSearchPage(int page_num, String needle) + { + int num_found; + lock (m_lock) + { + num_found = tc_mTextSearchPage(mu_object, page_num, needle); + } + return num_found; + } + + public bool GetTextSearchItem(int k, out Point top_left, out Size size_rect) + { + double top_x = 0, top_y = 0 , height = 0, width = 0; + bool found = tc_mGetTextSearchItem(k, ref top_x, ref top_y, ref height, ref width); + + top_left = new Point(); + size_rect = new Size(); + + top_left.X = top_x; + top_left.Y = top_y; + size_rect.Width = width; + size_rect.Height = height; + + return found; + } + + public void ReleaseTextSearch() + { + tc_mReleaseTextSearch(); + } + + public int GetLinksPage(int page_num) + { + int num_found; + lock (m_lock) + { + num_found = tc_mGetLinksPage(mu_object, page_num); + } + return num_found; + } + + public void GetLinkItem(int k, out Point top_left, out Size size_rect, + out String uri, out int topage, out int typea) + { + double top_x = 0, top_y = 0, height = 0, width = 0; + int typeb = 0; + int linkpage = 0; + + uri = tc_mGetLinkItem(k, ref top_x, ref top_y, ref height, ref width, + ref linkpage, ref typeb); + + topage = linkpage; + typea = typeb; + top_left = new Point(); + size_rect = new Size(); + + top_left.X = top_x; + top_left.Y = top_y; + size_rect.Width = width; + size_rect.Height = height; + } + + public void ReleaseLink() + { + tc_mReleaseLink(); + } + + public void ReleaseText(IntPtr textpage) + { + tc_mReleaseText(mu_object, textpage); + } + + public void HTMLSaveAs(String infile, String outfile, String password, + bool has_password, bool linearize, int num_pages, System.Collections.IList pages) + { + if (num_pages > 0) + { + /* We need to do an allocation for our array of page numbers and + * perform pinning to avoid GC while in the c++ code */ + GCHandle pagesPtrStable; + int[] page_list; + page_list = new int[pages.Count]; + + for (int kk = 0; kk < pages.Count; kk++) + { + SelectPage currpage = (SelectPage)pages[kk]; + page_list[kk] = currpage.Page; + } + pagesPtrStable = GCHandle.Alloc(page_list, GCHandleType.Pinned); + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, pagesPtrStable.AddrOfPinnedObject()); + pagesPtrStable.Free(); + } + else + { + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, IntPtr.Zero); + } + } + + public void PDFExtract(String infile, String outfile, String password, + bool has_password, bool linearize, int num_pages, System.Collections.IList pages) + { + if (num_pages > 0) + { + /* We need to do an allocation for our array of page numbers and + * perform pinning to avoid GC while in the c++ code */ + GCHandle pagesPtrStable; + int[] page_list; + page_list = new int[pages.Count]; + + for (int kk = 0; kk < pages.Count; kk++) + { + SelectPage currpage = (SelectPage)pages[kk]; + page_list[kk] = currpage.Page; + } + pagesPtrStable = GCHandle.Alloc(page_list, GCHandleType.Pinned); + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, pagesPtrStable.AddrOfPinnedObject()); + pagesPtrStable.Free(); + } + else + { + tc_mExtractPages(infile, outfile, password, has_password, linearize, + num_pages, IntPtr.Zero); + } + } + + public gsStatus ConvertSave(gsDevice_t device, String outputFile, int num_pages, + System.Collections.IList pages, int resolution) + { + ConvertParams_t convertparams = new ConvertParams_t(); + + convertparams.device = device; + convertparams.outputfile = outputFile; + convertparams.num_pages = num_pages; + convertparams.resolution = resolution; + convertparams.pages = pages; + convertparams.currpage = 1; + return ConvertMuPDF(convertparams); + } + + /* Render page by page in background with progress call back */ + private gsStatus ConvertMuPDF(ConvertParams_t Params) + { + try + { + if (m_worker != null && m_worker.IsBusy) + { + m_worker.CancelAsync(); + return gsStatus.GS_BUSY; + } + if (m_worker == null) + { + m_worker = new BackgroundWorker(); + m_worker.WorkerReportsProgress = true; + m_worker.WorkerSupportsCancellation = true; + m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MuPDFCompleted); + m_worker.ProgressChanged += new ProgressChangedEventHandler(MuPDFProgressChanged); + m_worker.DoWork += new DoWorkEventHandler(MuPDFWork); + } + + m_params = Params; + m_worker.RunWorkerAsync(Params); + return gsStatus.GS_READY; + } + catch (OutOfMemoryException e) + { + Console.WriteLine("Memory allocation failed during mupdf rendering\n"); + return gsStatus.GS_ERROR; + } + } + + private void MuPDFCompleted(object sender, RunWorkerCompletedEventArgs e) + { + ConvertParams_t Value; + muPDFEventArgs info; + + if (e.Cancelled) + { + Value = new ConvertParams_t(); + Value.result = GS_Result_t.gsCANCELLED; + info = new muPDFEventArgs(true, 100, Value); + } + else + { + Value = (ConvertParams_t)e.Result; + info = new muPDFEventArgs(true, 100, Value); + } + mupdfUpdateMain(this, info); + } + + private void MuPDFProgressChanged(object sender, ProgressChangedEventArgs e) + { + /* Callback with progress */ + ConvertParams_t Value = new ConvertParams_t(); + muPDFEventArgs info = new muPDFEventArgs(false, e.ProgressPercentage, Value); + mupdfUpdateMain(this, info); + } + + public void Cancel() + { + m_worker.CancelAsync(); + } + + /* ToDo: do we report pages that failed? or just push on */ + private void MuPDFWork(object sender, DoWorkEventArgs e) + { + ConvertParams_t muparams = (ConvertParams_t)e.Argument; + String out_file = muparams.outputfile; + int num_pages = muparams.num_pages; + int resolution = muparams.resolution; + var pages = muparams.pages; + BackgroundWorker worker = sender as BackgroundWorker; + + muparams.result = GS_Result_t.gsOK; + + int result; + + for (int kk = 0; kk < num_pages; kk++) + { + SelectPage curr_page = (SelectPage)pages[kk]; + int page_num = curr_page.Page; + bool append = (kk != 0); + + /* Look for file extension. */ + string extension = System.IO.Path.GetExtension(out_file); + int len = extension.Length; + String new_out_file = out_file.Substring(0, out_file.Length - len); + String out_file_name = new_out_file + "_" + page_num + extension; + + /* Question: is lock valid when done from this worker thread? */ + switch (muparams.device) + { + case gsDevice_t.svg: + lock (this.m_lock) /* Single-page format */ + result = tc_mSavePage(mu_object, out_file_name, + page_num - 1, resolution, (int) mudevice_t.SVG_OUT, + false); + break; + case gsDevice_t.pnm: + lock (this.m_lock) /* Single-page format */ + result = tc_mSavePage(mu_object, out_file_name, + page_num - 1, resolution, (int)mudevice_t.PNM_OUT, + false); + break; + case gsDevice_t.pclbitmap: /* Multi-page format */ + lock (this.m_lock) + result = tc_mSavePage(mu_object, out_file, + page_num - 1, resolution, (int)mudevice_t.PCL_OUT, + append); + break; + case gsDevice_t.pwg: /* Multi-page format */ + lock (this.m_lock) + result = tc_mSavePage(mu_object, out_file, + page_num - 1, resolution, (int)mudevice_t.PWG_OUT, + append); + break; + } + double prog = (double) (kk+1.0)/((double) num_pages) * 100.0; + worker.ReportProgress((int)prog); + + if (worker.CancellationPending == true) + { + e.Cancel = true; + muparams.result = GS_Result_t.gsCANCELLED; + break; + } + } + e.Result = muparams; + return; + } + } +} |