Componentes.Terceros.jvcl/official/3.32/run/JvFullColorSpaces.pas

1620 lines
46 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: ColorSpaces.pas, released on 2004-09-11.
The Initial Developer of the Original Code is Florent Ouchet [ouchet dott florent att laposte dott net]
Portions created by Florent Ouchet are Copyright (C) 2004 Florent Ouchet.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvFullColorSpaces.pas 11104 2006-12-29 17:55:15Z marquardt $
// TColorBox is implemented in ExtCtrls in Delphi and BCB version 6 and +
unit JvFullColorSpaces;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Windows, Classes, SysUtils, Graphics,
JvTypes;
type
TJvAxisIndex = (axIndex0, axIndex1, axIndex2);
TJvFullColorSpaceID = type Byte;
TJvFullColor = type Cardinal;
const
JvSystemColorMask = {$IFDEF COMPILER7_UP} clSystemColor; {$ELSE} $80000000; {$ENDIF}
JvSubFullColorMask = $03000000;
JvSystemFullColorMask = $01000000;
JvSpecialFullColorMask = $03000000;
const
csRGB = TJvFullColorSpaceID(1 shl 2);
csHLS = TJvFullColorSpaceID(2 shl 2);
csCMY = TJvFullColorSpaceID(3 shl 2);
csYUV = TJvFullColorSpaceID(4 shl 2);
csHSV = TJvFullColorSpaceID(5 shl 2);
csYIQ = TJvFullColorSpaceID(6 shl 2);
csYCC = TJvFullColorSpaceID(7 shl 2);
csXYZ = TJvFullColorSpaceID(8 shl 2);
csLAB = TJvFullColorSpaceID(9 shl 2);
csDEF = TJvFullColorSpaceID(10 shl 2);
csID_MASK = $FC;
csMIN = $04 and csID_MASK;
csMAX = $FF and csID_MASK;
RGB_MIN = 0;
RGB_MAX = 255;
HLS_MIN = 0;
HLS_MAX = 240;
CMY_MIN = 0;
CMY_MAX = 255;
YUV_MIN = 16;
YUV_MAX = 235;
HSV_MIN = 0;
HSV_MAX = 240;
YIQ_MIN = 0;
YIQ_MAX = 255;
YCC_MIN = 0;
YCC_MAX = 255;
XYZ_MIN = 0;
XYZ_MAX = 255;
LAB_MIN = 0;
LAB_MAX = 255;
DEF_MIN = 0;
DEF_MAX = 255;
fclRGBBlack = TJvFullColor((Ord(csRGB) shl 24) or $000000);
fclRGBWhite = TJvFullColor((Ord(csRGB) shl 24) or $FFFFFF);
fclRGBRed = TJvFullColor((Ord(csRGB) shl 24) or $0000FF);
fclRGBLime = TJvFullColor((Ord(csRGB) shl 24) or $00FF00);
fclRGBBlue = TJvFullColor((Ord(csRGB) shl 24) or $FF0000);
fclDEFWindowText = TJvFullColor((Ord(csDEF) shl 24) or JvSystemFullColorMask or COLOR_WINDOWTEXT);
type
TJvColorSpace = class(TPersistent)
private
FID: TJvFullColorSpaceID;
protected
function GetAxisName(Index: TJvAxisIndex): string; virtual;
function GetAxisMin(Index: TJvAxisIndex): Byte; virtual;
function GetAxisMax(Index: TJvAxisIndex): Byte; virtual;
function GetAxisDefault(Index: TJvAxisIndex): Byte; virtual;
function GetName: string; virtual;
function GetShortName: string; virtual;
function GetNumberOfColors: Cardinal; virtual;
public
constructor Create(ColorID: TJvFullColorSpaceID); virtual;
function ConvertFromColor(AColor: TColor): TJvFullColor; virtual;
function ConvertToColor(AColor: TJvFullColor): TColor; virtual;
property ID: TJvFullColorSpaceID read FID;
property NumberOfColors: Cardinal read GetNumberOfColors;
property Name: string read GetName;
property ShortName: string read GetShortName;
property AxisName[Index: TJvAxisIndex]: string read GetAxisName;
property AxisMin[Index: TJvAxisIndex]: Byte read GetAxisMin;
property AxisMax[Index: TJvAxisIndex]: Byte read GetAxisMax;
property AxisDefault[Index: TJvAxisIndex]: Byte read GetAxisDefault;
end;
{TJvColorConversionMatrix = array[0..3,0..3] of Extended; // OpenGL and D3D style matrix
PJvColorConversionMatrix = ^TJvColorConversionMatrix;
TJvMatrixType = (mtFromRGB, mtToRGB);
TJvMatrixColorSpace = class(TJvColorSpace)
protected
FToRGBMatrix,
FFromRGBMatrix: TJvColorConversionMatrix;
public
constructor Create(ColorID: TJvFullColorSpaceID; AMatrix: PJvColorConversionMatrix;
MatrixType: TJvMatrixType); reintroduce;
destructor Destroy; override;
function ConvertToID(AFullColor: TJvFullColor; NewID: TJvFullColorSpaceID; //
RGBToNewIDMatrix: PJvColorConversionMatrix): TJvFullColor; // use a call with pointer argument
function ConvertFromID(AFullColor: TJvFullColor; OldID: TJvFullColorSpaceID; // because a matrix is 160 Bytes !!!
OldIDToRGBMatrix: PJvColorConversionMatrix): TJvFullColor; // /!\ not on the stack /!\
function ConvertFromColor(AColor: TColor): TColor; override; //
function ConvertToColor(AColor: TJvFullColor): TColor; override;
function GetToRGBMatrix: PJvColorConversionMatrix;
function GetFromRGBMatrix: PJvColorConversionMatrix;
end;}
TJvRGBColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvHLSColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvCMYColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvYUVColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvHSVColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvYIQColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvYCCColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvXYZColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvLABColorSpace = class(TJvColorSpace)
protected
function GetAxisName(Index: TJvAxisIndex): string; override;
function GetAxisMin(Index: TJvAxisIndex): Byte; override;
function GetAxisMax(Index: TJvAxisIndex): Byte; override;
function GetName: string; override;
function GetShortName: string; override;
function GetAxisDefault(Index: TJvAxisIndex): Byte; override;
public
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
end;
TJvDEFColorSpace = class(TJvColorSpace)
private
FDelphiColors: TStringList;
procedure GetColorValuesCallBack(const S: string);
protected
function GetName: string; override;
function GetShortName: string; override;
function GetNumberOfColors: Cardinal; override;
function GetColorName(Index: Integer): string;
function GetPrettyName(Index: Integer): string;
function GetColorValue(Index: Integer): TColor;
public
constructor Create(ColorID: TJvFullColorSpaceID); override;
destructor Destroy; override;
function ConvertFromColor(AColor: TColor): TJvFullColor; override;
function ConvertToColor(AColor: TJvFullColor): TColor; override;
procedure AddCustomColor(AColor: TColor; ShortName: string; PrettyName: string);
procedure AddDelphiColor(Value: TColor);
property ColorCount: Cardinal read GetNumberOfColors;
property ColorName[Index: Integer]: string read GetColorName;
property ColorPrettyName[Index: Integer]: string read GetPrettyName;
property ColorValue[Index: Integer]: TColor read GetColorValue; default;
end;
TJvColorSpaceManager = class(TPersistent)
private
FColorSpaceList: TList;
function GetCount: Integer;
function GetColorSpaceByIndex(Index: Integer): TJvColorSpace;
protected
function GetColorSpace(ID: TJvFullColorSpaceID): TJvColorSpace; virtual;
public
procedure RegisterColorSpace(NewColorSpace: TJvColorSpace);
procedure UnRegisterColorSpace(AColorSpace: TJvColorSpace);
constructor Create;
destructor Destroy; override;
function ConvertToID(AColor: TJvFullColor; DestID: TJvFullColorSpaceID): TJvFullColor;
function ConvertToColor(AColor: TJvFullColor): TColor;
function ConvertFromColor(AColor: TColor): TJvFullColor;
function GetColorSpaceID(AColor: TJvFullColor): TJvFullColorSpaceID;
property ColorSpace[ID: TJvFullColorSpaceID]: TJvColorSpace read GetColorSpace;
property ColorSpaceByIndex[Index: Integer]: TJvColorSpace read GetColorSpaceByIndex;
property Count: Integer read GetCount;
end;
EJvColorSpaceError = class(EJVCLException);
function ColorSpaceManager: TJvColorSpaceManager;
function GetAxisValue(AColor: TJvFullColor; AAxis: TJvAxisIndex): Byte;
function SetAxisValue(AColor: TJvFullColor; AAxis: TJvAxisIndex; NewValue: Byte): TJvFullColor;
procedure SplitColorParts(AColor: TJvFullColor; var Part1, Part2, Part3: Integer);
function JoinColorParts(const Part1, Part2, Part3: Integer): TJvFullColor;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_32/run/JvFullColorSpaces.pas $';
Revision: '$Revision: 11104 $';
Date: '$Date: 2006-12-29 18:55:15 +0100 (ven., 29 déc. 2006) $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
{$IFDEF COMPILER6_UP}
Controls, StdCtrls, ExtCtrls,
{$ENDIF COMPILER6_UP}
JvResources, TypInfo, JvJCLUtils ,JvJVCLUtils,
JclMath;
var
GlobalColorSpaceManager: TJvColorSpaceManager = nil;
const
HLS_MAX_HALF = HLS_MAX / 2.0;
HLS_MAX_ONE_THIRD = HLS_MAX / 3.0;
HLS_MAX_TWO_THIRDS = (HLS_MAX * 2.0) / 3.0;
HLS_MAX_SIXTH = HLS_MAX / 6.0;
HLS_MAX_TWELVETH = HLS_MAX / 12.0;
function ColorSpaceManager: TJvColorSpaceManager;
begin
if GlobalColorSpaceManager = nil then
begin
GlobalColorSpaceManager := TJvColorSpaceManager.Create;
GlobalColorSpaceManager.RegisterColorSpace(TJvRGBColorSpace.Create(csRGB));
GlobalColorSpaceManager.RegisterColorSpace(TJvHLSColorSpace.Create(csHLS));
GlobalColorSpaceManager.RegisterColorSpace(TJvCMYColorSpace.Create(csCMY));
GlobalColorSpaceManager.RegisterColorSpace(TJvYUVColorSpace.Create(csYUV));
GlobalColorSpaceManager.RegisterColorSpace(TJvHSVColorSpace.Create(csHSV));
GlobalColorSpaceManager.RegisterColorSpace(TJvYIQColorSpace.Create(csYIQ));
GlobalColorSpaceManager.RegisterColorSpace(TJvYCCColorSpace.Create(csYCC));
GlobalColorSpaceManager.RegisterColorSpace(TJvXYZColorSpace.Create(csXYZ));
GlobalColorSpaceManager.RegisterColorSpace(TJvLABColorSpace.Create(csLAB));
GlobalColorSpaceManager.RegisterColorSpace(TJvDEFColorSpace.Create(csDEF));
end;
Result := GlobalColorSpaceManager;
end;
function SetAxisValue(AColor: TJvFullColor; AAxis: TJvAxisIndex;
NewValue: Byte): TJvFullColor;
begin
case AAxis of
axIndex0:
AColor := (AColor and $FFFFFF00) or NewValue;
axIndex1:
AColor := (AColor and $FFFF00FF) or (NewValue shl 8);
axIndex2:
AColor := (AColor and $FF00FFFF) or (NewValue shl 16);
end;
Result := AColor;
end;
function GetAxisValue(AColor: TJvFullColor; AAxis: TJvAxisIndex): Byte;
begin
case AAxis of
axIndex0:
Result := (AColor and $000000FF);
axIndex1:
Result := (AColor and $0000FF00) shr 8;
axIndex2:
Result := (AColor and $00FF0000) shr 16;
else
Result := 0;
end;
end;
procedure SplitColorParts(AColor: TJvFullColor; var Part1, Part2, Part3: Integer);
begin
Part1 := AColor and $000000FF;
Part2 := (AColor shr 8) and $000000FF;
Part3 := (AColor shr 16) and $000000FF;
end;
function JoinColorParts(const Part1, Part2, Part3: Integer): TJvFullColor;
begin
Result :=
(Part1 and $000000FF) or
((Part2 and $000000FF) shl 8) or
((Part3 and $000000FF) shl 16);
end;
//=== { TJvColorSpace } ======================================================
constructor TJvColorSpace.Create(ColorID: TJvFullColorSpaceID);
begin
inherited Create;
if (ColorID >= csMIN) and (ColorID <= csMAX) then
FID := ColorID
else
raise EJvColorSpaceError.CreateResFmt(@RsEIllegalID, [Ord(ColorID)]);
end;
function TJvColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
begin
Result := (AColor and $00FFFFFF) or (ID shl 24);
end;
function TJvColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
begin
Result := AColor and $00FFFFFF;
end;
function TJvColorSpace.GetNumberOfColors: Cardinal;
begin
Result :=
(AxisMax[axIndex0] - AxisMin[axIndex0] + 1) *
(AxisMax[axIndex1] - AxisMin[axIndex1] + 1) *
(AxisMax[axIndex2] - AxisMin[axIndex2] + 1);
end;
function TJvColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := Low(Byte);
end;
function TJvColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := High(Byte);
end;
function TJvColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := Low(Byte);
end;
function TJvColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
Result := RsEUnnamedAxis;
end;
function TJvColorSpace.GetName: string;
begin
Result := RsEUnnamedSpace;
end;
function TJvColorSpace.GetShortName: string;
begin
Result := RsEUCS;
end;
//=== { TJvRGBColorSpace } ===================================================
function TJvRGBColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
begin
Result := inherited ConvertFromColor(AColor);
end;
function TJvRGBColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
begin
Result := inherited ConvertToColor(AColor);
end;
function TJvRGBColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 0;
end;
function TJvRGBColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := RGB_MAX;
end;
function TJvRGBColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := RGB_MIN;
end;
function TJvRGBColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsRGB_Red;
axIndex1:
Result := RsRGB_Green;
axIndex2:
Result := RsRGB_Blue;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvRGBColorSpace.GetName: string;
begin
Result := RsRGB_FullName;
end;
function TJvRGBColorSpace.GetShortName: string;
begin
Result := RsRGB_ShortName;
end;
//=== { TJvHLSColorSpace } ===================================================
function TJvHLSColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Hue, Lightness, Saturation: Double;
Red, Green, Blue: Integer;
ColorMax, ColorMin, ColorDiff, ColorSum: Double;
RedDelta, GreenDelta, BlueDelta: Extended;
begin
SplitColorParts(AColor, Red, Green, Blue);
if Red > Green then
ColorMax := Red
else
ColorMax := Green;
if Blue > ColorMax then
ColorMax := Blue;
if Red < Green then
ColorMin := Red
else
ColorMin := Green;
if Blue < ColorMin then
ColorMin := Blue;
ColorDiff := ColorMax - ColorMin;
ColorSum := ColorMax + ColorMin;
Lightness := (ColorSum * HLS_MAX + RGB_MAX) / (2.0 * RGB_MAX);
if ColorMax = ColorMin then
AColor := (Round(Lightness) shl 8) or (2 * HLS_MAX div 3)
else
begin
if Lightness <= HLS_MAX_HALF then
Saturation := (ColorDiff * HLS_MAX + ColorSum / 2.0) / ColorSum
else
Saturation := (ColorDiff * HLS_MAX + ((2.0 * RGB_MAX - ColorMax - ColorMin) / 2.0)) /
(2.0 * RGB_MAX - ColorMax - ColorMin);
RedDelta := ((ColorMax - Red) * HLS_MAX_SIXTH + ColorDiff / 2.0) / ColorDiff;
GreenDelta := ((ColorMax - Green) * HLS_MAX_SIXTH + ColorDiff / 2.0) / ColorDiff;
BlueDelta := ((ColorMax - Blue) * HLS_MAX_SIXTH + ColorDiff / 2.0) / ColorDiff;
if Red = ColorMax then
Hue := BlueDelta - GreenDelta
else
if Green = ColorMax then
Hue := HLS_MAX_ONE_THIRD + RedDelta - BlueDelta
else
Hue := 2.0 * HLS_MAX_ONE_THIRD + GreenDelta - RedDelta;
if Hue < 0 then
Hue := Hue + HLS_MAX;
if Hue > HLS_MAX then
Hue := Hue - HLS_MAX;
AColor :=
JoinColorParts(Cardinal(Round(Hue)), Cardinal(Round(Lightness)), Cardinal(Round(Saturation)));
end;
Result := inherited ConvertFromColor(AColor);
end;
function TJvHLSColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Double;
Magic1, Magic2: Double;
Hue, Lightness, Saturation: Integer;
function HueToRGB(Lightness, Saturation, Hue: Double): Integer;
var
ResultEx: Double;
begin
if Hue < 0 then
Hue := Hue + HLS_MAX;
if Hue > HLS_MAX then
Hue := Hue - HLS_MAX;
if Hue < HLS_MAX_SIXTH then
ResultEx := Lightness + ((Saturation - Lightness) * Hue + HLS_MAX_TWELVETH) / HLS_MAX_SIXTH
else
if Hue < HLS_MAX_HALF then
ResultEx := Saturation
else
if Hue < HLS_MAX_TWO_THIRDS then
ResultEx := Lightness + ((Saturation - Lightness) * (HLS_MAX_TWO_THIRDS - Hue) + HLS_MAX_TWELVETH) / HLS_MAX_SIXTH
else
ResultEx := Lightness;
Result := Round(ResultEx);
end;
function RoundColor(Value: Double): Integer;
begin
if Value > RGB_MAX then
Result := RGB_MAX
else
Result := Round(Value);
end;
begin
SplitColorParts(AColor, Hue, Lightness, Saturation);
if Saturation = 0 then
begin
Red := (Lightness * RGB_MAX) / HLS_MAX;
Green := Red;
Blue := Red;
end
else
begin
if Lightness <= HLS_MAX_HALF then
Magic2 := (Lightness * (HLS_MAX + Saturation) + HLS_MAX_HALF) / HLS_MAX
else
Magic2 := Lightness + Saturation - ((Lightness * Saturation) + HLS_MAX_HALF) / HLS_MAX;
Magic1 := 2 * Lightness - Magic2;
Red := (HueToRGB(Magic1, Magic2, Hue + HLS_MAX_ONE_THIRD) * RGB_MAX + HLS_MAX_HALF) / HLS_MAX;
Green := (HueToRGB(Magic1, Magic2, Hue) * RGB_MAX + HLS_MAX_HALF) / HLS_MAX;
Blue := (HueToRGB(Magic1, Magic2, Hue - HLS_MAX_ONE_THIRD) * RGB_MAX + HLS_MAX_HALF) / HLS_MAX;
end;
Result := inherited ConvertToColor(
JoinColorParts(RoundColor(Red), RoundColor(Green), RoundColor(Blue)));
end;
function TJvHLSColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 120;
end;
function TJvHLSColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := HLS_MAX;
end;
function TJvHLSColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := HLS_MIN;
end;
function TJvHLSColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsHLS_Hue;
axIndex1:
Result := RsHLS_Lightness;
axIndex2:
Result := RsHLS_Saturation;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvHLSColorSpace.GetName: string;
begin
Result := RsHLS_FullName;
end;
function TJvHLSColorSpace.GetShortName: string;
begin
Result := RsHLS_ShortName;
end;
//=== { TJvCMYColorSpace } ===================================================
function TJvCMYColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Red, Green, Blue: Integer;
Cyan, Magenta, Yellow: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
Cyan := ((RGB_MAX - Red ) * (CMY_MAX-CMY_MIN+1) div (RGB_MAX-RGB_MIN+1)) + CMY_MIN;
Magenta := ((RGB_MAX - Green) * (CMY_MAX-CMY_MIN+1) div (RGB_MAX-RGB_MIN+1)) + CMY_MIN;
Yellow := ((RGB_MAX - Blue ) * (CMY_MAX-CMY_MIN+1) div (RGB_MAX-RGB_MIN+1)) + CMY_MIN;
Result := inherited ConvertFromColor(JoinColorParts(Cyan, Magenta, Yellow));
end;
function TJvCMYColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Cyan, Magenta, Yellow: Integer;
Red, Green, Blue: Integer;
begin
SplitColorParts(AColor, Cyan, Magenta, Yellow);
Red := ((CMY_MAX - Cyan ) * (RGB_MAX-RGB_MIN+1) div (CMY_MAX-CMY_MIN+1)) + RGB_MIN;
Green := ((CMY_MAX - Magenta) * (RGB_MAX-RGB_MIN+1) div (CMY_MAX-CMY_MIN+1)) + RGB_MIN;
Blue := ((CMY_MAX - Yellow ) * (RGB_MAX-RGB_MIN+1) div (CMY_MAX-CMY_MIN+1)) + RGB_MIN;
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvCMYColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 255;
end;
function TJvCMYColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := CMY_MAX;
end;
function TJvCMYColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := CMY_MIN;
end;
function TJvCMYColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsCMY_Cyan;
axIndex1:
Result := RsCMY_Magenta;
axIndex2:
Result := RsCMY_Yellow;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvCMYColorSpace.GetName: string;
begin
Result := RsCMY_FullName;
end;
function TJvCMYColorSpace.GetShortName: string;
begin
Result := RsCMY_ShortName;
end;
//=== { TJvYUVColorSpace } ===================================================
function TJvYUVColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Y, U, V: Integer;
Red, Green, Blue: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
Y := Round(0.257*Red + 0.504*Green + 0.098*Blue) + 16;
V := Round(0.439*Red - 0.368*Green - 0.071*Blue) + 128;
U := Round(-0.148*Red - 0.291*Green + 0.439*Blue) + 128;
Y := EnsureRange(Y, YUV_MIN, YUV_MAX);
U := EnsureRange(U, YUV_MIN, YUV_MAX);
V := EnsureRange(V, YUV_MIN, YUV_MAX);
Result := inherited ConvertFromColor(JoinColorParts(Y, U, V));
end;
function TJvYUVColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Integer;
Y, U, V: Integer;
begin
SplitColorParts(AColor, Y, U, V);
Y := Y - 16;
U := U - 128;
V := V - 128;
Red := Round(1.164*Y - 0.002*U + 1.596*V);
Green := Round(1.164*Y - 0.391*U - 0.813*V);
Blue := Round(1.164*Y + 2.018*U - 0.001*V);
Red := EnsureRange(Red , RGB_MIN, RGB_MAX);
Green := EnsureRange(Green, RGB_MIN, RGB_MAX);
Blue := EnsureRange(Blue, RGB_MIN, RGB_MAX);
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvYUVColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 128;
end;
function TJvYUVColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := YUV_MAX;
end;
function TJvYUVColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := YUV_MIN;
end;
function TJvYUVColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsYUV_Y;
axIndex1:
Result := RsYUV_U;
axIndex2:
Result := RsYUV_V;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvYUVColorSpace.GetName: string;
begin
Result := RsYUV_FullName;
end;
function TJvYUVColorSpace.GetShortName: string;
begin
Result := RsYUV_ShortName;
end;
//=== { TJvHSVColorSpace } ===================================================
function TJvHSVColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Hue, Saturation, Value: Integer;
Red, Green, Blue: Integer;
ColorMax, ColorMin, ColorDelta: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
if Red > Green then
ColorMax := Red
else
ColorMax := Green;
if Blue > ColorMax then
ColorMax := Blue;
if Red < Green then
ColorMin := Red
else
ColorMin := Green;
if Blue < ColorMin then
ColorMin := Blue;
ColorDelta := ColorMax - ColorMin;
Value := ColorMax;
if Value = 0 then
Saturation := 0
else
Saturation := (255 * ColorDelta) div Value;
if Saturation = 0 then
Hue := 0
else
begin
Hue := 0;
if Value = Red then
Hue := (40 * (Green - Blue) div ColorDelta);
if Value = Green then
Hue := (HSV_MAX div 3) + (40 * (Blue - Red) div ColorDelta);
if Value = Blue then
Hue := ((HSV_MAX * 2) div 3) + (40 * (Red - Green) div ColorDelta);
end;
if Hue < 0 then
Hue := Hue + HSV_MAX;
if Hue > HSV_MAX then
Hue := Hue - HSV_MAX;
Result := inherited ConvertFromColor(JoinColorParts(Hue, Saturation, Value));
end;
function TJvHSVColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Hue, Saturation, Value: Integer;
Red, Green, Blue: Integer;
P, Q, T, Summ, Rest: Integer;
begin
SplitColorParts(AColor, Hue, Saturation, Value);
if Saturation = 0 then
begin
Red := Value;
Green := Value;
Blue := Value;
end
else
begin
if Hue = HSV_MAX then
Hue := 0;
Rest := Hue mod (HSV_MAX div 6);
Hue := Hue div (HSV_MAX div 6);
Summ := Value * Saturation;
P := Value - Summ div RGB_MAX;
Q := Value - (Summ * Rest) div (RGB_MAX * (HSV_MAX div 6));
T := Value - (Summ * ((HSV_MAX div 6) - Rest)) div (RGB_MAX * (HSV_MAX div 6));
case Hue of
0:
begin
Red := Value;
Green := T;
Blue := P;
end;
1:
begin
Red := Q;
Green := Value;
Blue := P;
end;
2:
begin
Red := P;
Green := Value;
Blue := T;
end;
3:
begin
Red := P;
Green := Q;
Blue := Value;
end;
4:
begin
Red := T;
Green := P;
Blue := Value;
end;
else
Red := Value;
Green := P;
Blue := Q;
end;
end;
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvHSVColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
case Index of
axIndex0:
Result := 120;
axIndex1:
Result := 240;
else
Result := 150;
end;
end;
function TJvHSVColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
case Index of
axIndex0:
Result := HSV_MAX;
else
Result := RGB_MAX;
end;
end;
function TJvHSVColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := HSV_MIN;
end;
function TJvHSVColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsHSV_Hue;
axIndex1:
Result := RsHSV_Saturation;
axIndex2:
Result := RsHSV_Value;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvHSVColorSpace.GetName: string;
begin
Result := RsHSV_FullName;
end;
function TJvHSVColorSpace.GetShortName: string;
begin
Result := RsHSV_ShortName;
end;
//=== { TJvYIQColorSpace } ===================================================
function TJvYIQColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Y, I, Q: Integer;
Red, Green, Blue: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
Y := Round(0.299*Red + 0.587*Green + 0.114*Blue);
I := Round(0.596*Red - 0.275*Green - 0.321*Blue) + 128;
Q := Round(0.212*Red - 0.523*Green + 0.311*Blue) + 128;
Y := EnsureRange(Y, YIQ_MIN, YIQ_MAX);
I := EnsureRange(I, YIQ_MIN, YIQ_MAX);
Q := EnsureRange(Q, YIQ_MIN, YIQ_MAX);
Result := inherited ConvertFromColor(JoinColorParts(Y, I, Q));
end;
function TJvYIQColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Integer;
Y, I, Q: Integer;
begin
SplitColorParts(AColor, Y, I, Q);
//Y := Y;
I := I - 128;
Q := Q - 128;
Red := Round(Y + 0.956*I + 0.620*Q);
Green := Round(Y - 0.272*I - 0.647*Q);
Blue := Round(Y - 1.108*I + 1.705*Q);
Red := EnsureRange(Red , RGB_MIN, RGB_MAX);
Green := EnsureRange(Green, RGB_MIN, RGB_MAX);
Blue := EnsureRange(Blue, RGB_MIN, RGB_MAX);
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvYIQColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 128;
end;
function TJvYIQColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := YIQ_MAX;
end;
function TJvYIQColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := YIQ_MIN;
end;
function TJvYIQColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsYIQ_Y;
axIndex1:
Result := RsYIQ_I;
axIndex2:
Result := RsYIQ_Q;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvYIQColorSpace.GetName: string;
begin
Result := RsYIQ_FullName;
end;
function TJvYIQColorSpace.GetShortName: string;
begin
Result := RsYIQ_ShortName;
end;
//=== { TJvYCCColorSpace } ===================================================
function TJvYCCColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
Y, Cr, Cb: Integer;
Red, Green, Blue: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
Y := Round( 0.299*Red + 0.587*Green + 0.114*Blue);
Cr := Round(-0.150*Red - 0.293*Green + 0.443*Blue) + 128;
Cb := Round( 0.438*Red - 0.367*Green - 0.071*Blue) + 128;
Y := EnsureRange(Y, YCC_MIN, YCC_MAX);
Cr := EnsureRange(Cr, YCC_MIN, YCC_MAX);
Cb := EnsureRange(Cb, YCC_MIN, YCC_MAX);
Result := inherited ConvertFromColor(JoinColorParts(Y, Cr, Cb));
end;
function TJvYCCColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Integer;
Y, Cr, Cb: Integer;
begin
SplitColorParts(AColor, Y, Cr, Cb);
Y := Y;
Cr := Cr - 128;
Cb := Cb - 128;
Red := Round(Y - 0.001*Cr + 1.600*Cb);
Green := Round(Y - 0.388*Cr - 0.816*Cb);
Blue := Round(Y + 2.000*Cr + 0.002*Cb);
Red := EnsureRange(Red , RGB_MIN, RGB_MAX);
Green := EnsureRange(Green, RGB_MIN, RGB_MAX);
Blue := EnsureRange(Blue, RGB_MIN, RGB_MAX);
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvYCCColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 128;
end;
function TJvYCCColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := YCC_MAX;
end;
function TJvYCCColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := YCC_MIN;
end;
function TJvYCCColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsYCC_Y;
axIndex1:
Result := RsYCC_Cr;
axIndex2:
Result := RsYCC_Cb;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvYCCColorSpace.GetName: string;
begin
Result := RsYCC_FullName;
end;
function TJvYCCColorSpace.GetShortName: string;
begin
Result := RsYCC_ShortName;
end;
//=== { TJvXYZColorSpace } ===================================================
function TJvXYZColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
X, Y, Z: Integer;
Red, Green, Blue: Integer;
begin
SplitColorParts(AColor, Red, Green, Blue);
X := Round( 0.618*Red + 0.177*Green + 0.205*Blue);
Y := Round( 0.299*Red + 0.587*Green + 0.114*Blue);
Z := Round( 0.056*Green + 0.944*Blue);
X := EnsureRange(X, XYZ_MIN, XYZ_MAX);
Y := EnsureRange(Y, XYZ_MIN, XYZ_MAX);
Z := EnsureRange(Z, XYZ_MIN, XYZ_MAX);
Result := inherited ConvertFromColor(JoinColorParts(X, Y, Z));
end;
function TJvXYZColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Integer;
X, Y, Z: Integer;
begin
SplitColorParts(AColor, X, Y, Z);
Red := Round( 1.876*X - 0.533*Y - 0.343*Z);
Green := Round(-0.967*X + 1.998*Y - 0.031*Z);
Blue := Round( 0.057*X - 0.118*Y + 1.061*Z);
Red := EnsureRange(Red , RGB_MIN, RGB_MAX);
Green := EnsureRange(Green, RGB_MIN, RGB_MAX);
Blue := EnsureRange(Blue, RGB_MIN, RGB_MAX);
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvXYZColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 128;
end;
function TJvXYZColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := XYZ_MAX;
end;
function TJvXYZColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := XYZ_MIN;
end;
function TJvXYZColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsXYZ_X;
axIndex1:
Result := RsXYZ_Y;
axIndex2:
Result := RsXYZ_Z;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvXYZColorSpace.GetName: string;
begin
Result := RsXYZ_FullName;
end;
function TJvXYZColorSpace.GetShortName: string;
begin
Result := RsXYZ_ShortName;
end;
//=== { TJvLABColorSpace } ===================================================
function TJvLABColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
X, Y, Z: Extended;
L, A, B: Integer;
Red, Green, Blue: Integer;
function Calc(Value: Extended): Extended;
begin
if Value > 0.008856 then
Result := Power(Value, 1.0 / 3.0)
else
Result := 7.7787 * Value + (16.0 / 116.0);
end;
begin
SplitColorParts(AColor, Red, Green, Blue);
X := (0.618*Red + 0.177*Green + 0.205*Blue) / XYZ_MAX;
Y := (0.299*Red + 0.587*Green + 0.114*Blue) / XYZ_MAX;
Z := ( 0.056*Green + 0.944*Blue) / XYZ_MAX;
X := EnsureRange(X, 0.0, 1.0);
Y := EnsureRange(Y, 0.0, 1.0);
Z := EnsureRange(Z, 0.0, 1.0);
if Y > 0.008856 then
L := Round(116.0 * Power(Y, 1.0 / 3.0) - 16.0)
else
L := Round(903.3 * Y);
A := Round(500.0 *(Calc(X) - Calc(Y)))+128;
B := Round(200.0 *(Calc(Y) - Calc(Z)))+128;
L := EnsureRange(L, LAB_MIN, LAB_MAX);
A := EnsureRange(A, LAB_MIN, LAB_MAX);
B := EnsureRange(B, LAB_MIN, LAB_MAX);
Result := inherited ConvertFromColor(JoinColorParts(L, A, B));
end;
function TJvLABColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
var
Red, Green, Blue: Integer;
X, Y, Z: Extended;
L, A, B: Integer;
function Calc(Value: Extended): Extended;
begin
if Value > 0.207 then
Result := Power(Value, 3.0)
else
Result := ((116.0 * Value) - 16.0) / 903.3;
end;
begin
SplitColorParts(AColor, L, A, B);
if L > 8 then
Y := XYZ_MAX * Power((L + 16.0) / 116.0, 3.0)
else
Y := (XYZ_MAX * L) / 903.3;
X := XYZ_MAX * Calc(((A-128) / 500.0) + ((L + 16.0) / 116.0));
Z := XYZ_MAX * Calc(((L + 16.0) / 116.0) - ((B-128) / 200.0));
X := EnsureRange(X, XYZ_MIN, XYZ_MAX);
Y := EnsureRange(Y, XYZ_MIN, XYZ_MAX);
Z := EnsureRange(Z, XYZ_MIN, XYZ_MAX);
Red := Round( 1.876*X - 0.533*Y - 0.343*Z);
Green := Round(-0.967*X + 1.998*Y - 0.031*Z);
Blue := Round( 0.057*X - 0.118*Y + 1.061*Z);
Red := EnsureRange(Red , RGB_MIN, RGB_MAX);
Green := EnsureRange(Green, RGB_MIN, RGB_MAX);
Blue := EnsureRange(Blue, RGB_MIN, RGB_MAX);
Result := inherited ConvertToColor(JoinColorParts(Red, Green, Blue));
end;
function TJvLABColorSpace.GetAxisDefault(Index: TJvAxisIndex): Byte;
begin
Result := 50;
end;
function TJvLABColorSpace.GetAxisMax(Index: TJvAxisIndex): Byte;
begin
Result := LAB_MAX;
end;
function TJvLABColorSpace.GetAxisMin(Index: TJvAxisIndex): Byte;
begin
Result := LAB_MIN;
end;
function TJvLABColorSpace.GetAxisName(Index: TJvAxisIndex): string;
begin
case Index of
axIndex0:
Result := RsLAB_L;
axIndex1:
Result := RsLAB_A;
axIndex2:
Result := RsLAB_B;
else
Result := inherited GetAxisName(Index);
end;
end;
function TJvLABColorSpace.GetName: string;
begin
Result := RsLAB_FullName;
end;
function TJvLABColorSpace.GetShortName: string;
begin
Result := RsLAB_ShortName;
end;
//=== { TJvDEFColorSpace } ===================================================
constructor TJvDEFColorSpace.Create(ColorID: TJvFullColorSpaceID);
begin
inherited Create(ColorID);
FDelphiColors := TStringList.Create;
// ignore duplicates
FDelphiColors.Duplicates := dupIgnore;
GetColorValues(GetColorValuesCallBack);
AddDelphiColor(clNone);
end;
destructor TJvDEFColorSpace.Destroy;
begin
FDelphiColors.Free;
inherited Destroy;
end;
procedure TJvDEFColorSpace.GetColorValuesCallBack(const S: string);
var
AColor: TColor;
begin
AColor := StringToColor(S);
AddCustomColor(AColor,Copy(S,3,Length(S)-2),ColorToPrettyName(AColor));
end;
procedure TJvDEFColorSpace.AddDelphiColor(Value: TColor);
begin
AddCustomColor(Value,ColorToString(Value),ColorToPrettyName(Value));
end;
procedure TJvDEFColorSpace.AddCustomColor(AColor: TColor; ShortName,
PrettyName: string);
begin
if FDelphiColors.IndexOfObject(TObject(AColor)) = -1 then
begin
FDelphiColors.Values[ShortName] := PrettyName;
FDelphiColors.Objects[FDelphiColors.IndexOfName(ShortName)] := TObject(AColor);
end;
end;
function TJvDEFColorSpace.ConvertFromColor(AColor: TColor): TJvFullColor;
var
I: Integer;
NewColor: TColor;
begin
NewColor := clNone;
for I := 0 to FDelphiColors.Count - 1 do
if AColor = TColor(FDelphiColors.Objects[I]) then
begin
NewColor := AColor;
Break;
end;
Result := inherited ConvertFromColor(NewColor);
if NewColor = clNone then
// mark it as clNone
Result := Result or JvSpecialFullColorMask
else
if NewColor = clDefault then
// mark it as clDefault
Result := Result or JvSpecialFullColorMask
else
if (NewColor and JvSystemColorMask) = JvSystemColorMask then
// mark it as predefined color
Result := Result or JvSystemFullColorMask
else
if (NewColor and JvSystemColorMask) = 0 then
Result := ColorSpaceManager.ColorSpace[csRGB].ConvertFromColor(NewColor)
// should never happend because there should be no way ...
else
raise EJvColorSpaceError.CreateResFmt(@RsEInconvertibleColor, [Cardinal(NewColor)]);
end;
function TJvDEFColorSpace.ConvertToColor(AColor: TJvFullColor): TColor;
begin
Result := inherited ConvertToColor(AColor);
case AColor and JvSubFullColorMask of
JvSystemFullColorMask:
Result := Cardinal(Result) or JvSystemColorMask;
JvSpecialFullColorMask:
begin
if Result = (clNone and $FFFFFF) then
Result := clNone
else
if Result = (clDefault and $FFFFFF) then
Result := clDefault
else
raise EJvColorSpaceError.CreateResFmt(@RsEInconvertibleColor, [Cardinal(AColor)]);
end;
else
raise EJvColorSpaceError.CreateResFmt(@RsEInconvertibleColor, [Cardinal(AColor)]);
end;
end;
function TJvDEFColorSpace.GetColorName(Index: Integer): string;
begin
if (Index >= 0) and (Index < FDelphiColors.Count) then
Result := FDelphiColors.Names[Index]
else
Result := '';
end;
function TJvDEFColorSpace.GetPrettyName(Index: Integer): string;
begin
Result := FDelphiColors.Values[FDelphiColors.Names[Index]];
end;
function TJvDEFColorSpace.GetColorValue(Index: Integer): TColor;
begin
if (Index >= 0) and (Index < FDelphiColors.Count) then
Result := TColor(FDelphiColors.Objects[Index])
else
Result := clNone;
end;
function TJvDEFColorSpace.GetName: string;
begin
Result := RsDEF_FullName;
end;
function TJvDEFColorSpace.GetShortName: string;
begin
Result := RsDEF_ShortName;
end;
function TJvDEFColorSpace.GetNumberOfColors: Cardinal;
begin
Result := FDelphiColors.Count;
end;
//=== { TJvColorSpaceManager } ===============================================
constructor TJvColorSpaceManager.Create;
begin
inherited Create;
FColorSpaceList := TList.Create;
end;
destructor TJvColorSpaceManager.Destroy;
var
Index: Integer;
begin
for Index := 0 to FColorSpaceList.Count - 1 do
TJvColorSpace(FColorSpaceList.Items[Index]).Free;
FColorSpaceList.Free;
inherited Destroy;
end;
function TJvColorSpaceManager.ConvertToID(AColor: TJvFullColor;
DestID: TJvFullColorSpaceID): TJvFullColor;
var
SourceID: TJvFullColorSpaceID;
Color: TColor;
begin
SourceID := GetColorSpaceID(AColor);
if SourceID = DestID then
Result := AColor
else
begin
Color := ColorToRGB(ColorSpace[SourceID].ConvertToColor(AColor));
Result := ColorSpace[DestID].ConvertFromColor(Color);
end;
end;
function TJvColorSpaceManager.ConvertToColor(AColor: TJvFullColor): TColor;
begin
Result := ColorSpace[GetColorSpaceID(AColor)].ConvertToColor(AColor);
end;
function TJvColorSpaceManager.ConvertFromColor(AColor: TColor): TJvFullColor;
var
MaskedColor:Cardinal;
begin
MaskedColor := Cardinal(AColor) and JvSystemColorMask;
if (AColor = clNone) or (AColor = clDefault) or
(MaskedColor = JvSystemColorMask) then
Result := ColorSpace[csDEF].ConvertFromColor(AColor)
else
if MaskedColor = 0 then
Result := ColorSpace[csRGB].ConvertFromColor(AColor)
else
raise EJvColorSpaceError.CreateResFmt(@RsEInconvertibleColor, [Cardinal(AColor)]);
end;
function TJvColorSpaceManager.GetColorSpaceID(AColor: TJvFullColor): TJvFullColorSpaceID;
var
I: Integer;
begin
Result := TJvFullColorSpaceID(AColor shr 24) and csID_MASK;
for I := 0 to Count - 1 do
if ColorSpaceByIndex[I].ID = Result then
Exit;
raise EJvColorSpaceError.CreateResFmt(@RsEIllegalID, [Ord(Result)]);
end;
function TJvColorSpaceManager.GetColorSpace(ID: TJvFullColorSpaceID): TJvColorSpace;
var
I: Integer;
begin
Result := nil;
for I := 0 to FColorSpaceList.Count - 1 do
begin
Result := TJvColorSpace(FColorSpaceList.Items[I]);
if Result.ID = ID then
Break;
end;
if Result = nil then
raise EJvColorSpaceError.CreateResFmt(@RsECSNotFound, [Ord(ID)]);
end;
function TJvColorSpaceManager.GetCount: Integer;
begin
Result := FColorSpaceList.Count;
end;
function TJvColorSpaceManager.GetColorSpaceByIndex(Index: Integer): TJvColorSpace;
begin
Result := TJvColorSpace(FColorSpaceList.Items[Index]);
end;
procedure TJvColorSpaceManager.RegisterColorSpace(NewColorSpace: TJvColorSpace);
var
Index: Integer;
CS: TJvColorSpace;
begin
for Index := 0 to FColorSpaceList.Count - 1 do
begin
CS := TJvColorSpace(FColorSpaceList.Items[Index]);
if CS.ID = NewColorSpace.ID then
raise EJvColorSpaceError.CreateResFmt(@RsECSAlreadyExists, [CS.ID, CS.Name]);
end;
FColorSpaceList.Add(Pointer(NewColorSpace));
end;
procedure TJvColorSpaceManager.UnRegisterColorSpace(AColorSpace: TJvColorSpace);
begin
// maybe more than one instance of one class
while FColorSpaceList.Remove(AColorSpace) >= 0 do
;
end;
initialization
{$IFDEF UNITVERSIONING}
RegisterUnitVersion(HInstance, UnitVersioning);
{$ENDIF UNITVERSIONING}
finalization
FreeAndNil(GlobalColorSpaceManager);
{$IFDEF UNITVERSIONING}
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.