RVFMisc.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:18k
源码类别:

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       Miscellaneous procedures related to             }
  5. {       RichView Format (RVF).                          }
  6. {                                                       }
  7. {       Copyright (c) Sergey Tkachenko                  }
  8. {       svt@trichview.com                               }
  9. {       http://www.trichview.com                        }
  10. {                                                       }
  11. {*******************************************************}
  12. unit RVFMisc;
  13. interface
  14. {$I RV_Defs.inc}
  15. uses Classes, SysUtils, Graphics, Controls,
  16.      RVStyle, RVUni;
  17. procedure RVFWrite(Stream: TStream; const s: String);
  18. procedure RVFWriteLine(Stream: TStream; s: String);
  19. procedure RVFWriteLineX(Stream: TStream; const s: String;
  20.   Unicode, HexUnicode: Boolean);
  21. function RVFStream2TextString(Stream: TMemoryStream): String;
  22. function RVFTextString2Stream(const str: String; Stream: TMemoryStream): Boolean;
  23. function RVEncodeString(const str: String): String;
  24. function RVDecodeString(const str: String): String;
  25. {$IFDEF RICHVIEWCBDEF3}
  26. function RVEncodeWideString(const str: WideString): String;
  27. function RVDecodeWideString(const str: String): WideString;
  28. {$ENDIF}
  29. function RVFLoadPicture(const s: String; gr: TGraphic): Boolean;
  30. function RVFSavePicture(gr: TGraphic): String;
  31. procedure RVFLoadPictureBinary(const Data: String; gr: TGraphic);
  32. procedure RVFLoadPictureBinary2(AStream: TStream; gr: TGraphic);
  33. procedure RVFSavePictureBinary(Stream: TStream; gr: TGraphic);
  34. function RVFLoadControl(const s: String; var ctrl: TComponent;
  35.                         const ClassName: String;
  36.                         ParentControl: TWinControl): Boolean;
  37. function RVFSaveControl(ctrl: TComponent): String;
  38. function RVFLoadControlBinary(const Data: String; var ctrl: TComponent;
  39.   const ClassName: String; ParentControl: TWinControl): Boolean;
  40. procedure RVFSaveControlBinary(Stream: TStream; ctrl: TComponent);
  41. function RVFReadString(var P: PChar; var s: String): Boolean;
  42. function RVFReadInteger(var P: PChar; var V: Integer): Boolean;
  43. {$IFDEF RICHVIEWCBDEF3}
  44. function RVFReadText(var P: PChar): String;
  45. {$ENDIF}
  46. function RVFReadTag(var P: PChar; TagsArePChars, Quoted: Boolean;
  47.   var Tag: Integer): Boolean;
  48. function RVFReadParaStyle(RVStyle: TRVStyle; var P: PChar; var V: Integer): Boolean;
  49. function RVFReadTextStyle(RVStyle: TRVStyle; var P: PChar; var V: Integer): Boolean;
  50. function RVFSaveTag(TagsArePChars:Boolean; Tag: Integer): String;
  51. function RVFSaveText(RVStyle:TRVStyle; UseStyleNames: Boolean; TextIdx: Integer): String;
  52. function RVFSavePara(RVStyle:TRVStyle; UseStyleNames: Boolean; TextIdx: Integer): String;
  53. function RVFItemSavePara(ParaNo: Integer; RVData: TPersistent;
  54.                          ForceSameAsPrev: Boolean): String;
  55. function RVFEncodeLineBreaks(const s: String): String;
  56. function RVFDecodeLineBreaks(const s: String): String;
  57. implementation
  58. uses RVStr, RVFuncs, CRVData;
  59. const
  60.   crlf = #13#10;
  61. {-----------------------------------------------------------------------}
  62. procedure RVFWrite(Stream: TStream; const s: String);
  63. begin
  64.   Stream.WriteBuffer(PChar(s)^, Length(s));
  65. end;
  66. {-----------------------------------------------------------------------}
  67. procedure RVFWriteLine(Stream: TStream; s: String);
  68. begin
  69.   s := s+crlf;
  70.   Stream.WriteBuffer(PChar(s)^, Length(s));
  71. end;
  72. {-----------------------------------------------------------------------}
  73. procedure RVFWriteLineX(Stream: TStream; const s: String;
  74.   Unicode, HexUnicode: Boolean);
  75. var sep: String;
  76. begin
  77.   {$IFDEF RICHVIEWCBDEF3}
  78.   if Unicode and HexUnicode then begin
  79.     sep := RVEncodeString(s);
  80.     Stream.WriteBuffer(PChar(sep)^, Length(sep));
  81.     end
  82.   else
  83.   {$ENDIF}
  84.     Stream.WriteBuffer(PChar(s)^, Length(s));
  85.   if Unicode and not HexUnicode then
  86.     sep := String(Chr(Lo(UNI_ParagraphSeparator)))+Chr(Hi(UNI_ParagraphSeparator))
  87.   else
  88.     sep := crlf;
  89.   Stream.WriteBuffer(PChar(sep)^, Length(sep));
  90. end;
  91. {-----------------------------------------------------------------------}
  92. function RVFStream2TextString(Stream: TMemoryStream): String;
  93. var i: Integer;
  94.     hex: String;
  95. begin
  96.  SetLength(Result, Stream.Size*2);
  97.  for i := 0 to Stream.Size-1 do begin
  98.    hex := IntToHex(Ord(PChar(Stream.Memory)[i]),2);
  99.    Result[i*2+1] := hex[1];
  100.    Result[i*2+2] := hex[2];
  101.  end;
  102. end;
  103. {-----------------------------------------------------------------------}
  104. function RVEncodeString(const str: String): String;
  105. var i: Integer;
  106.     hex: String;
  107. begin
  108.  SetLength(Result, Length(str)*2);
  109.  for i := 0 to Length(str)-1 do begin
  110.    hex := IntToHex(Ord(str[i+1]),2);
  111.    Result[i*2+1] := hex[1];
  112.    Result[i*2+2] := hex[2];
  113.  end;
  114. end;
  115. {-----------------------------------------------------------------------}
  116. function RVFTextString2Stream(const str: String; Stream: TMemoryStream): Boolean;
  117. var i,d1,d2, idx1, idx2: Integer;
  118.     s: String;
  119. begin
  120.  Result := False;
  121.  if (Length(str) mod 2)<>0 then exit;
  122.  Stream.SetSize(Length(str) div 2);
  123.  s := UpperCase(str);
  124.  for i := 0 to (Length(s) div 2)-1 do begin
  125.    idx1 := i*2+1;
  126.    idx2 := i*2+2;
  127.    if not (s[idx1] in ['0'..'9','A'..'F']) or
  128.      not (s[idx2] in ['0'..'9','A'..'F']) then exit;
  129.    if s[idx1] in ['0'..'9'] then
  130.      d1 := Ord(s[idx1])-Ord('0')
  131.    else
  132.      d1 := Ord(s[idx1])-Ord('A')+10;
  133.    if s[idx2] in ['0'..'9'] then
  134.      d2 := Ord(s[idx2])-Ord('0')
  135.    else
  136.      d2 := Ord(s[idx2])-Ord('A')+10;
  137.    PChar(Stream.Memory)[i] := Chr(d1*16+d2);
  138.  end;
  139.  Result := True;
  140. end;
  141. {-----------------------------------------------------------------------}
  142. function RVDecodeString(const str: String): String;
  143. var i,d1,d2, idx1, idx2: Integer;
  144.     s: String;
  145. begin
  146.  Result := '';
  147.  if (Length(str) mod 2)<>0 then exit;
  148.  SetLength(Result, Length(str) div 2);
  149.  s := UpperCase(str);
  150.  for i := 0 to (Length(s) div 2)-1 do begin
  151.    idx1 := i*2+1;
  152.    idx2 := i*2+2;
  153.    if not (s[idx1] in ['0'..'9','A'..'F']) or
  154.      not (s[idx2] in ['0'..'9','A'..'F']) then exit;
  155.    if s[idx1] in ['0'..'9'] then
  156.      d1 := Ord(s[idx1])-Ord('0')
  157.    else
  158.      d1 := Ord(s[idx1])-Ord('A')+10;
  159.    if s[idx2] in ['0'..'9'] then
  160.      d2 := Ord(s[idx2])-Ord('0')
  161.    else
  162.      d2 := Ord(s[idx2])-Ord('A')+10;
  163.    Result[i+1] := Chr(d1*16+d2);
  164.  end;
  165. end;
  166. {-----------------------------------------------------------------------}
  167. {$IFDEF RICHVIEWCBDEF3}
  168. function RVEncodeWideString(const str: WideString): String;
  169. var i: Integer;
  170.     hex: String;
  171. begin
  172.  SetLength(Result, Length(str)*4);
  173.  for i := 0 to Length(str)-1 do begin
  174.    hex := IntToHex(Word(str[i+1]),4);
  175.    Result[i*4+1] := hex[1];
  176.    Result[i*4+2] := hex[2];
  177.    Result[i*4+3] := hex[3];
  178.    Result[i*4+4] := hex[4];
  179.  end;
  180. end;
  181. {-----------------------------------------------------------------------}
  182. function RVDecodeWideString(const str: String): WideString;
  183. var i,d1,d2,d3,d4, idx1, idx2, idx3, idx4: Integer;
  184.     s: String;
  185. begin
  186.  Result := '';
  187.  if (Length(str) mod 4)<>0 then exit;
  188.  SetLength(Result, Length(str) div 4);
  189.  s := UpperCase(str);
  190.  for i := 0 to (Length(s) div 4)-1 do begin
  191.    idx1 := i*4+1;
  192.    idx2 := idx1+1;
  193.    idx3 := idx2+1;
  194.    idx4 := idx3+1;
  195.    if not (s[idx1] in ['0'..'9','A'..'F']) or
  196.      not (s[idx2] in ['0'..'9','A'..'F']) or
  197.      not (s[idx3] in ['0'..'9','A'..'F']) or
  198.      not (s[idx4] in ['0'..'9','A'..'F']) then exit;
  199.    if s[idx1] in ['0'..'9'] then
  200.      d1 := Ord(s[idx1])-Ord('0')
  201.    else
  202.      d1 := Ord(s[idx1])-Ord('A')+10;
  203.    if s[idx2] in ['0'..'9'] then
  204.      d2 := Ord(s[idx2])-Ord('0')
  205.    else
  206.      d2 := Ord(s[idx2])-Ord('A')+10;
  207.    if s[idx3] in ['0'..'9'] then
  208.      d3 := Ord(s[idx3])-Ord('0')
  209.    else
  210.      d3 := Ord(s[idx3])-Ord('A')+10;
  211.    if s[idx4] in ['0'..'9'] then
  212.      d4 := Ord(s[idx4])-Ord('0')
  213.    else
  214.      d4 := Ord(s[idx4])-Ord('A')+10;
  215.    Result[i+1] := WideChar(((d1*16+d2)*16+d3)*16+d4);
  216.  end;
  217. end;
  218. {$ENDIF}
  219. {-----------------------------------------------------------------------}
  220. function RVFLoadPicture(const s: String; gr: TGraphic): Boolean;
  221. var Stream: TMemoryStream;
  222. begin
  223.   Stream := TMemoryStream.Create;
  224.   try
  225.     Result := RVFTextString2Stream(s,Stream);
  226.     Stream.Position := 0;
  227.     gr.LoadFromStream(Stream);
  228.   finally
  229.     Stream.Free;
  230.   end;
  231. end;
  232. {-----------------------------------------------------------------------}
  233. function RVFSavePicture(gr: TGraphic): String;
  234. var Stream: TMemoryStream;
  235. begin
  236.   Stream := TMemoryStream.Create;
  237.   try
  238.     gr.SaveToStream(Stream);
  239.     Result := RVFStream2TextString(Stream);
  240.   finally
  241.     Stream.Free;
  242.   end;
  243. end;
  244. {-----------------------------------------------------------------------}
  245. procedure RVFLoadPictureBinary(const Data: String; gr: TGraphic);
  246. var Stream: TMemoryStream;
  247. begin
  248.   Stream  := TMemoryStream.Create;
  249.   try
  250.     Stream.SetSize(Length(Data));
  251.     Move(PChar(Data)^, Stream.Memory^, Length(Data));
  252.     Stream.Position := 0;
  253.     gr.LoadFromStream(Stream);
  254.   finally
  255.     Stream.Free;
  256.   end;
  257. end;
  258. {-----------------------------------------------------------------------}
  259. procedure RVFLoadPictureBinary2(AStream: TStream; gr: TGraphic);
  260. var Stream: TMemoryStream;
  261.     v: Integer;
  262. begin
  263.   Stream  := TMemoryStream.Create;
  264.   try
  265.     AStream.ReadBuffer(v, sizeof(v));
  266.     Stream.SetSize(v);
  267.     AStream.ReadBuffer(Stream.Memory^, v);
  268.     Stream.Position := 0;
  269.     gr.LoadFromStream(Stream);
  270.   finally
  271.     Stream.Free;
  272.   end;
  273. end;
  274. {-----------------------------------------------------------------------}
  275. procedure RVFSavePictureBinary(Stream: TStream; gr: TGraphic);
  276. var p, newp: Integer;
  277. begin
  278.   // writes size of picture body, then picture body
  279.   p := Stream.Position;
  280.   Stream.WriteBuffer(p, SizeOf(p));
  281.   gr.SaveToStream(Stream);
  282.   newp := Stream.Position;
  283.   Stream.Position := p;
  284.   p := newp - p - SizeOf(p);
  285.   Stream.WriteBuffer(p, SizeOf(p));
  286.   Stream.Position := newp;
  287. end;
  288. {-----------------------------------------------------------------------}
  289. function RVFLoadControl(const s: String; var ctrl: TComponent;
  290.                         const ClassName: String;
  291.                         ParentControl: TWinControl): Boolean;
  292. var Stream: TMemoryStream;
  293. begin
  294.   Stream := TMemoryStream.Create;
  295.   try
  296.     Result := RVFTextString2Stream(s,Stream);
  297.     if ClassName<>'' then
  298.       ctrl := TComponentClass(GetClass(ClassName)).Create(nil);
  299.     if (ctrl<>nil) and (ctrl is TControl) then
  300.       TControl(ctrl).Parent := ParentControl;
  301.     Stream.Position := 0;
  302.     try
  303.       ctrl := Stream.ReadComponent(ctrl);
  304.     except
  305.       ctrl := nil;
  306.       Result := False;
  307.     end;
  308.     if (ParentControl<>nil) and (ctrl<>nil) and (ctrl is TControl) then
  309.       TControl(ctrl).Parent := ParentControl;    
  310.   finally
  311.     Stream.Free;
  312.   end;
  313. end;
  314. {-----------------------------------------------------------------------}
  315. function RVFSaveControl(ctrl: TComponent): String;
  316. var Stream: TMemoryStream;
  317. begin
  318.   Stream := TMemoryStream.Create;
  319.   try
  320.     Stream.WriteComponent(ctrl);
  321.     Result := RVFStream2TextString(Stream);
  322.   finally
  323.     Stream.Free;
  324.   end;
  325. end;
  326. {-----------------------------------------------------------------------}
  327. function RVFLoadControlBinary(const Data: String; var ctrl: TComponent;
  328.   const ClassName: String; ParentControl: TWinControl): Boolean;
  329. var Stream: TMemoryStream;
  330. begin
  331.   Result := True;
  332.   Stream := TMemoryStream.Create;
  333.   try
  334.     Stream.SetSize(Length(Data));
  335.     Move(PChar(Data)^, Stream.Memory^, Length(Data));
  336.     if ClassName<>'' then
  337.       ctrl := TComponentClass(GetClass(ClassName)).Create(nil);
  338.     if (ctrl<>nil) and (ctrl is TControl) then
  339.       TControl(ctrl).Parent := ParentControl;
  340.     Stream.Position := 0;
  341.     try
  342.       ctrl := Stream.ReadComponent(ctrl);
  343.     except
  344.       ctrl := nil;
  345.       Result := False;
  346.     end;
  347.     if (ParentControl<>nil) and (ctrl<>nil) and (ctrl is TControl) then
  348.       TControl(ctrl).Parent := ParentControl;
  349.   finally
  350.     Stream.Free;
  351.   end;
  352. end;
  353. {-----------------------------------------------------------------------}
  354. procedure RVFSaveControlBinary(Stream: TStream; ctrl: TComponent);
  355. var p, newp: Integer;
  356. begin
  357.   p := Stream.Position;
  358.   Stream.WriteBuffer(p, SizeOf(p));
  359.   Stream.WriteComponent(ctrl);
  360.   newp := Stream.Position;
  361.   Stream.Position := p;
  362.   p := newp - p - SizeOf(p);
  363.   Stream.WriteBuffer(p, SizeOf(p));
  364.   Stream.Position := newp;
  365. end;
  366. {-----------------------------------------------------------------------}
  367. function RVFReadString(var P: PChar; var s: String): Boolean;
  368. begin
  369.   s := '';
  370.   while not (P[0] in [#0,' ']) do begin
  371.     s := s + P[0];
  372.     inc(P);
  373.   end;
  374.   if P[0]=' ' then inc(P);
  375.   Result := s<>'';
  376. end;
  377. {-----------------------------------------------------------------------}
  378. function RVFReadInteger(var P: PChar; var V: Integer): Boolean;
  379. var minus: ByteBool;
  380. begin
  381.   if not (P[0] in ['-','0'..'9']) then begin
  382.     Result := False;
  383.     exit;
  384.   end;
  385.   V:=0;
  386.   minus := (P[0]='-');
  387.   if minus then inc(P);
  388.   while not (P[0] in [#0,' ']) do
  389.     if P[0] in ['0'..'9'] then begin
  390.       V := V*10+(Ord(P[0])-Ord('0'));
  391.       inc(P);
  392.       end
  393.     else begin
  394.       Result := False;
  395.       exit;
  396.     end;
  397.     if P[0]=' ' then inc(P);
  398.     if minus then V := -V;
  399.     Result := True;
  400. end;
  401. {--------------------------------------------------------------------}
  402. {$IFDEF RICHVIEWCBDEF3}
  403. function RVFReadText(var P: PChar): String;
  404. begin
  405.   Result := AnsiExtractQuotedStr(P, '"');
  406.   if (P^ = ' ') then inc(P);
  407. end;
  408. {$ENDIF}
  409. {--------------------------------------------------------------------}
  410. function RVFReadTag(var P: PChar; TagsArePChars, Quoted: Boolean;
  411.   var Tag: Integer): Boolean;
  412. var s: String;
  413. begin
  414.   {$IFDEF RICHVIEWCBDEF3}
  415.   Quoted := Quoted and (P^ = '"');
  416.   if Quoted then begin
  417.     s := AnsiExtractQuotedStr(P, '"');
  418.     if (P^ = ' ') then
  419.       inc(P);
  420.     end
  421.   else
  422.   {$ENDIF}
  423.   if not RVFReadString(P,s) then begin
  424.     Result := False;
  425.     exit;
  426.   end;
  427.   Result := True;
  428.   if TagsArePChars then
  429.     if (s=RVFTagEmptyStr) and not Quoted then
  430.       Tag := 0
  431.     else
  432.       Tag := Integer(StrNew(PChar(s)))
  433.   else
  434.     try
  435.       Tag := StrToInt(s);
  436.     except
  437.       Result := False;
  438.     end;
  439. end;
  440. {------------------------------------------------------------------------------}
  441. function RVFReadParaStyle(RVStyle: TRVStyle; var P: PChar; var V: Integer): Boolean;
  442.    {$IFDEF RICHVIEWCBDEF3}
  443.     function ParaNameToIndex(const aParaName: String): Integer;
  444.     begin
  445.       with RVStyle.ParaStyles do
  446.         for Result := 0 to Count-1 do
  447.           if Items[result].StyleName = aParaName then Exit;
  448.       Result := 0;
  449.     end;
  450.     {$ENDIF}
  451. begin
  452.   Result := RVFReadInteger(P, V);
  453.   {$IFDEF RICHVIEWCBDEF3}
  454.   if not Result then begin
  455.     V := ParaNameToIndex(RVFReadText(P));
  456.     Result := True;
  457.   end;
  458.   {$ENDIF}
  459. end;
  460. {-----------------------------------------------------------------------}
  461. function RVFReadTextStyle(RVStyle: TRVStyle; var P: PChar; var V: Integer): Boolean;
  462.     {$IFDEF RICHVIEWCBDEF3}
  463.     function TextNameToIndex(const aParaName: String): Integer;
  464.     begin
  465.       with RVStyle.TextStyles do
  466.         for Result := 0 to Count-1 do
  467.           if Items[result].StyleName = aParaName then Exit;
  468.       Result := 0;
  469.     end;
  470.     {$ENDIF}
  471. begin
  472.   Result := RVFReadInteger(P, V);
  473.   {$IFDEF RICHVIEWCBDEF3}
  474.   if not Result then begin
  475.     V := TextNameToIndex(RVFReadText(P));
  476.     Result := True;
  477.   end;
  478.   {$ENDIF}
  479. end;
  480. {-----------------------------------------------------------------------}
  481. function RVFSaveTag(TagsArePChars:Boolean; Tag: Integer): String;
  482. begin
  483.   if TagsArePChars then
  484.     if (Tag=0) or (PChar(Tag)[0]=#0) then
  485.       Result := RVFTagEmptyStr
  486.     else
  487.      {$IFDEF RICHVIEWCBDEF3}
  488.       Result := AnsiQuotedStr(PChar(Tag), '"')
  489.      {$ELSE}
  490.      Result := PChar(Tag)
  491.      {$ENDIF}
  492.   else
  493.     Result := IntToStr(Tag)
  494. end;
  495. {-----------------------------------------------------------------------}
  496. function RVFSaveText(RVStyle:TRVStyle; UseStyleNames: Boolean; TextIdx: Integer): String;
  497. begin
  498.   {$IFDEF RICHVIEWCBDEF3}
  499.   with RVStyle.TextStyles do
  500.     if (TextIdx>=0) and UseStyleNames then
  501.       Result := AnsiQuotedStr(Items[TextIdx].StyleName, '"')
  502.     else
  503.   {$ENDIF}
  504.       Result := IntToStr(TextIdx);
  505. end;
  506. {-----------------------------------------------------------------------}
  507. function RVFSavePara(RVStyle:TRVStyle; UseStyleNames: Boolean; TextIdx: Integer): String;
  508. begin
  509.   {$IFDEF RICHVIEWCBDEF3}
  510.   with RVStyle.ParaStyles do
  511.     if (TextIdx>=0) and UseStyleNames then
  512.       Result := AnsiQuotedStr(Items[TextIdx].StyleName, '"')
  513.     else
  514.   {$ENDIF}
  515.       Result := IntToStr(TextIdx);
  516. end;
  517. {-----------------------------------------------------------------------}
  518. function RVFItemSavePara(ParaNo: Integer; RVData: TPersistent;
  519.                          ForceSameAsPrev: Boolean): String;
  520. begin
  521.   if ForceSameAsPrev then
  522.     ParaNo := -1;
  523.   Result := RVFSavePara(TCustomRVData(RVData).GetRVStyle,
  524.                         rvfoUseStyleNames in TCustomRVData(RVData).RVFOptions,
  525.                         ParaNo);
  526. end;
  527. {-----------------------------------------------------------------------}
  528. function RVFEncodeLineBreaks(const s: String): String;
  529. var i: Integer;
  530. begin
  531.   Result := s;
  532.   for i := 1 to Length(Result) do
  533.     case Result[i] of
  534.       #13:
  535.         Result[i] := #1;
  536.       #10:
  537.         Result[i] := #2;
  538.     end;
  539. end;
  540. {-----------------------------------------------------------------------}
  541. function RVFDecodeLineBreaks(const s: String): String;
  542. var i: Integer;
  543. begin
  544.   Result := s;
  545.   for i := 1 to Length(Result) do
  546.     case Result[i] of
  547.       #1:
  548.         Result[i] := #13;
  549.       #2:
  550.         Result[i] := #10;
  551.     end;
  552. end;
  553. end.