39 int best_char_index = -1;
40 double best_difference = DBL_MAX;
43 for ( ; char_index <
_characters.size() ; char_index++) {
44 if (
_characters[char_index].chunk(
this).in_line != line_index)
break;
46 if (!
_characters[char_index].char_attributes.is_cursor_position)
continue;
59 double this_difference = std::sqrt(delta_x*delta_x + delta_y*delta_y);
61 if (this_difference < best_difference) {
62 best_difference = this_difference;
63 best_char_index = char_index;
73 if (char_index == 0) {
74 delta_x =
_spans.front().x_end +
_chunks.front().left_x - local_x;
75 delta_y =
_spans.front().y_offset +
_spans.front().line(
this).baseline_y - local_y;
77 delta_x =
_characters[char_index - 1].span(
this).x_end +
_characters[char_index - 1].chunk(
this).left_x - local_x;
78 delta_y =
_characters[char_index - 1].span(
this).y_offset +
_characters[char_index - 1].line(
this).baseline_y - local_y;
81 double this_difference = std::sqrt(delta_x*delta_x + delta_y*delta_y);
83 if (this_difference < best_difference) {
84 best_char_index = char_index;
85 best_difference = this_difference;
90 if (best_char_index == -1) {
91 best_char_index = char_index;
98 return iterator(
this, best_char_index);
103 double chunk_width = 0.0;
107 for ( ; span_index <
_spans.size() &&
_spans[span_index].in_chunk < chunk_index ; span_index++){};
112 for ( ; span_index <
_spans.size() &&
_spans[span_index].in_chunk == chunk_index ; span_index++) {
113 chunk_width = std::max(chunk_width, (
double)std::max(
_spans[span_index].x_start,
_spans[span_index].x_end));
152 for (
const auto & _span :
_spans) {
153 double span_left, span_right;
154 if (_span.x_start < _span.x_end) {
155 span_left = _span.x_start;
156 span_right = _span.x_end;
158 span_left = _span.x_end;
159 span_right = _span.x_start;
162 double y_line = _span.line(
this).baseline_y + _span.baseline_shift + _span.y_offset;
163 if ( local_x >=
_chunks[_span.in_chunk].left_x + span_left
164 && local_x <=
_chunks[_span.in_chunk].left_x + span_right
165 && local_y >= y_line - _span.line_height.ascent
166 && local_y <= y_line + _span.line_height.descent) {
172 unsigned span_index = 0;
173 unsigned chunk_index;
174 int best_chunk_index = -1;
175 double best_y_range = DBL_MAX;
176 double best_x_range = DBL_MAX;
177 for (chunk_index = 0 ; chunk_index <
_chunks.size() ; chunk_index++) {
180 double chunk_width = 0.0;
181 for ( ; span_index <
_spans.size() &&
_spans[span_index].in_chunk == chunk_index ; span_index++) {
182 line_height.
max(
_spans[span_index].line_height);
183 chunk_width = std::max(chunk_width, (
double)std::max(
_spans[span_index].x_start,
_spans[span_index].x_end));
187 this_y_range =
_lines[
_chunks[chunk_index].in_line].baseline_y - line_height.
ascent - local_y;
189 this_y_range = local_y - (
_lines[
_chunks[chunk_index].in_line].baseline_y + line_height.
descent);
192 if (this_y_range <= best_y_range) {
193 if (this_y_range < best_y_range) best_x_range = DBL_MAX;
195 if (local_x <
_chunks[chunk_index].left_x)
196 this_x_range =
_chunks[chunk_index].left_x - local_y;
197 else if (local_x >
_chunks[chunk_index].left_x + chunk_width)
198 this_x_range = local_x - (
_chunks[chunk_index].left_x + chunk_width);
201 if (this_x_range < best_x_range) {
202 best_y_range = this_y_range;
203 best_x_range = this_x_range;
204 best_chunk_index = chunk_index;
210 if (best_chunk_index == -1)
return begin();
229 unsigned source_index;
231 for (source_index = 0 ; source_index <
_input_stream.size() ; source_index++)
298 std::swap(right_pt, left_pt);
306 return (left_pt + right_pt)/2;
312 return std::optional<Geom::Point>();
336 while (pos !=
end()) {
341 _baselines.emplace_back(start_anchor_pt, end_anchor_pt);
348 unsigned chunk_index;
356 chunk_index =
_chunks.size() - 1;
360 double x =
_chunks[chunk_index].left_x;
363 if (alignment ==
RIGHT) {
365 }
else if (alignment ==
CENTER) {
366 x += chunk_width * 0.5;
382 double cluster_half_width = 0.0;
383 for (
int glyph_index =
_characters[char_index].in_glyph ;
_glyphs.size() != glyph_index ; glyph_index++) {
384 if (
_glyphs[glyph_index].in_character != char_index)
break;
385 cluster_half_width +=
_glyphs[glyph_index].advance;
387 cluster_half_width *= 0.5;
389 double midpoint_offset =
_characters[char_index].span(
this).x_start +
_characters[char_index].x + cluster_half_width;
392 if (midpoint_offset >= 0.0 && midpoint_otp !=
nullptr && midpoint_otp[0].piece >= 0) {
397 const_cast<Path*
>(
_path_fitted)->PointAndTangentAt(midpoint_otp[0].piece, midpoint_otp[0].t, midpoint, tangent);
406 *rotation = atan2(tangent[1], tangent[0]);
408 g_free(midpoint_otp);
422 double baseline_y =
_characters[char_index].line(
this).baseline_y +
_characters[char_index].span(
this).baseline_shift;
424 double span_height =
_spans[
_characters[char_index].in_span].line_height.emSize();
426 top_left[
Geom::X] = baseline_y - span_height * 0.5;
428 bottom_right[
Geom::X] = baseline_y + span_height * 0.5;
438 *rotation =
_glyphs.back().rotation;
449 std::vector<Geom::Point> quads;
451 unsigned end_char_index;
460 for ( ; char_index < end_char_index ; ) {
466 unsigned span_index =
_characters[char_index].in_span;
471 top_left = box.
min();
472 bottom_right = box.
max();
475 double span_x =
_spans[span_index].x_start +
_spans[span_index].chunk(
this).left_x;
477 while (char_index < end_char_index &&
_characters[char_index].in_span == span_index)
484 double baseline_y =
_spans[span_index].line(
this).baseline_y +
_spans[span_index].baseline_shift;
485 double vertical_scale =
_glyphs.back().vertical_scale;
486 double offset_y =
_spans[span_index].y_offset;
489 double span_height = vertical_scale *
_spans[span_index].line_height.emSize();
491 top_left[
Geom::X] = offset_y + baseline_y - span_height * 0.5;
493 bottom_right[
Geom::X] = offset_y + baseline_y + span_height * 0.5;
495 top_left[
Geom::Y] = offset_y + baseline_y - vertical_scale *
_spans[span_index].line_height.ascent;
496 bottom_right[
Geom::Y] = offset_y + baseline_y + vertical_scale *
_spans[span_index].line_height.descent;
506 for(
int i = 0; i < 4; i ++)
507 quads.push_back(char_box.
corner(i) * total_transform);
539 double x_on_path = x;
540 if (x_on_path < 0.0) x_on_path = 0.0;
546 if (path_parameter_list !=
nullptr && path_parameter_list[0].piece >= 0)
547 path_parameter = path_parameter_list[0];
550 path_parameter.
t = 0.9999;
552 g_free(path_parameter_list);
556 const_cast<Path*
>(
_path_fitted)->PointAndTangentAt(path_parameter.
piece, path_parameter.
t, point, tangent);
558 point += x * tangent;
559 if (x > path_length )
560 point += (x - path_length) * tangent;
566 rotation = atan2(tangent);
574 bool last_char_is_newline =
false;
582 last_char_is_newline =
true;
601 if (last_char_is_newline) {
603 double vertical_scale =
_glyphs.empty() ? 1.0 :
_glyphs.back().vertical_scale;
614 double vertical_scale =
_glyphs.empty() ? 1.0 :
_glyphs.back().vertical_scale;
619 rotation += M_PI / 2;
621 position[
Geom::X] -= vertical_scale * sin(rotation) *
height * 0.5;
622 position[
Geom::Y] += vertical_scale * cos(rotation) *
height * 0.5;
625 double caret_slope_run = 0.0, caret_slope_rise = 1.0;
627 span->
font->FontSlope(caret_slope_run, caret_slope_rise);
629 double caret_slope = atan2(caret_slope_run, caret_slope_rise);
631 rotation += caret_slope;
651 *source = stream_item->
source;
657 Glib::ustring::iterator text_iter =
const_cast<Glib::ustring *
>(text_source->
text)->
begin();
660 unsigned original_input_source_index =
_spans[
_characters[char_index].in_span].in_input_stream_item;
663 while (char_index &&
_spans[
_characters[char_index - 1].in_span].in_input_stream_item == original_input_source_index) {
669 *text_iterator = text_iter;
690 if (!
_characters[char_index].char_attributes.is_char_break)
697 unsigned prev_cluster_char_index;
698 for (prev_cluster_char_index = char_index - 1 ;
699 prev_cluster_char_index != 0 && !
_characters[prev_cluster_char_index].char_attributes.is_cursor_position ;
700 prev_cluster_char_index--){};
705 double glyphs_width = 0.0;
706 if (
_characters[prev_cluster_char_index].in_glyph != -1)
707 for (
int glyph_index =
_characters[prev_cluster_char_index].in_glyph ; glyph_index <
_characters[char_index].in_glyph ; glyph_index++)
708 glyphs_width +=
_glyphs[glyph_index].advance;
710 glyphs_width = -glyphs_width;
720 if (
_characters[char_index].char_attributes.is_white)
722 if (
_characters[char_index].char_attributes.is_cursor_position)
727 if (fabs(dx) > 0.0001) {
732 double dy =
_characters[char_index].span(
this).baseline_shift -
_characters[prev_cluster_char_index].span(
this).baseline_shift;
733 if (fabs(dy) > 0.0001) {
744#define PREV_START_OF_ITEM(this_func) \
746 _cursor_moving_vertically = false; \
747 if (_char_index == 0) return false; \
749 return this_func(); \
753#define THIS_START_OF_ITEM(item_getter) \
755 _cursor_moving_vertically = false; \
756 if (_char_index == 0) return false; \
757 unsigned original_item; \
758 if (_char_index >= _parent_layout->_characters.size()) { \
759 _char_index = _parent_layout->_characters.size() - 1; \
760 original_item = item_getter; \
762 original_item = item_getter; \
765 while (item_getter == original_item) { \
766 if (_char_index == 0) { \
767 _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \
773 _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \
778#define NEXT_START_OF_ITEM(item_getter) \
780 _cursor_moving_vertically = false; \
781 if (_char_index >= _parent_layout->_characters.size()) return false; \
782 unsigned original_item = item_getter; \
785 if (_char_index == _parent_layout->_characters.size()) { \
786 _glyph_index = _parent_layout->_glyphs.size(); \
789 if (item_getter != original_item) break; \
791 _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \
797 PREV_START_OF_ITEM(thisStartOfSpan);
799bool Layout::iterator::thisStartOfSpan()
800 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].in_span);
802bool Layout::iterator::nextStartOfSpan()
803 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].in_span);
806bool Layout::iterator::prevStartOfChunk()
807 PREV_START_OF_ITEM(thisStartOfChunk);
809bool Layout::iterator::thisStartOfChunk()
810 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_chunk);
812bool Layout::iterator::nextStartOfChunk()
813 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_chunk);
816bool Layout::iterator::prevStartOfLine()
817 PREV_START_OF_ITEM(thisStartOfLine);
819bool Layout::iterator::thisStartOfLine()
820 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].chunk(_parent_layout).in_line);
822bool Layout::iterator::nextStartOfLine()
823 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].chunk(_parent_layout).in_line);
826bool Layout::iterator::prevStartOfShape()
827 PREV_START_OF_ITEM(thisStartOfShape);
829bool Layout::iterator::thisStartOfShape()
830 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_shape);
832bool Layout::iterator::nextStartOfShape()
833 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_shape);
836bool Layout::iterator::prevStartOfParagraph()
837 PREV_START_OF_ITEM(thisStartOfParagraph);
839bool Layout::iterator::thisStartOfParagraph()
840 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_paragraph);
842bool Layout::iterator::nextStartOfParagraph()
843 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_paragraph);
846bool Layout::iterator::prevStartOfSource()
847 PREV_START_OF_ITEM(thisStartOfSource);
849bool Layout::iterator::thisStartOfSource()
850 THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_input_stream_item);
852bool Layout::iterator::nextStartOfSource()
853 NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_input_stream_item);
858 if (_char_index >= _parent_layout->_characters.size())
return false;
859 if (nextStartOfLine())
861 if (_char_index && _parent_layout->_characters[_char_index - 1].char_attributes.is_white)
862 return prevCursorPosition();
865 if (_char_index && _parent_layout->_characters[_char_index - 1].chunk(_parent_layout).in_line != _parent_layout->_lines.size() - 1)
866 return prevCursorPosition();
881 if (!_cursor_moving_vertically)
883 if (_char_index >= _parent_layout->_characters.size())
885 unsigned line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line;
886 if (line_index == _parent_layout->_lines.size() - 1)
889 n =
MIN (n,
static_cast<int>(_parent_layout->_lines.size() - 1 - line_index));
890 if (_parent_layout->_lines[line_index + n].in_shape != _parent_layout->_lines[line_index].in_shape) {
892 _x_coordinate += _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index + n)].in_chunk].left_x
893 - _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index)].in_chunk].left_x;
895 _char_index = _parent_layout->_cursorXOnLineToIterator(line_index + n, _x_coordinate)._char_index;
896 if (_char_index >= _parent_layout->_characters.size())
897 _glyph_index = _parent_layout->_glyphs.size();
899 _glyph_index = _parent_layout->_characters[_char_index].in_glyph;
905 if (!_cursor_moving_vertically)
908 if (_char_index >= _parent_layout->_characters.size())
909 line_index = _parent_layout->_lines.size() - 1;
911 line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line;
915 n =
MIN (n,
static_cast<int>(line_index));
916 if (_parent_layout->_lines[line_index - n].in_shape != _parent_layout->_lines[line_index].in_shape) {
918 _x_coordinate += _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index - n)].in_chunk].left_x
919 - _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index)].in_chunk].left_x;
921 _char_index = _parent_layout->_cursorXOnLineToIterator(line_index - n, _x_coordinate)._char_index;
922 _glyph_index = _parent_layout->_characters[_char_index].in_glyph;
926#define NEXT_WITH_ATTRIBUTE_SET(attr) \
928 _cursor_moving_vertically = false; \
930 if (_char_index + 1 >= _parent_layout->_characters.size()) { \
931 _char_index = _parent_layout->_characters.size(); \
932 _glyph_index = _parent_layout->_glyphs.size(); \
936 if (_parent_layout->_characters[_char_index].char_attributes.attr) break; \
938 _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \
943#define PREV_WITH_ATTRIBUTE_SET(attr) \
945 _cursor_moving_vertically = false; \
947 if (_char_index == 0) { \
952 if (_parent_layout->_characters[_char_index].char_attributes.attr) break; \
954 _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \
960 NEXT_WITH_ATTRIBUTE_SET(is_cursor_position);
963 PREV_WITH_ATTRIBUTE_SET(is_cursor_position);
966 NEXT_WITH_ATTRIBUTE_SET(is_word_start);
969 PREV_WITH_ATTRIBUTE_SET(is_word_start);
972 NEXT_WITH_ATTRIBUTE_SET(is_word_end);
975 PREV_WITH_ATTRIBUTE_SET(is_word_end);
978 NEXT_WITH_ATTRIBUTE_SET(is_sentence_start);
981 PREV_WITH_ATTRIBUTE_SET(is_sentence_start);
984 NEXT_WITH_ATTRIBUTE_SET(is_sentence_end);
987 PREV_WITH_ATTRIBUTE_SET(is_sentence_end);
993 if (_parent_layout->_characters.empty())
return false;
994 unsigned old_span_index;
996 if (_char_index >= _parent_layout->_characters.size())
997 old_span_index = _parent_layout->_spans.size() - 1;
999 old_span_index = _parent_layout->_characters[_char_index].in_span;
1000 old_span_direction = _parent_layout->_spans[old_span_index].direction;
1001 Direction para_direction = _parent_layout->_spans[old_span_index].paragraph(_parent_layout).base_direction;
1004 unsigned old_char_index = _char_index;
1005 if (old_span_direction != para_direction
1006 && ((_char_index == 0 && direction == para_direction)
1007 || (_char_index >= _parent_layout->_characters.size() && direction != para_direction))) {
1009 scan_direction = direction == para_direction ? +1 : -1;
1011 if (direction == old_span_direction) {
1012 if (!nextCursorPosition())
return false;
1014 if (!prevCursorPosition())
return false;
1017 unsigned new_span_index = _parent_layout->_characters[_char_index].in_span;
1018 if (new_span_index == old_span_index)
return true;
1019 if (old_span_direction != _parent_layout->_spans[new_span_index].direction) {
1021 scan_direction = direction == para_direction ? +1 : -1;
1022 }
else if (_parent_layout->_spans[old_span_index].in_chunk != _parent_layout->_spans[new_span_index].in_chunk) {
1024 if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph != _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph)
1026 if (old_span_direction == para_direction)
1028 scan_direction = direction == para_direction ? +1 : -1;
1033 unsigned new_span_index = old_span_index;
1035 if (scan_direction > 0) {
1036 if (new_span_index == _parent_layout->_spans.size() - 1) {
1037 if (_parent_layout->_spans[new_span_index].direction == old_span_direction) {
1038 _char_index = old_char_index;
1045 if (new_span_index == 0) {
1046 if (_parent_layout->_spans[new_span_index].direction == old_span_direction) {
1047 _char_index = old_char_index;
1054 if (_parent_layout->_spans[new_span_index].direction == para_direction) {
1055 if (para_direction == old_span_direction)
1056 new_span_index -= scan_direction;
1059 if (_parent_layout->_spans[new_span_index].in_chunk != _parent_layout->_spans[old_span_index].in_chunk) {
1060 if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph == _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph
1061 && para_direction == old_span_direction)
1062 new_span_index -= scan_direction;
1068 if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph != _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph) {
1069 if (new_span_index > old_span_index)
1070 _char_index = _parent_layout->_spanToCharacter(new_span_index);
1072 _char_index = _parent_layout->_spanToCharacter(new_span_index + 1) - 1;
1074 if (_parent_layout->_spans[new_span_index].direction != direction) {
1075 if (new_span_index >= _parent_layout->_spans.size() - 1)
1076 _char_index = _parent_layout->_characters.size();
1078 _char_index = _parent_layout->_spanToCharacter(new_span_index + 1) - 1;
1080 _char_index = _parent_layout->_spanToCharacter(new_span_index);
1082 if (_char_index >= _parent_layout->_characters.size()) {
1083 _glyph_index = _parent_layout->_glyphs.size();
1086 _glyph_index = _parent_layout->_characters[_char_index].in_glyph;
1087 return _char_index != 0;
1093 while ((r = _cursorLeftOrRightLocalX(direction))
1094 && !_parent_layout->_characters[_char_index].char_attributes.is_word_start){};
1100 Direction block_progression = _parent_layout->_blockProgression();
1102 return prevLineCursor(n);
1104 return nextLineCursor(n);
1111 Direction block_progression = _parent_layout->_blockProgression();
1113 return nextLineCursor(n);
1115 return prevLineCursor(n);
1122 Direction block_progression = _parent_layout->_blockProgression();
1124 return prevLineCursor();
1126 return nextLineCursor();
1133 Direction block_progression = _parent_layout->_blockProgression();
1135 return nextLineCursor();
1137 return prevLineCursor();
1144 Direction block_progression = _parent_layout->_blockProgression();
1146 return prevStartOfParagraph();
1148 return nextStartOfParagraph();
1155 Direction block_progression = _parent_layout->_blockProgression();
1157 return nextStartOfParagraph();
1159 return prevStartOfParagraph();
1166 Direction block_progression = _parent_layout->_blockProgression();
1168 return prevStartOfParagraph();
1170 return nextStartOfParagraph();
1177 Direction block_progression = _parent_layout->_blockProgression();
1179 return nextStartOfParagraph();
1181 return prevStartOfParagraph();
TODO: insert short description here.
3x3 matrix representing an affine transformation.
bool contains(GenericRect< C > const &r) const
Check whether the rectangle includes all points in the given rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
CPoint dimensions() const
Get rectangle's width and height as a point.
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
CPoint max() const
Get the corner of the rectangle with largest coordinate values.
Axis-aligned rectangle that can be empty.
Sequence of contiguous curves, aka spline.
void clear()
Remove all curves from the path.
void appendNew(Args &&... args)
Append a new curve to the path.
void start(Point const &p)
Two-dimensional point that doubles as a vector.
constexpr Coord x() const noexcept
constexpr Point cw() const
Return a point like this point but rotated +90 degrees.
Axis aligned, non-empty rectangle.
Rotation around the origin.
Keep track of font metrics.
void max(FontMetrics const &other)
Save the larger values of ascent and descent between this and other.
virtual InputStreamItemType Type() const =0
Represents a text item in the input stream.
Glib::ustring const * text
Holds a position within the glyph output of Layout.
bool cursorLeftWithControl()
bool prevLineCursor(int n=1)
bool _cursor_moving_vertically
index into Layout::character
bool nextCursorPosition()
bool nextLineCursor(int n=1)
bool cursorDownWithControl()
unsigned _char_index
index into Layout::glyphs, or -1
bool cursorRightWithControl()
Layout const * _parent_layout
bool cursorUpWithControl()
double _x_coordinate
for cursor up/down movement we must maintain the x position where we started so the cursor doesn't 'd...
bool _cursorLeftOrRightLocalXByWord(Direction direction)
moves forward or backwards by until the next character with is_word_start according to the directiona...
Generates the layout for either wrapped or non-wrapped text and stores the result.
iterator getLetterAt(double x, double y) const
Returns an iterator pointing to the letter whose bounding box contains the given coordinates.
void transform(Geom::Affine const &transform)
Apply the given transform to all the output presently stored in this object.
std::vector< Geom::Point > createSelectionShape(iterator const &it_start, iterator const &it_end, Geom::Affine const &transform) const
Basically uses characterBoundingBox() on all the characters from start to end and returns the union o...
void simulateLayoutUsingKerning(iterator const &from, iterator const &to, OptionalTextTagAttrs *result) const
Returns kerning information which could cause the current output to be exactly reproduced if the lett...
std::vector< Line > _lines
void queryCursorShape(iterator const &it, Geom::Point &position, double &height, double &rotation) const
Gets the ideal cursor shape for a given iterator.
Alignment
For expressing paragraph alignment.
double getTextLengthMultiplierDue() const
Get the actual scale multiplier if it's due with the current values of above stuff,...
std::vector< Glyph > _glyphs
iterator sourceToIterator(SPObject *source) const
Returns an iterator pointing to the first character in the output which was created from the given so...
bool isHidden(iterator const &it) const
Returns true if the text at it is hidden (i.e.
unsigned _lineToSpan(unsigned line_index) const
Geom::Path baseline() const
std::vector< Chunk > _chunks
Geom::Point characterAnchorPoint(iterator const &it) const
For latin text, the left side of the character, on the baseline.
iterator _cursorXOnLineToIterator(unsigned line_index, double local_x, double local_y=0) const
given an x and y coordinate and a line number, returns an iterator pointing to the closest cursor pos...
std::vector< Geom::LineSegment > _baselines
Direction _blockProgression() const
The overall block-progression of the whole flow.
struct Inkscape::Text::Layout::CursorShape _empty_cursor_shape
std::optional< Geom::Point > baselineAnchorPoint() const
For left aligned text, the leftmost end of the baseline For rightmost text, the rightmost....
void _calculateBaselines()
unsigned _sourceToCharacter(unsigned source_index) const
Geom::Point chunkAnchorPoint(iterator const &it) const
This is that value to apply to the x,y attributes of tspan role=line elements, and hence it takes ali...
std::vector< Paragraph > _paragraphs
static bool _directions_are_orthogonal(Direction d1, Direction d2)
so that LEFT_TO_RIGHT == RIGHT_TO_LEFT but != TOP_TO_BOTTOM
iterator end() const
Returns an iterator pointing just past the end of the last glyph, which is also just past the end of ...
Geom::Rect characterBoundingBox(iterator const &it, double *rotation=nullptr) const
Returns the box extents (not ink extents) of the given character.
void getSourceOfCharacter(iterator const &it, SPObject **source, Glib::ustring::iterator *text_iterator=nullptr) const
Discovers where the character pointed to by it came from, by retrieving the object that was passed to...
Alignment paragraphAlignment(iterator const &it) const
Returns the actual alignment used for the paragraph containing the character pointed to by it.
double getTextLengthIncrementDue() const
Get the actual spacing increment if it's due with the current values of above stuff,...
std::vector< InputStreamItem * > _input_stream
This is our internal storage for all the stuff passed to the appendText() and appendControlCode() fun...
unsigned _lineToCharacter(unsigned line_index) const
double _getChunkWidth(unsigned chunk_index) const
calculates the width of a chunk, which is the largest x coordinate (start or end) of the spans contai...
std::vector< Character > _characters
Geom::OptRect glyphBoundingBox(iterator const &it, double *rotation) const
Returns the bounding box of the given glyph, and its rotation.
Direction
Used to specify any particular text direction required.
Path const * _path_fitted
as passed to fitToPathAlign()
iterator getNearestCursorPositionTo(double x, double y) const
Returns an iterator pointing to the cursor position for a mouse click at the given coordinates.
iterator begin() const
Returns an iterator pointing at the first glyph of the flowed output.
std::vector< Span > _spans
Path and its polyline approximation.
std::vector< PathDescr * > descr_cmd
SPObject is an abstract base class of all of the document nodes at the SVG document level.
T< SPAttr::LETTER_SPACING, SPILengthOrNormal > letter_spacing
letter spacing (css2 16.4)
T< SPAttr::WORD_SPACING, SPILengthOrNormal > word_spacing
word spacing (also css2 16.4)
The data describing a single loaded font.
Helper class to stream background task notifications as a series of messages.
The optional attributes which can be applied to a SVG text or related tag.
float y_offset
relative to the start of the chunk
std::shared_ptr< FontInstance > font
float x_end
relative to the start of the chunk
Line const & line(Layout const *l) const
SPStyle - a style object for SPItem objects.
std::vector< Texture > unused