857 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			857 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
     Apophysis Copyright (C) 2001-2004 Mark Townsend
 | 
						|
 | 
						|
     This program is free software; you can redistribute it and/or modify
 | 
						|
     it under the terms of the GNU General Public License as published by
 | 
						|
     the Free Software Foundation; either version 2 of the License, or
 | 
						|
     (at your option) any later version.
 | 
						|
 | 
						|
     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.  See the
 | 
						|
     GNU General Public License for more details.
 | 
						|
 | 
						|
     You should have received a copy of the GNU General Public License
 | 
						|
     along with this program; if not, write to the Free Software
 | 
						|
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
}
 | 
						|
unit Gradient;
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
 | 
						|
uses
 | 
						|
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 | 
						|
  ExtCtrls, StdCtrls, ComCtrls, Registry, cmap, Menus, ToolWin, Buttons,
 | 
						|
  AppEvnts;
 | 
						|
const
 | 
						|
  PixelCountMax = 32768;
 | 
						|
 | 
						|
type
 | 
						|
  pRGBTripleArray = ^TRGBTripleArray;
 | 
						|
  TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
 | 
						|
 | 
						|
type
 | 
						|
  TGradientForm = class(TForm)
 | 
						|
    pnlPalette: TPanel;
 | 
						|
    pnlControls: TPanel;
 | 
						|
    cmbPalette: TComboBox;
 | 
						|
    GradientImage: TImage;
 | 
						|
    PopupMenu: TPopupMenu;
 | 
						|
    mnuReverse: TMenuItem;
 | 
						|
    mnuInvert: TMenuItem;
 | 
						|
    btnMenu: TSpeedButton;
 | 
						|
    Popup: TPopupMenu;
 | 
						|
    mnuHue: TMenuItem;
 | 
						|
    mnuRotate: TMenuItem;
 | 
						|
    N1: TMenuItem;
 | 
						|
    mnuSaturation: TMenuItem;
 | 
						|
    mnuBrightness: TMenuItem;
 | 
						|
    N2: TMenuItem;
 | 
						|
    ScrollBar: TScrollBar;
 | 
						|
    lblVal: TLabel;
 | 
						|
    mnuBlur: TMenuItem;
 | 
						|
    btnOpen: TSpeedButton;
 | 
						|
    N3: TMenuItem;
 | 
						|
    mnuGradientBrowser: TMenuItem;
 | 
						|
    mnuSmoothPalette: TMenuItem;
 | 
						|
    btnSmoothPalette: TSpeedButton;
 | 
						|
    N4: TMenuItem;
 | 
						|
    SaveGradient1: TMenuItem;
 | 
						|
    SaveasMapfile1: TMenuItem;
 | 
						|
    SaveDialog: TSaveDialog;
 | 
						|
    Label1: TLabel;
 | 
						|
    btnPaste: TSpeedButton;
 | 
						|
    btnCopy: TSpeedButton;
 | 
						|
    N5: TMenuItem;
 | 
						|
    mnuCopy: TMenuItem;
 | 
						|
    mnuPaste: TMenuItem;
 | 
						|
    ApplicationEvents: TApplicationEvents;
 | 
						|
    mnuSaveasDefault: TMenuItem;
 | 
						|
    N6: TMenuItem;
 | 
						|
    mnuRandomize: TMenuItem;
 | 
						|
    N7: TMenuItem;
 | 
						|
    mnuFrequency: TMenuItem;
 | 
						|
    Contrast1: TMenuItem;
 | 
						|
    procedure cmbPaletteChange(Sender: TObject);
 | 
						|
    procedure FormShow(Sender: TObject);
 | 
						|
    procedure btnApplyClick(Sender: TObject);
 | 
						|
    procedure DrawPalette;
 | 
						|
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
 | 
						|
    procedure mnuReverseClick(Sender: TObject);
 | 
						|
    procedure mnuInvertClick(Sender: TObject);
 | 
						|
    procedure btnMenuClick(Sender: TObject);
 | 
						|
    procedure mnuRotateClick(Sender: TObject);
 | 
						|
    procedure mnuHueClick(Sender: TObject);
 | 
						|
    procedure mnuSaturationClick(Sender: TObject);
 | 
						|
    procedure ScrollBarChange(Sender: TObject);
 | 
						|
    procedure mnuBrightnessClick(Sender: TObject);
 | 
						|
    procedure mnuBlurClick(Sender: TObject);
 | 
						|
    procedure btnOpenClick(Sender: TObject);
 | 
						|
    procedure mnuSmoothPaletteClick(Sender: TObject);
 | 
						|
    procedure SaveGradient1Click(Sender: TObject);
 | 
						|
    procedure SaveasMapfile1Click(Sender: TObject);
 | 
						|
    procedure cmbPaletteDrawItem(Control: TWinControl; Index: Integer;
 | 
						|
      Rect: TRect; State: TOwnerDrawState);
 | 
						|
    procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
 | 
						|
      var ScrollPos: Integer);
 | 
						|
    procedure btnCopyClick(Sender: TObject);
 | 
						|
    procedure btnPasteClick(Sender: TObject);
 | 
						|
    procedure ApplicationEventsActivate(Sender: TObject);
 | 
						|
    procedure mnuSaveasDefaultClick(Sender: TObject);
 | 
						|
    procedure mnuRandomizeClick(Sender: TObject);
 | 
						|
    procedure mnuFrequencyClick(Sender: TObject);
 | 
						|
    procedure Contrast1Click(Sender: TObject);
 | 
						|
    procedure FormCreate(Sender: TObject);
 | 
						|
  private
 | 
						|
    procedure Apply;
 | 
						|
    function Blur(const radius: integer; const pal: TColorMap): TColorMap;
 | 
						|
    function Frequency(const times: Integer; const pal: TColorMap): TColorMap;
 | 
						|
    procedure SaveMap(FileName: string);
 | 
						|
  public
 | 
						|
    Palette: TColorMap;
 | 
						|
    BackupPal: TColorMap;
 | 
						|
    procedure UpdateGradient(Pal: TColorMap);
 | 
						|
    function RandomGradient: TColorMap;
 | 
						|
  end;
 | 
						|
 | 
						|
var
 | 
						|
  GradientForm: TGradientForm;
 | 
						|
  pCmap: integer;
 | 
						|
 | 
						|
function GradientInClipboard: boolean;
 | 
						|
procedure RGBToHSV(R, G, B: byte; var H, S, V: real);
 | 
						|
procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer);
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
uses Main, cmapdata, Math, Browser, Editor, Global, Save, Adjust, Mutate, ClipBrd;
 | 
						|
 | 
						|
{$R *.DFM}
 | 
						|
 | 
						|
procedure TGradientForm.Apply;
 | 
						|
begin
 | 
						|
  MainForm.StopThread;
 | 
						|
  MainForm.UpdateUndo;
 | 
						|
  MainCp.CmapIndex := cmbPalette.ItemIndex;
 | 
						|
  MainCp.cmap := Palette;
 | 
						|
  if EditForm.visible then EditForm.UpdateDisplay;
 | 
						|
//  if AdjustForm.visible then AdjustForm.UpdateDisplay;
 | 
						|
  if MutateForm.Visible then MutateForm.UpdateDisplay;
 | 
						|
  MainForm.RedrawTimer.enabled := true;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.SaveMap(FileName: string);
 | 
						|
var
 | 
						|
  i: Integer;
 | 
						|
  l: string;
 | 
						|
  MapFile: TextFile;
 | 
						|
begin
 | 
						|
{ Save a map file }
 | 
						|
  AssignFile(MapFile, FileName);
 | 
						|
  try
 | 
						|
    ReWrite(MapFile);
 | 
						|
    { first line with comment }
 | 
						|
    l := Format(' %3d %3d %3d  Exported from Apophysis 2.0', [Palette[0][0], palette[0][1],
 | 
						|
      palette[0][2]]);
 | 
						|
    Writeln(MapFile, l);
 | 
						|
    { now the rest }
 | 
						|
    for i := 1 to 255 do
 | 
						|
    begin
 | 
						|
      l := Format(' %3d %3d %3d', [Palette[i][0], palette[i][1],
 | 
						|
        palette[i][2]]);
 | 
						|
      Writeln(MapFile, l);
 | 
						|
    end;
 | 
						|
    CloseFile(MapFile);
 | 
						|
  except
 | 
						|
    on EInOutError do Application.MessageBox(PChar('Cannot Open File: ' +
 | 
						|
        FileName), 'Apophysis', 16);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.UpdateGradient(Pal: TColorMap);
 | 
						|
begin
 | 
						|
  Palette := Pal;
 | 
						|
  BackupPal := Pal;
 | 
						|
  DrawPalette;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer);
 | 
						|
var
 | 
						|
  R, G, B, Sa, Va, Hue, i, f, p, q, t: real;
 | 
						|
begin
 | 
						|
  R := 0;
 | 
						|
  G := 0;
 | 
						|
  B := 0;
 | 
						|
  Sa := S / 100;
 | 
						|
  Va := V / 100;
 | 
						|
  if S = 0 then
 | 
						|
  begin
 | 
						|
    R := Va;
 | 
						|
    G := Va;
 | 
						|
    B := Va;
 | 
						|
  end
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    Hue := H / 60;
 | 
						|
    if Hue = 6 then Hue := 0;
 | 
						|
    i := Int(Hue);
 | 
						|
    f := Hue - i;
 | 
						|
    p := Va * (1 - Sa);
 | 
						|
    q := Va * (1 - (Sa * f));
 | 
						|
    t := Va * (1 - (Sa * (1 - f)));
 | 
						|
    case Round(i) of
 | 
						|
      0: begin
 | 
						|
          R := Va;
 | 
						|
          G := t;
 | 
						|
          B := p;
 | 
						|
        end;
 | 
						|
      1: begin
 | 
						|
          R := q;
 | 
						|
          G := Va;
 | 
						|
          B := p;
 | 
						|
        end;
 | 
						|
      2: begin
 | 
						|
          R := p;
 | 
						|
          G := Va;
 | 
						|
          B := t;
 | 
						|
        end;
 | 
						|
      3: begin
 | 
						|
          R := p;
 | 
						|
          G := q;
 | 
						|
          B := Va;
 | 
						|
        end;
 | 
						|
      4: begin
 | 
						|
          R := t;
 | 
						|
          G := p;
 | 
						|
          B := Va;
 | 
						|
        end;
 | 
						|
      5: begin
 | 
						|
          R := Va;
 | 
						|
          G := p;
 | 
						|
          B := q;
 | 
						|
        end;
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  Rb := Round(Int(255.9999 * R));
 | 
						|
  Gb := Round(Int(255.9999 * G));
 | 
						|
  Bb := Round(Int(255.9999 * B));
 | 
						|
end;
 | 
						|
 | 
						|
procedure RGBToHSV(R, G, B: byte; var H, S, V: real);
 | 
						|
var
 | 
						|
  vRed, vGreen, vBlue, Mx, Mn, Va, Sa, rc, gc, bc: real;
 | 
						|
begin
 | 
						|
  vRed := R / 255;
 | 
						|
  vGreen := G / 255;
 | 
						|
  vBlue := B / 255;
 | 
						|
  Mx := vRed;
 | 
						|
  if vGreen > Mx then Mx := vGreen;
 | 
						|
  if vBlue > Mx then Mx := vBlue;
 | 
						|
  Mn := vRed;
 | 
						|
  if vGreen < Mn then Mn := vGreen;
 | 
						|
  if vBlue < Mn then Mn := vBlue;
 | 
						|
  Va := Mx;
 | 
						|
  if Mx <> 0 then
 | 
						|
    Sa := (Mx - Mn) / Mx
 | 
						|
  else
 | 
						|
    Sa := 0;
 | 
						|
  if Sa = 0 then
 | 
						|
    H := 0
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    rc := (Mx - vRed) / (Mx - Mn);
 | 
						|
    gc := (Mx - vGreen) / (Mx - Mn);
 | 
						|
    bc := (Mx - vBlue) / (Mx - Mn);
 | 
						|
    if Mx = vRed then
 | 
						|
      H := bc - gc
 | 
						|
    else if Mx = vGreen then
 | 
						|
      H := 2 + rc - bc
 | 
						|
    else if Mx = vBlue then
 | 
						|
      H := 4 + gc - rc;
 | 
						|
    H := H * 60;
 | 
						|
    if H < 0 then H := H + 360;
 | 
						|
  end;
 | 
						|
  S := Sa * 100;
 | 
						|
  V := Va * 100;
 | 
						|
end;
 | 
						|
 | 
						|
function TGradientForm.Blur(const Radius: Integer; const pal: TColorMap): TColorMap;
 | 
						|
var
 | 
						|
  r, g, b, n, i, j, k: Integer;
 | 
						|
begin
 | 
						|
  Result := Pal;
 | 
						|
  if Radius <> 0 then
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      n := -1;
 | 
						|
      r := 0;
 | 
						|
      g := 0;
 | 
						|
      b := 0;
 | 
						|
      for j := i - radius to i + radius do
 | 
						|
      begin
 | 
						|
        inc(n);
 | 
						|
        k := (256 + j) mod 256;
 | 
						|
        if k <> i then begin
 | 
						|
          r := r + Pal[k][0];
 | 
						|
          g := g + Pal[k][1];
 | 
						|
          b := b + Pal[k][2];
 | 
						|
        end;
 | 
						|
      end;
 | 
						|
      if n <> 0 then begin
 | 
						|
        Result[i][0] := r div n;
 | 
						|
        Result[i][1] := g div n;
 | 
						|
        Result[i][2] := b div n;
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
function TGradientForm.Frequency(const times: Integer; const pal: TColorMap): TColorMap;
 | 
						|
{ This can be improved }
 | 
						|
var
 | 
						|
  n, i, j: Integer;
 | 
						|
begin
 | 
						|
  Result := Pal;
 | 
						|
  if times <> 1 then
 | 
						|
  begin
 | 
						|
    n := 256 div times;
 | 
						|
    for j := 0 to times do
 | 
						|
      for i := 0 to n do
 | 
						|
      begin
 | 
						|
        if (i + j * n) < 256 then
 | 
						|
        begin
 | 
						|
          Result[i + j * n][0] := pal[i * times][0];
 | 
						|
          Result[i + j * n][1] := pal[i * times][1];
 | 
						|
          Result[i + j * n][2] := pal[i * times][2];
 | 
						|
        end;
 | 
						|
      end;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.DrawPalette;
 | 
						|
var
 | 
						|
  i, j: integer;
 | 
						|
  Row: pRGBTripleArray;
 | 
						|
  BitMap: TBitMap;
 | 
						|
begin
 | 
						|
  BitMap := TBitMap.Create;
 | 
						|
  try
 | 
						|
    Bitmap.PixelFormat := pf24bit;
 | 
						|
    BitMap.Width := 256;
 | 
						|
    BitMap.Height := 1;
 | 
						|
    for j := 0 to Bitmap.Height - 1 do
 | 
						|
    begin
 | 
						|
      Row := Bitmap.Scanline[j];
 | 
						|
      for i := 0 to Bitmap.Width - 1 do
 | 
						|
      begin
 | 
						|
        with Row[i] do
 | 
						|
        begin
 | 
						|
          rgbtRed := Palette[i][0];
 | 
						|
          rgbtGreen := Palette[i][1];
 | 
						|
          rgbtBlue := Palette[i][2];
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end;
 | 
						|
    GradientImage.Picture.Graphic := Bitmap;
 | 
						|
    GradientImage.Refresh;
 | 
						|
  finally
 | 
						|
    BitMap.Free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.cmbPaletteChange(Sender: TObject);
 | 
						|
var
 | 
						|
  i: integer;
 | 
						|
begin
 | 
						|
  i := cmbPalette.ItemIndex;
 | 
						|
  GetCmap(i, 1, Palette);
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
  DrawPalette;
 | 
						|
  Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.FormShow(Sender: TObject);
 | 
						|
var
 | 
						|
  Registry: TRegistry;
 | 
						|
begin
 | 
						|
  { Read posution from registry }
 | 
						|
  Registry := TRegistry.Create;
 | 
						|
  try
 | 
						|
    Registry.RootKey := HKEY_CURRENT_USER;
 | 
						|
    if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Gradient', False) then
 | 
						|
    begin
 | 
						|
      if Registry.ValueExists('Left') then
 | 
						|
        GradientForm.Left := Registry.ReadInteger('Left');
 | 
						|
      if Registry.ValueExists('Top') then
 | 
						|
        GradientForm.Top := Registry.ReadInteger('Top');
 | 
						|
    end;
 | 
						|
    Registry.CloseKey;
 | 
						|
  finally
 | 
						|
    Registry.Free;
 | 
						|
  end;
 | 
						|
  DrawPalette;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.FormClose(Sender: TObject;
 | 
						|
  var Action: TCloseAction);
 | 
						|
var
 | 
						|
  Registry: TRegistry;
 | 
						|
begin
 | 
						|
  { Write position to registry }
 | 
						|
  Registry := TRegistry.Create;
 | 
						|
  try
 | 
						|
    Registry.RootKey := HKEY_CURRENT_USER;
 | 
						|
    { Defaults }
 | 
						|
    if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Gradient', True) then
 | 
						|
    begin
 | 
						|
      Registry.WriteInteger('Top', GradientForm.Top);
 | 
						|
      Registry.WriteInteger('Left', GradientForm.Left);
 | 
						|
    end;
 | 
						|
  finally
 | 
						|
    Registry.Free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TGradientForm.btnApplyClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuReverseClick(Sender: TObject);
 | 
						|
var
 | 
						|
  i: integer;
 | 
						|
  pal: TColorMap;
 | 
						|
begin
 | 
						|
  for i := 0 to 255 do begin
 | 
						|
    pal[i][0] := Palette[255 - i][0];
 | 
						|
    pal[i][1] := Palette[255 - i][1];
 | 
						|
    pal[i][2] := Palette[255 - i][2];
 | 
						|
  end;
 | 
						|
  UpdateGradient(pal);
 | 
						|
  Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuInvertClick(Sender: TObject);
 | 
						|
var
 | 
						|
  i: integer;
 | 
						|
begin
 | 
						|
  for i := 0 to 255 do
 | 
						|
  begin
 | 
						|
    Palette[i][0] := 255 - Palette[i][0];
 | 
						|
    Palette[i][1] := 255 - Palette[i][1];
 | 
						|
    Palette[i][2] := 255 - Palette[i][2];
 | 
						|
  end;
 | 
						|
  UpdateGradient(palette);
 | 
						|
  Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.btnMenuClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  Popup.Popup(btnMenu.ClientOrigin.x, btnMenu.ClientOrigin.y + btnMenu.Height);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.ScrollBarChange(Sender: TObject);
 | 
						|
var
 | 
						|
  intens, i, r, g, b: integer;
 | 
						|
  h, s, v: real;
 | 
						|
begin
 | 
						|
  lblVal.Caption := IntToStr(ScrollBar.Position);
 | 
						|
  if btnMenu.Caption = 'Hue' then
 | 
						|
  begin
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v);
 | 
						|
      h := Round(360 + h + ScrollBar.Position) mod 360;
 | 
						|
      HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]);
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Saturation' then
 | 
						|
  begin
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v);
 | 
						|
      s := s + ScrollBar.Position;
 | 
						|
      if s > 100 then s := 100;
 | 
						|
      if s < 0 then s := 0;
 | 
						|
      HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]);
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Contrast' then
 | 
						|
  begin
 | 
						|
    intens := scrollBar.Position;
 | 
						|
    if intens > 0 then intens := intens * 2;
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      r := BackupPal[i][0];
 | 
						|
      g := BackupPal[i][1];
 | 
						|
      b := BackupPal[i][2];
 | 
						|
      r := round(r + intens / 100 * (r - 127));
 | 
						|
      g := round(g + intens / 100 * (g - 127));
 | 
						|
      b := round(b + intens / 100 * (b - 127));
 | 
						|
      if R > 255 then R := 255 else if R < 0 then R := 0;
 | 
						|
      if G > 255 then G := 255 else if G < 0 then G := 0;
 | 
						|
      if B > 255 then B := 255 else if B < 0 then B := 0;
 | 
						|
      Palette[i][0] := r;
 | 
						|
      Palette[i][1] := g;
 | 
						|
      Palette[i][2] := b;
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Brightness' then
 | 
						|
  begin
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      Palette[i][0] := BackupPal[i][0] + ScrollBar.Position;
 | 
						|
      if Palette[i][0] > 255 then Palette[i][0] := 255;
 | 
						|
      if Palette[i][0] < 0 then Palette[i][0] := 0;
 | 
						|
      Palette[i][1] := BackupPal[i][1] + ScrollBar.Position;
 | 
						|
      if Palette[i][1] > 255 then Palette[i][1] := 255;
 | 
						|
      if Palette[i][1] < 0 then Palette[i][1] := 0;
 | 
						|
      Palette[i][2] := BackupPal[i][2] + ScrollBar.Position;
 | 
						|
      if Palette[i][2] > 255 then Palette[i][2] := 255;
 | 
						|
      if Palette[i][2] < 0 then Palette[i][2] := 0;
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Rotate' then
 | 
						|
  begin
 | 
						|
    for i := 0 to 255 do
 | 
						|
    begin
 | 
						|
      Palette[i][0] := BackupPal[(255 + i - ScrollBar.Position) mod 256][0];
 | 
						|
      Palette[i][1] := BackupPal[(255 + i - ScrollBar.Position) mod 256][1];
 | 
						|
      Palette[i][2] := BackupPal[(255 + i - ScrollBar.Position) mod 256][2];
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Blur' then
 | 
						|
  begin
 | 
						|
    Palette := Blur(ScrollBar.Position, BackupPal);
 | 
						|
  end;
 | 
						|
  if btnMenu.Caption = 'Frequency' then
 | 
						|
  begin
 | 
						|
    Palette := Frequency(ScrollBar.Position, BackupPal);
 | 
						|
  end;
 | 
						|
  DrawPalette;
 | 
						|
end;
 | 
						|
 | 
						|
{ ***************************** Adjust menu ********************************* }
 | 
						|
 | 
						|
procedure TGradientForm.mnuRotateClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Rotate';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := 0;
 | 
						|
  ScrollBar.Max := 255;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuHueClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Hue';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := 0;
 | 
						|
  ScrollBar.Max := 360;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuBrightnessClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Brightness';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := -255;
 | 
						|
  ScrollBar.Max := 255;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuSaturationClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Saturation';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := -100;
 | 
						|
  ScrollBar.Max := 100;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuBlurClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Blur';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := 0;
 | 
						|
  ScrollBar.Max := 127;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuFrequencyClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Frequency';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := 1;
 | 
						|
  ScrollBar.Max := 10;
 | 
						|
  ScrollBar.LargeChange := 1;
 | 
						|
  ScrollBar.Position := 1;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.btnOpenClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  GradientBrowser.Filename := GradientFile;
 | 
						|
  GradientBrowser.Show;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuSmoothPaletteClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  MainForm.SmoothPalette;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.SaveGradient1Click(Sender: TObject);
 | 
						|
var
 | 
						|
  gradstr: TStringList;
 | 
						|
begin
 | 
						|
  gradstr := TStringList.Create;
 | 
						|
  try
 | 
						|
    SaveForm.Caption := 'Save Gradient';
 | 
						|
    SaveForm.Filename := GradientFile;
 | 
						|
    SaveForm.Title := MainCp.name;
 | 
						|
    if SaveForm.ShowModal = mrOK then
 | 
						|
    begin
 | 
						|
      gradstr.add(CleanIdentifier(SaveForm.Title) + ' {');
 | 
						|
      gradstr.add(MainForm.GradientFromPalette(Palette, SaveForm.Title));
 | 
						|
      gradstr.add('}');
 | 
						|
      if MainForm.SaveGradient(gradstr.text, SaveForm.Title, SaveForm.Filename) then
 | 
						|
        GradientFile := SaveForm.FileName;
 | 
						|
    end;
 | 
						|
  finally
 | 
						|
    gradstr.free
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.SaveasMapfile1Click(Sender: TObject);
 | 
						|
begin
 | 
						|
  SaveDialog.Filename := MainCp.name + '.map';
 | 
						|
  if SaveDialog.execute then
 | 
						|
    SaveMap(SaveDialog.Filename);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.cmbPaletteDrawItem(Control: TWinControl;
 | 
						|
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
 | 
						|
var
 | 
						|
  i, j: integer;
 | 
						|
  Row: pRGBTripleArray;
 | 
						|
  Bitmap: TBitmap;
 | 
						|
  pal: TColorMap;
 | 
						|
  PalName: string;
 | 
						|
begin
 | 
						|
{ Draw the preset palettes on the combo box items }
 | 
						|
  GetCMap(index, 1, pal);
 | 
						|
  GetCmapName(index, PalName);
 | 
						|
 | 
						|
  BitMap := TBitMap.create;
 | 
						|
  Bitmap.PixelFormat := pf24bit;
 | 
						|
  BitMap.Width := 256;
 | 
						|
  BitMap.Height := 100;
 | 
						|
 | 
						|
  for j := 0 to Bitmap.Height - 1 do
 | 
						|
  begin
 | 
						|
    Row := Bitmap.Scanline[j];
 | 
						|
    for i := 0 to Bitmap.Width - 1 do
 | 
						|
    begin
 | 
						|
      with Row[i] do
 | 
						|
      begin
 | 
						|
        rgbtRed := Pal[i][0];
 | 
						|
        rgbtGreen := Pal[i][1];
 | 
						|
        rgbtBlue := Pal[i][2];
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end;
 | 
						|
  with Control as TComboBox do
 | 
						|
  begin
 | 
						|
    Canvas.Rectangle(Rect);
 | 
						|
 | 
						|
    Canvas.TextOut(4, Rect.Top, PalName);
 | 
						|
    Rect.Left := (Rect.Left + rect.Right) div 2;
 | 
						|
    Canvas.StretchDraw(Rect, Bitmap);
 | 
						|
  end;
 | 
						|
  BitMap.Free;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.ScrollBarScroll(Sender: TObject;
 | 
						|
  ScrollCode: TScrollCode; var ScrollPos: Integer);
 | 
						|
begin
 | 
						|
  if ScrollCode = scEndScroll then Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.btnCopyClick(Sender: TObject);
 | 
						|
var
 | 
						|
  gradstr: TStringList;
 | 
						|
begin
 | 
						|
  gradstr := TStringList.Create;
 | 
						|
  try
 | 
						|
    gradstr.add(CleanIdentifier(MainCp.name) + ' {');
 | 
						|
    gradstr.add('gradient:');
 | 
						|
    gradstr.add(' title="' + MainCp.name + '" smooth=no');
 | 
						|
    gradstr.add(GradientString(Palette));
 | 
						|
    gradstr.add('}');
 | 
						|
    Clipboard.SetTextBuf(PChar(gradstr.text));
 | 
						|
    btnPaste.enabled := true;
 | 
						|
    mnuPaste.enabled := true;
 | 
						|
    MainForm.btnPaste.enabled := False;
 | 
						|
    MainForm.mnuPaste.enabled := False;
 | 
						|
  finally
 | 
						|
    gradstr.free
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.btnPasteClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  if Clipboard.HasFormat(CF_TEXT) then
 | 
						|
  begin
 | 
						|
    UpdateGradient(CreatePalette(Clipboard.AsText));
 | 
						|
    Apply;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
function GradientInClipboard: boolean;
 | 
						|
var
 | 
						|
  gradstr: TStringList;
 | 
						|
begin
 | 
						|
  { returns true if gradient in clipboard - can be tricked }
 | 
						|
  result := true;
 | 
						|
  if Clipboard.HasFormat(CF_TEXT) then
 | 
						|
  begin
 | 
						|
    gradstr := TStringList.Create;
 | 
						|
    try
 | 
						|
      gradstr.text := Clipboard.AsText;
 | 
						|
      if (Pos('}', gradstr.text) = 0) or (Pos('{', gradstr.text) = 0) or
 | 
						|
        (Pos('gradient:', gradstr.text) = 0) or (Pos('fractal:', gradstr.text) <> 0) then
 | 
						|
      begin
 | 
						|
        result := false;
 | 
						|
        exit;
 | 
						|
      end;
 | 
						|
    finally
 | 
						|
      gradstr.free;
 | 
						|
    end;
 | 
						|
  end
 | 
						|
  else
 | 
						|
    result := false;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.ApplicationEventsActivate(Sender: TObject);
 | 
						|
begin
 | 
						|
  if GradientInClipboard then begin
 | 
						|
    mnuPaste.enabled := true;
 | 
						|
    btnPaste.enabled := true;
 | 
						|
  end
 | 
						|
  else
 | 
						|
  begin
 | 
						|
    mnuPaste.enabled := false;
 | 
						|
    btnPaste.enabled := false;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuSaveasDefaultClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  MainForm.DefaultPalette := Palette;
 | 
						|
  SaveMap(AppPath + 'default.map');
 | 
						|
end;
 | 
						|
 | 
						|
procedure RGBBlend(a, b: integer; var Palette: TColorMap);
 | 
						|
{ Linear blend between to indices of a palette }
 | 
						|
var
 | 
						|
  c, v: real;
 | 
						|
  vrange, range: real;
 | 
						|
  i: integer;
 | 
						|
begin
 | 
						|
  if a = b then
 | 
						|
  begin
 | 
						|
    Exit;
 | 
						|
  end;
 | 
						|
  range := b - a;
 | 
						|
  vrange := Palette[b mod 256][0] - Palette[a mod 256][0];
 | 
						|
  c := Palette[a mod 256][0];
 | 
						|
  v := vrange / range;
 | 
						|
  for i := (a + 1) to (b - 1) do
 | 
						|
  begin
 | 
						|
    c := c + v;
 | 
						|
    Palette[i mod 256][0] := Round(c);
 | 
						|
  end;
 | 
						|
  vrange := Palette[b mod 256][1] - Palette[a mod 256][1];
 | 
						|
  c := Palette[a mod 256][1];
 | 
						|
  v := vrange / range;
 | 
						|
  for i := a + 1 to b - 1 do
 | 
						|
  begin
 | 
						|
    c := c + v;
 | 
						|
    Palette[i mod 256][1] := Round(c);
 | 
						|
  end;
 | 
						|
  vrange := Palette[b mod 256][2] - Palette[a mod 256][2];
 | 
						|
  c := Palette[a mod 256][2];
 | 
						|
  v := vrange / range;
 | 
						|
  for i := a + 1 to b - 1 do
 | 
						|
  begin
 | 
						|
    c := c + v;
 | 
						|
    Palette[i mod 256][2] := Round(c);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
function TGradientForm.RandomGradient: TColorMap;
 | 
						|
var
 | 
						|
  a, b, n, nodes: integer;
 | 
						|
  rgb: array[0..2] of double;
 | 
						|
  hsv: array[0..2] of double;
 | 
						|
  pal: TColorMap;
 | 
						|
begin
 | 
						|
  inc(MainForm.Seed);
 | 
						|
  RandSeed := MainForm.seed;
 | 
						|
  nodes := random((MaxNodes - 1) - (MinNodes - 2)) + (MinNodes - 1);
 | 
						|
  n := 256 div nodes;
 | 
						|
  b := 0;
 | 
						|
  hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100;
 | 
						|
  hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100;
 | 
						|
  hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100;
 | 
						|
  hsv2rgb(hsv, rgb);
 | 
						|
  Pal[0][0] := Round(rgb[0] * 255);
 | 
						|
  Pal[0][1] := Round(rgb[1] * 255);
 | 
						|
  Pal[0][2] := Round(rgb[2] * 255);
 | 
						|
  repeat
 | 
						|
    a := b;
 | 
						|
    b := b + n;
 | 
						|
    hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100;
 | 
						|
    hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100;
 | 
						|
    hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100;
 | 
						|
    hsv2rgb(hsv, rgb);
 | 
						|
    if b > 255 then b := 255;
 | 
						|
    Pal[b][0] := Round(rgb[0] * 255);
 | 
						|
    Pal[b][1] := Round(rgb[1] * 255);
 | 
						|
    Pal[b][2] := Round(rgb[2] * 255);
 | 
						|
    RGBBlend(a, b, pal);
 | 
						|
  until b = 255;
 | 
						|
  Result := Pal;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.mnuRandomizeClick(Sender: TObject);
 | 
						|
begin
 | 
						|
  GradientForm.UpdateGradient(RandomGradient);
 | 
						|
  GradientForm.Apply;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.Contrast1Click(Sender: TObject);
 | 
						|
begin
 | 
						|
  btnMenu.Caption := 'Contrast';
 | 
						|
  BackupPal := Palette;
 | 
						|
  ScrollBar.Min := -100;
 | 
						|
  ScrollBar.Max := 100;
 | 
						|
  ScrollBar.LargeChange := 15;
 | 
						|
  ScrollBar.Position := 0;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TGradientForm.FormCreate(Sender: TObject);
 | 
						|
begin
 | 
						|
  Sendmessage(cmbPalette.Handle, CB_SETDROPPEDWIDTH , cmbPalette.width * 2, 0);
 | 
						|
end;
 | 
						|
 | 
						|
end.
 | 
						|
 |