OSDN Git Service

TStringListの代わりにTHashedStringListを使うように変更。
[winbottle/svg-dll.git] / SVG.dpr
diff --git a/SVG.dpr b/SVG.dpr
index 7312daf..098877e 100644 (file)
--- a/SVG.dpr
+++ b/SVG.dpr
@@ -1,6 +1,6 @@
 {
 SSTP Bottle Surface Preview Plug-In for "SVG"
-(C)2003 naru, Mikage Sawatari / SSTP Bottle
+(C)2003-2004 WinBottle Project / SSTP Bottle
 }
 
 library SVG;
@@ -18,7 +18,7 @@ const
 var
   MyPath: String;
   GhostFile: String;
-  Ghost2File: TStringList;
+  Ghost2File: THashedStringList;
 
   Pic: TPicture;       // \93Ç\82Ý\8eæ\82Á\82½\89æ\91\9c(*.png, *.bmp, *.jpg)
   PicFileName: String; // \82»\82Ì\83t\83@\83C\83\8b\96¼
@@ -41,7 +41,7 @@ begin
   end;
   if not FileExists(GhostFile) then
     ShowMessage('SVG.dll Warning: Ghost file is not specified');
-  Ghost2File := TStringList.Create;
+  Ghost2File := THashedStringList.Create;
   Pic := TPicture.Create;
   PicFileName := '';
 end;
@@ -62,7 +62,7 @@ end;
 // CanConfigure\82Í\81AConfigure\82ð\8cÄ\82Î\82ê\82Ä\82â\82é\82±\82Æ\82ª\82 \82é\82©\82Ç\82¤\82©\82ð\95Ô\82·\81B
 function GetVersion(DLLName: PChar; NameLen: integer;
   var Version: integer; var CanConfigure: boolean): integer; cdecl;
-const ThisDLL = 'SVG Surface Loader Ver. 2.2';
+const ThisDLL = 'SVG Surface Loader Ver. 2.5';
 begin
   Version := 1;
   CanConfigure := true;
@@ -144,95 +144,132 @@ end;
 procedure ParseKeyVal(const Line: String; out Key, Val: String);
 var p: integer;
 begin
+  // Key=Value\8c`\8e®\82Ì\95\8e\9a\97ñ\82©\82çKey\82ÆValue\82ð\8eæ\82è\8fo\82·
+  // Value\82Í""\82Å\88Í\82ñ\82Å\82à\82æ\82¢\81BKey\82Í\8f¬\95\8e\9a\82É\82±\82Ì\92i\8aK\82Å\93\9d\88ê
   p := Pos('=', Line);
   if p > 0 then
   begin
-    Key := Copy(Line, 1, p-1);
+    Key := AnsiLowerCase(Copy(Line, 1, p-1));
     Val := AnsiDequotedStr(Copy(Line, p+1, High(integer)), '"');
   end else begin
     Key := '';
-    Val := Line;
+    Val := AnsiDequotedStr(Line, '"');
+  end;
+end;
+
+procedure SplitBlocks(Lines, Blocks: TStringList);
+var
+  Str, Block: String;
+  i: integer;
+  Start: integer; // \8c»\8dÝ\92\8d\96Ú\82µ\82Ä\82¢\82é\83u\83\8d\83b\83N\82Ì\90æ\93ª\82Ì\95\8e\9a\83C\83\93\83f\83b\83N\83X
+  InLead: boolean; // DBCS\82ÌLeadBytes\82ð\8c©\82Ä\82¢\82é\82©\82Ç\82¤\82©\82ð\95Û\8e\9d
+begin
+  // SVG\82Ì\8ae\8ds\82ð\83u\83\8d\83b\83N\82É\95Ï\8a·
+  // \83R\83\81\83\93\83g\82ð\8eæ\82è\8aO\82µ\81A/EOF\88È\8d~\82ð\93K\90Ø\82É\96³\8e\8b\82·\82é
+  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
+          // \90Ø\82è\8fo\82µ
+          Block := Copy(Str, Start, i-Start);
+          if Block = '/EOF' then
+            Break
+          else if Block[1] <> '/' then // \83R\83\81\83\93\83g\82Í\96³\8e\8b
+            Blocks.Add(Block);
+        end;
+        Start := i+1;
+      end;
+    end;
   end;
 end;
 
 function LoadDefinitionFileVer3(Ghost: String;
   Surface: integer; Lines: TStringList; const FileName: String;
   out Pos: integer): String;
-var i, j, k, smin, smax, oldsur: integer;
+var i, k, smin, smax, oldsur: integer;
     Key, Val, SurStr, PosStr, SakuraName: String;
-    Dat, Sur2Pos: TStringList;
+    Blocks, Sur2Pos: TStringList;
 begin
   oldsur := -1;
   Sur2Pos := TStringList.Create;
+  Blocks := TStringList.Create;
   try
-    for i := 1 to Lines.Count-1 do // 1\8ds\96Ú\82Í"SVG"\82Ì\95\8e\9a\97ñ
+    Lines.Delete(0);
+    SplitBlocks(Lines, Blocks);
+    for i := 0 to Blocks.Count-1 do
     begin
-      if System.Pos('/', Lines[i]) = 1 then // \83R\83\81\83\93\83g\8ds\82ð\82Æ\82Î\82·
-        Continue;
-      ParseKeyVal(Lines[i], Key, Val);
-      if SameText(Key, 'sakura') then
+      ParseKeyVal(Blocks[i], Key, Val);
+      if Key = 'sakura' then
       begin
         SakuraName := Val;
         Ghost2File.Values[SakuraName] := FileName; //\8e\9f\82©\82ç\82Ì\83V\83\87\81[\83g\83J\83b\83g
         if SakuraName <> Ghost then //\95Ê\83S\81[\83X\83g\82Ì\92è\8b`\83t\83@\83C\83\8b\82È\82Ì\82Å\83p\83X
+        begin
+          Result := '';
           Exit;
-      end else if SameText(Key, 'surfacefile') then
+        end;
+      end else if Key = 'surfacefile' then
       begin
         Result := Val;
-      end else if (Length(Val) = 0) or (Val[1] = '/') then
-      begin
-        Continue; // \83R\83\81\83\93\83g\82ð\96³\8e\8b
-      end else if SameText(Key, 'surface') or (Length(Key) = 0) then
+      end else if (Key = 'surface') or (Length(Key) = 0) then
       begin
         // \83T\81[\83t\83B\83X
-        Dat := TStringList.Create;
+        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
-          Dat.CommaText := Val;
-          for j := 0 to Dat.Count-1 do
+          if System.Pos('-', SurStr) > 0 then
           begin
-            if System.Pos(':', Dat[j]) <= 0 then
-              Continue;
-            SurStr := Copy(Dat[j], 1, System.Pos(':', Dat[j])-1);
-            PosStr := Copy(Dat[j], System.Pos(':', Dat[j])+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)] := '' // \92è\8b`\89ð\8f\9c
-                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;
+            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)] := '' // \92è\8b`\89ð\8f\9c
+            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;
-        finally
-          Dat.Free;
+        except
+          Continue;
         end;
       end;
     end;
-    // ShowMessage(Sur2Pos.Text);
+    // ShowMessage(SakuraName + #13#10 + Sur2Pos.Text);
     if SakuraName <> Ghost then //sakura=??\82Ì\8ew\92è\82ª\94²\82¯\82Ä\82¢\82é\92è\8b`\83t\83@\83C\83\8b\82Ì\8fê\8d\87
       Result := ''
     else
@@ -244,10 +281,10 @@ begin
     end;
   finally
     Sur2Pos.Free;
+    Blocks.Free;
   end;
 end;
 
-
 function LoadDefinitionFile(Ghost: String;
   Surface: integer; FileName: String; out Pos: integer): String;
 var Lines: TStringList;
@@ -305,6 +342,8 @@ begin
       for i := 0 to Ghosts.Count-1 do
       begin
         AGhost.CommaText := Ghosts[i];
+        if AGhost.Count = 0 then
+          Continue;
         if AGhost[0] <> 'GHOST' then
           Continue;
         DefFileName := Dir + AGhost[3];