www.pudn.com > OSD 测试程序.rar > xlOSD.pas
{ *********************************************************************** }
{ }
{ EM84XX系统OSD组件 }
{ Ver1.0 }
{ Created: 03-18-2004 }
{ Copyright (c) 1998-2004 吉首市先凌科技 }
{ }
{ 因Delphi功底较差有一点凌乱,其中可能有很多Bug. }
{ 您可以修改,如果修改了请你寄我一份(因我还要做其它的事). }
{ 从您们的修改中来提高我的功底,谢谢! }
{ E-Mail:xlkj_ok@163.com }
{ Last update: 03-24-2004 by xlkjok }
{ }
{ *********************************************************************** }
unit xlOSD;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, UnitRmOSD, ActiveX, UnitOSDFunctions,
Dialogs, ExtCtrls;
const
HEADERLONG = 1032; //osd文件头部大小
c_PANELVALUE = $4F;
type
TScrollStyle = (ssLeftToRight, ssRightToLeft, ssTopToBottom, ssBottomToTop);
{ TxlOSD }
TxlOSD = class (TComponent)
private
FFree: Boolean; //是否空闲
FPOldData: Pointer; //OSD文件指针
FPPalette: Pointer; //调色板指针
FPData: Pointer; //数据指针
FPTempData: Pointer; //文字数据指针
FPBitmapData: Pointer; //位图数据指针 可用于模拟动画
FBitmapFrames: Integer; //位图帧数
FPlaying: Boolean;
FTimer: TTimer;
FInterval: Cardinal;
pOSD: IRmStream;
pDevice: IRmControlNode;
pMemAlloc: IRmMapMem;
rc_dest: MPEG_OVERLAY_RECT;
FSize: RMuint32; //OSD文件大小
FCaptionScrolled: Boolean;
FCaptionX: Integer;
FCaptionY: Integer;
FOldCaptionX: Integer;
FOldCaptionY: Integer;
FOldCaptionWidth: Integer;
FOldCaptionHeight: Integer;
FCaptionWidth: Integer;
FCaptionHeight: Integer;
FScrollStyle: TScrollStyle;
FScrollStep: Integer;
FScrolled: Boolean;
FIsUsePanel: Boolean;
FRectx: Integer;
FRecty: Integer;
FRectWidth: Integer;
FRectHeight: Integer;
FBitmapY: Integer;
FBitmapX: Integer;
FCaption: TStringList;
FBitmapFile: string;
FBitmap: TBitmap;
FBitmapWidth: Integer;
FBitmapHeight: Integer;
FActive: Boolean;
FVisible: Boolean;
FHeight: Integer;
FWidth: Integer;
FFont: TFont;
FY: LongWord;
FX: LongWord;
FIsShowBitmap: Boolean;
FIsFillGrid: Boolean;
FlogFont: TlogFont;
function MakeBitmap(var AmStream: TMemoryStream): Boolean;
procedure ShowOSD;
function WriteToOSD(var AmStream: TMemoryStream): Boolean;
procedure WriteData(pdata: Pointer; Size: RMuint32);
function InitDevice: Boolean;
procedure ClearOldData(x, y, AWidth, AHeight: Integer);
procedure SetCaptionPos;
procedure CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer);
function CopyFromTempData(ASrcx, ASrcy: Integer; ASize: Integer;
ALines: Integer; ADstx, ADsty: Integer): Boolean;
function CopyDataToOldData(APSrcData, APDstData: Pointer; ASrcx, ASrcy: Integer; ASize: Integer;
ALines: Integer; ADstx, ADsty: Integer): Boolean;
procedure MakePanel;
procedure EditWordValue;
procedure OSDTimer(Sender: TObject);
function ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;
function GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;
function CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
function CopyBitmapDataToOldData: Boolean;
procedure SetActive(const Value: Boolean);
procedure SetBitmap(const Value: TBitmap);
procedure SetBitmapFile(const Value: string);
procedure SetBitmapX(const Value: Integer);
procedure SetBitmapY(const Value: Integer);
procedure SetCaption(Value: TStringList);
procedure SetCaptionScrolled(const Value: Boolean);
procedure SetCaptionX(const Value: Integer);
procedure SetcaptionY(const Value: Integer);
procedure SetInterval(const Value: Cardinal);
procedure SetScrollStyle(const Value: TScrollStyle);
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
procedure SetFont(const Value: TFont);
procedure SetX(const Value: LongWord);
procedure SetY(const Value: LongWord);
procedure SetScrollStep(const Value: Integer);
procedure SetScrolled(const Value: Boolean);
procedure SetVisible(const Value: Boolean);
procedure SetCaptionRect(const Value: TRect);
procedure SetIsUsePanel(const Value: Boolean);
procedure SetRectHeight(const Value: Integer);
procedure SetRectWidth(const Value: Integer);
procedure SetRectx(const Value: Integer);
procedure SetRecty(const Value: Integer);
procedure SetIsShowBitmap(const Value: Boolean);
procedure SetIsFillGrid(const Value: Boolean);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure InitTempData;
function Play: Boolean;
function Stop: Boolean;
property Active: Boolean read FActive write SetActive;
property Caption: TStringList read FCaption write SetCaption;
property BitmapFile: string read FBitmapFile write SetBitmapFile;
property Bitmap: TBitmap read FBitmap write SetBitmap;
property ScrollStyle: TScrollStyle read FScrollStyle write SetScrollStyle default ssRightToLeft;
property BitmapX: Integer read FBitmapX write SetBitmapX default 1;
property BitmapY: Integer read FBitmapY write SetBitmapY default 1;
property CaptionX: Integer read FCaptionX write SetCaptionX default 1;
property CaptionY: Integer read FCaptionY write SetCaptionY default 300;
property CaptionScrolled: Boolean read FCaptionScrolled write SetCaptionScrolled;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property Width: Integer read FWidth write SetWidth default 640;
property Height: Integer read FHeight write SetHeight default 480;
property Font: TFont read FFont write SetFont;
property X: LongWord read FX write SetX default 0;
property Y: LongWord read FY write SetY default 0;
property Scrolled: Boolean read FScrolled write SetScrolled default False;
property ScrollStep: Integer read FScrollStep write SetScrollStep default 10;
property Visible: Boolean read FVisible write SetVisible default False;
property IsUsePanel: Boolean read FIsUsePanel write SetIsUsePanel;
property Rectx: Integer read FRectx write SetRectx;
property Recty: Integer read FRecty write SetRecty;
property RectWidth: Integer read FRectWidth write SetRectWidth;
property RectHeight: Integer read FRectHeight write SetRectHeight;
property IsShowBitmap: Boolean read FIsShowBitmap write SetIsShowBitmap;
property IsFillGrid: Boolean read FIsFillGrid write SetIsFillGrid;
end;
implementation
{
************************************ TxlOSD ************************************
}
constructor TxlOSD.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWidth := 640;
FHeight := 480;
FRectx := 100;
FRecty := 20;
FRectWidth := 500;
FRectHeight := 400;
FBitmapX := 100;
FBitmapY := 20;
FCaptionX := 100;
FCaptionY := 20;
FOldCaptionX := 0;
FOldCaptionY := 200;
FX := 20;
FY := 30;
FScrollStep := 10;
FIsUsePanel := True;
FScrolled := False;
FScrollStyle:= ssRightToLeft;//ssBottomToTop;//ssRightToLeft;
FCaption := TStringList.Create;
//FCaption.Add('吉首市先凌科技开发公司');
FBitmap := TBitmap.Create;
//FmsBitmap := TMemoryStream.Create;
FTimer := TTimer.Create(self);
FTimer.Enabled := False;
FTimer.Interval := 10;
FTimer.OnTimer := OSDTimer;//MovePanel;
FFont := TFont.Create;
FFont.Color := clBlue;
FFont.Size := 24;
FFont.Name := '幼圆';
FIsFillGrid := True;
FPlaying := False;
FVisible := False;
FFree := True;
InitDevice();
Play();
end;
//------------------------------------------------------------------------------
destructor TxlOSD.Destroy;
begin
Stop();
if FTimer <> nil then
begin
FTimer.Enabled := False;
FTimer.Free;
end;
if FPOldData <> nil then
FreeMem(FPOldData);
if FPTempData <> nil then
FreeMem(FPTempData);
if FFont <> nil then
FFont.Free;
if FBitmap <> nil then
FBitmap.Free;
if FCaption <> nil then
FCaption.Free;
CoUninitialize();
inherited Destroy;
end;
//------------------------------------------------------------------------------
function TxlOSD.MakeBitmap(var AmStream: TMemoryStream): Boolean;
var
OSDBitmap: TBitmap;
begin
Result := False;
if AmStream.Size > 0 then
AmStream.Clear;
OSDBitmap := TBitmap.Create;
try
OSDBitmap.Width := FWidth;
OSDBitmap.Height := FHeight;
OSDBitmap.PixelFormat := pf8bit;
OSDBitmap.SaveToStream(AmStream);
Result := True;
finally
OSDBitmap.Free;
end;
end;
//------------------------------------------------------------------------------
//******************初始化********************************
function TxlOSD.InitDevice: Boolean;
var
hr: HRESULT;
pIRmObjectFinder: IRmObjectFinder;
dwTvOutKeep: RMint32;
HwLibVersion, dwTvOut: RMint32;
begin
Result := False;
CoInitialize(nil);
hr := CoCreateInstance( CLSID_RMBASE, nil,
CLSCTX_INPROC_SERVER,
IID_IRmObjectFinder,
pIRmObjectFinder );
if FAILED(hr) then Exit;
hr := pIRmObjectFinder.FindObject(nil,
FIRST_AVALIABLE_INSTANCE,
CATEGORY_PIN_OSD,
IID_IRmStream,
pOSD);
pIRmObjectFinder := nil;
if FAILED(hr) then Exit;
pOSD.Reset();
pDevice := nil;
hr := pOSD.QueryInterface(IID_IRmControlNode, pDevice);
if FAILED(hr) then Exit;
hr := pOSD.QueryInterface(IID_IRmMapMem, pMemAlloc);
if FAILED(hr) then Exit;
pDevice.GetAttributes(MpegAttrCodeVersion, HwLibVersion);
pDevice.GetAttributes(MpegAttrVideoTv, dwTvOutKeep);
dwTvOut := dwTvOutKeep and (not OUTPUT_OFF);
if HwLibVersion < 9 then
dwTvOut := dwTvOut or SET_TV
else
begin
dwTvOut := dwTvOut or SET_TV or $80000000;
dwTvOut := dwTvOut and (not SET_HDTV);
end;
pDevice.SetAttributes(MpegAttrVideoTv, dwTvOut);
Result := True;
end;
//------------------------------------------------------------------------------
//*****************清除上一次的滚动文字数据***************
procedure TxlOSD.ClearOldData(x, y, AWidth, AHeight: Integer);
var
p: Pointer;
i: Integer;
begin
p := Ptr(DWORD(FPData) + FWidth * y + x);
for i := 0 to AHeight - 1 do
begin
p := Ptr(DWORD(p) + FWidth);
FillChar(P^, AWidth , $7F);
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.OSDTimer(Sender: TObject);
var
pLine, ptmp: Pointer;
i, ii: Integer;
iX: Integer;
iY: Integer;
p: Pointer;
srcx,srcy,isize,lines,dstx,dsty: Integer;
begin
if (FCaption.Count < 0) or (not FScrolled) or (not FActive) then
begin
FTimer.Enabled := False;
Exit;
end;
if not FFree then Exit;
FFree := False;
//if not FIsUsePanel then
ClearOldData(FOldCaptionx, FOldCaptionY, FOldCaptionWidth, FOldCaptionHeight); //清除上一次内容
SetCaptionPos; //改变坐标
CalPos(srcx,srcy,isize,lines,dstx,dsty); //计算出现范围
if FIsUsePanel then
MakePanel(); //加面板条
CopyFromTempData(srcx,srcy,isize,lines,dstx,dsty); //复制数据
if FIsUsePanel then
EditWordValue(); //
WriteData(FPOldData, FSize); //写OSD数据
end;
//------------------------------------------------------------------------------
function TxlOSD.Play: Boolean;
var
ms: TMemoryStream;
begin
Result := False;
if FPlaying then Exit;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Play);
ms := TMemoryStream.Create;
try
FPlaying := True;
FActive := True;
finally
ms.Free;
end;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetActive(const Value: Boolean);
begin
if FActive <> Value then
begin
FActive := Value;
if Value then
Play
else
Stop;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetBitmap(const Value: TBitmap);
begin
if Value <> nil then
begin
FBitmap.Assign(Value);
FBitmapFile := '';
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetBitmapFile(const Value: string);
begin
if Value <> FBitmapFile then
FBitmapFile := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetBitmapX(const Value: Integer);
begin
if FBitmapX <> Value then
FBitmapX := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetBitmapY(const Value: Integer);
begin
if FBitmapY <> Value then
FBitmapY := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetCaption(Value: TStringList);
begin
if nil <> Value then
FCaption.Assign(Value);
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetCaptionScrolled(const Value: Boolean);
begin
if FCaptionScrolled <> Value then
FCaptionScrolled := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetCaptionX(const Value: Integer);
begin
if FCaptionX <> Value then
begin
FCaptionX := Value;
FOldCaptionX := Value;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetcaptionY(const Value: Integer);
begin
if FCaptionY <> Value then
begin
FCaptionY := Value;
FOldCaptionY := Value;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetFont(const Value: TFont);
begin
if FFont <> nil then
begin
if Value is TFont then
FFont.Assign(Value);
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetHeight(const Value: Integer);
begin
if FHeight <> Value then
FHeight := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetInterval(const Value: Cardinal);
begin
if FInterval <> Value then
begin
FInterval := Value;
FTimer.Interval := Value;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetScrolled(const Value: Boolean);
begin
if FScrolled <> Value then
FScrolled := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetScrollStep(const Value: Integer);
begin
if FScrollStep <> Value then
FScrollStep := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetScrollStyle(const Value: TScrollStyle);
begin
if FScrollStyle <> Value then
FScrollStyle := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetWidth(const Value: Integer);
begin
if FWidth <> Value then
FWidth := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetX(const Value: LongWord);
begin
if FX <> Value then
FX := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetY(const Value: LongWord);
begin
if FY <> Value then
FY := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.ShowOSD;
var
msSrc, msDest: TMemoryStream;
mslines: TMemoryStream;
begin
msSrc := TMemoryStream.Create;
msDest := TMemoryStream.Create;
mslines := TMemoryStream.Create;
try
MakeBitmap(msSrc);
Streamrgb2x(msSrc, msDest);
if FCaption.Count > 0 then //(FCaption.Count > 0) and (not FIsShowBitmap)
begin
InitTempData();
end
else
FScrolled := False;
WriteToOSD(msDest);
if (FPTempData <> nil) and (not FIsShowBitmap) then
if not Scrolled then
CopyFromTempData(0, 0, FOldCaptionWidth, FOldCaptionHeight,
FOldCaptionX, FOldCaptionY);
if FIsShowBitmap then
CopyBitmapDataToOldData();
WriteData(FPOldData, FSize);
finally
msSrc.Free;
msDest.Free;
mslines.Free;
end;
FVisible := True;
FTimer.Enabled := FScrolled;
end;
//------------------------------------------------------------------------------
function TxlOSD.Stop: Boolean;
begin
Result := False;
if not FPlaying then Exit;
FTimer.Enabled := False;
while not FFree do
begin
end;
FFree := False;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Stop);
if pDevice <> nil then //pDevice.SetAttributes(MpegAttrVideoTv,dwTvOutKeep)
pDevice.SetAttributes(MpegAttrOsdOFF,1);
FActive := False;
FPlaying := False;
FVisible := False;
end;
end;
//------------------------------------------------------------------------------
//*****************写入OSD数据到pDevice中*************************
procedure TxlOSD.WriteData(pdata: Pointer; Size: RMuint32);
var
hdr: HEADER;
ovr: RMOVERLAPIO;
begin
FillChar(hdr, Sizeof(hdr), 0);
hdr.multi.Count := 1;
hdr.multi.Size := SizeOf(HEADER);
hdr.header.Size := SizeOf(RMSTREAM_HEADER);
hdr.header.pData := pdata;
hdr.header.FrameExtent := Size;
ovr.do_not_use[0] := 0;
ovr.do_not_use[1] := 0;
ovr.do_not_use[2] := 0;
ovr.do_not_use[3] := 0;
ovr.hEvent := CreateEvent(nil, True, False, nil);
pOSD.Write(@hdr.multi, ovr);
WaitForSingleObject(ovr.hEvent,10000);
pDevice.SetAttributes(MpegAttrOsdDest, LongInt(@rc_dest));
pDevice.SetAttributes(MpegAttrOsdON, 1);
CloseHandle(ovr.hEvent);
FFree := True;
end;
//------------------------------------------------------------------------------
//************转换成OSD数据**************************
function TxlOSD.WriteToOSD(var AmStream: TMemoryStream): Boolean;
var
phys: Pointer;
hdr: HEADER;
Buff_8: array[0..7] of Byte;
pshared: Pointer;
i,j: Integer;
b: Boolean;
p,ptmp: PBYTE;
begin
Result := False;
AmStream.Seek(0, soFromBeginning);
AmStream.ReadBuffer(Buff_8[0], SizeOf(Buff_8));
// 从前8个字节中算出图形大小Width, Height
FSize := (buff_8[1] shl (8*2)) or (buff_8[2] shl 8) or buff_8[3];
rc_dest.X := FX;
rc_dest.Y := FY;
rc_dest.cX := (buff_8[4] shl 8) or buff_8[5];
rc_dest.cY := (buff_8[6] shl 8) or buff_8[7];
// 重新读取所有的数据
if FSize = 0 then Exit;
AmStream.Seek(0, soFromBeginning);
if FPoldData <> nil then
begin
FreeMem(FPOldData);
FPOldData := nil;
end;
Getmem(pshared, FSize);
Getmem(FPOldData, FSize);
if pshared = nil then Exit;
AmStream.ReadBuffer(pshared^, FSize);
if FIsFillGrid then
begin
for i := 0 to FHeight - 1 do
begin
p := PBYTE(DWORD(pshared) + 1032 + i * FWidth);
ptmp := p;
if Odd(i) then
for j := 0 to FWidth - 1 do
begin
if Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end
else
for j := 0 to FWidth - 1 do
begin
if not Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end;
end;
end;
WriteData(pshared, FSize);
CopyMemory(FPOldData, pshared, FSize);
FPPalette := Pointer(DWORD(FPOldData) + 8);
FPData := Pointer(DWORD(FPOldData) + HEADERLONG);
FreeMem(pshared);
Result := True;
end;
//------------------------------------------------------------------------------
//***************复制数据到OSD数据中****************************
function TxlOSD.CopyFromTempData(ASrcx, ASrcy, ASize, ALines, ADstx,
ADsty: Integer): Boolean;
var
pSrc, pDst: Pointer;
i, j, ii: Integer;
b: Boolean;
ptmp: PBYTE;
begin
Result := False;
pSrc := Pointer(DWORD(FPTempData) + ASrcy * FCaptionWidth + ASrcx);
pDst := Pointer(DWORD(FPOldData) + HEADERLONG + ADsty * FWidth + ADstx);
for i := 0 to ALines - 1 do
begin
CopyMemory(pDst, pSrc, ASize);
pSrc := Ptr(DWORD(pSrc) + FCaptionWidth);
pDst := Ptr(DWORD(pDst) + FWidth);
end;
Result := True;
end;
//------------------------------------------------------------------------------
//*************改变滚动文字的坐标*************************
procedure TxlOSD.SetCaptionPos;
begin
case FScrollStyle of
ssLeftToRight:
begin
if FCaptionX >= FRectx + FRectWidth then
FCaptionX := FRectx - FCaptionWidth + 10
else
Inc(FCaptionX, FScrollStep);
end;
ssRightToLeft:
begin
if FCaptionX <= FRectx - FCaptionWidth then
FCaptionX := FRectx + FRectWidth - 10
else
Dec(FCaptionX, FScrollStep);
end;
ssTopToBottom:
begin
if FCaptionY >= FRecty + FRectHeight then
FCaptionY := FRecty - FCaptionHeight + 10
else
Inc(FCaptionY, FScrollStep);
end;
ssBottomToTop:
begin
if FCaptionY <= FRecty - FCaptionHeight then
FCaptionY := FRecty + FRectHeight - 10
else
Dec(FCaptionY, FScrollStep);
end;
end;
end;
//------------------------------------------------------------------------------
//************计算要复制的数据cx,cy, 坐标**************************
procedure TxlOSD.CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx,
ADsty: Integer);
begin
if (FCaptionX >= FRectx) and (FCaptionX < FRectx + FRectWidth) then //FCaptionX 在画中
begin
ADstx := FCaptionX;
ASrcx := 0;
if FCaptionX + FCaptionWidth >= FRectx + FRectWidth then
ASize := FRectx + FRectWidth - FCaptionX
else
ASize := FCaptionWidth;
end
else begin
if (FCaptionX >= FRectx + FRectWidth) or (FCaptionX + FCaptionWidth <= FRectx) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end
else begin
if FCaptionWidth + FCaptionX > FRectx then
begin
ADstx := FRectx;
ASrcx := FRectx - FCaptionX;
if FCaptionWidth + FCaptionX >= FRectx + FRectWidth then
ASize := FRectWidth
else
ASize := FCaptionWidth - ASrcx;
end;
end;
end;
if (FCaptionY >= FRecty) and (FCaptionY < FRecty + FRectHeight) then //FCaptionY 在画中
begin
ADsty := FCaptionY;
ASrcy := 0;
if FCaptionY + FCaptionHeight > FRecty + FRectHeight then
ALines := FRecty + FRectHeight - FCaptionY
else
ALines := FCaptionHeight;
end
else begin //y<0
if (FCaptionY >= FRecty + FRectHeight) or (FCaptionY + FCaptionHeight <= FRecty) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end
else
if FCaptionY + FCaptionHeight > FRecty then
begin
ADsty := FRecty;
ASrcy := FRectY - FCaptionY;
if FCaptionY + FCaptionHeight >= FRecty + FRectHeight then
ALines := FRectHeight
else
ALines := FCaptionHeight - ASrcy;
end;
end;
FOldCaptionX := ADstx;
FOldCaptionY := ADsty;
FOldCaptionWidth := ASize;
FOldCaptionHeight := ALines;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.InitTempData;
var
mstmp: TMemoryStream;
begin
if FPTempData <> nil then
begin
FreeMem(FPTempData);
FPTempData := nil;
end;
mstmp := TmemoryStream.Create;
try
ConvertOSDFromWord(mstmp);
GetMem(FPTempData, FCaptionWidth * FCaptionHeight);//
mstmp.Seek(0, soFromBeginning);
mstmp.ReadBuffer(FPTempData^, FCaptionWidth * FCaptionHeight);
finally
mstmp.Free;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetVisible(const Value: Boolean);
var
p: Pointer;
begin
if FVisible <> Value then
begin
while not FFree do
begin
end;
FFree := False;
if Value then
begin
ShowOSD();
end
else begin
FTimer.Enabled := False;
p := Ptr(DWORD(FPOldData) + HEADERLONG);
FillChar(p^, FWidth * FHeight, $7F);
end;
FVisible := Value;
WriteData(FPOldData, FSize);
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetCaptionRect(const Value: TRect);
begin
// FCaptionRect := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetIsUsePanel(const Value: Boolean);
begin
if Value <> FIsUsePanel then
FIsUsePanel := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.MakePanel;
var
i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPData) + FOldCaptionY * FWidth);
for i := 0 to FOldCaptionHeight - 1 do
begin
p1 := PBYTE(DWORD(p1) + FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FWidth - 1 do
begin
if Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end
else begin
for j := 0 to FWidth - 1 do
begin
if not Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.EditWordValue;
var
i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPOldData) + HEADERLONG + FOldCaptionY * FWidth + FOldCaptionX);
for i := 0 to FOldCaptionHeight - 1 do
begin
p1 := PBYTE(DWORD(p) + i * FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FOldCaptionWidth - 1 do
begin
if Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end
else begin
for j := 0 to FOldCaptionWidth - 1 do
begin
if not Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetRectHeight(const Value: Integer);
begin
if Value <> FRectHeight then
FRectHeight := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetRectWidth(const Value: Integer);
begin
if Value <> FRectWidth then
FRectWidth := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetRectx(const Value: Integer);
begin
if Value <> FRectx then
FRectx := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetRecty(const Value: Integer);
begin
if Value <> FRecty then
FRecty := Value;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetIsShowBitmap(const Value: Boolean);
begin
if FIsShowBitmap <> Value then
FIsShowBitmap := Value;
end;
//------------------------------------------------------------------------------
function TxlOSD.GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;
var
bmfh: BITMAPFILEHEADER;
bmih: BITMAPINFOHEADER;
pb,pData, pSrc, pDst, pTemp: PBYTE;
i: Integer;
align: Integer;
xx: array[0..3] of Byte;
begin
Result := False;
ASourceStream.Seek(0, soFromBeginning);
if AOutStream.Size > 0 then
AOutStream.Clear;
ASourceStream.ReadBuffer(bmfh, SizeOf(bmfh));
ASourceStream.ReadBuffer(bmih, Sizeof(bmih));
bmih.biBitCount := 7;
Getmem(pData, bmih.biWidth * bmih.biHeight);
Getmem(pTemp, bmih.biWidth * bmih.biHeight);
ASourceStream.ReadBuffer(pData^, bmih.biClrUsed * 4);
pb := pData;
align := bmih.biWidth mod 4;
for i := 0 to bmih.biHeight - 1 do
begin
ASourceStream.ReadBuffer(pb^, bmih.biWidth);
pb := PBYTE(DWORD(pb) + bmih.biWidth);
ASourceStream.Read(xx[0], align);
end;
FCaptionWidth := bmih.biWidth;
FCaptionHeight := bmih.biHeight;
FOldCaptionWidth := bmih.biWidth;
FOldCaptionHeight := bmih.biHeight;
pb := pData;
for i := 0 to bmih.biWidth * bmih.biHeight - 1 do
begin
pb^ := pb^ and $7F;
pb := PBYTE(DWORD(pb) + 1);
end;
pSrc := PBYTE(DWORD(pData) + bmih.biWidth * bmih.biHeight);
pDst := pTemp;
for i := 0 to bmih.biHeight - 1 do
begin
pSrc :=PBYTE(DWORD(pSrc) - bmih.biWidth);
CopyMemory(pdst, psrc, bmih.biWidth);
pDst := PBYTE(DWORD(pDst) + bmih.biWidth);
end;
CopyMemory(pData, pTemp, bmih.biWidth * bmih.biHeight);
AOutStream.WriteBuffer(pData^, bmih.biWidth * bmih.biHeight);
FreeMem(pData);
FreeMem(pTemp);
Result := True;
end;
//------------------------------------------------------------------------------
//返回OSD可识别的数据流
function TxlOSD.ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;
var
stmp: TMemoryStream;
bitmaptmp: TBitmap;
i, j, fIndex: Integer;
m,n: Integer;
begin
Result := False;
if AOutStream.Size > 0 then
AOutStream.Clear;
bitmaptmp := TBitmap.Create;
stmp := TMemoryStream.Create;
try
bitmaptmp.PixelFormat := pf8bit;
bitmaptmp.Canvas.Font := FFont;
m := 0;
n := 0;
fIndex := 0;
for i := 0 to FCaption.Count - 1 do
begin
n := Length(FCaption.Strings[i]);
if n > m then
begin
m := n;
fIndex := i;
end;
end;
bitmaptmp.Width := bitmaptmp.Canvas.TextWidth(FCaption.Strings[fIndex]);
bitmaptmp.Height := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]) * FCaption.Count;
j := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]);
for i := 0 to FCaption.Count - 1 do
begin
bitmaptmp.Canvas.TextOut(0, i * j , FCaption.Strings[i]);
end;
bitmaptmp.SaveToStream(stmp);
// MakeMoreLinesWords(FCaption.Strings[0], 400, FFont, stmp);
GetOSDDataFromStream(stmp, AOutStream);
finally
bitmaptmp.Free;
stmp.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------
procedure TxlOSD.SetIsFillGrid(const Value: Boolean);
begin
if Value <> FIsFillGrid then
FIsFillGrid := Value;
end;
//------------------------------------------------------------------------------
function TxlOSD.CopyDataToOldData(APSrcData, APDstData: Pointer; ASrcx,
ASrcy, ASize, ALines, ADstx, ADsty: Integer): Boolean;
begin
//图形模拟动画 只变源x坐标,将其一帧的数据复制到FPOldData中去
end;
//------------------------------------------------------------------------------
function TxlOSD.CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
begin
Result := False;
if AmsSrc.Size <= 0 then Exit;
AmsSrc.Seek(0, soFromBeginning);
if (FPPalette <> nil) and (AmsSrc.Size >= 1024) then
begin
AmsSrc.ReadBuffer(FPPalette^, 1024);
Result := True;
end;
end;
//------------------------------------------------------------------------------
function TxlOSD.CopyBitmapDataToOldData: Boolean;
var
tmpBitmap: TBitmap;
tmpStream: TMemoryStream;
PaletteStream: TMemoryStream;
tmpmsOsd: TMemoryStream;
cx,cy: Integer;
pSrc, p1, p2: Pointer;
pbd: PBYTE;
i, j: Integer;
begin
Result := False;
if FBitmapFile = '' then Exit;
if not FileExists(FBitmapFile) then Exit;
tmpBitmap := TBitmap.Create;
tmpStream := TMemoryStream.Create;
PaletteStream := TMemoryStream.Create;
tmpmsOSD := TMemoryStream.Create;
try
tmpBitmap.LoadFromFile(FBitmapFile);
tmpBitmap.SaveToStream(tmpStream);
if GetPaletteFromBitmap(tmpStream, PaletteStream) then
begin
CopyPaletteToOldData(PaletteStream);
GetOSDDataFromStream(tmpStream, tmpmsOsd);
if tmpBitmap.Width + FBitmapX > FWidth then
cx := FWidth - FBitmapX
else
cx := tmpBitmap.Width;
if tmpBitmap.Height + FBitmapY > FHeight then
cy := FHeight - FBitmapY
else
cy := tmpBitmap.Height;
FBitmapWidth := cx;
FBitmapHeight := cy;
GetMem(pSrc, tmpBitmap.Width * tmpBitmap.Height);
tmpmsOsd.Seek(0, soFromBeginning);
tmpmsOsd.ReadBuffer(pSrc^, tmpBitmap.Width * tmpBitmap.Height);
p1 := pSrc;
p2 := Ptr(DWORD(FPData) + FBitmapY * FWidth + FBitmapX);
for i := 0 to cy - 1 do
begin
CopyMemory(p2, p1, cx);
pbd := PBYTE(DWORD(p2));
if FIsFillGrid then
begin
if Odd(i) then
begin
for j := 0 to cx - 1 do
begin
if Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end
else begin
for j := 0 to cx - 1 do
begin
if not Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end;
end;
p1 := Ptr(DWORD(p1) + tmpBitmap.Width);
p2 := Ptr(DWORD(p2) + FWidth);
end;
FreeMem(pSrc);
end;
finally
tmpBitmap.Free;
tmpStream.Free;
PaletteStream.Free;
tmpmsOSD.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------
end.