# HG changeset patch # User Vanya Sergeev # Date 1313444130 14400 # Node ID 6fc2c61660f2f606ba0488e564e435fd53777cb0 # Parent 58e46be87180bd759b09071150f68eb568e9ff54 Native multi-line text alignment. * txt-eng-ft.cc: Support horizontal and vertical alignment of multiline text. * txt-eng-ft.h: Ditto. diff --git a/src/txt-eng-ft.cc b/src/txt-eng-ft.cc --- a/src/txt-eng-ft.cc +++ b/src/txt-eng-ft.cc @@ -202,7 +202,8 @@ ft_render::ft_render (void) : text_processor (), face (0), bbox (1, 4, 0.0), - xoffset (0), yoffset (0), mode (MODE_BBOX), + xoffset (0), yoffset (0), multiline_halign (0), + multiline_align_xoffsets(), mode (MODE_BBOX), red (0), green (0), blue (0) { } @@ -270,10 +271,16 @@ { if (face) { + int line_index = 0; FT_UInt box_line_width = 0; std::string str = e.string_value (); FT_UInt glyph_index, previous = 0; + if (mode == MODE_BBOX) + multiline_align_xoffsets.clear(); + else if (mode == MODE_RENDER) + xoffset += multiline_align_xoffsets[line_index]; + for (size_t i = 0; i < str.length (); i++) { glyph_index = FT_Get_Char_Index (face, str[i]); @@ -297,7 +304,8 @@ } else { - xoffset = 0; + line_index++; + xoffset = multiline_align_xoffsets[line_index]; yoffset -= (face->size->metrics.height >> 6); } } @@ -360,6 +368,7 @@ } else { + multiline_align_xoffsets.push_back(box_line_width); // Reset the pixel width for this newline, so we don't // allocate a bounding box larger than the horizontal // width of the multi-line @@ -416,6 +425,24 @@ previous = glyph_index; } } + if (mode == MODE_BBOX) + { + /* Push last the width associated with the last line */ + multiline_align_xoffsets.push_back(box_line_width); + + for (unsigned int i = 0; i < multiline_align_xoffsets.size(); i++) + { + /* Center align */ + if (multiline_halign == 1) + multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i])/2; + /* Right align */ + else if (multiline_halign == 2) + multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i]); + /* Left align */ + else + multiline_align_xoffsets[i] = 0; + } + } } } @@ -556,6 +583,8 @@ { // FIXME: clip "rotation" between 0 and 360 int rot_mode = rotation_to_mode (rotation); + + multiline_halign = halign; text_element *elt = text_parser_none ().parse (txt); pixels_ = render (elt, box, rot_mode); diff --git a/src/txt-eng-ft.h b/src/txt-eng-ft.h --- a/src/txt-eng-ft.h +++ b/src/txt-eng-ft.h @@ -25,6 +25,8 @@ #if HAVE_FREETYPE +#include + #include #include FT_FREETYPE_H @@ -94,6 +96,8 @@ uint8NDArray pixels; int xoffset; int yoffset; + int multiline_halign; + std::vector multiline_align_xoffsets; int mode; uint8_t red, green, blue; };