editor: Extract text handling into text_layout
Create a text_layout struct and functions for handling simple text layouts. Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
f80bc06a8e
commit
b9eb02c46f
+94
-5
@@ -32,12 +32,25 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "text-client-protocol.h"
|
#include "text-client-protocol.h"
|
||||||
|
|
||||||
|
static const char *font_name = "sans-serif";
|
||||||
|
static int font_size = 14;
|
||||||
|
|
||||||
|
struct text_layout {
|
||||||
|
cairo_glyph_t *glyphs;
|
||||||
|
int num_glyphs;
|
||||||
|
cairo_text_cluster_t *clusters;
|
||||||
|
int num_clusters;
|
||||||
|
cairo_text_cluster_flags_t cluster_flags;
|
||||||
|
cairo_scaled_font_t *font;
|
||||||
|
};
|
||||||
|
|
||||||
struct text_entry {
|
struct text_entry {
|
||||||
struct widget *widget;
|
struct widget *widget;
|
||||||
struct window *window;
|
struct window *window;
|
||||||
char *text;
|
char *text;
|
||||||
int active;
|
int active;
|
||||||
struct text_model *model;
|
struct text_model *model;
|
||||||
|
struct text_layout *layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct editor {
|
struct editor {
|
||||||
@@ -49,6 +62,81 @@ struct editor {
|
|||||||
struct text_entry *editor;
|
struct text_entry *editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct text_layout *
|
||||||
|
text_layout_create(void)
|
||||||
|
{
|
||||||
|
struct text_layout *layout;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
layout = malloc(sizeof *layout);
|
||||||
|
if (!layout)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
layout->glyphs = NULL;
|
||||||
|
layout->num_glyphs = 0;
|
||||||
|
|
||||||
|
layout->clusters = NULL;
|
||||||
|
layout->num_clusters = 0;
|
||||||
|
|
||||||
|
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
|
||||||
|
cr = cairo_create(surface);
|
||||||
|
cairo_set_font_size(cr, font_size);
|
||||||
|
cairo_select_font_face(cr, font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||||
|
layout->font = cairo_get_scaled_font(cr);
|
||||||
|
cairo_scaled_font_reference(layout->font);
|
||||||
|
|
||||||
|
cairo_destroy(cr);
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_layout_destroy(struct text_layout *layout)
|
||||||
|
{
|
||||||
|
if (layout->glyphs)
|
||||||
|
cairo_glyph_free(layout->glyphs);
|
||||||
|
|
||||||
|
if (layout->clusters)
|
||||||
|
cairo_text_cluster_free(layout->clusters);
|
||||||
|
|
||||||
|
cairo_scaled_font_destroy(layout->font);
|
||||||
|
|
||||||
|
free(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_layout_set_text(struct text_layout *layout,
|
||||||
|
const char *text)
|
||||||
|
{
|
||||||
|
if (layout->glyphs)
|
||||||
|
cairo_glyph_free(layout->glyphs);
|
||||||
|
|
||||||
|
if (layout->clusters)
|
||||||
|
cairo_text_cluster_free(layout->clusters);
|
||||||
|
|
||||||
|
layout->glyphs = NULL;
|
||||||
|
layout->num_glyphs = 0;
|
||||||
|
layout->clusters = NULL;
|
||||||
|
layout->num_clusters = 0;
|
||||||
|
|
||||||
|
cairo_scaled_font_text_to_glyphs(layout->font, 0, 0, text, -1,
|
||||||
|
&layout->glyphs, &layout->num_glyphs,
|
||||||
|
&layout->clusters, &layout->num_clusters,
|
||||||
|
&layout->cluster_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_layout_draw(struct text_layout *layout, cairo_t *cr)
|
||||||
|
{
|
||||||
|
cairo_save(cr);
|
||||||
|
cairo_set_scaled_font(cr, layout->font);
|
||||||
|
cairo_show_glyphs(cr, layout->glyphs, layout->num_glyphs);
|
||||||
|
cairo_restore(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void text_entry_redraw_handler(struct widget *widget, void *data);
|
static void text_entry_redraw_handler(struct widget *widget, void *data);
|
||||||
static void text_entry_button_handler(struct widget *widget,
|
static void text_entry_button_handler(struct widget *widget,
|
||||||
struct input *input, uint32_t time,
|
struct input *input, uint32_t time,
|
||||||
@@ -60,6 +148,7 @@ text_entry_append(struct text_entry *entry, const char *text)
|
|||||||
{
|
{
|
||||||
entry->text = realloc(entry->text, strlen(entry->text) + strlen(text) + 1);
|
entry->text = realloc(entry->text, strlen(entry->text) + strlen(text) + 1);
|
||||||
strcat(entry->text, text);
|
strcat(entry->text, text);
|
||||||
|
text_layout_set_text(entry->layout, entry->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -162,6 +251,9 @@ text_entry_create(struct editor *editor, const char *text)
|
|||||||
entry->model = text_model_factory_create_text_model(editor->text_model_factory);
|
entry->model = text_model_factory_create_text_model(editor->text_model_factory);
|
||||||
text_model_add_listener(entry->model, &text_model_listener, entry);
|
text_model_add_listener(entry->model, &text_model_listener, entry);
|
||||||
|
|
||||||
|
entry->layout = text_layout_create();
|
||||||
|
text_layout_set_text(entry->layout, entry->text);
|
||||||
|
|
||||||
widget_set_redraw_handler(entry->widget, text_entry_redraw_handler);
|
widget_set_redraw_handler(entry->widget, text_entry_redraw_handler);
|
||||||
widget_set_button_handler(entry->widget, text_entry_button_handler);
|
widget_set_button_handler(entry->widget, text_entry_button_handler);
|
||||||
|
|
||||||
@@ -173,6 +265,7 @@ text_entry_destroy(struct text_entry *entry)
|
|||||||
{
|
{
|
||||||
widget_destroy(entry->widget);
|
widget_destroy(entry->widget);
|
||||||
text_model_destroy(entry->model);
|
text_model_destroy(entry->model);
|
||||||
|
text_layout_destroy(entry->layout);
|
||||||
free(entry->text);
|
free(entry->text);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
@@ -285,13 +378,9 @@ text_entry_redraw_handler(struct widget *widget, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cairo_set_source_rgba(cr, 0, 0, 0, 1);
|
cairo_set_source_rgba(cr, 0, 0, 0, 1);
|
||||||
cairo_select_font_face(cr, "sans",
|
|
||||||
CAIRO_FONT_SLANT_NORMAL,
|
|
||||||
CAIRO_FONT_WEIGHT_BOLD);
|
|
||||||
cairo_set_font_size(cr, 14);
|
|
||||||
|
|
||||||
cairo_translate(cr, 10, allocation.height / 2);
|
cairo_translate(cr, 10, allocation.height / 2);
|
||||||
cairo_show_text(cr, entry->text);
|
text_layout_draw(entry->layout, cr);
|
||||||
cairo_pop_group_to_source(cr);
|
cairo_pop_group_to_source(cr);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user