summaryrefslogtreecommitdiffstats
path: root/src/libnrtype
diff options
context:
space:
mode:
authorVeronika Irvine <vmi@uvic.ca>2012-04-13 23:32:19 +0000
committerVeronika Irvine <vmi@uvic.ca>2012-04-13 23:32:19 +0000
commitcc51441858513ed4596063086aa2581d1051a495 (patch)
tree07f6a29e527a3bb7ede37b73254a6bb73f4616b5 /src/libnrtype
parent2geom fix (diff)
downloadinkscape-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.cpp16
-rw-r--r--src/libnrtype/Layout-TNG-Output.cpp43
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