blob: 2618c3f08406a388a369f46d4597847244330fc7 [file] [log] [blame]
// Copyright 2013 The Flutter 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 "flutter/lib/ui/text/paragraph.h"
#include "flutter/common/settings.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/task_runner.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/dart_binding_macros.h"
#include "third_party/tonic/dart_library_natives.h"
using tonic::ToDart;
namespace flutter {
IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
#define FOR_EACH_BINDING(V) \
V(Paragraph, width) \
V(Paragraph, height) \
V(Paragraph, longestLine) \
V(Paragraph, minIntrinsicWidth) \
V(Paragraph, maxIntrinsicWidth) \
V(Paragraph, alphabeticBaseline) \
V(Paragraph, ideographicBaseline) \
V(Paragraph, didExceedMaxLines) \
V(Paragraph, layout) \
V(Paragraph, paint) \
V(Paragraph, getWordBoundary) \
V(Paragraph, getLineBoundary) \
V(Paragraph, getRectsForRange) \
V(Paragraph, getRectsForPlaceholders) \
V(Paragraph, getPositionForOffset) \
V(Paragraph, computeLineMetrics)
DART_BIND_ALL(Paragraph, FOR_EACH_BINDING)
Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraph(std::move(paragraph)) {}
Paragraph::~Paragraph() = default;
size_t Paragraph::GetAllocationSize() {
// We don't have an accurate accounting of the paragraph's memory consumption,
// so return a fixed size to indicate that its impact is more than the size
// of the Paragraph class.
return 2000;
}
double Paragraph::width() {
return m_paragraph->GetMaxWidth();
}
double Paragraph::height() {
return m_paragraph->GetHeight();
}
double Paragraph::longestLine() {
return m_paragraph->GetLongestLine();
}
double Paragraph::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
double Paragraph::maxIntrinsicWidth() {
return m_paragraph->GetMaxIntrinsicWidth();
}
double Paragraph::alphabeticBaseline() {
return m_paragraph->GetAlphabeticBaseline();
}
double Paragraph::ideographicBaseline() {
return m_paragraph->GetIdeographicBaseline();
}
bool Paragraph::didExceedMaxLines() {
return m_paragraph->DidExceedMaxLines();
}
void Paragraph::layout(double width) {
m_paragraph->Layout(width);
}
void Paragraph::paint(Canvas* canvas, double x, double y) {
SkCanvas* sk_canvas = canvas->canvas();
if (!sk_canvas)
return;
m_paragraph->Paint(sk_canvas, x, y);
}
std::vector<TextBox> Paragraph::getRectsForRange(unsigned start,
unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle) {
std::vector<TextBox> result;
std::vector<txt::Paragraph::TextBox> boxes = m_paragraph->GetRectsForRange(
start, end, static_cast<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
for (const txt::Paragraph::TextBox& box : boxes) {
result.emplace_back(box.rect, static_cast<TextDirection>(box.direction));
}
return result;
}
std::vector<TextBox> Paragraph::getRectsForPlaceholders() {
std::vector<TextBox> result;
std::vector<txt::Paragraph::TextBox> boxes =
m_paragraph->GetRectsForPlaceholders();
for (const txt::Paragraph::TextBox& box : boxes) {
result.emplace_back(box.rect, static_cast<TextDirection>(box.direction));
}
return result;
}
Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) {
Dart_Handle result = Dart_NewListOf(Dart_CoreType_Int, 2);
txt::Paragraph::PositionWithAffinity pos =
m_paragraph->GetGlyphPositionAtCoordinate(dx, dy);
Dart_ListSetAt(result, 0, ToDart(pos.position));
Dart_ListSetAt(result, 1, ToDart(static_cast<int>(pos.affinity)));
return result;
}
Dart_Handle Paragraph::getWordBoundary(unsigned offset) {
txt::Paragraph::Range<size_t> point = m_paragraph->GetWordBoundary(offset);
Dart_Handle result = Dart_NewListOf(Dart_CoreType_Int, 2);
Dart_ListSetAt(result, 0, ToDart(point.start));
Dart_ListSetAt(result, 1, ToDart(point.end));
return result;
}
Dart_Handle Paragraph::getLineBoundary(unsigned offset) {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
int line_start = -1;
int line_end = -1;
for (txt::LineMetrics& line : metrics) {
if (offset >= line.start_index && offset <= line.end_index) {
line_start = line.start_index;
line_end = line.end_index;
break;
}
}
Dart_Handle result = Dart_NewListOf(Dart_CoreType_Int, 2);
Dart_ListSetAt(result, 0, ToDart(line_start));
Dart_ListSetAt(result, 1, ToDart(line_end));
return result;
}
std::vector<LineMetrics> Paragraph::computeLineMetrics() {
std::vector<LineMetrics> result;
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
for (txt::LineMetrics& line : metrics) {
result.emplace_back(&line.hard_break, &line.ascent, &line.descent,
&line.unscaled_ascent, &line.height, &line.width,
&line.left, &line.baseline, &line.line_number);
}
return result;
}
} // namespace flutter