|
- {
- TextSuite (C) Steffen Xonna (aka Lossy eX)
- http://www.opengl24.de/
- -----------------------------------------------------------------------
- For copyright informations see file copyright.txt.
- }
-
- {$I TextSuiteOptions.inc}
-
- unit TextSuitePostProcess;
-
- interface
-
- uses
- TextSuite,
- TextSuiteClasses;
-
-
- type
- // ** Post Processing FillColor **
- TtsPostFillColor = class(TtsPostProcessStep)
- protected
- fRed: Single;
- fGreen: Single;
- fBlue: Single;
- fAlpha: Single;
- fLuminance: Single;
- fChannelMask: tsBitmask;
-
- fModes: TtsImageModes;
-
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- public
- constructor Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
- end;
-
-
- // ** Post Processing FillPattern **
- TtsPostFillPattern = class(TtsPostProcessStep)
- protected
- fPattern: TtsImage;
- fX: Integer;
- fY: Integer;
- fChannelMask: tsBitmask;
- fModes: TtsImageModes;
-
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- public
- constructor Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
- end;
-
-
- // ** Post Processing Border **
- TtsPostBorderLookupFuncData = record
- Kernel: TtsKernel2D;
- XPos, YPos, XMax, YMax: Integer;
-
- pData: pByte;
- end;
-
-
- TtsPostBorder = class(TtsPostProcessStep)
- protected
- fKernel: TtsKernel2D;
-
- fRed: Single;
- fGreen: Single;
- fBlue: Single;
- fAlpha: Single;
-
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- public
- constructor Create(Width, Strength: Single; Red, Green, Blue, Alpha: Single);
- destructor Destroy; override;
- end;
-
- // ** Post Processing Kerning **
- TtsPostKerning = class(TtsPostProcessStep)
- protected
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- end;
-
-
- // ** Post Processing Shadow **
- TtsPostShadow = class(TtsPostProcessStep)
- protected
- fKernel: TtsKernel1D;
-
- fX: Integer;
- fY: Integer;
-
- fRed: Single;
- fGreen: Single;
- fBlue: Single;
- fAlpha: Single;
-
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- public
- constructor Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
- destructor Destroy; override;
- end;
-
-
- // ** Post Processing Custom **
- TtsPostCustom = class(TtsPostProcessStep)
- protected
- fContext: TtsContext;
- fPostProcessProc: tsPostProcessProc;
- fData: Pointer;
-
- procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
- public
- constructor Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
- end;
-
-
- implementation
-
- //uses
- // TextSuiteImageUtils;
-
-
- { TtsPostFillColor }
-
- constructor TtsPostFillColor.Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
- begin
- inherited Create;
-
- fRed := Red;
- fGreen := Green;
- fBlue := Blue;
- fAlpha := Alpha;
- fChannelMask := ChannelMask;
- fModes := Modes;
- end;
-
-
- procedure TtsPostFillColor.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- begin
- if CharImage <> nil then
- CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, fChannelMask, fModes);
- end;
-
-
- { TtsPostFillPattern }
-
- constructor TtsPostFillPattern.Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
- begin
- inherited Create;
-
- fPattern := Pattern;
- fX := X;
- fY := Y;
- fChannelMask := ChannelMask;
- fModes := Modes;
- end;
-
-
- procedure TtsPostFillPattern.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- begin
- if CharImage <> nil then
- CharImage.FillPattern(fPattern, fX, fY, fChannelMask, fModes);
- end;
-
-
-
- { TtsPostBorder }
-
- constructor TtsPostBorder.Create(Width, Strength, Red, Green, Blue, Alpha: Single);
- begin
- inherited Create;
-
- fKernel := TtsKernel2D.Create(Width, Strength);
-
- fRed := Red;
- fGreen := Green;
- fBlue := Blue;
- fAlpha := Alpha;
- end;
-
-
- function BorderLookupMax(var Data: TtsPostBorderLookupFuncData): Byte;
- var
- Idx: Integer;
- Temp, TempValue: Single;
- pTempData: pByte;
- begin
- TempValue := 0;
-
- with Data, Data.Kernel do begin
- for Idx := 0 to ItemCount - 1 do
- with Items[Idx] do
- if ((XPos + OffsetX >= 0) and (XPos + OffsetX < XMax) and
- (YPos + OffsetY >= 0) and (YPos + OffsetY < YMax)) then begin
- pTempData := pData;
-
- Inc(pTempData, DataOffset);
-
- // there is no value
- if pTempData^ = $00 then
- Continue;
-
- // calculate pixel
- Temp := pTempData^ * Value;
- if (Temp > TempValue) then
- TempValue := Temp;
-
- // there is nothing greater than this
- if pTempData^ = $FF then
- Break;
- end;
- end;
-
- Result := Round(TempValue);
- end;
-
-
- destructor TtsPostBorder.Destroy;
- begin
- fKernel.Free;
-
- inherited;
- end;
-
-
- procedure TtsPostBorder.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- var
- OriginalImage: TtsImage;
-
- X, Y: Integer;
- pSource, pDest: ptsColor;
-
- Data: TtsPostBorderLookupFuncData;
- begin
- if CharImage <> nil then begin
- // Make image geater
- CharImage.Resize(CharImage.Width + fKernel.SizeX * 2, CharImage.Height + fKernel.SizeY * 2, fKernel.SizeX, fKernel.SizeY);
-
- // Create copy of Image
- OriginalImage := TtsImage.Create;
- try
- OriginalImage.AssignFrom(CharImage);
- CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesReplace);
-
- fKernel.UpdateDataOffset(4, OriginalImage.Width * 4);
-
- Data.Kernel := fKernel;
- Data.XMax := OriginalImage.Width;
- Data.YMax := OriginalImage.Height;
-
- for Y := 0 to OriginalImage.Height - 1 do begin
- pSource := OriginalImage.ScanLine[Y];
- pDest := CharImage.ScanLine[Y];
-
- Data.pData := @(pSource^.Alpha);
- Data.YPos := Y;
-
- for X := 0 to OriginalImage.Width - 1 do begin
- Data.XPos := X;
-
- pDest^.Alpha := Round(fAlpha * BorderLookupMax(Data));
-
- Inc(Data.pData, 4);
- Inc(pDest);
- end;
- end;
-
- // Blend OriginalImage over CharImage (shadow)
- CharImage.BlendImage(OriginalImage, 0, 0);
- finally
- OriginalImage.Free;
- end;
- end;
-
- // Set Char Data
- Char.GlyphRect.Left := Char.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX;
- Char.GlyphRect.Right := Char.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX;
-
- Char.GlyphRect.Top := Char.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY;
- Char.GlyphRect.Bottom := Char.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY;
-
- Char.GlyphOriginY := Char.GlyphOriginY + fKernel.MidSizeY;
- Char.Advance := Char.Advance + fKernel.MidSizeX;
- end;
-
-
- { TtsPostKerning }
-
- procedure TtsPostKerning.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- begin
- // if CharImage <> nil then
- // Char.CalculateKerningData(CharImage);
- end;
-
-
- { TtsPostShadow }
-
- constructor TtsPostShadow.Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
- begin
- inherited Create;
-
- fKernel := TtsKernel1D.Create(Radius, 0);
-
- fX := X;
- fY := Y;
- fRed := Red;
- fGreen := Green;
- fBlue := Blue;
- fAlpha := Alpha;
- end;
-
-
- destructor TtsPostShadow.Destroy;
- begin
- fKernel.Free;
-
- inherited;
- end;
-
-
- procedure TtsPostShadow.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- var
- OriginalImage: TtsImage;
- TempX, TempY: Integer;
- begin
- if CharImage <> nil then begin
- OriginalImage := TtsImage.Create;
- try
- // backup to original
- OriginalImage.AssignFrom(CharImage);
-
- // Resizing image
- CharImage.Resize(CharImage.Width + fKernel.Size * 2, CharImage.Height + fKernel.Size * 2, fKernel.Size, fKernel.Size);
-
- // fill char image with color
- CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesNormal);
-
- // blur charimage
- CharImage.Blur(fKernel, fKernel, TS_CHANNEL_ALPHA);
-
- TempX := fKernel.Size - fX;
- TempY := fKernel.Size - fY;
-
- // Blend OriginalImage over CharImage (shadow)
- CharImage.BlendImage(OriginalImage, TempX, TempY);
-
- // Set Chardimension
- with Char.GlyphRect do begin
- if TempX > 0 then begin
- Left := Left + TempX;
- Right := Right + TempX;
- end;
-
- if TempY > 0 then begin
- Top := Top + TempY;
- Bottom := Bottom + TempY;
- end;
- end;
- finally
- OriginalImage.Free;
- end;
- end;
- end;
-
-
- { TtsPostCustom }
-
- constructor TtsPostCustom.Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
- begin
- inherited Create;
-
- fContext := Context;
- fPostProcessProc := PostProcessProc;
- fData := Data;
- end;
-
-
- procedure TtsPostCustom.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
- var
- ImageID: tsImageID;
- begin
- if CharImage <> nil then begin
- if fContext <> nil then begin
- // temporary Add Image
- ImageID := fContext.ImageAdd(CharImage);
- try
- fPostProcessProc(ImageID, Char.CharCode, fData);
- finally
- fContext.ImageDelete(ImageID);
- end;
- end;
- end
- // call without an ImageID
- else fPostProcessProc(0, Char.CharCode, fData);
- end;
-
-
- end.
|