X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=SVG.dpr;h=115100e0ef24dc02d2cf92ac748f90a2f1ce2c39;hb=HEAD;hp=a30ffbd0dccfe8780e26e86db7f2787d452876e0;hpb=d1eec4ea70ddd9916013d03669fb532be193ba4f;p=winbottle%2Fsvg-dll.git diff --git a/SVG.dpr b/SVG.dpr index a30ffbd..115100e 100644 --- a/SVG.dpr +++ b/SVG.dpr @@ -1,9 +1,14 @@ +{ +SSTP Bottle Surface Preview Plug-In for "SVG" +(C)2003-2004 WinBottle Project / SSTP Bottle +} + library SVG; {$R *.res} uses - Windows, Classes, SysUtils, Graphics, IniFiles; + Windows, Classes, SysUtils, Graphics, IniFiles, Dialogs, PngImage, jpeg; const SurfaceWidth = 48; @@ -13,7 +18,10 @@ const var MyPath: String; GhostFile: String; - Ghost2File: TStringList; + Ghost2File: THashedStringList; + + Pic: TPicture; // “Ç‚ÝŽæ‚Á‚½‰æ‘œ(*.png, *.bmp, *.jpg) + PicFileName: String; // ‚»‚̃tƒ@ƒCƒ‹–¼ // DLLƒ[ƒhŽžA‚¨‚æ‚ÑDLLÄ‰Šú‰»Žž‚ɌĂ΂ê‚éB // “ǂݍž‚܂ꂽ‰æ‘œ‚́ABottle Client‘¤‚ŁuƒT[ƒtƒBƒXÄ“ǂݍž‚݁v‚ð @@ -31,14 +39,18 @@ begin finally Ini.Free; end; - Ghost2File := TStringList.Create; + if not FileExists(GhostFile) then + ShowMessage('SVG.dll Warning: Ghost file is not specified'); + Ghost2File := THashedStringList.Create; + Pic := TPicture.Create; + PicFileName := ''; end; // DLLƒAƒ“ƒ[ƒhŽž‚ɌĂ΂ê‚éB -// ‚½‚Ô‚ñ‚â‚邱‚Æ‚Í‚È‚¢B procedure Unload; cdecl; begin Ghost2File.Free; + Pic.Free; end; // DLL‚Ì–¼‘O‚¨‚æ‚уo[ƒWƒ‡ƒ“‚ð•Ô‚·B @@ -50,7 +62,7 @@ end; // CanConfigure‚́AConfigure‚ðŒÄ‚΂ê‚Ä‚â‚邱‚Æ‚ª‚ ‚é‚©‚Ç‚¤‚©‚ð•Ô‚·B function GetVersion(DLLName: PChar; NameLen: integer; var Version: integer; var CanConfigure: boolean): integer; cdecl; -const ThisDLL = 'SVG Surface Loader'; +const ThisDLL = 'SVG Surface Loader Ver. 2.6'; begin Version := 1; CanConfigure := true; @@ -58,63 +70,232 @@ begin Result := Length(ThisDLL) + 1; end; -function LoadDefinitionFile(Ghost: String; - Surface: integer; FileName: String; out Pos: integer): String; -var Lines, ALine, SurfaceMap: TStringList; - i, j, p: integer; +function LoadDefinitionFileVer2(Ghost: String; + Surface: integer; Lines: TStringList; const FileName: String; + out Pos: integer): String; +var ALine, SurfaceMap: TStringList; + i, j, p, sur, oldpos: integer; + posstr: String; begin // “à•”ŠÖ”BƒS[ƒXƒg’è‹`ƒtƒ@ƒCƒ‹‚ð‰ðÍ‚µ‚āA // –Ú“I‚̃S[ƒXƒg‚̊܂܂ꂽƒtƒ@ƒCƒ‹‚©‚Ç‚¤‚©”»’f‚·‚é - Lines := TStringList.Create; + ALine := TStringList.Create; try - Lines.LoadFromFile(FileName); - ALine := TStringList.Create; + ALine.CommaText := Lines[0]; + if (ALine[0] <> 'GHOST') then + Exit; + + Ghost2File.Values[Ghost] := FileName; // ŽŸ‚©‚ç‚̃Vƒ‡[ƒgƒJƒbƒg + if (ALine[1] <> Ghost) then + begin + Exit; + end; + + // –Ú“I‚̃S[ƒXƒg”­Œ© + oldpos := 0; + SurfaceMap := TStringList.Create; try - ALine.CommaText := Lines[0]; - if (ALine[0] <> 'GHOST') or (ALine[1] <> Ghost) then + for i := 1 to Lines.Count-1 do + begin + SurfaceMap.CommaText := Lines[i]; + for j := 0 to SurfaceMap.Count-1 do + begin + try + p := System.Pos(':', SurfaceMap[j]); + if p = 0 then + Continue; + sur := StrToInt(Copy(SurfaceMap[j], 1, p-1)); + posstr := Copy(SurfaceMap[j], p+1, High(integer)); + if posstr = '+' then + Pos := oldpos + 1 + else + Pos := StrToInt(posstr); + if sur = Surface then + begin + Result := ALine[4]; // BMPƒtƒ@ƒCƒ‹–¼ + Exit; + end else + oldpos := Pos; + except + on EConvertError do; // nothing. ’P‚È‚éƒRƒƒ“ƒgsˆµ‚¢ + end; + end; + end; + finally + SurfaceMap.Free; + end; + + // BASIC‚̏ꍇ‚̏ˆ— + if AnsiCompareText('BASIC', ALine[3]) = 0 then + begin + if (Surface >= 0) and (Surface <= 11) then + begin + Result := ALine[4]; // BMPƒtƒ@ƒCƒ‹–¼ + Pos := Surface; // BASIC‚̏ꍇ‚͈ʒu‚ƃT[ƒtƒBƒX”ԍ†‚ªˆê‘Έê‘Ήž‚µ‚Ä‚¢‚é Exit; - // –Ú“I‚̃S[ƒXƒg”­Œ© + end; + end; + + finally + ALine.Free; + end; +end; - SurfaceMap := TStringList.Create; - try - for i := 1 to Lines.Count-1 do +procedure ParseKeyVal(const Line: String; out Key, Val: String); +var p: integer; +begin + // Key=ValueŒ`Ž®‚Ì•¶Žš—ñ‚©‚çKey‚ÆValue‚ðŽæ‚èo‚· + // Value‚Í""‚ň͂ñ‚Å‚à‚æ‚¢BKey‚͏¬•¶Žš‚É‚±‚Ì’iŠK‚Å“ˆê + p := Pos('=', Line); + if p > 0 then + begin + Key := AnsiLowerCase(Copy(Line, 1, p-1)); + Val := AnsiDequotedStr(Copy(Line, p+1, High(integer)), '"'); + end else begin + Key := ''; + Val := AnsiDequotedStr(Line, '"'); + end; +end; + +procedure SplitBlocks(Lines, Blocks: TStringList); +var + Str, Block: String; + i: integer; + Start: integer; // Œ»Ý’–Ú‚µ‚Ä‚¢‚éƒuƒƒbƒN‚̐擪‚Ì•¶ŽšƒCƒ“ƒfƒbƒNƒX + InLead: boolean; // DBCS‚ÌLeadBytes‚ðŒ©‚Ä‚¢‚é‚©‚Ç‚¤‚©‚ð•ÛŽ +begin + // SVG‚ÌŠes‚ðƒuƒƒbƒN‚É•ÏŠ· + // ƒRƒƒ“ƒg‚ðŽæ‚èŠO‚µA/EOFˆÈ~‚ð“KØ‚É–³Ž‹‚·‚é + Str := Lines.Text; + i := 0; + Start := 1; + InLead := false; + while (i < Length(Str)) do + begin + Inc(i); + if InLead then + begin + InLead := false; + Continue; + end else if Str[i] in LeadBytes then + begin + InLead := true; + Continue; + end else + begin + if Str[i] in [',', #13, #10] then + begin + if Start < i then begin - SurfaceMap.CommaText := Lines[i]; - for j := 0 to SurfaceMap.Count-1 do - begin - try - p := System.Pos(':', SurfaceMap[j]); - if p = 0 then - Continue; - if StrToInt(Copy(SurfaceMap[j], 1, p-1)) = Surface then - begin - Pos := StrToInt(Copy(SurfaceMap[j], p+1, High(integer))); - Result := ALine[4]; // BMPƒtƒ@ƒCƒ‹–¼ - Exit; - end; - except - on EConvertError do; // nothing. ’P‚È‚éƒRƒƒ“ƒgsˆµ‚¢ - end; - end; + // Ø‚èo‚µ + Block := Copy(Str, Start, i-Start); + if Block = '/EOF' then + Break + else if Block[1] <> '/' then // ƒRƒƒ“ƒg‚Í–³Ž‹ + Blocks.Add(Block); end; - finally - SurfaceMap.Free; + Start := i+1; end; + end; + end; +end; - // BASIC‚̏ꍇ‚̏ˆ— - if AnsiCompareText('BASIC', ALine[3]) = 0 then +function LoadDefinitionFileVer3(Ghost: String; + Surface: integer; Lines: TStringList; const FileName: String; + out Pos: integer): String; +var i, k, smin, smax, oldsur: integer; + Key, Val, SurStr, PosStr, SakuraName: String; + Blocks, Sur2Pos: TStringList; +begin + oldsur := -1; + Sur2Pos := TStringList.Create; + Blocks := TStringList.Create; + try + Lines.Delete(0); + SplitBlocks(Lines, Blocks); + for i := 0 to Blocks.Count-1 do + begin + ParseKeyVal(Blocks[i], Key, Val); + if Key = 'sakura' then begin - if (Surface >= 0) and (Surface <= 11) then + SakuraName := Val; + Ghost2File.Values[SakuraName] := FileName; //ŽŸ‚©‚ç‚̃Vƒ‡[ƒgƒJƒbƒg + if SakuraName <> Ghost then //•ÊƒS[ƒXƒg‚Ì’è‹`ƒtƒ@ƒCƒ‹‚Ȃ̂ŃpƒX begin - Result := ALine[4]; // BMPƒtƒ@ƒCƒ‹–¼ - Pos := Surface; // BASIC‚̏ꍇ‚͈ʒu‚ƃT[ƒtƒBƒX”ԍ†‚ªˆê‘Έê‘Ήž‚µ‚Ä‚¢‚é + Result := ''; Exit; end; + end else if Key = 'surfacefile' then + begin + Result := Val; + end else if (Key = 'surface') or (Length(Key) = 0) then + begin + // ƒT[ƒtƒBƒX + if System.Pos(':', Val) <= 0 then + Continue; + SurStr := Copy(Val, 1, System.Pos(':', Val)-1); + PosStr := Copy(Val, System.Pos(':', Val)+1, High(integer)); + try + if System.Pos('-', SurStr) > 0 then + begin + smin := StrToInt(Copy(SurStr, 1, System.Pos('-', SurStr)-1)); + smax := StrToInt(Copy(SurStr, System.Pos('-', SurStr)+1, High(integer))); + end else + begin + smin := StrToInt(SurStr); + smax := smin; + end; + for k := smin to smax do + begin + if PosStr = '*' then + begin + Sur2Pos.Values[IntToStr(k)] := IntToStr(k); + oldsur := k; + end else if PosStr = '-2' then + begin + Sur2Pos.Values[IntToStr(k)] := '' // ’è‹`‰ðœ + end else if PosStr = '+' then + begin + Inc(oldsur); + Sur2Pos.Values[IntToStr(k)] := IntToStr(oldsur); + end else if StrToInt(PosStr) >= 0 then + begin + Sur2Pos.Values[IntToStr(k)] := PosStr; + oldsur := StrToInt(PosStr); + end; + end; + except + Continue; + end; end; - - finally - ALine.Free; end; + // ShowMessage(SakuraName + #13#10 + Sur2Pos.Text); + if SakuraName <> Ghost then //sakura=??‚ÌŽw’肪”²‚¯‚Ä‚¢‚é’è‹`ƒtƒ@ƒCƒ‹‚̏ꍇ + Result := '' + else + begin + if Sur2Pos.Values[IntToStr(Surface)] <> '' then + Pos := StrToInt(Sur2Pos.Values[IntToStr(Surface)]) + else + Result := ''; + end; + finally + Sur2Pos.Free; + Blocks.Free; + end; +end; + +function LoadDefinitionFile(Ghost: String; + Surface: integer; FileName: String; out Pos: integer): String; +var Lines: TStringList; +begin + Lines := TStringList.Create; + Lines.LoadFromFile(FileName); + try + if System.Pos('SVG3', Lines[0]) > 0 then + Result := LoadDefinitionFileVer3(Ghost, Surface, Lines, FileName, Pos) + else + Result := LoadDefinitionFileVer2(Ghost, Surface, Lines, FileName, Pos); finally Lines.Free; end; @@ -126,46 +307,58 @@ var Ghosts, AGhost: TStringList; i, dum: integer; Dir, DefFileName, BmpFileName: String; begin - if Ghost2File.Values[Ghost] <> '' then // ‚·‚Å‚É‚»‚̃S[ƒXƒg‚̃tƒ@ƒCƒ‹‚ð‹L‰¯‚µ‚Ä‚é + Result := ''; + if Ghost2File.Values[Ghost] <> '' then // ‚·‚Å‚É‚»‚̃S[ƒXƒg‚ɂ‚¢‚Ä’²¸Ï‚Ý begin DefFileName := Ghost2File.Values[Ghost]; - BmpFileName := LoadDefinitionFile(Ghost, Surface, - DefFileName, dum); - if BmpFileName <> '' then + if DefFileName = '*' then // ‚»‚̃S[ƒXƒg‚Í’m‚ç‚È‚¢A‚Æ‹L‰¯‚µ‚Ä‚¢‚é begin - Result := ExtractFilePath(DefFileName) + BmpFileName; - Pos := dum; Exit; + end else // ‚»‚̃S[ƒXƒg‚ð’m‚Á‚Ä‚¢‚é + begin + BmpFileName := LoadDefinitionFile(Ghost, Surface, + DefFileName, dum); + if BmpFileName <> '' then + begin + Result := ExtractFilePath(DefFileName) + BmpFileName; + Pos := dum; + Exit; + end; end; end; + // ƒS[ƒXƒg‚ªŒ©‚‚©‚ç‚È‚©‚Á‚½Œ‹‰Ê‚ð‹L‰¯B + // Œ©‚‚©‚Á‚½ê‡‚ɂ̓tƒ@ƒCƒ‹–¼‚ŏ㏑‚«‚³‚ê‚é + if Result = '' then + Ghost2File.Values[Ghost] := '*'; + // “à•”ŠÖ”Bghost.txt‚ð“ǂݍž‚ށB Dir := ExtractFilePath(GhostFile); Ghosts := TStringList.Create; try Ghosts.LoadFromFile(GhostFile); - for i := 0 to Ghosts.Count-1 do - begin - AGhost := TStringList.Create; - try - AGhost.CommaText := Ghosts[i]; + AGhost := TStringList.Create; + try + for i := 0 to Ghosts.Count-1 do + begin + AGhost.Text := StringReplace(Ghosts[i], ',', #13#10, [rfReplaceAll]); + if AGhost.Count = 0 then + Continue; if AGhost[0] <> 'GHOST' then Continue; - DefFileName := Dir + AGhost[3]; + DefFileName := Dir + StringReplace(AGhost[3], '"', '', [rfReplaceAll]); // ’è‹`ƒtƒ@ƒCƒ‹‚ð“ǂݍž‚Þ BmpFileName := LoadDefinitionFile(Ghost, Surface, DefFileName, dum); if BmpFileName <> '' then begin - // ”­Œ©! - Ghost2File.Values[Ghost] := DefFileName; // ŽŸ‚©‚ç‚Ì‚½‚ß‚É’è‹`ƒtƒ@ƒCƒ‹–¼‚ð‹L‰¯ Result := ExtractFilePath(DefFileName) + BmpFileName; Pos := dum; Break; end; - finally - AGhost.Free; end; + finally + AGhost.Free; end; finally Ghosts.Free; @@ -175,7 +368,7 @@ end; // Ghost‚ÅŽw’肳‚ê‚éƒS[ƒXƒg‚ÌSurface”Ԃ̃T[ƒtƒBƒXƒCƒ[ƒW‚ðŽÀÛ‚ɓǂݏo‚·B // H‚ÅŽw’肳‚ê‚Ä‚¢‚éƒrƒbƒgƒ}ƒbƒv‚ɏ‘‚«o‚·‚±‚ƁB function GetImage(Ghost: PChar; Surface: integer; H: HBITMAP): integer; cdecl; -var Bmp, Bmp2: TBitmap; +var Bmp: TBitmap; BmpFile: String; Position, x, y, nCol: integer; begin @@ -186,36 +379,34 @@ begin Result := 1; Exit; end; - except - on Exception do // ƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚Á‚Ä‚È‚¢‰Â”\«‚ª‚à‚Á‚Æ‚à‚‚¢ - begin - Result := 1; - Exit; - end; - end; - - Bmp := TBitmap.Create; - try - Bmp.Handle := H; - Bmp2 := TBitmap.Create; + Bmp := TBitmap.Create; try - Bmp2.LoadFromFile(BmpFile); - nCol := Bmp2.Width div SurfaceWidth; + Bmp.Handle := H; + if PicFileName <> BmpFile then + begin + try + Pic.LoadFromFile(BmpFile); + PicFileName := BmpFile; + except + // ì‚è’¼‚µ + FreeAndNil(Pic); + Pic := TPicture.Create; + PicFileName := ''; + raise; + end; + end; + nCol := Pic.Width div SurfaceWidth; x := SurfaceWidth * (Position mod nCol); y := SurfaceHeight * (Position div nCol); - Bmp.Canvas.CopyRect( - Rect(0, 0, Bmp.Width, Bmp.Height), - Bmp2.Canvas, - Rect(x, y, x+SurfaceWidth, y+SurfaceHeight) - ); + Bmp.Canvas.Draw(-x, -y, Pic.Graphic); finally - Bmp2.Free; + Bmp.ReleaseHandle; + Bmp.Free; end; - finally - Bmp.ReleaseHandle; - Bmp.Free; + Result := 0; + except + Result := 1; end; - Result := 0; end; // ƒCƒ[ƒW‚Ì‘å‚«‚³‚ð•Ô‚·B @@ -234,7 +425,34 @@ end; // DLLŒÅ—L‚̐ݒè‚ðs‚¤B // procedure Configure; cdecl; +var OpenDialog: TOpenDialog; + Ini: TIniFile; begin + try + ShowMessage('Specify SSTP Viewer''s ghost file.'); + OpenDialog := TOpenDialog.Create(nil); + try + OpenDialog.Filter := 'Ghost Definition File(ghost.txt)|ghost.txt|' + + 'All Files(*.*)|*.*'; + OpenDialog.FileName := GhostFile; + if OpenDialog.Execute then + begin + GhostFile := OpenDialog.FileName; + Ini := TIniFile.Create(MyPath + ConfigFile); + try + Ini.WriteString('SVG', 'GhostFile', GhostFile); + finally + Ini.Free; + end; + Ghost2File.Clear; + end; + finally + OpenDialog.Free; + end; + except + on E: Exception do + ShowMessage(E.Message); + end; end; exports