diff options
| author | Veronika Irvine <vmi@uvic.ca> | 2012-04-13 23:32:19 +0000 |
|---|---|---|
| committer | Veronika Irvine <vmi@uvic.ca> | 2012-04-13 23:32:19 +0000 |
| commit | cc51441858513ed4596063086aa2581d1051a495 (patch) | |
| tree | 07f6a29e527a3bb7ede37b73254a6bb73f4616b5 /src/libnrtype | |
| parent | 2geom fix (diff) | |
| download | inkscape-cc51441858513ed4596063086aa2581d1051a495.tar.gz inkscape-cc51441858513ed4596063086aa2581d1051a495.zip | |
support vertical text on path such that baseline is perpendiclar to the path and midline is centered on the path
Fixed bugs:
- https://launchpad.net/bugs/168862
(bzr r11241)
Diffstat (limited to 'src/libnrtype')
| -rw-r--r-- | src/libnrtype/Layout-TNG-OutIter.cpp | 16 | ||||
| -rw-r--r-- | src/libnrtype/Layout-TNG-Output.cpp | 43 |
2 files changed, 39 insertions, 20 deletions
diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 1d300b210..4e61c10a0 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -446,6 +446,8 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double } else { span = &_spans[_characters[it._char_index].in_span]; x = _chunks[span->in_chunk].left_x + span->x_start + _characters[it._char_index].x - _chunks[0].left_x; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) + x -= span->line_height.descent; if (it._char_index != 0) span = &_spans[_characters[it._char_index - 1].in_span]; } @@ -454,7 +456,7 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double if (x_on_path < 0.0) x_on_path = 0.0; int unused = 0; - // as far as I know these functions are const, they're just not marked as such + // as far as I know these functions are const, they're just not marked as such Path::cut_position *path_parameter_list = const_cast<Path*>(_path_fitted)->CurvilignToPosition(1, &x_on_path, unused); Path::cut_position path_parameter; if (path_parameter_list != NULL && path_parameter_list[0].piece >= 0) @@ -472,9 +474,15 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double point += x * tangent; if (x > path_length ) point += (x - path_length) * tangent; - rotation = atan2(tangent); - position[Geom::X] = point[Geom::X] - tangent[Geom::Y] * span->baseline_shift; - position[Geom::Y] = point[Geom::Y] + tangent[Geom::X] * span->baseline_shift; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + rotation = atan2(-tangent[Geom::X], tangent[Geom::Y]); + position[Geom::X] = point[Geom::Y] - tangent[Geom::X] * span->baseline_shift; + position[Geom::Y] = point[Geom::X] + tangent[Geom::Y] * span->baseline_shift; + } else { + rotation = atan2(tangent); + position[Geom::X] = point[Geom::X] - tangent[Geom::Y] * span->baseline_shift; + position[Geom::Y] = point[Geom::Y] + tangent[Geom::X] * span->baseline_shift; + } } else { // text is not on a path if (it._char_index >= _characters.size()) { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 07ed6062f..2830a8026 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -426,16 +426,21 @@ void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) Geom::Point tangent; const_cast<Path&>(path).PointAndTangentAt(point_otp[0].piece, point_otp[0].t, point, tangent); _empty_cursor_shape.position = point; - _empty_cursor_shape.rotation = atan2(tangent[Geom::Y], tangent[Geom::X]); + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + _empty_cursor_shape.rotation = atan2(-tangent[Geom::X], tangent[Geom::Y]); + } else { + _empty_cursor_shape.rotation = atan2(tangent[Geom::Y], tangent[Geom::X]); + } } } for (unsigned char_index = 0 ; char_index < _characters.size() ; ) { - int next_cluster_glyph_index; + unsigned current_cluster_glyph_index, next_cluster_glyph_index; unsigned next_cluster_char_index; - double character_advance; Span const &span = _characters[char_index].span(this); + current_cluster_glyph_index = _characters[char_index].in_glyph; + for (next_cluster_char_index = char_index + 1 ; next_cluster_char_index < _characters.size() ; next_cluster_char_index++) { if (_characters[next_cluster_char_index].in_glyph != -1 && _characters[next_cluster_char_index].char_attributes.is_cursor_position) break; @@ -443,17 +448,15 @@ void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) if (next_cluster_char_index == _characters.size()) { next_cluster_glyph_index = _glyphs.size(); - character_advance = 0.0; // arbitrary because we're not going to advance } else { next_cluster_glyph_index = _characters[next_cluster_char_index].in_glyph; - character_advance = (_glyphs[next_cluster_glyph_index].x + _glyphs[next_cluster_glyph_index].chunk(this).left_x) - - (_glyphs[_characters[char_index].in_glyph].x + span.chunk(this).left_x); } double start_offset = offset + span.x_start + _characters[char_index].x; double cluster_width = 0.0; - for (int glyph_index = _characters[char_index].in_glyph ; glyph_index < next_cluster_glyph_index ; glyph_index++) + for (int glyph_index = current_cluster_glyph_index ; glyph_index < next_cluster_glyph_index ; glyph_index++) cluster_width += _glyphs[glyph_index].width; + // TODO block progression? if (span.direction == RIGHT_TO_LEFT) start_offset -= cluster_width; double end_offset = start_offset + cluster_width; @@ -499,15 +502,23 @@ void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) } } - double rotation = atan2(tangent[1], tangent[0]); - for (int glyph_index = _characters[char_index].in_glyph ; glyph_index < next_cluster_glyph_index ; glyph_index++) { - double tangent_shift = -cluster_width * 0.5 + _glyphs[glyph_index].x - (_characters[char_index].x + span.x_start); - double normal_shift = _glyphs[glyph_index].y; - if (span.direction == RIGHT_TO_LEFT) - tangent_shift += cluster_width; - _glyphs[glyph_index].x = midpoint[0] - span.chunk(this).left_x + tangent[0] * tangent_shift - tangent[1] * normal_shift; - _glyphs[glyph_index].y = midpoint[1] - _lines.front().baseline_y + tangent[1] * tangent_shift + tangent[0] * normal_shift; - _glyphs[glyph_index].rotation += rotation; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + double rotation = atan2(-tangent[Geom::X], tangent[Geom::Y]); + for (int glyph_index = current_cluster_glyph_index; glyph_index < next_cluster_glyph_index ; glyph_index++) { + _glyphs[glyph_index].x = midpoint[Geom::Y] - tangent[Geom::X] * _glyphs[glyph_index].y - span.chunk(this).left_x; + _glyphs[glyph_index].y = midpoint[Geom::X] + tangent[Geom::Y] * _glyphs[glyph_index].y - _lines.front().baseline_y; + _glyphs[glyph_index].rotation += rotation; + } + } else { + double rotation = atan2(tangent[Geom::Y], tangent[Geom::X]); + for (int glyph_index = current_cluster_glyph_index; glyph_index < next_cluster_glyph_index ; glyph_index++) { + double tangent_shift = -cluster_width * 0.5 + _glyphs[glyph_index].x - (_characters[char_index].x + span.x_start); + if (span.direction == RIGHT_TO_LEFT) + tangent_shift += cluster_width; + _glyphs[glyph_index].x = midpoint[Geom::X] + tangent[Geom::X] * tangent_shift - tangent[Geom::Y] * _glyphs[glyph_index].y - span.chunk(this).left_x; + _glyphs[glyph_index].y = midpoint[Geom::Y] + tangent[Geom::Y] * tangent_shift + tangent[Geom::X] * _glyphs[glyph_index].y - _lines.front().baseline_y; + _glyphs[glyph_index].rotation += rotation; + } } _input_truncated = false; } else { // outside the bounds of the path: hide the glyphs |
