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.