|
@@ -2,13 +2,9 @@
|
|
|
// The graphics rendering engine GLScene http://glscene.org
|
|
|
//
|
|
|
unit GLS.Utils;
|
|
|
-
|
|
|
(* Miscellaneous support utilities & classes for localization *)
|
|
|
-
|
|
|
interface
|
|
|
-
|
|
|
{$I GLScene.inc}
|
|
|
-
|
|
|
uses
|
|
|
Winapi.Windows,
|
|
|
Winapi.ShellApi,
|
|
@@ -20,30 +16,22 @@ uses
|
|
|
Vcl.Controls,
|
|
|
Vcl.Dialogs,
|
|
|
Vcl.ExtDlgs,
|
|
|
-
|
|
|
GLS.VectorGeometry,
|
|
|
GLS.Strings;
|
|
|
-
|
|
|
type
|
|
|
THalfFloat = type Word;
|
|
|
PHalfFloat = ^THalfFloat;
|
|
|
-
|
|
|
EGLOSError = EOSError;
|
|
|
EGLUtilsException = class(Exception);
|
|
|
-
|
|
|
TSqrt255Array = array[0..255] of Byte;
|
|
|
PSqrt255Array = ^TSqrt255Array;
|
|
|
-
|
|
|
TProjectTargetNameFunc = function(): string;
|
|
|
-
|
|
|
const
|
|
|
FONT_CHARS_COUNT = 2024;
|
|
|
-
|
|
|
var
|
|
|
IsDesignTime: Boolean = False;
|
|
|
vProjectTargetName: TProjectTargetNameFunc;
|
|
|
|
|
|
-
|
|
|
// Copies the values of Source to Dest (converting word values to integer values)
|
|
|
procedure WordToIntegerArray(Source: PWordArray; Dest: PIntegerArray; Count: Cardinal);
|
|
|
// Round ups to the nearest power of two, value must be positive
|
|
@@ -64,7 +52,6 @@ function StringToColorAdvancedSafe(const Str: string; const Default: TColor): TC
|
|
|
function TryStringToColorAdvanced(const Str: string; var OutColor: TColor): Boolean;
|
|
|
// Converts a string into color
|
|
|
function StringToColorAdvanced(const Str: string): TColor;
|
|
|
-
|
|
|
(*Parses the next integer in the string.
|
|
|
Initial non-numeric characters are skipper, p is altered, returns 0 if none
|
|
|
found. '+' and '-' are acknowledged. *)
|
|
@@ -73,29 +60,23 @@ function ParseInteger(var p: PChar): Integer;
|
|
|
Initial non-numeric characters are skipper, p is altered, returns 0 if none
|
|
|
found. Both '.' and ',' are accepted as decimal separators. *)
|
|
|
function ParseFloat(var p: PChar): Extended;
|
|
|
-
|
|
|
//Saves ansistring "data" to "filename".
|
|
|
procedure SaveAnsiStringToFile(const fileName: string; const data: AnsiString);
|
|
|
//Returns the ansistring content of "filename".
|
|
|
function LoadAnsiStringFromFile(const fileName: string): AnsiString;
|
|
|
-
|
|
|
//Saves string "data" to "filename".
|
|
|
procedure SaveStringToFile(const fileName: string; const data: String);
|
|
|
//Returns the string content of "filename".
|
|
|
function LoadStringFromFile(const fileName: string): String;
|
|
|
-
|
|
|
//Saves component to a file.
|
|
|
procedure SaveComponentToFile(const Component: TComponent; const FileName: string; const AsText: Boolean = True);
|
|
|
// Loads component from a file.
|
|
|
procedure LoadComponentFromFile(const Component: TComponent; const FileName: string; const AsText: Boolean = True);
|
|
|
-
|
|
|
(* Returns the size of "filename".
|
|
|
Returns 0 (zero) is file does not exists. *)
|
|
|
function SizeOfFile(const fileName: string): Int64;
|
|
|
-
|
|
|
// Returns a pointer to an array containing the results of "255*sqrt(i/255)".
|
|
|
function GetSqrt255Array: PSqrt255Array;
|
|
|
-
|
|
|
// Pops up a simple dialog with msg and an Ok button.
|
|
|
procedure InformationDlg(const msg: string);
|
|
|
(* Pops up a simple question dialog with msg and yes/no buttons.
|
|
@@ -103,16 +84,12 @@ procedure InformationDlg(const msg: string);
|
|
|
function QuestionDlg(const msg: string): Boolean;
|
|
|
// Posp a simple dialog with a string input.
|
|
|
function InputDlg(const aCaption, aPrompt, aDefault: string): string;
|
|
|
-
|
|
|
// Pops up a simple save picture dialog.
|
|
|
function SavePictureDialog(var aFileName: string; const aTitle: string = ''): Boolean;
|
|
|
// Pops up a simple open picture dialog.
|
|
|
function OpenPictureDialog(var aFileName: string; const aTitle: string = ''): Boolean;
|
|
|
-
|
|
|
procedure SetGLSceneMediaDir();
|
|
|
-
|
|
|
//------------------ from CrossPlatform -----------------------
|
|
|
-
|
|
|
function GetGLRect(const aLeft, aTop, aRight, aBottom: Integer): TRect;
|
|
|
(* Increases or decreases the width and height of the specified rectangle.
|
|
|
Adds dx units to the left and right ends of the rectangle and dy units to
|
|
@@ -140,7 +117,6 @@ procedure QueryPerformanceCounter(out val: Int64);
|
|
|
Return value is in ticks per second (Hz), returns False if no precision
|
|
|
counter is available. *)
|
|
|
function QueryPerformanceFrequency(out val: Int64): Boolean;
|
|
|
-
|
|
|
(* Starts a precision timer.
|
|
|
Returned value should just be considered as 'handle', even if it ain't so.
|
|
|
Default platform implementation is to use QueryPerformanceCounter and
|
|
@@ -173,21 +149,26 @@ function GetValueFromStringsIndex(const AStrings: TStrings; const AIndex: Intege
|
|
|
function IsDirectoryWriteable(const AName: string): Boolean;
|
|
|
function CharToWideChar(const AChar: AnsiChar): WideChar;
|
|
|
|
|
|
+(*
|
|
|
+ Added by PAL to fix problem with decimal separator in not En-US configurations
|
|
|
+ Decimal separator in text descriptions of meshes for import/export is always '.' char
|
|
|
+ But in System.SysUtils.TextToFloat is Windows char, maybe ',' or others...
|
|
|
+*)
|
|
|
+function GLStrToFloatDef(const S: string; const Default: Extended; fs: TFormatSettings): Extended; overload;
|
|
|
+function GLStrToFloatDef(const S: string; const Default: Extended): Extended; overload;
|
|
|
+function GLStrToFloatDef(const S: string): Extended; overload;
|
|
|
+
|
|
|
//------------------------------------------------------
|
|
|
implementation
|
|
|
//------------------------------------------------------
|
|
|
|
|
|
-
|
|
|
var
|
|
|
vSqrt255: TSqrt255Array;
|
|
|
vInvPerformanceCounterFrequency: Double;
|
|
|
vInvPerformanceCounterFrequencyReady: Boolean = False;
|
|
|
vLastProjectTargetName: string;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
//---------------from Utils -----------------------
|
|
|
-
|
|
|
procedure WordToIntegerArray(Source: PWordArray; Dest: PIntegerArray; Count: Cardinal);
|
|
|
var
|
|
|
i: integer;
|
|
@@ -195,14 +176,12 @@ begin
|
|
|
for i := 0 to Count - 1 do
|
|
|
Dest^[i] := Source^[i];
|
|
|
end;
|
|
|
-
|
|
|
function RoundUpToPowerOf2(value: Integer): Integer;
|
|
|
begin
|
|
|
Result := 1;
|
|
|
while (Result < value) do
|
|
|
Result := Result shl 1;
|
|
|
end;
|
|
|
-
|
|
|
function RoundDownToPowerOf2(value: Integer): Integer;
|
|
|
begin
|
|
|
if value > 0 then
|
|
@@ -214,12 +193,10 @@ begin
|
|
|
else
|
|
|
Result := 1;
|
|
|
end;
|
|
|
-
|
|
|
function IsPowerOf2(value: Integer): Boolean;
|
|
|
begin
|
|
|
Result := (RoundUpToPowerOf2(value) = value);
|
|
|
end;
|
|
|
-
|
|
|
function ReadCRLFString(aStream: TStream): String;
|
|
|
var
|
|
|
c: Char;
|
|
@@ -232,7 +209,6 @@ begin
|
|
|
end;
|
|
|
Result := Copy(Result, 1, Length(Result) - 2);
|
|
|
end;
|
|
|
-
|
|
|
procedure WriteCRLFString(aStream: TStream; const aString: String);
|
|
|
const
|
|
|
cCRLF: Integer = $0A0D;
|
|
@@ -244,25 +220,21 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
function StrToFloatDef(const strValue: string; defValue: Extended = 0): Extended;
|
|
|
begin
|
|
|
if not TryStrToFloat(strValue, Result) then
|
|
|
result := defValue;
|
|
|
end;
|
|
|
-
|
|
|
function StringToColorAdvancedSafe(const Str: string; const Default: TColor): TColor;
|
|
|
begin
|
|
|
if not TryStringToColorAdvanced(Str, Result) then
|
|
|
Result := Default;
|
|
|
end;
|
|
|
-
|
|
|
function StringToColorAdvanced(const Str: string): TColor;
|
|
|
begin
|
|
|
if not TryStringToColorAdvanced(Str, Result) then
|
|
|
raise EGLUtilsException.CreateResFmt(@strInvalidColor, [Str]);
|
|
|
end;
|
|
|
-
|
|
|
function TryStringToColorAdvanced(const Str: string; var OutColor: TColor): Boolean;
|
|
|
var
|
|
|
Code, I: Integer;
|
|
@@ -270,7 +242,6 @@ var
|
|
|
begin
|
|
|
Result := True;
|
|
|
Temp := Str;
|
|
|
-
|
|
|
Val(Temp, I, Code); //to see if it is a number
|
|
|
if Code = 0 then
|
|
|
OutColor := TColor(I) //Str = $0000FF
|
|
@@ -289,7 +260,6 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function ParseInteger(var p: PChar): Integer;
|
|
|
var
|
|
|
neg: Boolean;
|
|
@@ -322,7 +292,6 @@ begin
|
|
|
if neg then
|
|
|
Result := -Result;
|
|
|
end;
|
|
|
-
|
|
|
function ParseFloat(var p: PChar): Extended;
|
|
|
var
|
|
|
decimals, expSign, exponent: Integer;
|
|
@@ -398,7 +367,6 @@ begin
|
|
|
if neg then
|
|
|
Result := -Result;
|
|
|
end;
|
|
|
-
|
|
|
procedure SaveAnsiStringToFile(const fileName: string; const data: AnsiString);
|
|
|
var
|
|
|
n: Cardinal;
|
|
@@ -413,7 +381,6 @@ begin
|
|
|
fs.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function LoadAnsiStringFromFile(const fileName: string): AnsiString;
|
|
|
var
|
|
|
n: Cardinal;
|
|
@@ -434,7 +401,6 @@ begin
|
|
|
else
|
|
|
Result := '';
|
|
|
end;
|
|
|
-
|
|
|
procedure SaveStringToFile(const fileName: string; const data: String);
|
|
|
var
|
|
|
n: Cardinal;
|
|
@@ -449,7 +415,6 @@ begin
|
|
|
fs.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function LoadStringFromFile(const fileName: string): String;
|
|
|
var
|
|
|
n: Cardinal;
|
|
@@ -471,7 +436,6 @@ begin
|
|
|
Result := '';
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
procedure SaveComponentToFile(const Component: TComponent; const FileName: string; const AsText: Boolean);
|
|
|
var
|
|
|
Stream: TStream;
|
|
@@ -496,7 +460,6 @@ begin
|
|
|
Stream.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
procedure LoadComponentFromFile(const Component: TComponent; const FileName: string; const AsText: Boolean = True);
|
|
|
var
|
|
|
Stream: TStream;
|
|
@@ -521,7 +484,6 @@ begin
|
|
|
Stream.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function SizeOfFile(const fileName: string): Int64;
|
|
|
var
|
|
|
fs: TStream;
|
|
@@ -538,7 +500,6 @@ begin
|
|
|
else
|
|
|
Result := 0;
|
|
|
end;
|
|
|
-
|
|
|
function GetSqrt255Array: PSqrt255Array;
|
|
|
const
|
|
|
cOneDiv255 = 1 / 255;
|
|
@@ -552,22 +513,18 @@ begin
|
|
|
end;
|
|
|
Result := @vSqrt255;
|
|
|
end;
|
|
|
-
|
|
|
procedure InformationDlg(const msg: string);
|
|
|
begin
|
|
|
ShowMessage(msg);
|
|
|
end;
|
|
|
-
|
|
|
function QuestionDlg(const msg: string): Boolean;
|
|
|
begin
|
|
|
Result := (MessageDlg(msg, mtConfirmation, [mbYes, mbNo], 0) = mrYes);
|
|
|
end;
|
|
|
-
|
|
|
function InputDlg(const aCaption, aPrompt, aDefault: string): string;
|
|
|
begin
|
|
|
Result := InputBox(aCaption, aPrompt, aDefault);
|
|
|
end;
|
|
|
-
|
|
|
function SavePictureDialog(var aFileName: string; const aTitle: string = ''): Boolean;
|
|
|
var
|
|
|
saveDialog: TSavePictureDialog;
|
|
@@ -588,7 +545,6 @@ begin
|
|
|
saveDialog.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function OpenPictureDialog(var aFileName: string; const aTitle: string = ''): Boolean;
|
|
|
var
|
|
|
openDialog: TOpenPictureDialog;
|
|
@@ -609,7 +565,6 @@ begin
|
|
|
openDialog.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
procedure SetGLSceneMediaDir();
|
|
|
var
|
|
|
path: String;
|
|
@@ -622,10 +577,8 @@ begin
|
|
|
path := IncludeTrailingPathDelimiter(path) + 'media';
|
|
|
SetCurrentDir(path);
|
|
|
end;
|
|
|
-
|
|
|
//------------ from CrossPfatform -------------------
|
|
|
|
|
|
-
|
|
|
procedure RaiseLastOSError;
|
|
|
var
|
|
|
e: EGLOSError;
|
|
@@ -633,37 +586,30 @@ begin
|
|
|
e := EGLOSError.Create('OS Error : ' + SysErrorMessage(GetLastError));
|
|
|
raise e;
|
|
|
end;
|
|
|
-
|
|
|
function IsSubComponent(const AComponent: TComponent): Boolean;
|
|
|
begin
|
|
|
Result := (csSubComponent in AComponent.ComponentStyle);
|
|
|
end;
|
|
|
-
|
|
|
procedure MakeSubComponent(const AComponent: TComponent; const Value: Boolean);
|
|
|
begin
|
|
|
AComponent.SetSubComponent(Value);
|
|
|
end;
|
|
|
-
|
|
|
function AnsiStartsText(const ASubText, AText: string): Boolean;
|
|
|
begin
|
|
|
Result := AnsiStartsText(ASubText, AText);
|
|
|
end;
|
|
|
-
|
|
|
function GLOKMessageBox(const Text, Caption: string): Integer;
|
|
|
begin
|
|
|
Result := Application.MessageBox(PChar(Text), PChar(Caption), MB_OK);
|
|
|
end;
|
|
|
-
|
|
|
procedure GLLoadBitmapFromInstance(Instance: LongInt; ABitmap: TBitmap; const AName: string);
|
|
|
begin
|
|
|
ABitmap.Handle := LoadBitmap(Instance, PChar(AName));
|
|
|
end;
|
|
|
-
|
|
|
procedure ShowHTMLUrl(const Url: string);
|
|
|
begin
|
|
|
ShellExecute(0, 'open', PChar(Url), nil, nil, SW_SHOW);
|
|
|
end;
|
|
|
-
|
|
|
function GetGLRect(const aLeft, aTop, aRight, aBottom: Integer): TRect;
|
|
|
begin
|
|
|
Result.Left := aLeft;
|
|
@@ -671,7 +617,6 @@ begin
|
|
|
Result.Right := aRight;
|
|
|
Result.Bottom := aBottom;
|
|
|
end;
|
|
|
-
|
|
|
procedure InflateGLRect(var aRect: TRect; dx, dy: Integer);
|
|
|
begin
|
|
|
aRect.Left := aRect.Left - dx;
|
|
@@ -683,7 +628,6 @@ begin
|
|
|
if aRect.Bottom < aRect.Top then
|
|
|
aRect.Bottom := aRect.Top;
|
|
|
end;
|
|
|
-
|
|
|
procedure IntersectGLRect(var aRect: TRect; const rect2: TRect);
|
|
|
var
|
|
|
a: Integer;
|
|
@@ -710,14 +654,12 @@ begin
|
|
|
aRect.Bottom := rect2.Bottom;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
type
|
|
|
TDeviceCapabilities = record
|
|
|
Xdpi, Ydpi: integer; // Number of pixels per logical inch.
|
|
|
Depth: integer; // The bit depth.
|
|
|
NumColors: integer; // Number of entries in the device's color table.
|
|
|
end;
|
|
|
-
|
|
|
function GetDeviceCapabilities: TDeviceCapabilities;
|
|
|
var
|
|
|
Device: HDC;
|
|
@@ -732,17 +674,14 @@ begin
|
|
|
ReleaseDC(0, Device);
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function GetDeviceLogicalPixelsX(device: HDC): Integer;
|
|
|
begin
|
|
|
result := GetDeviceCapabilities().Xdpi;
|
|
|
end;
|
|
|
-
|
|
|
function GetCurrentColorDepth: Integer;
|
|
|
begin
|
|
|
result := GetDeviceCapabilities().Depth;
|
|
|
end;
|
|
|
-
|
|
|
function PixelFormatToColorBits(aPixelFormat: TPixelFormat): Integer;
|
|
|
begin
|
|
|
case aPixelFormat of
|
|
@@ -760,7 +699,6 @@ begin
|
|
|
Result := 24;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
procedure FixPathDelimiter(var S: string);
|
|
|
var
|
|
|
I: Integer;
|
|
@@ -769,7 +707,6 @@ begin
|
|
|
if (S[I] = '/') or (S[I] = '\') then
|
|
|
S[I] := PathDelim;
|
|
|
end;
|
|
|
-
|
|
|
function RelativePath(const S: string): string;
|
|
|
var
|
|
|
path: string;
|
|
@@ -797,28 +734,23 @@ begin
|
|
|
if Pos(path, S) = 1 then
|
|
|
Delete(Result, 1, Length(path));
|
|
|
end;
|
|
|
-
|
|
|
procedure QueryPerformanceCounter(out val: Int64);
|
|
|
begin
|
|
|
Winapi.Windows.QueryPerformanceCounter(val);
|
|
|
end;
|
|
|
-
|
|
|
function QueryPerformanceFrequency(out val: Int64): Boolean;
|
|
|
begin
|
|
|
Result := Boolean(Winapi.Windows.QueryPerformanceFrequency(val));
|
|
|
end;
|
|
|
-
|
|
|
function StartPrecisionTimer: Int64;
|
|
|
begin
|
|
|
QueryPerformanceCounter(Result);
|
|
|
end;
|
|
|
-
|
|
|
function PrecisionTimerLap(const precisionTimer: Int64): Double;
|
|
|
begin
|
|
|
// we can do this, because we don't really stop anything
|
|
|
Result := StopPrecisionTimer(precisionTimer);
|
|
|
end;
|
|
|
-
|
|
|
function StopPrecisionTimer(const precisionTimer: Int64): Double;
|
|
|
var
|
|
|
cur, freq: Int64;
|
|
@@ -832,12 +764,10 @@ begin
|
|
|
end;
|
|
|
Result := (cur - precisionTimer) * vInvPerformanceCounterFrequency;
|
|
|
end;
|
|
|
-
|
|
|
var
|
|
|
vSStartTime : TDateTime;
|
|
|
vLastTime: TDateTime;
|
|
|
vDeltaMilliSecond: TDateTime;
|
|
|
-
|
|
|
function AppTime: Double;
|
|
|
var
|
|
|
SystemTime: TSystemTime;
|
|
@@ -859,7 +789,6 @@ begin
|
|
|
vDeltaMilliSecond := 0.1;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
function FindUnitName(anObject: TObject): string;
|
|
|
begin
|
|
|
if Assigned(anObject) then
|
|
@@ -867,7 +796,6 @@ begin
|
|
|
else
|
|
|
Result := '';
|
|
|
end;
|
|
|
-
|
|
|
function FindUnitName(aClass: TClass): string;
|
|
|
begin
|
|
|
if Assigned(aClass) then
|
|
@@ -875,7 +803,6 @@ begin
|
|
|
else
|
|
|
Result := '';
|
|
|
end;
|
|
|
-
|
|
|
procedure SetExeDirectory;
|
|
|
var
|
|
|
path: string;
|
|
@@ -901,12 +828,10 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
function GetValueFromStringsIndex(const AStrings: TStrings; const AIndex: Integer): string;
|
|
|
begin
|
|
|
Result := AStrings.ValueFromIndex[AIndex];
|
|
|
end;
|
|
|
-
|
|
|
function IsDirectoryWriteable(const AName: string): Boolean;
|
|
|
var
|
|
|
LFileName: String;
|
|
@@ -920,7 +845,6 @@ begin
|
|
|
CloseHandle(LHandle);
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
function CharToWideChar(const AChar: AnsiChar): WideChar;
|
|
|
var
|
|
|
lResult: PWideChar;
|
|
@@ -931,7 +855,6 @@ begin
|
|
|
FreeMem(lResult, 2);
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
function HalfToFloat(Half: THalfFloat): Single;
|
|
|
var
|
|
|
Dst, Sign, Mantissa: LongWord;
|
|
@@ -941,7 +864,6 @@ begin
|
|
|
Sign := Half shr 15;
|
|
|
Exp := (Half and $7C00) shr 10;
|
|
|
Mantissa := Half and 1023;
|
|
|
-
|
|
|
if (Exp > 0) and (Exp < 31) then
|
|
|
begin
|
|
|
// common normalized number
|
|
@@ -981,11 +903,9 @@ begin
|
|
|
// not a number - preserve sign and mantissa
|
|
|
Dst := (Sign shl 31) or $7F800000 or (Mantissa shl 13);
|
|
|
end;
|
|
|
-
|
|
|
// reinterpret LongWord as Single
|
|
|
Result := PSingle(@Dst)^;
|
|
|
end;
|
|
|
-
|
|
|
function FloatToHalf(Float: Single): THalfFloat;
|
|
|
var
|
|
|
Src: LongWord;
|
|
@@ -996,7 +916,6 @@ begin
|
|
|
Sign := Src shr 31;
|
|
|
Exp := LongInt((Src and $7F800000) shr 23) - 127 + 15;
|
|
|
Mantissa := Src and $007FFFFF;
|
|
|
-
|
|
|
if (Exp > 0) and (Exp < 30) then
|
|
|
begin
|
|
|
// simple case - round the significand and combine it with the sign and exponent
|
|
@@ -1055,7 +974,6 @@ begin
|
|
|
Exp := Exp + 1;
|
|
|
end;
|
|
|
end;
|
|
|
-
|
|
|
if Exp > 30 then
|
|
|
begin
|
|
|
// exponent overflow - return infinity half
|
|
@@ -1068,11 +986,31 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+//By PAL, added to fix problem with decimal separator in non En configurations
|
|
|
+function GLStrToFloatDef(const S: string; const Default: Extended; fs: TFormatSettings): Extended; overload;
|
|
|
+begin
|
|
|
+ fs.DecimalSeparator := '.';
|
|
|
+ if not System.SysUtils.TextToFloat(S, Result, fs) then
|
|
|
+ Result := Default;
|
|
|
+end;
|
|
|
+//By PAL, added to fix problem with decimal separator in non En configurations
|
|
|
+function GLStrToFloatDef(const S: string; const Default: Extended): Extended; overload;
|
|
|
+ var fs: TFormatSettings;
|
|
|
+begin
|
|
|
+ fs.DecimalSeparator := '.';
|
|
|
+ if not System.SysUtils.TextToFloat(S, Result, fs) then
|
|
|
+ Result := Default;
|
|
|
+end;
|
|
|
+//By PAL, added to fix problem with decimal separator in non En configurations
|
|
|
+function GLStrToFloatDef(const S: string): Extended; overload;
|
|
|
+ var fs: TFormatSettings;
|
|
|
+begin
|
|
|
+ fs.DecimalSeparator := '.';
|
|
|
+ if not System.SysUtils.TextToFloat(S, Result, fs) then
|
|
|
+ Result := 0;
|
|
|
+end;
|
|
|
//----------------------------------------
|
|
|
initialization
|
|
|
//----------------------------------------
|
|
|
-
|
|
|
vSStartTime := AppTime;
|
|
|
-
|
|
|
end.
|
|
|
-
|