From 153c93e8db5b893fc7fc3a5ff89879166b2f130f Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Fri, 29 Jan 2016 11:22:24 -0800 Subject: [PATCH] Introduce TextBox TextBox is a rect that understands TextDirection. --- sky/engine/bindings/dart_vm_entry_points.txt | 1 + sky/engine/core/core.gni | 2 + sky/engine/core/dart/text.dart | 85 +++++++++++++++++++- sky/engine/core/text/Paragraph.cpp | 12 +-- sky/engine/core/text/Paragraph.h | 3 +- sky/engine/core/text/TextBox.cpp | 32 ++++++++ sky/engine/core/text/TextBox.h | 33 ++++++++ 7 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 sky/engine/core/text/TextBox.cpp create mode 100644 sky/engine/core/text/TextBox.h diff --git a/sky/engine/bindings/dart_vm_entry_points.txt b/sky/engine/bindings/dart_vm_entry_points.txt index a96d4cf8e..3aef7d6dd 100644 --- a/sky/engine/bindings/dart_vm_entry_points.txt +++ b/sky/engine/bindings/dart_vm_entry_points.txt @@ -36,6 +36,7 @@ dart:ui,RRect,RRect. dart:ui,Scene,Scene. dart:ui,SceneBuilder,SceneBuilder. dart:ui,Shader,Shader. +dart:ui,TextBox,TextBox._ dart:ui,Tracing,Tracing. dart:ui,VelocityTracker,VelocityTracker. dart:ui,WheelEvent,WheelEvent. diff --git a/sky/engine/core/core.gni b/sky/engine/core/core.gni index 1ebbffe43..5b01d0187 100644 --- a/sky/engine/core/core.gni +++ b/sky/engine/core/core.gni @@ -214,6 +214,8 @@ sky_core_files = [ "text/Paragraph.h", "text/ParagraphBuilder.cpp", "text/ParagraphBuilder.h", + "text/TextBox.cpp", + "text/TextBox.h", "window/window.cc", "window/window.h", ] diff --git a/sky/engine/core/dart/text.dart b/sky/engine/core/dart/text.dart index 928a1b581..0354ada25 100644 --- a/sky/engine/core/dart/text.dart +++ b/sky/engine/core/dart/text.dart @@ -394,6 +394,89 @@ class ParagraphStyle { } } +/// A direction in which text flows. +enum TextDirection { + /// The text flows from right to left (e.g. Arabic, Hebrew). + rtl, + + /// The text flows from left to right (e.g., English, French). + ltr +} + +/// A rectangle enclosing a run of text. +class TextBox { + const TextBox.fromLTRBD( + this.left, + this.top, + this.right, + this.bottom, + this.direction + ); + + TextBox._( + this.left, + this.top, + this.right, + this.bottom, + int directionIndex + ) : direction = TextDirection.values[directionIndex]; + + /// The left edge of the text box, irrespective of direction. + final double left; + + /// The top edge of the text box. + final double top; + + /// The right edge of the text box, irrespective of direction. + final double right; + + /// The bottom edge of the text box. + final double bottom; + + /// The direction in which text inside this box flows. + final TextDirection direction; + + /// Returns a rect of the same size as this box. + Rect toRect() => new Rect.fromLTRB(left, top, right, bottom); + + /// The left edge of the box for ltr text; the right edge of the box for rtl text. + double get start { + switch (direction) { + case TextDirection.rtl: + return right; + case TextDirection.ltr: + return left; + } + } + + /// The right edge of the box for ltr text; the left edge of the box for rtl text. + double get end { + switch (direction) { + case TextDirection.rtl: + return left; + case TextDirection.ltr: + return right; + } + } + + bool operator ==(dynamic other) { + if (identical(this, other)) + return true; + if (other is! TextBox) + return false; + final TextBox typedOther = other; + return typedOther.left == left + && typedOther.top == top + && typedOther.right == right + && typedOther.bottom == bottom + && typedOther.direction == direction; + } + + int get hashCode => hashValues(left, top, right, bottom, direction); + + String toString() => "TextBox.fromLTRBD(${left.toStringAsFixed(1)}, ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)}, $direction)"; +} + abstract class Paragraph extends NativeFieldWrapperClass2 { double get minWidth native "Paragraph_minWidth"; void set minWidth(double value) native "Paragraph_setMinWidth"; @@ -413,7 +496,7 @@ abstract class Paragraph extends NativeFieldWrapperClass2 { void layout() native "Paragraph_layout"; void paint(Canvas canvas, Offset offset) native "Paragraph_paint"; - List getRectsForRange(int start, int end) native "Paragraph_getRectsForRange"; + List getBoxesForRange(int start, int end) native "Paragraph_getRectsForRange"; } class ParagraphBuilder extends NativeFieldWrapperClass2 { diff --git a/sky/engine/core/text/Paragraph.cpp b/sky/engine/core/text/Paragraph.cpp index dab5a6d91..915946c87 100644 --- a/sky/engine/core/text/Paragraph.cpp +++ b/sky/engine/core/text/Paragraph.cpp @@ -110,9 +110,9 @@ void Paragraph::paint(Canvas* canvas, const Offset& offset) skCanvas->translate(-offset.sk_size.width(), -offset.sk_size.height()); } -std::vector Paragraph::getRectsForRange(unsigned start, unsigned end) { +std::vector Paragraph::getRectsForRange(unsigned start, unsigned end) { if (end <= start || start == end) - return std::vector(); + return std::vector(); unsigned offset = 0; Vector rects; @@ -131,10 +131,12 @@ std::vector Paragraph::getRectsForRange(unsigned start, unsigned end) { break; } - std::vector result; + std::vector result; result.reserve(rects.size()); - for (auto& rect : rects) - result.emplace_back(rect); + for (auto& rect : rects) { + // TODO(abarth): Actually figure out the direction of the box. + result.emplace_back(rect, LTR); + } return result; } diff --git a/sky/engine/core/text/Paragraph.h b/sky/engine/core/text/Paragraph.h index f76943110..536f039af 100644 --- a/sky/engine/core/text/Paragraph.h +++ b/sky/engine/core/text/Paragraph.h @@ -11,6 +11,7 @@ #include "sky/engine/core/painting/Canvas.h" #include "sky/engine/core/painting/Offset.h" #include "sky/engine/core/rendering/RenderView.h" +#include "sky/engine/core/text/TextBox.h" namespace blink { class DartLibraryNatives; @@ -46,7 +47,7 @@ public: void layout(); void paint(Canvas* canvas, const Offset& offset); - std::vector getRectsForRange(unsigned start, unsigned end); + std::vector getRectsForRange(unsigned start, unsigned end); RenderView* renderView() const { return m_renderView.get(); } diff --git a/sky/engine/core/text/TextBox.cpp b/sky/engine/core/text/TextBox.cpp new file mode 100644 index 000000000..04cd2fd7e --- /dev/null +++ b/sky/engine/core/text/TextBox.cpp @@ -0,0 +1,32 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sky/engine/core/text/TextBox.h" + +#include "base/logging.h" +#include "sky/engine/core/script/dom_dart_state.h" +#include "sky/engine/tonic/dart_class_library.h" +#include "sky/engine/tonic/dart_error.h" + +namespace blink { + +Dart_Handle DartConverter::ToDart(const TextBox& val) { + if (val.is_null) + return Dart_Null(); + DartClassLibrary& class_library = DartState::Current()->class_library(); + Dart_Handle type = Dart_HandleFromPersistent( + class_library.GetClass("ui", "TextBox")); + DCHECK(!LogIfError(type)); + const int argc = 5; + Dart_Handle argv[argc] = { + blink::ToDart(val.sk_rect.fLeft), + blink::ToDart(val.sk_rect.fTop), + blink::ToDart(val.sk_rect.fRight), + blink::ToDart(val.sk_rect.fBottom), + blink::ToDart(static_cast(val.direction)), + }; + return Dart_New(type, blink::ToDart("_"), argc, argv); +} + +} // namespace blink diff --git a/sky/engine/core/text/TextBox.h b/sky/engine/core/text/TextBox.h new file mode 100644 index 000000000..98c4abe79 --- /dev/null +++ b/sky/engine/core/text/TextBox.h @@ -0,0 +1,33 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SKY_ENGINE_CORE_TEXT_TEXT_BOX_H_ +#define SKY_ENGINE_CORE_TEXT_TEXT_BOX_H_ + +#include "dart/runtime/include/dart_api.h" +#include "sky/engine/platform/text/TextDirection.h" +#include "sky/engine/tonic/dart_converter.h" +#include "third_party/skia/include/core/SkRect.h" + +namespace blink { + +class TextBox { + public: + TextBox() : is_null(true) { } + TextBox(SkRect r, TextDirection direction) + : sk_rect(std::move(r)), direction(direction), is_null(false) { } + + SkRect sk_rect; + TextDirection direction; + bool is_null; +}; + +template <> +struct DartConverter { + static Dart_Handle ToDart(const TextBox& val); +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_TEXT_TEXT_BOX_H_