# HG changeset patch
# User Neil <nyamatongwe@gmail.com>
# Date 1520661051 -39600
#      Sat Mar 10 16:50:51 2018 +1100
# Node ID 006c18e8efae56f1f19f89653603fdf0a3848327
# Parent  c45f23c0fbbe1f3ce2edbbd08c6c1ee9353f7d7e
Split decorations into interface and implementation and templatize to allow
32-bit or 64-bit positions.

diff -r c45f23c0fbbe -r 006c18e8efae src/Decoration.cxx
--- a/src/Decoration.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/Decoration.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -26,26 +26,113 @@
 
 using namespace Scintilla;
 
-Decoration::Decoration(int indicator_) : indicator(indicator_) {
-}
+namespace {
+
+template <typename POS>
+class Decoration : public IDecoration {
+	int indicator;
+public:
+	RunStyles<POS, int> rs;
+
+	explicit Decoration(int indicator_) : indicator(indicator_) {
+	}
+	~Decoration() {
+	}
 
-Decoration::~Decoration() {
-}
+	bool Empty() const override {
+		return (rs.Runs() == 1) && (rs.AllSameAs(0));
+	}
+	int Indicator() const override {
+		return indicator;
+	}
+	Sci::Position Length() const override {
+		return rs.Length();
+	}
+	int ValueAt(Sci::Position position) const override {
+		return rs.ValueAt(static_cast<POS>(position));
+	}
+	Sci::Position StartRun(Sci::Position position) const override {
+		return rs.StartRun(static_cast<POS>(position));
+	}
+	Sci::Position EndRun(Sci::Position position) const override {
+		return rs.EndRun(static_cast<POS>(position));
+	}
+	void SetValueAt(Sci::Position position, int value) override {
+		rs.SetValueAt(static_cast<POS>(position), value);
+	}
+	void InsertSpace(Sci::Position position, Sci::Position insertLength) override {
+		rs.InsertSpace(static_cast<POS>(position), static_cast<POS>(insertLength));
+	}
+	Sci::Position Runs() const override {
+		return rs.Runs();
+	}
+};
 
-bool Decoration::Empty() const {
-	return (rs.Runs() == 1) && (rs.AllSameAs(0));
-}
+template <typename POS>
+class DecorationList : public IDecorationList {
+	int currentIndicator;
+	int currentValue;
+	Decoration<POS> *current;	// Cached so FillRange doesn't have to search for each call.
+	Sci::Position lengthDocument;
+	// Ordered by indicator
+	std::vector<std::unique_ptr<Decoration<POS>>> decorationList;
+	std::vector<const IDecoration*> decorationView;	// Read-only view of decorationList
+	bool clickNotified;
+
+	Decoration<POS> *DecorationFromIndicator(int indicator);
+	Decoration<POS> *Create(int indicator, Sci::Position length);
+	void Delete(int indicator);
+	void DeleteAnyEmpty();
+	void SetView();
+public:
+
+	DecorationList();
+	~DecorationList();
+
+	const std::vector<const IDecoration*> &View() const override {
+		return decorationView;
+	}
 
-DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
+	void SetCurrentIndicator(int indicator) override;
+	int GetCurrentIndicator() const override { return currentIndicator; }
+
+	void SetCurrentValue(int value) override;
+	int GetCurrentValue() const override { return currentValue; }
+
+	// Returns true if some values may have changed
+	bool FillRange(Sci::Position &position, int value, Sci::Position &fillLength) override;
+
+	void InsertSpace(Sci::Position position, Sci::Position insertLength) override;
+	void DeleteRange(Sci::Position position, Sci::Position deleteLength) override;
+
+	void DeleteLexerDecorations() override;
+
+	int AllOnFor(Sci::Position position) const override;
+	int ValueAt(int indicator, Sci::Position position) override;
+	Sci::Position Start(int indicator, Sci::Position position) override;
+	Sci::Position End(int indicator, Sci::Position position) override;
+
+	bool ClickNotified() const override {
+		return clickNotified;
+	}
+	void SetClickNotified(bool notified) override {
+		clickNotified = notified;
+	}
+};
+
+template <typename POS>
+DecorationList<POS>::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
 	lengthDocument(0), clickNotified(false) {
 }
 
-DecorationList::~DecorationList() {
+template <typename POS>
+DecorationList<POS>::~DecorationList() {
 	current = nullptr;
 }
 
-Decoration *DecorationList::DecorationFromIndicator(int indicator) {
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
+template <typename POS>
+Decoration<POS> *DecorationList<POS>::DecorationFromIndicator(int indicator) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
 		if (deco->Indicator() == indicator) {
 			return deco.get();
 		}
@@ -53,17 +140,18 @@
 	return nullptr;
 }
 
-Decoration *DecorationList::Create(int indicator, Sci::Position length) {
+template <typename POS>
+Decoration<POS> *DecorationList<POS>::Create(int indicator, Sci::Position length) {
 	currentIndicator = indicator;
-	std::unique_ptr<Decoration> decoNew = std::make_unique<Decoration>(indicator);
-	decoNew->rs.InsertSpace(0, length);
+	std::unique_ptr<Decoration<POS>> decoNew = std::make_unique<Decoration<POS>>(indicator);
+	decoNew->rs.InsertSpace(0, static_cast<POS>(length));
 
-	std::vector<std::unique_ptr<Decoration>>::iterator it = std::lower_bound(
-		decorationList.begin(), decorationList.end(), decoNew, 
-		[](const std::unique_ptr<Decoration> &a, const std::unique_ptr<Decoration> &b) {
+	typename std::vector<std::unique_ptr<Decoration<POS>>>::iterator it = std::lower_bound(
+		decorationList.begin(), decorationList.end(), decoNew,
+		[](const std::unique_ptr<Decoration<POS>> &a, const std::unique_ptr<Decoration<POS>> &b) {
 		return a->Indicator() < b->Indicator();
 	});
-	std::vector<std::unique_ptr<Decoration>>::iterator itAdded = 
+	typename std::vector<std::unique_ptr<Decoration<POS>>>::iterator itAdded =
 		decorationList.insert(it, std::move(decoNew));
 
 	SetView();
@@ -71,54 +159,66 @@
 	return itAdded->get();
 }
 
-void DecorationList::Delete(int indicator) {
+template <typename POS>
+void DecorationList<POS>::Delete(int indicator) {
 	decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-		[=](const std::unique_ptr<Decoration> &deco) {
+		[=](const std::unique_ptr<Decoration<POS>> &deco) {
 		return deco->Indicator() == indicator;
 	}), decorationList.end());
 	current = nullptr;
 	SetView();
 }
 
-void DecorationList::SetCurrentIndicator(int indicator) {
+template <typename POS>
+void DecorationList<POS>::SetCurrentIndicator(int indicator) {
 	currentIndicator = indicator;
 	current = DecorationFromIndicator(indicator);
 	currentValue = 1;
 }
 
-void DecorationList::SetCurrentValue(int value) {
+template <typename POS>
+void DecorationList<POS>::SetCurrentValue(int value) {
 	currentValue = value ? value : 1;
 }
 
-bool DecorationList::FillRange(Sci::Position &position, int value, Sci::Position &fillLength) {
+template <typename POS>
+bool DecorationList<POS>::FillRange(Sci::Position &position, int value, Sci::Position &fillLength) {
 	if (!current) {
 		current = DecorationFromIndicator(currentIndicator);
 		if (!current) {
 			current = Create(currentIndicator, lengthDocument);
 		}
 	}
-	const bool changed = current->rs.FillRange(position, value, fillLength);
+	POS positionPos = static_cast<POS>(position);
+	POS fillLengthPos = static_cast<POS>(fillLength);
+	const bool changed = current->rs.FillRange(positionPos, value, fillLengthPos);
+	position = positionPos;
+	fillLength = fillLengthPos;
 	if (current->Empty()) {
 		Delete(currentIndicator);
 	}
 	return changed;
 }
 
-void DecorationList::InsertSpace(Sci::Position position, Sci::Position insertLength) {
+template <typename POS>
+void DecorationList<POS>::InsertSpace(Sci::Position position, Sci::Position insertLength) {
 	const bool atEnd = position == lengthDocument;
 	lengthDocument += insertLength;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		deco->rs.InsertSpace(position, insertLength);
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		deco->rs.InsertSpace(static_cast<POS>(position), static_cast<POS>(insertLength));
 		if (atEnd) {
-			deco->rs.FillRange(position, 0, insertLength);
+			POS positionPos = static_cast<POS>(position);
+			POS insertLengthPos = static_cast<POS>(insertLength);
+			deco->rs.FillRange(positionPos, 0, insertLengthPos);
 		}
 	}
 }
 
-void DecorationList::DeleteRange(Sci::Position position, Sci::Position deleteLength) {
+template <typename POS>
+void DecorationList<POS>::DeleteRange(Sci::Position position, Sci::Position deleteLength) {
 	lengthDocument -= deleteLength;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		deco->rs.DeleteRange(position, deleteLength);
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		deco->rs.DeleteRange(static_cast<POS>(position), static_cast<POS>(deleteLength));
 	}
 	DeleteAnyEmpty();
 	if (decorationList.size() != decorationView.size()) {
@@ -128,37 +228,41 @@
 	}
 }
 
-void DecorationList::DeleteLexerDecorations() {
+template <typename POS>
+void DecorationList<POS>::DeleteLexerDecorations() {
 	decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-		[=](const std::unique_ptr<Decoration> &deco) {
+		[=](const std::unique_ptr<Decoration<POS>> &deco) {
 		return deco->Indicator() < INDIC_CONTAINER;
 	}), decorationList.end());
 	current = nullptr;
 	SetView();
 }
 
-void DecorationList::DeleteAnyEmpty() {
+template <typename POS>
+void DecorationList<POS>::DeleteAnyEmpty() {
 	if (lengthDocument == 0) {
 		decorationList.clear();
 	} else {
 		decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(),
-			[=](const std::unique_ptr<Decoration> &deco) {
+			[=](const std::unique_ptr<Decoration<POS>> &deco) {
 			return deco->Empty();
 		}), decorationList.end());
 	}
 }
 
-void DecorationList::SetView() {
+template <typename POS>
+void DecorationList<POS>::SetView() {
 	decorationView.clear();
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
 		decorationView.push_back(deco.get());
 	}
 }
 
-int DecorationList::AllOnFor(Sci::Position position) const {
+template <typename POS>
+int DecorationList<POS>::AllOnFor(Sci::Position position) const {
 	int mask = 0;
-	for (const std::unique_ptr<Decoration> &deco : decorationList) {
-		if (deco->rs.ValueAt(position)) {
+	for (const std::unique_ptr<Decoration<POS>> &deco : decorationList) {
+		if (deco->rs.ValueAt(static_cast<POS>(position))) {
 			if (deco->Indicator() < INDIC_IME) {
 				mask |= 1 << deco->Indicator();
 			}
@@ -167,26 +271,50 @@
 	return mask;
 }
 
-int DecorationList::ValueAt(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
+template <typename POS>
+int DecorationList<POS>::ValueAt(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
 	if (deco) {
-		return deco->rs.ValueAt(position);
+		return deco->rs.ValueAt(static_cast<POS>(position));
+	}
+	return 0;
+}
+
+template <typename POS>
+Sci::Position DecorationList<POS>::Start(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
+	if (deco) {
+		return deco->rs.StartRun(static_cast<POS>(position));
 	}
 	return 0;
 }
 
-Sci::Position DecorationList::Start(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
+template <typename POS>
+Sci::Position DecorationList<POS>::End(int indicator, Sci::Position position) {
+	const Decoration<POS> *deco = DecorationFromIndicator(indicator);
 	if (deco) {
-		return deco->rs.StartRun(position);
+		return deco->rs.EndRun(static_cast<POS>(position));
 	}
 	return 0;
 }
 
-Sci::Position DecorationList::End(int indicator, Sci::Position position) {
-	const Decoration *deco = DecorationFromIndicator(indicator);
-	if (deco) {
-		return deco->rs.EndRun(position);
-	}
-	return 0;
+}
+
+namespace Scintilla {
+
+std::unique_ptr<IDecoration> CreateDecoration(bool largeDocument, int indicator) {
+	if (largeDocument)
+		return std::make_unique<Decoration<Sci::Position>>(indicator);
+	else
+		return std::make_unique<Decoration<int>>(indicator);
 }
+
+std::unique_ptr<IDecorationList> CreateDecorationList(bool largeDocument) {
+	if (largeDocument)
+		return std::make_unique<DecorationList<Sci::Position>>();
+	else
+		return std::make_unique<DecorationList<int>>();
+}
+
+}
+
diff -r c45f23c0fbbe -r 006c18e8efae src/Decoration.h
--- a/src/Decoration.h	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/Decoration.h	Sat Mar 10 16:50:51 2018 +1100
@@ -9,69 +9,51 @@
 
 namespace Scintilla {
 
-class Decoration {
-	int indicator;
+class IDecoration {
 public:
-	RunStyles<Sci::Position, int> rs;
-
-	explicit Decoration(int indicator_);
-	~Decoration();
-
-	bool Empty() const;
-	int Indicator() const {
-		return indicator;
-	}
+	virtual ~IDecoration() {}
+	virtual bool Empty() const = 0;
+	virtual int Indicator() const = 0;
+	virtual Sci::Position Length() const = 0;
+	virtual int ValueAt(Sci::Position position) const = 0;
+	virtual Sci::Position StartRun(Sci::Position position) const = 0;
+	virtual Sci::Position EndRun(Sci::Position position) const = 0;
+	virtual void SetValueAt(Sci::Position position, int value) = 0;
+	virtual void InsertSpace(Sci::Position position, Sci::Position insertLength) = 0;
+	virtual Sci::Position Runs() const = 0;
 };
 
-class DecorationList {
-	int currentIndicator;
-	int currentValue;
-	Decoration *current;	// Cached so FillRange doesn't have to search for each call.
-	Sci::Position lengthDocument;
-	// Ordered by indicator
-	std::vector<std::unique_ptr<Decoration>> decorationList;
-	std::vector<const Decoration*> decorationView;	// Read-only view of decorationList
-	bool clickNotified;
+class IDecorationList {
+public:
+	virtual ~IDecorationList() {}
+
+	virtual const std::vector<const IDecoration*> &View() const =0;
 
-	Decoration *DecorationFromIndicator(int indicator);
-	Decoration *Create(int indicator, Sci::Position length);
-	void Delete(int indicator);
-	void DeleteAnyEmpty();
-	void SetView();
-public:
+	virtual void SetCurrentIndicator(int indicator) = 0;
+	virtual int GetCurrentIndicator() const = 0;
 
-	DecorationList();
-	~DecorationList();
-
-	const std::vector<const Decoration*> &View() const { return decorationView; }
-
-	void SetCurrentIndicator(int indicator);
-	int GetCurrentIndicator() const { return currentIndicator; }
-
-	void SetCurrentValue(int value);
-	int GetCurrentValue() const { return currentValue; }
+	virtual void SetCurrentValue(int value) = 0;
+	virtual int GetCurrentValue() const = 0;
 
 	// Returns true if some values may have changed
-	bool FillRange(Sci::Position &position, int value, Sci::Position &fillLength);
-
-	void InsertSpace(Sci::Position position, Sci::Position insertLength);
-	void DeleteRange(Sci::Position position, Sci::Position deleteLength);
-
-	void DeleteLexerDecorations();
+	virtual bool FillRange(Sci::Position &position, int value, Sci::Position &fillLength) = 0;
+	virtual void InsertSpace(Sci::Position position, Sci::Position insertLength) = 0;
+	virtual void DeleteRange(Sci::Position position, Sci::Position deleteLength) = 0;
+	virtual void DeleteLexerDecorations() = 0;
 
-	int AllOnFor(Sci::Position position) const;
-	int ValueAt(int indicator, Sci::Position position);
-	Sci::Position Start(int indicator, Sci::Position position);
-	Sci::Position End(int indicator, Sci::Position position);
+	virtual int AllOnFor(Sci::Position position) const = 0;
+	virtual int ValueAt(int indicator, Sci::Position position) = 0;
+	virtual Sci::Position Start(int indicator, Sci::Position position) = 0;
+	virtual Sci::Position End(int indicator, Sci::Position position) = 0;
 
-	bool ClickNotified() const {
-		return clickNotified;
-	}
-	void SetClickNotified(bool notified) {
-		clickNotified = notified;
-	}
+	virtual bool ClickNotified() const = 0;
+	virtual void SetClickNotified(bool notified) = 0;
 };
 
+std::unique_ptr<IDecoration> CreateDecoration(bool largeDocument, int indicator);
+
+std::unique_ptr<IDecorationList> CreateDecorationList(bool largeDocument);
+
 }
 
 #endif
diff -r c45f23c0fbbe -r 006c18e8efae src/Document.cxx
--- a/src/Document.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/Document.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -124,6 +124,8 @@
 	perLineData[ldMargin] = std::make_unique<LineAnnotation>();
 	perLineData[ldAnnotation] = std::make_unique<LineAnnotation>();
 
+	decorations = CreateDecorationList(IsLarge());
+
 	cb.SetPerLine(this);
 }
 
@@ -2242,13 +2244,13 @@
 }
 
 void SCI_METHOD Document::DecorationSetCurrentIndicator(int indicator) {
-	decorations.SetCurrentIndicator(indicator);
+	decorations->SetCurrentIndicator(indicator);
 }
 
 void SCI_METHOD Document::DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) {
 	Sci::Position sciPosition = static_cast<Sci::Position>(position);
 	Sci::Position sciFillLength = static_cast<Sci::Position>(fillLength);
-	if (decorations.FillRange(sciPosition, value, sciFillLength)) {
+	if (decorations->FillRange(sciPosition, value, sciFillLength)) {
 		const DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
 							sciPosition, sciFillLength);
 		NotifyModified(mh);
@@ -2289,9 +2291,9 @@
 
 void Document::NotifyModified(DocModification mh) {
 	if (mh.modificationType & SC_MOD_INSERTTEXT) {
-		decorations.InsertSpace(mh.position, mh.length);
+		decorations->InsertSpace(mh.position, mh.length);
 	} else if (mh.modificationType & SC_MOD_DELETETEXT) {
-		decorations.DeleteRange(mh.position, mh.length);
+		decorations->DeleteRange(mh.position, mh.length);
 	}
 	for (const WatcherWithUserData &watcher : watchers) {
 		watcher.watcher->NotifyModified(this, mh, watcher.userData);
diff -r c45f23c0fbbe -r 006c18e8efae src/Document.h
--- a/src/Document.h	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/Document.h	Sat Mar 10 16:50:51 2018 +1100
@@ -263,7 +263,7 @@
 	bool backspaceUnindents;
 	double durationStyleOneLine;
 
-	DecorationList decorations;
+	std::unique_ptr<IDecorationList> decorations;
 
 	Document(int options);
 	// Deleted so Document objects can not be copied.
diff -r c45f23c0fbbe -r 006c18e8efae src/EditView.cxx
--- a/src/EditView.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/EditView.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -1044,25 +1044,25 @@
 	const Sci::Position lineStart = ll->LineStart(subLine);
 	const Sci::Position posLineEnd = posLineStart + lineEnd;
 
-	for (const Decoration *deco : model.pdoc->decorations.View()) {
+	for (const IDecoration *deco : model.pdoc->decorations->View()) {
 		if (under == vsDraw.indicators[deco->Indicator()].under) {
 			Sci::Position startPos = posLineStart + lineStart;
-			if (!deco->rs.ValueAt(startPos)) {
-				startPos = deco->rs.EndRun(startPos);
+			if (!deco->ValueAt(startPos)) {
+				startPos = deco->EndRun(startPos);
 			}
-			while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) {
-				const Range rangeRun(deco->rs.StartRun(startPos), deco->rs.EndRun(startPos));
+			while ((startPos < posLineEnd) && (deco->ValueAt(startPos))) {
+				const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos));
 				const Sci::Position endPos = std::min(rangeRun.end, posLineEnd);
 				const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() &&
 					rangeRun.ContainsCharacter(hoverIndicatorPos);
-				const int value = deco->rs.ValueAt(startPos);
+				const int value = deco->ValueAt(startPos);
 				const Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal;
 				const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1);
 				DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart,
 					surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, drawState, value);
 				startPos = endPos;
-				if (!deco->rs.ValueAt(startPos)) {
-					startPos = deco->rs.EndRun(startPos);
+				if (!deco->ValueAt(startPos)) {
+					startPos = deco->EndRun(startPos);
 				}
 			}
 		}
@@ -1662,8 +1662,8 @@
 			}
 			if (vsDraw.indicatorsSetFore) {
 				// At least one indicator sets the text colour so see if it applies to this segment
-				for (const Decoration *deco : model.pdoc->decorations.View()) {
-					const int indicatorValue = deco->rs.ValueAt(ts.start + posLineStart);
+				for (const IDecoration *deco : model.pdoc->decorations->View()) {
+					const int indicatorValue = deco->ValueAt(ts.start + posLineStart);
 					if (indicatorValue) {
 						const Indicator &indicator = vsDraw.indicators[deco->Indicator()];
 						const bool hover = indicator.IsDynamic() &&
diff -r c45f23c0fbbe -r 006c18e8efae src/Editor.cxx
--- a/src/Editor.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/Editor.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -2110,7 +2110,7 @@
 }
 
 void Editor::ClearDocumentStyle() {
-	pdoc->decorations.DeleteLexerDecorations();
+	pdoc->decorations->DeleteLexerDecorations();
 	pdoc->StartStyling(0);
 	pdoc->SetStyleFor(pdoc->Length(), 0);
 	pcs->ShowAll();
@@ -2395,10 +2395,10 @@
 }
 
 void Editor::NotifyIndicatorClick(bool click, Sci::Position position, int modifiers) {
-	const int mask = pdoc->decorations.AllOnFor(position);
-	if ((click && mask) || pdoc->decorations.ClickNotified()) {
+	const int mask = pdoc->decorations->AllOnFor(position);
+	if ((click && mask) || pdoc->decorations->ClickNotified()) {
 		SCNotification scn = {};
-		pdoc->decorations.SetClickNotified(click);
+		pdoc->decorations->SetClickNotified(click);
 		scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE;
 		scn.modifiers = modifiers;
 		scn.position = position;
@@ -4672,9 +4672,9 @@
 	if (!vs.indicatorsDynamic)
 		return;
 	if (position != INVALID_POSITION) {
-		for (const Decoration *deco : pdoc->decorations.View()) {
+		for (const IDecoration *deco : pdoc->decorations->View()) {
 			if (vs.indicators[deco->Indicator()].IsDynamic()) {
-				if (pdoc->decorations.ValueAt(deco->Indicator(), position)) {
+				if (pdoc->decorations->ValueAt(deco->Indicator(), position)) {
 					hoverIndicatorPos = position;
 				}
 			}
@@ -7384,15 +7384,15 @@
 		pdoc->DecorationSetCurrentIndicator(static_cast<int>(wParam));
 		break;
 	case SCI_GETINDICATORCURRENT:
-		return pdoc->decorations.GetCurrentIndicator();
+		return pdoc->decorations->GetCurrentIndicator();
 	case SCI_SETINDICATORVALUE:
-		pdoc->decorations.SetCurrentValue(static_cast<int>(wParam));
+		pdoc->decorations->SetCurrentValue(static_cast<int>(wParam));
 		break;
 	case SCI_GETINDICATORVALUE:
-		return pdoc->decorations.GetCurrentValue();
+		return pdoc->decorations->GetCurrentValue();
 
 	case SCI_INDICATORFILLRANGE:
-		pdoc->DecorationFillRange(static_cast<int>(wParam), pdoc->decorations.GetCurrentValue(), static_cast<int>(lParam));
+		pdoc->DecorationFillRange(static_cast<int>(wParam), pdoc->decorations->GetCurrentValue(), static_cast<int>(lParam));
 		break;
 
 	case SCI_INDICATORCLEARRANGE:
@@ -7400,16 +7400,16 @@
 		break;
 
 	case SCI_INDICATORALLONFOR:
-		return pdoc->decorations.AllOnFor(static_cast<int>(wParam));
+		return pdoc->decorations->AllOnFor(static_cast<int>(wParam));
 
 	case SCI_INDICATORVALUEAT:
-		return pdoc->decorations.ValueAt(static_cast<int>(wParam), static_cast<int>(lParam));
+		return pdoc->decorations->ValueAt(static_cast<int>(wParam), static_cast<int>(lParam));
 
 	case SCI_INDICATORSTART:
-		return pdoc->decorations.Start(static_cast<int>(wParam), static_cast<int>(lParam));
+		return pdoc->decorations->Start(static_cast<int>(wParam), static_cast<int>(lParam));
 
 	case SCI_INDICATOREND:
-		return pdoc->decorations.End(static_cast<int>(wParam), static_cast<int>(lParam));
+		return pdoc->decorations->End(static_cast<int>(wParam), static_cast<int>(lParam));
 
 	case SCI_LINEDOWN:
 	case SCI_LINEDOWNEXTEND:
diff -r c45f23c0fbbe -r 006c18e8efae src/PositionCache.cxx
--- a/src/PositionCache.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/src/PositionCache.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -471,12 +471,12 @@
 		}
 	}
 	if (pvsDraw && pvsDraw->indicatorsSetFore) {
-		for (const Decoration *deco : pdoc->decorations.View()) {
+		for (const IDecoration *deco : pdoc->decorations->View()) {
 			if (pvsDraw->indicators[deco->Indicator()].OverridesTextFore()) {
-				Sci::Position startPos = deco->rs.EndRun(posLineStart);
+				Sci::Position startPos = deco->EndRun(posLineStart);
 				while (startPos < (posLineStart + lineRange.end)) {
 					Insert(static_cast<int>(startPos - posLineStart));
-					startPos = deco->rs.EndRun(startPos);
+					startPos = deco->EndRun(startPos);
 				}
 			}
 		}
diff -r c45f23c0fbbe -r 006c18e8efae test/unit/testDecoration.cxx
--- a/test/unit/testDecoration.cxx	Sat Mar 10 14:17:29 2018 +1100
+++ b/test/unit/testDecoration.cxx	Sat Mar 10 16:50:51 2018 +1100
@@ -25,27 +25,27 @@
 
 TEST_CASE("Decoration") {
 
-	Decoration deco(indicator);
+	std::unique_ptr<IDecoration> deco = CreateDecoration(false, indicator);
 
 	SECTION("HasCorrectIndicator") {
-		REQUIRE(indicator == deco.Indicator());
+		REQUIRE(indicator == deco->Indicator());
 	}
 
 	SECTION("IsEmptyInitially") {
-		REQUIRE(0 == deco.rs.Length());
-		REQUIRE(1 == deco.rs.Runs());
-		REQUIRE(deco.Empty());
+		REQUIRE(0 == deco->Length());
+		REQUIRE(1 == deco->Runs());
+		REQUIRE(deco->Empty());
 	}
 
 	SECTION("SimpleSpace") {
-		deco.rs.InsertSpace(0, 1);
-		REQUIRE(deco.Empty());
+		deco->InsertSpace(0, 1);
+		REQUIRE(deco->Empty());
 	}
 
 	SECTION("SimpleRun") {
-		deco.rs.InsertSpace(0, 1);
-		deco.rs.SetValueAt(0, 2);
-		REQUIRE(!deco.Empty());
+		deco->InsertSpace(0, 1);
+		deco->SetValueAt(0, 2);
+		REQUIRE(!deco->Empty());
 	}
 }
 
@@ -53,42 +53,42 @@
 
 TEST_CASE("DecorationList") {
 
-	DecorationList decol;
+	std::unique_ptr<IDecorationList> decol = CreateDecorationList(false);
 
 	SECTION("HasCorrectIndicator") {
-		decol.SetCurrentIndicator(indicator);
-		REQUIRE(indicator == decol.GetCurrentIndicator());
+		decol->SetCurrentIndicator(indicator);
+		REQUIRE(indicator == decol->GetCurrentIndicator());
 	}
 
 	SECTION("HasCorrectCurrentValue") {
 		const int value = 55;
-		decol.SetCurrentValue(value);
-		REQUIRE(value == decol.GetCurrentValue());
+		decol->SetCurrentValue(value);
+		REQUIRE(value == decol->GetCurrentValue());
 	}
 
 	SECTION("ExpandSetValues") {
-		decol.SetCurrentIndicator(indicator);
-		decol.InsertSpace(0, 9);
+		decol->SetCurrentIndicator(indicator);
+		decol->InsertSpace(0, 9);
 		const int value = 59;
 		Sci::Position position = 4;
 		Sci::Position fillLength = 3;
-		bool changed = decol.FillRange(position, value, fillLength);
+		bool changed = decol->FillRange(position, value, fillLength);
 		REQUIRE(changed);
 		REQUIRE(position == 4);
 		REQUIRE(fillLength == 3);
 		REQUIRE(fillLength == 3);
-		REQUIRE(decol.ValueAt(indicator, 5) == value);
-		REQUIRE(decol.AllOnFor(5) == (1 << indicator));
-		REQUIRE(decol.Start(indicator, 5) == 4);
-		REQUIRE(decol.End(indicator, 5) == 7);
+		REQUIRE(decol->ValueAt(indicator, 5) == value);
+		REQUIRE(decol->AllOnFor(5) == (1 << indicator));
+		REQUIRE(decol->Start(indicator, 5) == 4);
+		REQUIRE(decol->End(indicator, 5) == 7);
 		const int indicatorB=6;
-		decol.SetCurrentIndicator(indicatorB);
-		changed = decol.FillRange(position, value, fillLength);
+		decol->SetCurrentIndicator(indicatorB);
+		changed = decol->FillRange(position, value, fillLength);
 		REQUIRE(changed);
-		REQUIRE(decol.AllOnFor(5) == ((1 << indicator) | (1 << indicatorB)));
-		decol.DeleteRange(5, 1);
-		REQUIRE(decol.Start(indicatorB, 5) == 4);
-		REQUIRE(decol.End(indicatorB, 5) == 6);
+		REQUIRE(decol->AllOnFor(5) == ((1 << indicator) | (1 << indicatorB)));
+		decol->DeleteRange(5, 1);
+		REQUIRE(decol->Start(indicatorB, 5) == 4);
+		REQUIRE(decol->End(indicatorB, 5) == 6);
 	}
 
 }
