summaryrefslogtreecommitdiff
path: root/src/gui/fpg_colormapping.pas
blob: a22b949ef64c143ebf3b65e10e4371f94a8c584c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
{
    fpGUI  -  Free Pascal GUI Toolkit

    Copyright (C) 2006 - 2015 See the file AUTHORS.txt, included in this
    distribution, for details of the copyright.

    See the file COPYING.modifiedLGPL, included in this distribution,
    for details about redistributing fpGUI.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Description:
      This unit contains some color conversion/mapping functions.
}

unit fpg_ColorMapping;

{$mode objfpc}{$H+}

interface

uses
  Classes, fpg_base;

 // IN these functions the following definitions apply:
 // Hue: 0 - 1535
 //   red = 0  green = 512  blue = 1024
 // Saturation: 0 - 1
 //   grey (no color) = 0  max color = 1
 // Value: 0 - 1
 //   black =0   max brightness = 1

procedure RGBToHSV(C: TfpgColor; out Hue: longint; out Saturation, Value: double);
function HSVToRGB(const H: longint; const S, V: double): TfpgColor;

implementation

uses
  Math;

procedure RGBToHSV(C: TfpgColor; out Hue: longint; out Saturation, Value: double);
var
  r, g, b: longint;
  hi, lo: longint;
  d:   longint;
  rgb: TRGBTriple;
begin
  rgb   := fpgColorToRGBTriple(C);
  r     := rgb.Red;
  g     := rgb.Green;
  b     := rgb.Blue;
  hi    := max(max(r, g), b);
  lo    := min(min(r, g), b);
  d     := hi - lo;
  Value := hi / 256;
  if d > 0 then
  begin
    if r = hi then
      Hue := 256 * (g - b) div d
    else if g = hi then
      Hue := 512 + 256 * (b - r) div d
    else
      Hue := 1024 + 256 * (r - g) div d;
    if Hue < 0 then
      Hue := Hue + 1536;
  end
  else
    Hue := 0; // doesn't matter (grey: Sat = 0)

  if hi > 0 then
    Saturation := d / hi
  else
    Saturation := 0; // doesn't matter (black: Val = 0
end;

function HSVToRGB(const H: longint; const S, V: double): TfpgColor;
var
  r, g, b: longint;
  rgb: TRGBTriple;
begin
  if (h < 0) or (h > 1535) or (S < 0) or (S > 1) or (V < 0) or (V > 1) then
  begin
    // Invalid value, use black
    Result := 0;
    exit;
  end;
  case h div 256 of
    0:
    begin
      r := 255;
      g := h;
      b := 0;
    end;
    1:
    begin
      r := 511 - h;
      g := 255;
      b := 0;
    end;
    2:
    begin
      r := 0;
      g := 255;
      b := h - 512;
    end;
    3:
    begin
      r := 0;
      g := 1023 - h;
      b := 255;
    end;
    4:
    begin
      r := h - 1024;
      g := 0;
      b := 255;
    end;
    5:
    begin
      r := 255;
      g := 0;
      b := 1535 - h;
    end;
  end;
  r      := Trunc(V * (255 - S * (255 - r)));
  g      := Trunc(V * (255 - S * (255 - g)));
  b      := Trunc(V * (255 - S * (255 - b)));
  rgb.Red := r;
  rgb.Green := g;
  rgb.Blue := b;
  Result := RGBTripleTofpgColor(rgb);
end;


end.