diff -r 6bdd215bedf9 gtk/PlatGTK.cxx
--- a/gtk/PlatGTK.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/gtk/PlatGTK.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -164,12 +164,12 @@
 	void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
 	void Copy(PRectangle rc, Point from, Surface &surfaceSource) override;
 
-	void DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore);
-	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override;
-	void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override;
-	XYPOSITION WidthText(Font &font_, const char *s, int len) override;
+	void DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore);
+	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
+	void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) override;
+	XYPOSITION WidthText(Font &font_, std::string_view text) override;
 	XYPOSITION WidthChar(Font &font_, char ch) override;
 	XYPOSITION Ascent(Font &font_) override;
 	XYPOSITION Descent(Font &font_) override;
@@ -598,11 +598,11 @@
 	}
 }
 
-std::string UTF8FromLatin1(const char *s, int len) {
-	std::string utfForm(len*2 + 1, '\0');
+std::string UTF8FromLatin1(std::string_view text) {
+	std::string utfForm(text.length()*2 + 1, '\0');
 	size_t lenU = 0;
-	for (int i=0; i<len; i++) {
-		unsigned int uch = static_cast<unsigned char>(s[i]);
+	for (size_t i=0; i<text.length(); i++) {
+		unsigned int uch = static_cast<unsigned char>(text[i]);
 		if (uch < 0x80) {
 			utfForm[lenU++] = uch;
 		} else {
@@ -614,14 +614,14 @@
 	return utfForm;
 }
 
-static std::string UTF8FromIconv(const Converter &conv, const char *s, int len) {
+static std::string UTF8FromIconv(const Converter &conv, std::string_view text) {
 	if (conv) {
-		std::string utfForm(len*3+1, '\0');
-		char *pin = const_cast<char *>(s);
-		gsize inLeft = len;
+		std::string utfForm(text.length()*3+1, '\0');
+		char *pin = const_cast<char *>(text.data());
+		gsize inLeft = text.length();
 		char *putf = &utfForm[0];
 		char *pout = putf;
-		gsize outLeft = len*3+1;
+		gsize outLeft = text.length()*3+1;
 		gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
 		if (conversions != sizeFailure) {
 			*pout = '\0';
@@ -649,7 +649,7 @@
 	return 1;
 }
 
-void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
                                  ColourDesired fore) {
 	PenColour(fore);
 	if (context) {
@@ -657,12 +657,12 @@
 		if (PFont(font_)->pfd) {
 			std::string utfForm;
 			if (et == UTF8) {
-				pango_layout_set_text(layout, s, len);
+				pango_layout_set_text(layout, text.data(), text.length());
 			} else {
 				SetConverter(PFont(font_)->characterSet);
-				utfForm = UTF8FromIconv(conv, s, len);
+				utfForm = UTF8FromIconv(conv, text);
 				if (utfForm.empty()) {	// iconv failed so treat as Latin1
-					utfForm = UTF8FromLatin1(s, len);
+					utfForm = UTF8FromLatin1(text);
 				}
 				pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
 			}
@@ -675,25 +675,25 @@
 	}
 }
 
-void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
                                  ColourDesired fore, ColourDesired back) {
 	FillRectangle(rc, back);
-	DrawTextBase(rc, font_, ybase, s, len, fore);
+	DrawTextBase(rc, font_, ybase, text, fore);
 }
 
 // On GTK+, exactly same as DrawTextNoClip
-void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
                                   ColourDesired fore, ColourDesired back) {
 	FillRectangle(rc, back);
-	DrawTextBase(rc, font_, ybase, s, len, fore);
+	DrawTextBase(rc, font_, ybase, text, fore);
 }
 
-void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
                                   ColourDesired fore) {
 	// Avoid drawing spaces in transparent mode
-	for (int i=0; i<len; i++) {
-		if (s[i] != ' ') {
-			DrawTextBase(rc, font_, ybase, s, len, fore);
+	for (size_t i=0; i<text.length(); i++) {
+		if (text[i] != ' ') {
+			DrawTextBase(rc, font_, ybase, text, fore);
 			return;
 		}
 	}
@@ -702,14 +702,14 @@
 class ClusterIterator {
 	PangoLayoutIter *iter;
 	PangoRectangle pos;
-	int lenPositions;
+	size_t lenPositions;
 public:
 	bool finished;
 	XYPOSITION positionStart;
 	XYPOSITION position;
 	XYPOSITION distance;
 	int curIndex;
-	ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false),
+	ClusterIterator(PangoLayout *layout, size_t len) : lenPositions(len), finished(false),
 		positionStart(0), position(0), distance(0), curIndex(0) {
 		iter = pango_layout_get_iter(layout);
 		pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
@@ -733,15 +733,15 @@
 	}
 };
 
-void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) {
+void SurfaceImpl::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
 	if (font_.GetID()) {
-		const int lenPositions = len;
+		const size_t lenPositions = text.length();
 		if (PFont(font_)->pfd) {
 			pango_layout_set_font_description(layout, PFont(font_)->pfd);
 			if (et == UTF8) {
 				// Simple and direct as UTF-8 is native Pango encoding
 				int i = 0;
-				pango_layout_set_text(layout, s, len);
+				pango_layout_set_text(layout, text.data(), text.length());
 				ClusterIterator iti(layout, lenPositions);
 				while (!iti.finished) {
 					iti.Next();
@@ -760,7 +760,7 @@
 				int positionsCalculated = 0;
 				if (et == dbcs) {
 					SetConverter(PFont(font_)->characterSet);
-					std::string utfForm = UTF8FromIconv(conv, s, len);
+					std::string utfForm = UTF8FromIconv(conv, text);
 					if (!utfForm.empty()) {
 						// Convert to UTF-8 so can ask Pango for widths, then
 						// Loop through UTF-8 and DBCS forms, taking account of different
@@ -776,7 +776,7 @@
 							int places = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart);
 							int place = 1;
 							while (clusterStart < clusterEnd) {
-								size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i);
+								size_t lenChar = MultiByteLenFromIconv(convMeasure, text.data()+i, text.length()-i);
 								while (lenChar--) {
 									positions[i++] = iti.position - (places - place) * iti.distance / places;
 									positionsCalculated++;
@@ -793,12 +793,12 @@
 					SetConverter(PFont(font_)->characterSet);
 					const bool rtlCheck = PFont(font_)->characterSet == SC_CHARSET_HEBREW ||
 						PFont(font_)->characterSet == SC_CHARSET_ARABIC;
-					std::string utfForm = UTF8FromIconv(conv, s, len);
+					std::string utfForm = UTF8FromIconv(conv, text);
 					if (utfForm.empty()) {
-						utfForm = UTF8FromLatin1(s, len);
+						utfForm = UTF8FromLatin1(text);
 					}
 					pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
-					int i = 0;
+					size_t i = 0;
 					int clusterStart = 0;
 					// Each 8-bit input character may take 1 or 2 bytes in UTF-8
 					// and groups of up to 3 may be represented as ligatures.
@@ -812,7 +812,7 @@
 							int widthLayout = 0;
 							pango_layout_get_size(layout, &widthLayout, NULL);
 							XYPOSITION widthTotal = doubleFromPangoUnits(widthLayout);
-							for (int bytePos=0; bytePos<lenPositions; bytePos++) {
+							for (size_t bytePos=0; bytePos<lenPositions; bytePos++) {
 								positions[bytePos] = widthTotal / lenPositions * (bytePos + 1);
 							}
 							return;
@@ -833,25 +833,25 @@
 		}
 	} else {
 		// No font so return an ascending range of values
-		for (int i = 0; i < len; i++) {
+		for (size_t i = 0; i < text.length(); i++) {
 			positions[i] = i + 1;
 		}
 	}
 }
 
-XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
+XYPOSITION SurfaceImpl::WidthText(Font &font_, std::string_view text) {
 	if (font_.GetID()) {
 		if (PFont(font_)->pfd) {
 			std::string utfForm;
 			pango_layout_set_font_description(layout, PFont(font_)->pfd);
 			PangoRectangle pos;
 			if (et == UTF8) {
-				pango_layout_set_text(layout, s, len);
+				pango_layout_set_text(layout, text.data(), text.length());
 			} else {
 				SetConverter(PFont(font_)->characterSet);
-				utfForm = UTF8FromIconv(conv, s, len);
+				utfForm = UTF8FromIconv(conv, text);
 				if (utfForm.empty()) {	// iconv failed so treat as Latin1
-					utfForm = UTF8FromLatin1(s, len);
+					utfForm = UTF8FromLatin1(text);
 				}
 				pango_layout_set_text(layout, utfForm.c_str(), utfForm.length());
 			}
@@ -868,7 +868,7 @@
 XYPOSITION SurfaceImpl::WidthChar(Font &font_, char ch) {
 	if (font_.GetID()) {
 		if (PFont(font_)->pfd) {
-			return WidthText(font_, &ch, 1);
+			return WidthText(font_, std::string_view(&ch, 1));
 		}
 		return 1;
 	} else {
diff -r 6bdd215bedf9 gtk/ScintillaGTK.cxx
--- a/gtk/ScintillaGTK.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/gtk/ScintillaGTK.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -110,7 +110,7 @@
 	return gtk_widget_get_window(widget);
 }
 
-extern std::string UTF8FromLatin1(const char *s, int len);
+extern std::string UTF8FromLatin1(std::string_view text);
 
 enum {
     COMMAND_SIGNAL,
@@ -1389,7 +1389,7 @@
 	if (selectionTypeData == GDK_TARGET_STRING) {
 		if (IsUnicodeMode()) {
 			// Unknown encoding so assume in Latin1
-			dest = UTF8FromLatin1(dest.c_str(), dest.length());
+			dest = UTF8FromLatin1(dest);
 			selText.Copy(dest, SC_CP_UTF8, 0, isRectangular, false);
 		} else {
 			// Assume buffer is in same encoding as selection
diff -r 6bdd215bedf9 include/Platform.h
--- a/include/Platform.h	Mon Apr 23 10:12:11 2018 +1000
+++ b/include/Platform.h	Mon Apr 23 12:43:55 2018 +1000
@@ -319,11 +319,11 @@
 	virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
 	virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
 
-	virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
-	virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
-	virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0;
-	virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0;
-	virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0;
+	virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back)=0;
+	virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back)=0;
+	virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore)=0;
+	virtual void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions)=0;
+	virtual XYPOSITION WidthText(Font &font_, std::string_view text)=0;
 	virtual XYPOSITION WidthChar(Font &font_, char ch)=0;
 	virtual XYPOSITION Ascent(Font &font_)=0;
 	virtual XYPOSITION Descent(Font &font_)=0;
diff -r 6bdd215bedf9 src/CallTip.cxx
--- a/src/CallTip.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/CallTip.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -151,13 +151,13 @@
 			} else if (IsTabCharacter(s[startSeg])) {
 				xEnd = NextTabPos(x);
 			} else {
-				xEnd = x + static_cast<int>(lround(surface->WidthText(font, s + startSeg, endSeg - startSeg)));
+				std::string_view segText(s + startSeg, endSeg - startSeg);
+				xEnd = x + static_cast<int>(lround(surface->WidthText(font, segText)));
 				if (draw) {
 					rcClient.left = static_cast<XYPOSITION>(x);
 					rcClient.right = static_cast<XYPOSITION>(xEnd);
 					surface->DrawTextTransparent(rcClient, font, static_cast<XYPOSITION>(ytext),
-										s+startSeg, endSeg - startSeg,
-					                             highlight ? colourSel : colourUnSel);
+										segText, highlight ? colourSel : colourUnSel);
 				}
 			}
 			x = xEnd;
diff -r 6bdd215bedf9 src/EditModel.cxx
--- a/src/EditModel.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/EditModel.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -13,6 +13,7 @@
 
 #include <stdexcept>
 #include <string>
+#include <string_view>
 #include <vector>
 #include <map>
 #include <algorithm>
diff -r 6bdd215bedf9 src/EditView.cxx
--- a/src/EditView.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/EditView.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -92,8 +92,8 @@
 		while ((endSegment + 1 < len) && (styles[endSegment + 1] == style))
 			endSegment++;
 		FontAlias fontText = vs.styles[style + styleOffset].font;
-		width += static_cast<int>(surface->WidthText(fontText, text + start,
-			static_cast<int>(endSegment - start + 1)));
+		width += static_cast<int>(surface->WidthText(fontText,
+			std::string_view(text + start, endSegment - start + 1)));
 		start = endSegment + 1;
 	}
 	return width;
@@ -110,7 +110,7 @@
 		} else {
 			FontAlias fontText = vs.styles[styleOffset + st.style].font;
 			widthSubLine = static_cast<int>(surface->WidthText(fontText,
-				st.text + start, static_cast<int>(lenLine)));
+				std::string_view(st.text + start, lenLine)));
 		}
 		if (widthSubLine > widthMax)
 			widthMax = widthSubLine;
@@ -120,18 +120,18 @@
 }
 
 void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase,
-	const char *s, int len, DrawPhase phase) {
+	std::string_view text, DrawPhase phase) {
 	FontAlias fontText = style.font;
 	if (phase & drawBack) {
 		if (phase & drawText) {
 			// Drawing both
-			surface->DrawTextNoClip(rc, fontText, ybase, s, len,
+			surface->DrawTextNoClip(rc, fontText, ybase, text,
 				style.fore, style.back);
 		} else {
 			surface->FillRectangle(rc, style.back);
 		}
 	} else if (phase & drawText) {
-		surface->DrawTextTransparent(rc, fontText, ybase, s, len, style.fore);
+		surface->DrawTextTransparent(rc, fontText, ybase, text, style.fore);
 	}
 }
 
@@ -149,21 +149,21 @@
 			style += styleOffset;
 			FontAlias fontText = vs.styles[style].font;
 			const int width = static_cast<int>(surface->WidthText(fontText,
-				st.text + start + i, static_cast<int>(end - i + 1)));
+				std::string_view(st.text + start + i, end - i + 1)));
 			PRectangle rcSegment = rcText;
 			rcSegment.left = static_cast<XYPOSITION>(x);
 			rcSegment.right = static_cast<XYPOSITION>(x + width + 1);
 			DrawTextNoClipPhase(surface, rcSegment, vs.styles[style],
-				rcText.top + vs.maxAscent, st.text + start + i,
-				static_cast<int>(end - i + 1), phase);
+				rcText.top + vs.maxAscent,
+				std::string_view(st.text + start + i, end - i + 1), phase);
 			x += width;
 			i = end + 1;
 		}
 	} else {
 		const size_t style = st.style + styleOffset;
 		DrawTextNoClipPhase(surface, rcText, vs.styles[style],
-			rcText.top + vs.maxAscent, st.text + start,
-			static_cast<int>(length), phase);
+			rcText.top + vs.maxAscent,
+			std::string_view(st.text + start, length), phase);
 	}
 }
 
@@ -801,7 +801,7 @@
 }
 
 static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle rcSegment,
-	const char *s, ColourDesired textBack, ColourDesired textFore, bool fillBackground) {
+	std::string_view text, ColourDesired textBack, ColourDesired textFore, bool fillBackground) {
 	if (rcSegment.Empty())
 		return;
 	if (fillBackground) {
@@ -821,7 +821,7 @@
 	rcChar.left++;
 	rcChar.right--;
 	surface->DrawTextClipped(rcChar, ctrlCharsFont,
-		rcSegment.top + vsDraw.maxAscent, s, static_cast<int>(s ? strlen(s) : 0),
+		rcSegment.top + vsDraw.maxAscent, text,
 		textBack, textFore);
 }
 
@@ -1102,9 +1102,8 @@
 
 	PRectangle rcSegment = rcLine;
 	const char *foldDisplayText = model.pcs->GetFoldDisplayText(line);
-	const int lengthFoldDisplayText = static_cast<int>(strlen(foldDisplayText));
 	FontAlias fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font;
-	const int widthFoldDisplayText = static_cast<int>(surface->WidthText(fontText, foldDisplayText, lengthFoldDisplayText));
+	const int widthFoldDisplayText = static_cast<int>(surface->WidthText(fontText, foldDisplayText));
 
 	int eolInSelection = 0;
 	int alpha = SC_ALPHA_NOALPHA;
@@ -1152,11 +1151,11 @@
 		if (phasesDraw != phasesOne) {
 			surface->DrawTextTransparent(rcSegment, textFont,
 				rcSegment.top + vsDraw.maxAscent, foldDisplayText,
-				lengthFoldDisplayText, textFore);
+				textFore);
 		} else {
 			surface->DrawTextNoClip(rcSegment, textFont,
 				rcSegment.top + vsDraw.maxAscent, foldDisplayText,
-				lengthFoldDisplayText, textFore, textBack);
+				textFore, textBack);
 		}
 	}
 
@@ -1306,8 +1305,8 @@
 	const int styleMain = ll->styles[offsetFirstChar];
 	FontAlias fontText = vsDraw.styles[styleMain].font;
 	surface->DrawTextClipped(rcCaret, fontText,
-		rcCaret.top + vsDraw.maxAscent, &ll->chars[offsetFirstChar],
-		static_cast<int>(numCharsToDraw), vsDraw.styles[styleMain].back,
+		rcCaret.top + vsDraw.maxAscent,
+		std::string_view(&ll->chars[offsetFirstChar], numCharsToDraw), vsDraw.styles[styleMain].back,
 		caretColour);
 }
 
@@ -1730,23 +1729,24 @@
 						const char cc[2] = { static_cast<char>(vsDraw.controlCharSymbol), '\0' };
 						surface->DrawTextNoClip(rcSegment, ctrlCharsFont,
 							rcSegment.top + vsDraw.maxAscent,
-							cc, 1, textBack, textFore);
+							cc, textBack, textFore);
 					} else {
-						DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep.c_str(),
+						DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep,
 							textBack, textFore, phasesDraw == phasesOne);
 					}
 				}
 			} else {
 				// Normal text display
 				if (vsDraw.styles[styleMain].visible) {
+					std::string_view piece(&ll->chars[ts.start], i - ts.start + 1);
 					if (phasesDraw != phasesOne) {
 						surface->DrawTextTransparent(rcSegment, textFont,
-							rcSegment.top + vsDraw.maxAscent, &ll->chars[ts.start],
-							static_cast<int>(i - ts.start + 1), textFore);
+							rcSegment.top + vsDraw.maxAscent,
+							piece, textFore);
 					} else {
 						surface->DrawTextNoClip(rcSegment, textFont,
-							rcSegment.top + vsDraw.maxAscent, &ll->chars[ts.start],
-							static_cast<int>(i - ts.start + 1), textFore, textBack);
+							rcSegment.top + vsDraw.maxAscent,
+							piece, textFore, textBack);
 					}
 				}
 				if (vsDraw.viewWhitespace != wsInvisible ||
@@ -2256,7 +2256,7 @@
 	int lineNumberWidth = 0;
 	if (lineNumberIndex >= 0) {
 		lineNumberWidth = static_cast<int>(surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,
-			"99999" lineNumberPrintSpace, 5 + static_cast<int>(strlen(lineNumberPrintSpace))));
+			"99999" lineNumberPrintSpace));
 		vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
 		vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars);	// Recalculate fixedColumnWidth
 	}
@@ -2337,10 +2337,10 @@
 			rcNumber.right = rcNumber.left + lineNumberWidth;
 			// Right justify
 			rcNumber.left = rcNumber.right - surfaceMeasure->WidthText(
-				vsPrint.styles[STYLE_LINENUMBER].font, number.c_str(), static_cast<int>(number.length()));
+				vsPrint.styles[STYLE_LINENUMBER].font, number);
 			surface->FlushCachedState();
 			surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
-				static_cast<XYPOSITION>(ypos + vsPrint.maxAscent), number.c_str(), static_cast<int>(number.length()),
+				static_cast<XYPOSITION>(ypos + vsPrint.maxAscent), number,
 				vsPrint.styles[STYLE_LINENUMBER].fore,
 				vsPrint.styles[STYLE_LINENUMBER].back);
 		}
diff -r 6bdd215bedf9 src/EditView.h
--- a/src/EditView.h	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/EditView.h	Mon Apr 23 12:43:55 2018 +1000
@@ -36,7 +36,7 @@
 bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st);
 int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st);
 void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase,
-	const char *s, int len, DrawPhase phase);
+	std::string_view text, DrawPhase phase);
 void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRectangle rcText,
 	const StyledText &st, size_t start, size_t length, DrawPhase phase);
 
diff -r 6bdd215bedf9 src/Editor.cxx
--- a/src/Editor.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/Editor.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -1797,7 +1797,7 @@
 	RefreshStyleData();
 	AutoSurface surface(this);
 	if (surface) {
-		return static_cast<int>(surface->WidthText(vs.styles[style].font, text, static_cast<int>(strlen(text))));
+		return static_cast<int>(surface->WidthText(vs.styles[style].font, text));
 	} else {
 		return 1;
 	}
diff -r 6bdd215bedf9 src/LineMarker.cxx
--- a/src/LineMarker.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/LineMarker.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -377,13 +377,12 @@
 		DrawMinus(surface, centreX, centreY, blobSize, colourTail);
 
 	} else if (markType >= SC_MARK_CHARACTER) {
-		char character[1];
-		character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
-		const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1);
+		std::string character(1, static_cast<char>(markType - SC_MARK_CHARACTER));
+		const XYPOSITION width = surface->WidthText(fontForCharacter, character);
 		rc.left += (rc.Width() - width) / 2;
 		rc.right = rc.left + width;
 		surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
-			character, 1, fore, back);
+			character, fore, back);
 
 	} else if (markType == SC_MARK_DOTDOTDOT) {
 		XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);
diff -r 6bdd215bedf9 src/MarginView.cxx
--- a/src/MarginView.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/MarginView.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -389,11 +389,11 @@
 						}
 						PRectangle rcNumber = rcMarker;
 						// Right justify
-						const XYPOSITION width = surface->WidthText(fontLineNumber, sNumber.c_str(), static_cast<int>(sNumber.length()));
+						const XYPOSITION width = surface->WidthText(fontLineNumber, sNumber);
 						const XYPOSITION xpos = rcNumber.right - width - vs.marginNumberPadding;
 						rcNumber.left = xpos;
 						DrawTextNoClipPhase(surface, rcNumber, vs.styles[STYLE_LINENUMBER],
-							rcNumber.top + vs.maxAscent, sNumber.c_str(), static_cast<int>(sNumber.length()), drawAll);
+							rcNumber.top + vs.maxAscent, sNumber, drawAll);
 					} else if (vs.wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) {
 						PRectangle rcWrapMarker = rcMarker;
 						rcWrapMarker.right -= wrapMarkerPaddingRight;
diff -r 6bdd215bedf9 src/PositionCache.cxx
--- a/src/PositionCache.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/src/PositionCache.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -680,7 +680,7 @@
 		while (startSegment < len) {
 			const unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
 			FontAlias fontStyle = vstyle.styles[styleNumber].font;
-			surface->MeasureWidths(fontStyle, s + startSegment, lenSegment, positions + startSegment);
+			surface->MeasureWidths(fontStyle, std::string_view(s + startSegment, lenSegment), positions + startSegment);
 			for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
 				positions[startSegment + inSeg] += xStartSegment;
 			}
@@ -689,7 +689,7 @@
 		}
 	} else {
 		FontAlias fontStyle = vstyle.styles[styleNumber].font;
-		surface->MeasureWidths(fontStyle, s, len, positions);
+		surface->MeasureWidths(fontStyle, std::string_view(s, len), positions);
 	}
 	if (probe < pces.size()) {
 		// Store into cache
diff -r 6bdd215bedf9 win32/PlatWin.cxx
--- a/win32/PlatWin.cxx	Mon Apr 23 10:12:11 2018 +1000
+++ b/win32/PlatWin.cxx	Mon Apr 23 12:43:55 2018 +1000
@@ -507,6 +507,16 @@
 			tlen = ::MultiByteToWideChar(codePage, 0, s, len, buffer, len);
 		}
 	}
+	TextWide(std::string_view text, bool unicodeMode, int codePage=0) :
+		VarBuffer<wchar_t, stackBufferLength>(text.length()) {
+		if (unicodeMode) {
+			tlen = static_cast<int>(UTF16FromUTF8(text.data(), text.length(), buffer, text.length()));
+		} else {
+			// Support Asian string display in 9x English
+			tlen = ::MultiByteToWideChar(codePage, 0, text.data(), static_cast<int>(text.length()),
+				buffer, static_cast<int>(text.length()));
+		}
+	}
 };
 typedef VarBuffer<XYPOSITION, stackBufferLength> TextPositions;
 
@@ -563,12 +573,12 @@
 	void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
 	void Copy(PRectangle rc, Point from, Surface &surfaceSource) override;
 
-	void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions);
-	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override;
-	void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override;
-	XYPOSITION WidthText(Font &font_, const char *s, int len) override;
+	void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
+	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
+	void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) override;
+	XYPOSITION WidthText(Font &font_, std::string_view text) override;
 	XYPOSITION WidthChar(Font &font_, char ch) override;
 	XYPOSITION Ascent(Font &font_) override;
 	XYPOSITION Descent(Font &font_) override;
@@ -913,89 +923,90 @@
 
 typedef VarBuffer<int, stackBufferLength> TextPositionsI;
 
-void SurfaceGDI::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions) {
+void SurfaceGDI::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
 	SetFont(font_);
 	const RECT rcw = RectFromPRectangle(rc);
 	const int x = static_cast<int>(rc.left);
 	const int yBaseInt = static_cast<int>(ybase);
 
 	if (unicodeMode) {
-		const TextWide tbuf(s, len, unicodeMode, codePage);
+		const TextWide tbuf(text, unicodeMode, codePage);
 		::ExtTextOutW(hdc, x, yBaseInt, fuOptions, &rcw, tbuf.buffer, tbuf.tlen, NULL);
 	} else {
-		::ExtTextOutA(hdc, x, yBaseInt, fuOptions, &rcw, s, len, NULL);
+		::ExtTextOutA(hdc, x, yBaseInt, fuOptions, &rcw, text.data(), static_cast<UINT>(text.length()), NULL);
 	}
 }
 
-void SurfaceGDI::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceGDI::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore, ColourDesired back) {
 	::SetTextColor(hdc, fore.AsLong());
 	::SetBkColor(hdc, back.AsLong());
-	DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE);
+	DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE);
 }
 
-void SurfaceGDI::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceGDI::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore, ColourDesired back) {
 	::SetTextColor(hdc, fore.AsLong());
 	::SetBkColor(hdc, back.AsLong());
-	DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED);
+	DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE | ETO_CLIPPED);
 }
 
-void SurfaceGDI::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceGDI::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore) {
 	// Avoid drawing spaces in transparent mode
-	for (int i=0; i<len; i++) {
-		if (s[i] != ' ') {
+	for (size_t i=0; i<text.length(); i++) {
+		if (text[i] != ' ') {
 			::SetTextColor(hdc, fore.AsLong());
 			::SetBkMode(hdc, TRANSPARENT);
-			DrawTextCommon(rc, font_, ybase, s, len, 0);
+			DrawTextCommon(rc, font_, ybase, text, 0);
 			::SetBkMode(hdc, OPAQUE);
 			return;
 		}
 	}
 }
 
-XYPOSITION SurfaceGDI::WidthText(Font &font_, const char *s, int len) {
+XYPOSITION SurfaceGDI::WidthText(Font &font_, std::string_view text) {
 	SetFont(font_);
 	SIZE sz={0,0};
 	if (!unicodeMode) {
-		::GetTextExtentPoint32A(hdc, s, std::min(len, maxLenText), &sz);
+		::GetTextExtentPoint32A(hdc, text.data(), std::min(static_cast<int>(text.length()), maxLenText), &sz);
 	} else {
-		const TextWide tbuf(s, len, unicodeMode, codePage);
+		const TextWide tbuf(text, unicodeMode, codePage);
 		::GetTextExtentPoint32W(hdc, tbuf.buffer, tbuf.tlen, &sz);
 	}
 	return static_cast<XYPOSITION>(sz.cx);
 }
 
-void SurfaceGDI::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) {
+void SurfaceGDI::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
 	// Zero positions to avoid random behaviour on failure.
-	std::fill(positions, positions + len, 0.0f);
+	std::fill(positions, positions + text.length(), 0.0f);
 	SetFont(font_);
 	SIZE sz={0,0};
 	int fit = 0;
 	int i = 0;
 	if (unicodeMode) {
-		const TextWide tbuf(s, len, unicodeMode, codePage);
+		const TextWide tbuf(text, unicodeMode, codePage);
 		TextPositionsI poses(tbuf.tlen);
 		if (!::GetTextExtentExPointW(hdc, tbuf.buffer, tbuf.tlen, maxWidthMeasure, &fit, poses.buffer, &sz)) {
 			// Failure
 			return;
 		}
 		// Map the widths given for UTF-16 characters back onto the UTF-8 input string
-		const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
+		const unsigned char *us = reinterpret_cast<const unsigned char *>(text.data());
 		for (int ui = 0; ui < fit; ui++) {
 			const unsigned char uch = us[i];
 			const unsigned int byteCount = UTF8BytesOfLead[uch];
 			if (byteCount == 4) {	// Non-BMP
 				ui++;
 			}
-			for (unsigned int bytePos=0; (bytePos<byteCount) && (i<len); bytePos++) {
+			for (size_t bytePos=0; (bytePos<byteCount) && (i<text.length()); bytePos++) {
 				positions[i++] = static_cast<XYPOSITION>(poses.buffer[ui]);
 			}
 		}
 	} else {
-		TextPositionsI poses(len);
-		if (!::GetTextExtentExPointA(hdc, s, len, maxWidthMeasure, &fit, poses.buffer, &sz)) {
+		TextPositionsI poses(text.length());
+		if (!::GetTextExtentExPointA(hdc, text.data(), static_cast<int>(text.length()), maxWidthMeasure,
+			&fit, poses.buffer, &sz)) {
 			// Eeek - a NULL DC or other foolishness could cause this.
 			return;
 		}
@@ -1006,7 +1017,7 @@
 	}
 	// If any positions not filled in then use the last position for them
 	const XYPOSITION lastPos = (fit > 0) ? positions[fit - 1] : 0.0f;
-	std::fill(positions+i, positions + len, lastPos);
+	std::fill(positions+i, positions + text.length(), lastPos);
 }
 
 XYPOSITION SurfaceGDI::WidthChar(Font &font_, char ch) {
@@ -1134,12 +1145,12 @@
 	void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override;
 	void Copy(PRectangle rc, Point from, Surface &surfaceSource) override;
 
-	void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions);
-	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override;
-	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override;
-	void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override;
-	XYPOSITION WidthText(Font &font_, const char *s, int len) override;
+	void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions);
+	void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) override;
+	void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) override;
+	void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) override;
+	XYPOSITION WidthText(Font &font_, std::string_view text) override;
 	XYPOSITION WidthChar(Font &font_, char ch) override;
 	XYPOSITION Ascent(Font &font_) override;
 	XYPOSITION Descent(Font &font_) override;
@@ -1540,11 +1551,11 @@
 	}
 }
 
-void SurfaceD2D::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions) {
+void SurfaceD2D::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, UINT fuOptions) {
 	SetFont(font_);
 
 	// Use Unicode calls
-	const TextWide tbuf(s, len, unicodeMode, codePageText);
+	const TextWide tbuf(text, unicodeMode, codePageText);
 	if (pRenderTarget && pTextFormat && pBrush) {
 		if (fuOptions & ETO_CLIPPED) {
 			D2D1_RECT_F rcClip = {rc.left, rc.top, rc.right, rc.bottom};
@@ -1567,42 +1578,42 @@
 	}
 }
 
-void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore, ColourDesired back) {
 	if (pRenderTarget) {
 		FillRectangle(rc, back);
 		D2DPenColour(fore);
-		DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE);
+		DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE);
 	}
 }
 
-void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore, ColourDesired back) {
 	if (pRenderTarget) {
 		FillRectangle(rc, back);
 		D2DPenColour(fore);
-		DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED);
+		DrawTextCommon(rc, font_, ybase, text, ETO_OPAQUE | ETO_CLIPPED);
 	}
 }
 
-void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
+void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text,
 	ColourDesired fore) {
 	// Avoid drawing spaces in transparent mode
-	for (int i=0; i<len; i++) {
-		if (s[i] != ' ') {
+	for (size_t i=0; i<text.length(); i++) {
+		if (text[i] != ' ') {
 			if (pRenderTarget) {
 				D2DPenColour(fore);
-				DrawTextCommon(rc, font_, ybase, s, len, 0);
+				DrawTextCommon(rc, font_, ybase, text, 0);
 			}
 			return;
 		}
 	}
 }
 
-XYPOSITION SurfaceD2D::WidthText(Font &font_, const char *s, int len) {
+XYPOSITION SurfaceD2D::WidthText(Font &font_, std::string_view text) {
 	FLOAT width = 1.0;
 	SetFont(font_);
-	const TextWide tbuf(s, len, unicodeMode, codePageText);
+	const TextWide tbuf(text, unicodeMode, codePageText);
 	if (pIDWriteFactory && pTextFormat) {
 		// Create a layout
 		IDWriteTextLayout *pTextLayout = 0;
@@ -1617,13 +1628,13 @@
 	return width;
 }
 
-void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) {
+void SurfaceD2D::MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) {
 	SetFont(font_);
 	if (!pIDWriteFactory || !pTextFormat) {
 		// SetFont failed or no access to DirectWrite so give up.
 		return;
 	}
-	const TextWide tbuf(s, len, unicodeMode, codePageText);
+	const TextWide tbuf(text, unicodeMode, codePageText);
 	TextPositions poses(tbuf.tlen);
 	// Initialize poses for safety.
 	std::fill(poses.buffer, poses.buffer + tbuf.tlen, 0.0f);
@@ -1654,7 +1665,7 @@
 	if (unicodeMode) {
 		// Map the widths given for UTF-16 characters back onto the UTF-8 input string
 		int ui=0;
-		const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
+		const unsigned char *us = reinterpret_cast<const unsigned char *>(text.data());
 		int i=0;
 		while (ui<tbuf.tlen) {
 			const unsigned char uch = us[i];
@@ -1662,7 +1673,7 @@
 			if (byteCount == 4) {	// Non-BMP
 				ui++;
 			}
-			for (unsigned int bytePos=0; (bytePos<byteCount) && (i<len); bytePos++) {
+			for (size_t bytePos=0; (bytePos<byteCount) && (i<text.length()); bytePos++) {
 				positions[i++] = poses.buffer[ui];
 			}
 			ui++;
@@ -1670,13 +1681,13 @@
 		XYPOSITION lastPos = 0.0f;
 		if (i > 0)
 			lastPos = positions[i-1];
-		while (i<len) {
+		while (i<text.length()) {
 			positions[i++] = lastPos;
 		}
 	} else if (codePageText == 0) {
 
 		// One char per position
-		PLATFORM_ASSERT(len == tbuf.tlen);
+		PLATFORM_ASSERT(text.length() == tbuf.tlen);
 		for (int kk=0; kk<tbuf.tlen; kk++) {
 			positions[kk] = poses.buffer[kk];
 		}
@@ -1685,9 +1696,9 @@
 
 		// May be one or two bytes per position
 		int ui = 0;
-		for (int i=0; i<len && ui<tbuf.tlen;) {
+		for (size_t i=0; i<text.length() && ui<tbuf.tlen;) {
 			positions[i] = poses.buffer[ui];
-			if (DBCSIsLeadByte(codePageText, s[i])) {
+			if (DBCSIsLeadByte(codePageText, text[i])) {
 				positions[i+1] = poses.buffer[ui];
 				i += 2;
 			} else {
