OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / RunStyles.cxx
diff --git a/ext/scintilla/src/RunStyles.cxx b/ext/scintilla/src/RunStyles.cxx
new file mode 100644 (file)
index 0000000..eed5897
--- /dev/null
@@ -0,0 +1,216 @@
+/** @file RunStyles.cxx\r
+ ** Data structure used to store sparse styles.\r
+ **/\r
+// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>\r
+// The License.txt file describes the conditions under which this software may be distributed.\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+\r
+#include "Platform.h"\r
+\r
+#include "Scintilla.h"\r
+#include "SplitVector.h"\r
+#include "Partitioning.h"\r
+#include "RunStyles.h"\r
+\r
+#ifdef SCI_NAMESPACE\r
+using namespace Scintilla;\r
+#endif\r
+\r
+// Find the first run at a position\r
+int RunStyles::RunFromPosition(int position) {\r
+       int run = starts->PartitionFromPosition(position);\r
+       // Go to first element with this position\r
+       while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {\r
+               run--;\r
+       }\r
+       return run;\r
+}\r
+\r
+// If there is no run boundary at position, insert one continuing style.\r
+int RunStyles::SplitRun(int position) {\r
+       int run = RunFromPosition(position);\r
+       int posRun = starts->PositionFromPartition(run);\r
+       if (posRun < position) {\r
+               int runStyle = ValueAt(position);\r
+               run++;\r
+               starts->InsertPartition(run, position);\r
+               styles->InsertValue(run, 1, runStyle);\r
+       }\r
+       return run;\r
+}\r
+\r
+void RunStyles::RemoveRun(int run) {\r
+       starts->RemovePartition(run);\r
+       styles->DeleteRange(run, 1);\r
+}\r
+\r
+void RunStyles::RemoveRunIfEmpty(int run) {\r
+       if ((run < starts->Partitions()) && (starts->Partitions() > 1)) {\r
+               if (starts->PositionFromPartition(run) == starts->PositionFromPartition(run+1)) {\r
+                       RemoveRun(run);\r
+               }\r
+       }\r
+}\r
+\r
+void RunStyles::RemoveRunIfSameAsPrevious(int run) {\r
+       if ((run > 0) && (run < starts->Partitions())) {\r
+               if (styles->ValueAt(run-1) == styles->ValueAt(run)) {\r
+                       RemoveRun(run);\r
+               }\r
+       }\r
+}\r
+\r
+RunStyles::RunStyles() {\r
+       starts = new Partitioning(8);\r
+       styles = new SplitVector<int>();\r
+       styles->InsertValue(0, 2, 0);\r
+}\r
+\r
+RunStyles::~RunStyles() {\r
+       delete starts;\r
+       starts = NULL;\r
+       delete styles;\r
+       styles = NULL;\r
+}\r
+\r
+int RunStyles::Length() const {\r
+       return starts->PositionFromPartition(starts->Partitions());\r
+}\r
+\r
+int RunStyles::ValueAt(int position) const {\r
+       return styles->ValueAt(starts->PartitionFromPosition(position));\r
+}\r
+\r
+int RunStyles::FindNextChange(int position, int end) {\r
+       int run = starts->PartitionFromPosition(position);\r
+       if (run < starts->Partitions()) {\r
+               int runChange = starts->PositionFromPartition(run);\r
+               if (runChange > position)\r
+                       return runChange;\r
+               int nextChange = starts->PositionFromPartition(run + 1);\r
+               if (nextChange > position) {\r
+                       return nextChange;\r
+               } else if (position < end) {\r
+                       return end;\r
+               } else {\r
+                       return end + 1;\r
+               }\r
+       } else {\r
+               return end + 1;\r
+       }\r
+}\r
+\r
+int RunStyles::StartRun(int position) {\r
+       return starts->PositionFromPartition(starts->PartitionFromPosition(position));\r
+}\r
+\r
+int RunStyles::EndRun(int position) {\r
+       return starts->PositionFromPartition(starts->PartitionFromPosition(position) + 1);\r
+}\r
+\r
+bool RunStyles::FillRange(int &position, int value, int &fillLength) {\r
+       int end = position + fillLength;\r
+       int runEnd = RunFromPosition(end);\r
+       if (styles->ValueAt(runEnd) == value) {\r
+               // End already has value so trim range.\r
+               end = starts->PositionFromPartition(runEnd);\r
+               if (position >= end) {\r
+                       // Whole range is already same as value so no action\r
+                       return false;\r
+               }\r
+               fillLength = end - position;\r
+       } else {\r
+               runEnd = SplitRun(end);\r
+       }\r
+       int runStart = RunFromPosition(position);\r
+       if (styles->ValueAt(runStart) == value) {\r
+               // Start is in expected value so trim range.\r
+               runStart++;\r
+               position = starts->PositionFromPartition(runStart);\r
+               fillLength = end - position;\r
+       } else {\r
+               if (starts->PositionFromPartition(runStart) < position) {\r
+                       runStart = SplitRun(position);\r
+                       runEnd++;\r
+               }\r
+       }\r
+       if (runStart < runEnd) {\r
+               styles->SetValueAt(runStart, value);\r
+               // Remove each old run over the range\r
+               for (int run=runStart+1; run<runEnd; run++) {\r
+                       RemoveRun(runStart+1);\r
+               }\r
+               runEnd = RunFromPosition(end);\r
+               RemoveRunIfSameAsPrevious(runEnd);\r
+               RemoveRunIfSameAsPrevious(runStart);\r
+       }\r
+       return true;\r
+}\r
+\r
+void RunStyles::SetValueAt(int position, int value) {\r
+       int len = 1;\r
+       FillRange(position, value, len);\r
+}\r
+\r
+void RunStyles::InsertSpace(int position, int insertLength) {\r
+       int runStart = RunFromPosition(position);\r
+       if (starts->PositionFromPartition(runStart) == position) {\r
+               int runStyle = ValueAt(position);\r
+               // Inserting at start of run so make previous longer\r
+               if (runStart == 0) {\r
+                       // Inserting at start of document so ensure 0\r
+                       if (runStyle) {\r
+                               styles->SetValueAt(0, 0);\r
+                               starts->InsertPartition(1, 0);\r
+                               styles->InsertValue(1, 1, runStyle);\r
+                               starts->InsertText(0, insertLength);\r
+                       } else {\r
+                               starts->InsertText(runStart, insertLength);\r
+                       }\r
+               } else {\r
+                       if (runStyle) {\r
+                               starts->InsertText(runStart-1, insertLength);\r
+                       } else {\r
+                               // Insert at end of run so do not extend style\r
+                               starts->InsertText(runStart, insertLength);\r
+                       }\r
+               }\r
+       } else {\r
+               starts->InsertText(runStart, insertLength);\r
+       }\r
+}\r
+\r
+void RunStyles::DeleteAll() {\r
+       delete starts;\r
+       starts = NULL;\r
+       delete styles;\r
+       styles = NULL;\r
+       starts = new Partitioning(8);\r
+       styles = new SplitVector<int>();\r
+       styles->InsertValue(0, 2, 0);\r
+}\r
+\r
+void RunStyles::DeleteRange(int position, int deleteLength) {\r
+       int end = position + deleteLength;\r
+       int runStart = RunFromPosition(position);\r
+       int runEnd = RunFromPosition(end);\r
+       if (runStart == runEnd) {\r
+               // Deleting from inside one run\r
+               starts->InsertText(runStart, -deleteLength);\r
+       } else {\r
+               runStart = SplitRun(position);\r
+               runEnd = SplitRun(end);\r
+               starts->InsertText(runStart, -deleteLength);\r
+               // Remove each old run over the range\r
+               for (int run=runStart; run<runEnd; run++) {\r
+                       RemoveRun(runStart);\r
+               }\r
+               RemoveRunIfEmpty(runStart);\r
+               RemoveRunIfSameAsPrevious(runStart);\r
+       }\r
+}\r
+\r