// ===========================================================================
// ©2013-2026 WebSupergoo. All rights reserved.
//
// This source code is for use exclusively with the ABCpdf product with
// which it is distributed, under the terms of the license for that
// product. Details can be found at
//
// http://www.websupergoo.com/
//
// This copyright notice must not be deleted and must be reproduced alongside
// any sections of code extracted from this module.
// ===========================================================================
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System.Linq.Expressions;
using System.ComponentModel;
namespace Glue3DUtilities
{
[System.Security.SecuritySafeCritical]
internal static class SafeUtils {
public static GCHandle GCHandle_Alloc(object v, GCHandleType type) {
return GCHandle.Alloc(v, type);
}
public static void GCHandle_Free(ref GCHandle handle) {
handle.Free();
}
public static IntPtr GCHandle_AddrOfPinnedObject(ref GCHandle handle) {
return handle.AddrOfPinnedObject();
}
}
/// <summary>Helper class to represent version/summary>
public struct Version
{
public int major;
public int minor;
public int build;
public Version(int _major, int _minor, int _build)
{
major = _major;
minor = _minor;
build = _build;
}
public override string ToString()
{
return major.ToString() + "." + minor.ToString() + "." + build.ToString();
}
}
/// <summary>Various static utilites</summary>
public static class Utilities
{
/// <summary>Allow setting the company name (will be used when writing to APPDATA)</summary>
public static void SetCompanyName(string companyName)
{
Dll_Glue3D.SetCompanyName(companyName);
}
/// <summary>Get the currently set company name</summary>
public static string GetCompanyName()
{
return Dll_Glue3D.GetCompanyName();
}
/// <summary>Allow setting the application name (will be used when writing to APPDATA)</summary>
public static void SetApplicationName(string companyName)
{
Dll_Glue3D.SetApplicationName(companyName);
}
/// <summary>Get the currently set application name</summary>
public static string GetApplicationName()
{
return Dll_Glue3D.GetApplicationName();
}
/// <summary>Set the HiWord of an Int32</summary>
public static Int32 HiWord(Int32 number)
{
if ((number & 0x80000000) == 0x80000000)
return (number >> 16);
else
return (number >> 16) & 0xffff;
}
/// <summary>Set the LoWord of an Int32</summary>
public static Int32 LoWord(Int32 number)
{
return (number & 0xffff);
}
/// <summary>Make a DWord from the provided HiWord and LoWord</summary>
public static Int32 MakeDword(Int32 LoWord, Int32 HiWord)
{
return (HiWord << 16) | (LoWord & 0xffff);
}
/// <summary>Make a PARAM (IntPtr of a Dword)</summary>
public static IntPtr MakeParam(Int32 LoWord, Int32 HiWord)
{
return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
}
/// <summary>Convenience function to get the name of the lighting scheme as a string</summary>
public static string LightingSchemeToString(WebSupergoo.ELightingScheme scheme)
{
string outStr = "";
switch (scheme)
{
case WebSupergoo.ELightingScheme.LightingScheme_None:
outStr = "None"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Artwork:
outStr = "Artwork"; break;
case WebSupergoo.ELightingScheme.LightingScheme_White:
outStr = "White"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Day:
outStr = "Day"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Night:
outStr = "Night"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Hard:
outStr = "Hard"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Primary:
outStr = "Primary"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Blue:
outStr = "Blue"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Red:
outStr = "Red"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Cube:
outStr = "Cube"; break;
case WebSupergoo.ELightingScheme.LightingScheme_CAD:
outStr = "CAD"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Headlamp:
outStr = "Headlamp"; break;
case WebSupergoo.ELightingScheme.LightingScheme_Custom:
outStr = "Custom"; break;
default:
outStr = "<Invalid>"; break;
}
return outStr;
}
/// <summary>Create an open file dialog to ask the user to choose a file to open</summary>
public static string GetOpenFileDialogResult(string title, string defaultExt, string filter)
{
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
openFileDlg.Title = title;
openFileDlg.DefaultExt = defaultExt;
openFileDlg.Filter = filter;
// Show open file dialog box
Nullable<bool> result = openFileDlg.ShowDialog();
// Process open file dialog box results
if (result == true)
return openFileDlg.FileName;
return string.Empty;
}
/// <summary>Create an save file dialog to ask the user to choose a file to save to</summary>
public static string GetSaveFileDialogResult(string title, string defaultExt, string filter)
{
Microsoft.Win32.SaveFileDialog saveFileDlg = new Microsoft.Win32.SaveFileDialog();
saveFileDlg.Title = title;
saveFileDlg.DefaultExt = defaultExt;
saveFileDlg.Filter = filter;
// Show save file dialog box
Nullable<bool> result = saveFileDlg.ShowDialog();
// Process open file dialog box results
if (result == true)
return saveFileDlg.FileName;
return string.Empty;
}
/// <summary>Convenience function to open a file dialog that allows opening a 3D file type</summary>
public static string Get3DFileDialogResult()
{
return GetOpenFileDialogResult("Open 3D File", ".pdf;.u3d;.prc;.obj", "3D Files|*.pdf;*.u3d;*.prc;*.obj");
}
/// <summary>Convenience function to open a file dialog that allows opening a view file</summary>
public static string GetViewFileDialogResult()
{
return GetOpenFileDialogResult("Open ViewInfo File", ".txt", "Text Files (.txt)|*.txt");
}
/// <summary>Convenience function to open a file dialog that allows opening a PDF file</summary>
public static string GetPDFFileDialogResult()
{
return GetOpenFileDialogResult("Open PDF File", ".pdf", "PDF Files (.pdf)|*.pdf");
}
/// <summary>Convenience function to open a file dialog that allows saving to PRC file type</summary>
public static string GetSaveToPRCFileDialogResult()
{
return GetSaveFileDialogResult("Save to PRC file", ".prc", "PRC files (.prc)|*.prc");
}
/// <summary>Retrieve an Image from an assembly</summary>
public static ImageSource GetImageSourceFromResource(string assemblyName, string resourceName)
{
try
{
Uri oUri = new Uri("pack://application:,,,/" + assemblyName + ";component/" + resourceName, UriKind.RelativeOrAbsolute);
return BitmapFrame.Create(oUri);
}
catch (IOException)
{
return null;
}
}
/// <summary>Retrieve an Image from a file</summary>
public static ImageSource GetImageSourceFromFile(string filename)
{
if (!File.Exists(filename))
return null;
try
{
return BitmapFrame.Create(new Uri(filename));
}
catch (IOException)
{
return null;
}
}
/// <summary>Convert a Color to an UInt32</summary>
public static UInt32 Color2Int(System.Windows.Media.Color inColor)
{
UInt32 col = 0xFF000000;
col |= (((UInt32)inColor.R << 16) | ((UInt32)inColor.G << 8) | ((UInt32)inColor.B));
return col;
}
/// <summary>Convert an UInt32 to a Color</summary>
public static System.Windows.Media.Color UInt2Color(UInt32 inColor)
{
System.Windows.Media.Color bgCol = new System.Windows.Media.Color();
bgCol.R = (byte)((inColor & 0x00FF0000) >> 16);
bgCol.G = (byte)((inColor & 0x0000FF00) >> 8);
bgCol.B = (byte)(inColor & 0x000000FF);
bgCol.A = 0xFF;
return bgCol;
}
/// <summary>Set the value of a property and send a notification upon change</summary>
public static bool SetPropertyAndNotify<T>(PropertyChangedEventHandler changeHandler, ref T field, T value, System.Linq.Expressions.Expression<Func<T>> expr)
{
if (expr == null)
{
throw new ArgumentNullException("ChangePropertyAndNotify - Missing expression");
}
var body = expr.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException("ChangePropertyAndNotify - Expression missing body");
}
if (EqualityComparer<T>.Default.Equals(field, value))
{
return false;
}
field = value;
var vmExpr = body.Expression as ConstantExpression;
if (vmExpr != null)
{
LambdaExpression lambda = System.Linq.Expressions.Expression.Lambda(vmExpr);
Delegate vmFunc = lambda.Compile();
object sender = vmFunc.DynamicInvoke();
if (changeHandler != null)
{
changeHandler(sender, new PropertyChangedEventArgs(body.Member.Name));
}
}
return true;
}
/// <summary>Helper for comparing versions</summary>
public static bool IsVersionOk(Version minVersion, Version currVersion, bool exactSame = false, bool compareBuild = false)
{
// if exactSame, means all the build numbers must be exactly the same
if (exactSame)
{
if (currVersion.major != minVersion.major || currVersion.minor != minVersion.minor)
return false;
if (compareBuild && currVersion.build != minVersion.build)
return false;
return true;
}
// otherwise a newer build will be accepted
else
{
// check fail on major version
if (currVersion.major < minVersion.major)
return false;
else if (currVersion.major > minVersion.major)
return true;
// major version same, check minor
if (currVersion.minor < minVersion.minor)
return false;
else if (currVersion.minor > minVersion.minor)
return true;
// minor version same, check build
if (compareBuild && currVersion.build < minVersion.build)
return false;
return true;
}
}
/// <summary>Output the pinned handles of ViewData strings</summary>
public static void PinViews(IList<PdfUtilities.ViewInfo> list, out GCHandle[] outHandles) {
if(list == null) {
outHandles = null;
return;
}
outHandles = new GCHandle[list.Count];
for (int i = 0; i < list.Count; ++i) {
string s = list[i].View;
if (s != null)
outHandles[i] = SafeUtils.GCHandle_Alloc(s, GCHandleType.Pinned);
}
}
}
}