From 06d46a19aef83cbe0f960f0dc73e7bdbd77f1166 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Mar 05 2020 12:34:50 +0000 Subject: freetype: floating alignment --- diff --git a/c++/freetype/src/freetypeview.cpp b/c++/freetype/src/freetypeview.cpp index 3717311..a21067b 100644 --- a/c++/freetype/src/freetypeview.cpp +++ b/c++/freetype/src/freetypeview.cpp @@ -28,8 +28,7 @@ FreeTypeView::FreeTypeView(): params.italic = false; params.size = 12; - params.hor_spacing = 2; - params.vert_spacing = 20; + params.spacing = Vector2(3, 2); params.hinting = false; params.antialiasing = true; @@ -47,9 +46,12 @@ FreeTypeView::FreeTypeView(): "sunt in culpa qui officia deserunt mollit anim id est laborum."; //params.text = "1\n2\n3\n"; - params.alignment = 1; + params.alignment = -1; params.justify = true; params.wrap_width = 600; + params.alignment_by_origin = true; + + params.origin = Vector2(0.25, 0.8); Glib::signal_timeout().connect( sigc::mem_fun(*this, &FreeTypeView::on_timeout), @@ -83,20 +85,26 @@ FreeTypeView::update_surface() { if (width <= 0 || height <= 0) return; - const Real hor_spacing = params.hor_spacing > real_precision ? params.hor_spacing : 1; + const Vector2 spacing( + params.spacing.x > real_precision ? params.spacing.x : 1, + params.spacing.y > real_precision ? params.spacing.y : 1 ); + const Vector2 origin( + clamp(params.origin.x, 0, 1), + clamp(params.origin.y, 0, 1) ); + Matrix matrix = params.matrix; Matrix2 glyph_matrix( matrix.row_x().vec2(), matrix.row_y().vec2() ); - matrix.row_x() *= hor_spacing; + matrix *= Matrix().scaling(spacing); if (fabs(glyph_matrix.det()) <= real_precision_sqr) return; const Real size = params.size; - const Real wrap_width = params.wrap_width/hor_spacing; + const Real wrap_width = params.wrap_width; // init PangoFontMap *font_map = lab_pango_font_map_new(params.hinting, params.antialiasing); @@ -120,24 +128,17 @@ FreeTypeView::update_surface() { params.alignment < 0 ? PANGO_ALIGN_LEFT : params.alignment > 0 ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_CENTER ); pango_layout_set_justify(layout, params.justify); - if (params.vert_spacing > real_precision) - pango_layout_set_spacing(layout, (int)round(params.vert_spacing*PANGO_SCALE)); pango_layout_set_text(layout, params.text.c_str(), (int)params.text.size()); // move origin PangoRectangle rect; pango_layout_get_extents(layout, nullptr, &rect); - const IntVector2 offset_to_origin_int( - params.origin.x < 0 ? 0 : - params.origin.x > 0 ? (rect.x + rect.width) : (rect.x + rect.width)/2, - params.origin.y < 0 ? 0 : - params.origin.y > 0 ? (rect.y + rect.height) : (rect.y + rect.height)/2 ); const Vector2 offset_to_origin( - offset_to_origin_int.x/Real(PANGO_SCALE), - offset_to_origin_int.y/Real(PANGO_SCALE) ); + (rect.x + rect.width)/Real(PANGO_SCALE) * origin.x, + (rect.y + rect.height)/Real(PANGO_SCALE) * origin.y ); matrix *= Matrix().translation(-offset_to_origin); - // reneder + // create renderer DataSurface surface(width, height); LabPangoRendererParams rp; rp.surface = &surface; @@ -147,7 +148,22 @@ FreeTypeView::update_surface() { rp.hinting = params.hinting; rp.antialiasing = params.antialiasing; PangoRenderer *renderer = lab_pango_renderer_new(&rp); - pango_renderer_draw_layout(renderer, layout, 0, 0); + + // render line by line + pango_renderer_activate(renderer); + PangoLayoutIter *iter = pango_layout_get_iter(layout); + do { + PangoRectangle line_rect; + pango_layout_iter_get_line_extents(iter, nullptr, &line_rect); + PangoLayoutLine *line = pango_layout_iter_get_line_readonly(iter); + int baseline = pango_layout_iter_get_baseline(iter); + int x = params.alignment_by_origin + ? (int)round((rect.x + rect.width - line_rect.width)*origin.x) + : line_rect.x; + pango_renderer_draw_layout_line(renderer, line, x, baseline); + } while(pango_layout_iter_next_line(iter)); + pango_layout_iter_free(iter); + pango_renderer_deactivate(renderer); // free pango g_object_unref(renderer); diff --git a/c++/freetype/src/freetypeview.h b/c++/freetype/src/freetypeview.h index bdc2c60..9caac6e 100644 --- a/c++/freetype/src/freetypeview.h +++ b/c++/freetype/src/freetypeview.h @@ -18,11 +18,11 @@ public: int alignment; bool justify; Real wrap_width; + bool alignment_by_origin; - Real hor_spacing; - Real vert_spacing; + Vector2 spacing; - IntVector2 origin; + Vector2 origin; Matrix matrix; Color color; @@ -37,8 +37,7 @@ public: alignment(), justify(), wrap_width(), - hor_spacing(), - vert_spacing() + alignment_by_origin() { } };