|
|
b8976b |
|
|
|
b8976b |
#include <algorithm></algorithm>
|
|
|
b8976b |
#include <iostream></iostream>
|
|
|
b8976b |
|
|
|
b8976b |
#include <glibmm.h></glibmm.h>
|
|
|
b8976b |
|
|
|
71e4f2 |
#include "labpangorenderer.h"
|
|
|
b8976b |
|
|
|
b8976b |
#include "surface.h"
|
|
|
b8976b |
#include "log.h"
|
|
|
b8976b |
|
|
|
b8976b |
#include "freetypeview.h"
|
|
|
b8976b |
|
|
|
b8976b |
|
|
|
f77c6c |
FreeTypeView::FreeTypeView():
|
|
|
f77c6c |
p0(new View::Point( Vector2(0, 0))),
|
|
|
f77c6c |
px(new View::Point( Vector2(1, 0))),
|
|
|
f77c6c |
py(new View::Point( Vector2(0, 1)))
|
|
|
f77c6c |
{
|
|
|
f77c6c |
prev_p0 = p0->position;
|
|
|
f77c6c |
transform *= Matrix().scaling(Vector2(50, 50));
|
|
|
f77c6c |
points.push_back(p0);
|
|
|
f77c6c |
points.push_back(px);
|
|
|
f77c6c |
points.push_back(py);
|
|
|
f77c6c |
|
|
|
b8976b |
params.family = "Ani";
|
|
|
b8976b |
params.bold = false;
|
|
|
b8976b |
params.italic = false;
|
|
|
b8976b |
params.size = 12;
|
|
|
b8976b |
|
|
|
f77c6c |
params.hor_spacing = 2;
|
|
|
f77c6c |
params.vert_spacing = 20;
|
|
|
f77c6c |
|
|
|
f77c6c |
params.hinting = false;
|
|
|
f77c6c |
params.antialiasing = true;
|
|
|
f77c6c |
|
|
|
71e4f2 |
params.matrix = Matrix().translation(Vector2(15.5, 18.4));
|
|
|
b8976b |
params.color = Color(1, 1, 0, 1);
|
|
|
b8976b |
|
|
|
f77c6c |
params.text =
|
|
|
f77c6c |
"Lorem ipsum dolor sit amet, consectetur adipisici elit,"
|
|
|
f77c6c |
"sed eiusmod tempor incidunt ut labore et dolore magna aliqua."
|
|
|
f77c6c |
"Ut enim ad minim veniam, quis nostrud exercitation ullamco "
|
|
|
f77c6c |
"laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure"
|
|
|
f77c6c |
"reprehenderit in voluptate velit esse cillum dolore eu fugiat "
|
|
|
f77c6c |
"nulla pariatur. Excepteur sint obcaecat cupiditat non proident, "
|
|
|
f77c6c |
"sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
|
|
f77c6c |
//params.text = "1\n2\n3\n";
|
|
|
f77c6c |
|
|
|
f77c6c |
params.alignment = 1;
|
|
|
f77c6c |
params.justify = true;
|
|
|
f77c6c |
params.wrap_width = 600;
|
|
|
b8976b |
|
|
|
b8976b |
Glib::signal_timeout().connect(
|
|
|
b8976b |
sigc::mem_fun(*this, &FreeTypeView::on_timeout),
|
|
|
f77c6c |
50,
|
|
|
b8976b |
Glib::PRIORITY_DEFAULT_IDLE );
|
|
|
b8976b |
}
|
|
|
b8976b |
|
|
|
b8976b |
FreeTypeView::~FreeTypeView()
|
|
|
b8976b |
{ }
|
|
|
b8976b |
|
|
|
b8976b |
bool
|
|
|
b8976b |
FreeTypeView::on_timeout() {
|
|
|
b8976b |
if (!is_visible()) return false;
|
|
|
f77c6c |
p0->position.x += 0.001;
|
|
|
f77c6c |
point_motion(p0);
|
|
|
b8976b |
return true;
|
|
|
b8976b |
}
|
|
|
b8976b |
|
|
|
b8976b |
void
|
|
|
b8976b |
FreeTypeView::update_surface() {
|
|
|
b8976b |
this->surface.clear();
|
|
|
f77c6c |
|
|
|
f77c6c |
Matrix in_matrix(
|
|
|
f77c6c |
Vector3(px->position - p0->position)/50,
|
|
|
f77c6c |
Vector3(py->position - p0->position)/50,
|
|
|
f77c6c |
Vector3(p0->position, 1) );
|
|
|
f77c6c |
params.matrix = transform_to_pixels() * in_matrix;
|
|
|
f77c6c |
|
|
|
b8976b |
const int width = get_allocated_width();
|
|
|
b8976b |
const int height = get_allocated_height();
|
|
|
b8976b |
if (width <= 0 || height <= 0)
|
|
|
b8976b |
return;
|
|
|
b8976b |
|
|
|
f77c6c |
const Real hor_spacing = params.hor_spacing > real_precision ? params.hor_spacing : 1;
|
|
|
f77c6c |
|
|
|
71e4f2 |
Matrix matrix = params.matrix;
|
|
|
f77c6c |
Matrix2 glyph_matrix(
|
|
|
f77c6c |
matrix.row_x().vec2(),
|
|
|
f77c6c |
matrix.row_y().vec2() );
|
|
|
f77c6c |
matrix.row_x() *= hor_spacing;
|
|
|
f77c6c |
|
|
|
f77c6c |
if (fabs(glyph_matrix.det()) <= real_precision_sqr)
|
|
|
71e4f2 |
return;
|
|
|
f77c6c |
|
|
|
f77c6c |
|
|
|
f77c6c |
const Real size = params.size;
|
|
|
f77c6c |
const Real wrap_width = params.wrap_width/hor_spacing;
|
|
|
71e4f2 |
|
|
|
b8976b |
// init
|
|
|
f77c6c |
PangoFontMap *font_map = lab_pango_font_map_new(params.hinting, params.antialiasing);
|
|
|
b8976b |
PangoContext *context = pango_font_map_create_context(font_map);
|
|
|
71e4f2 |
|
|
|
b8976b |
// load font
|
|
|
b8976b |
PangoFontDescription *font_desc = pango_font_description_new();
|
|
|
b8976b |
pango_font_description_set_family(font_desc, params.family.c_str());
|
|
|
b8976b |
pango_font_description_set_weight(font_desc, params.bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
|
|
|
b8976b |
pango_font_description_set_style(font_desc, params.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
|
|
|
71e4f2 |
pango_font_description_set_absolute_size(font_desc, size * PANGO_SCALE);
|
|
|
71e4f2 |
|
|
|
71e4f2 |
PangoFont *font = pango_context_load_font(context, font_desc);
|
|
|
b8976b |
|
|
|
b8976b |
// create layout
|
|
|
b8976b |
PangoLayout *layout = pango_layout_new(context);
|
|
|
b8976b |
pango_layout_set_font_description(layout, font_desc);
|
|
|
f77c6c |
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
|
|
f77c6c |
pango_layout_set_width(layout, wrap_width > real_precision ? (int)round(wrap_width *PANGO_SCALE) : -1);
|
|
|
f77c6c |
pango_layout_set_alignment(layout,
|
|
|
f77c6c |
params.alignment < 0 ? PANGO_ALIGN_LEFT :
|
|
|
f77c6c |
params.alignment > 0 ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_CENTER );
|
|
|
f77c6c |
pango_layout_set_justify(layout, params.justify);
|
|
|
f77c6c |
if (params.vert_spacing > real_precision)
|
|
|
f77c6c |
pango_layout_set_spacing(layout, (int)round(params.vert_spacing*PANGO_SCALE));
|
|
|
b8976b |
pango_layout_set_text(layout, params.text.c_str(), (int)params.text.size());
|
|
|
b8976b |
|
|
|
f77c6c |
// move origin
|
|
|
f77c6c |
PangoRectangle rect;
|
|
|
f77c6c |
pango_layout_get_extents(layout, nullptr, &rect);
|
|
|
f77c6c |
const IntVector2 offset_to_origin_int(
|
|
|
f77c6c |
params.origin.x < 0 ? 0 :
|
|
|
f77c6c |
params.origin.x > 0 ? (rect.x + rect.width) : (rect.x + rect.width)/2,
|
|
|
f77c6c |
params.origin.y < 0 ? 0 :
|
|
|
f77c6c |
params.origin.y > 0 ? (rect.y + rect.height) : (rect.y + rect.height)/2 );
|
|
|
f77c6c |
const Vector2 offset_to_origin(
|
|
|
f77c6c |
offset_to_origin_int.x/Real(PANGO_SCALE),
|
|
|
f77c6c |
offset_to_origin_int.y/Real(PANGO_SCALE) );
|
|
|
f77c6c |
matrix *= Matrix().translation(-offset_to_origin);
|
|
|
f77c6c |
|
|
|
b8976b |
// reneder
|
|
|
b8976b |
DataSurface surface(width, height);
|
|
|
f77c6c |
LabPangoRendererParams rp;
|
|
|
f77c6c |
rp.surface = &surface;
|
|
|
f77c6c |
rp.matrix = matrix;
|
|
|
f77c6c |
rp.glyph_matrix = glyph_matrix;
|
|
|
f77c6c |
rp.color = params.color;
|
|
|
f77c6c |
rp.hinting = params.hinting;
|
|
|
f77c6c |
rp.antialiasing = params.antialiasing;
|
|
|
f77c6c |
PangoRenderer *renderer = lab_pango_renderer_new(&rp);
|
|
|
71e4f2 |
pango_renderer_draw_layout(renderer, layout, 0, 0);
|
|
|
71e4f2 |
|
|
|
b8976b |
// free pango
|
|
|
b8976b |
g_object_unref(renderer);
|
|
|
b8976b |
pango_font_description_free(font_desc);
|
|
|
b8976b |
g_object_unref(layout);
|
|
|
b8976b |
g_object_unref(font);
|
|
|
b8976b |
g_object_unref(context);
|
|
|
b8976b |
g_object_unref(font_map);
|
|
|
b8976b |
|
|
|
b8976b |
this->surface = surface.to_cairo_surface(true);
|
|
|
b8976b |
|
|
|
b8976b |
queue_draw();
|
|
|
b8976b |
}
|
|
|
b8976b |
|
|
|
b8976b |
void
|
|
|
f77c6c |
FreeTypeView::on_point_motion(const View::PointPtr &point) {
|
|
|
f77c6c |
if (point == p0) {
|
|
|
f77c6c |
px->position += p0->position - prev_p0;
|
|
|
f77c6c |
py->position += p0->position - prev_p0;
|
|
|
f77c6c |
prev_p0 = p0->position;
|
|
|
f77c6c |
}
|
|
|
f77c6c |
update_surface();
|
|
|
f77c6c |
}
|
|
|
f77c6c |
|
|
|
f77c6c |
void
|
|
|
b8976b |
FreeTypeView::on_draw_view(const Cairo::RefPtr<cairo::context> &context) {</cairo::context>
|
|
|
f77c6c |
const Real ps = get_pixel_size();
|
|
|
f77c6c |
|
|
|
f77c6c |
context->save();
|
|
|
f77c6c |
context->set_line_width(ps);
|
|
|
f77c6c |
|
|
|
f77c6c |
context->set_source_rgba(0, 0, 1, 1);
|
|
|
f77c6c |
context->move_to(px->position.x, px->position.y);
|
|
|
f77c6c |
context->line_to(p0->position.x, p0->position.y);
|
|
|
f77c6c |
context->line_to(py->position.x, py->position.y);
|
|
|
f77c6c |
context->stroke();
|
|
|
f77c6c |
|
|
|
b8976b |
if (surface) {
|
|
|
b8976b |
context->save();
|
|
|
b8976b |
context->transform(transform_from_pixels().to_cairo());
|
|
|
b8976b |
context->set_source(surface, 0, 0);
|
|
|
b8976b |
context->paint();
|
|
|
b8976b |
context->restore();
|
|
|
b8976b |
}
|
|
|
f77c6c |
context->restore();
|
|
|
b8976b |
}
|
|
|
b8976b |
|