experimental/editor: progress
- selection
- some state moved out of editor.
- Editor::getPosition() translates x,y mouse position into text
position
- General Editor::move() function for moving cursor
- Editor::insert() (does not yet handle newlines)
- Editor::remove() (does not yet delete across lines)
- new StringSlice class to replace SkString.
Change-Id: I1ca03247a745bc045e41619cd5a839c495dc405b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/211884
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/experimental/editor/stringslice.cpp b/experimental/editor/stringslice.cpp
new file mode 100644
index 0000000..5581ab9
--- /dev/null
+++ b/experimental/editor/stringslice.cpp
@@ -0,0 +1,74 @@
+// Copyright 2019 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+
+#include "stringslice.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+using namespace editor;
+
+void StringSlice::FreeWrapper::operator()(void* t) { std::free(t); }
+
+StringSlice::StringSlice(StringSlice&& that)
+ : fPtr(std::move(that.fPtr))
+ , fLength(that.fLength)
+ , fCapacity(that.fCapacity)
+{
+ that.fLength = 0;
+ that.fCapacity = 0;
+}
+
+StringSlice& StringSlice::operator=(StringSlice&& that) {
+ if (this != &that) {
+ this->~StringSlice();
+ new (this)StringSlice(std::move(that));
+ }
+ return *this;
+}
+
+void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
+ if (length) {
+ offset = std::min(fLength, offset);
+ this->reserve(fLength + length); // TODO: reserve extra???
+ char* s = fPtr.get();
+ assert(s);
+ if (offset != fLength) {
+ std::memmove(s + offset + length, s + offset, fLength - offset);
+ }
+ if (text) {
+ std::memcpy(s + offset, text, length);
+ } else {
+ std::memset(s + offset, 0, length);
+ }
+ fLength += length;
+ }
+}
+
+void StringSlice::remove(std::size_t offset, std::size_t length) {
+ if (length && offset < fLength) {
+ length = std::min(length, fLength - offset);
+ assert(length > 0);
+ assert(length + offset <= fLength);
+ if (length + offset < fLength) {
+ char* s = fPtr.get();
+ assert(s);
+ std::memmove(s + offset, s + offset + length, fLength - (length + offset));
+ }
+ fLength -= length;
+ }
+}
+
+void StringSlice::reserve(std::size_t length) {
+ if (length && length > fCapacity) {
+ fPtr.reset((char*)std::realloc(fPtr.release(), length));
+ fCapacity = length;
+ }
+}
+
+void StringSlice::shrink() {
+ fPtr.reset((char*)std::realloc(fPtr.release(), fLength));
+ fCapacity = fLength;
+}