[gtk+/wip/matthiasc/text-node] Add code to put glyphs in a vulkan image
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/text-node] Add code to put glyphs in a vulkan image
- Date: Sun, 10 Sep 2017 14:06:03 +0000 (UTC)
commit b47fe87d611a2bc9d89d29fdc6ac5cff09707b49
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Sep 10 09:35:32 2017 -0400
Add code to put glyphs in a vulkan image
gsk/gskvulkanrenderer.c | 105 ++++++++++++++++++++++++++++++++++++++++
gsk/gskvulkanrendererprivate.h | 11 ++++
2 files changed, 116 insertions(+), 0 deletions(-)
---
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 4ae0f4d..f70935f 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -343,3 +343,108 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
return image;
}
+
+#ifndef STACK_BUFFER_SIZE
+#define STACK_BUFFER_SIZE (512 * sizeof (int))
+#endif
+
+#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
+
+static void
+render_text (cairo_t *cr,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ GskRectangle *glyph_rects,
+ int *num_glyphs,
+ float x,
+ float y,
+ float width,
+ float height)
+{
+ int i, count;
+ int x_position = 0;
+ cairo_scaled_font_t *scaled_font;
+ cairo_glyph_t *cairo_glyphs;
+ cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
+
+ scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
+ if (G_UNLIKELY (!scaled_font || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
+ return;
+
+ cairo_set_scaled_font (cr, scaled_font);
+ cairo_set_source_rgba (cr, 0, 0, 0, 1);
+
+ if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
+ cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
+ else
+ cairo_glyphs = stack_glyphs;
+
+ count = 0;
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ PangoGlyphInfo *gi = &glyphs->glyphs[i];
+
+ if (gi->glyph != PANGO_GLYPH_EMPTY)
+ {
+ double cx = x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
+
+ if (!(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
+ {
+ cairo_glyphs[count].index = gi->glyph;
+ cairo_glyphs[count].x = cx;
+ cairo_glyphs[count].y = cy;
+
+ glyph_rects[count].x = cx / width;
+ glyph_rects[count].y = 0.0;
+ glyph_rects[count].width = (float)gi->geometry.width / width;
+ glyph_rects[count].height = 1.0; // FIXME get actual glyph height
+
+ count++;
+ }
+ }
+ x_position += gi->geometry.width;
+ }
+
+ *num_glyphs = count;
+
+ cairo_show_glyphs (cr, cairo_glyphs, count);
+
+ if (cairo_glyphs != stack_glyphs)
+ g_free (cairo_glyphs);
+}
+
+GskVulkanImage *
+gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
+ GskVulkanUploader *uploader,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ GskRectangle *glyph_rects,
+ int *num_glyphs)
+{
+ PangoRectangle ink_rect;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ GskVulkanImage *image;
+
+ pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
+ pango_extents_to_pixels (&ink_rect, NULL);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ ink_rect.x + ink_rect.width,
+ ink_rect.height);
+
+ cr = cairo_create (surface);
+ render_text (cr, font, glyphs, glyph_rects, num_glyphs,
+ 0, - ink_rect.y, ink_rect.x + ink_rect.width, ink_rect.height);
+ cairo_destroy (cr);
+
+ image = gsk_vulkan_image_new_from_data (uploader,
+ cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface),
+ cairo_image_surface_get_stride (surface));
+ cairo_surface_destroy (surface);
+
+ return image;
+}
diff --git a/gsk/gskvulkanrendererprivate.h b/gsk/gskvulkanrendererprivate.h
index 5794ba1..6d06bc1 100644
--- a/gsk/gskvulkanrendererprivate.h
+++ b/gsk/gskvulkanrendererprivate.h
@@ -25,6 +25,17 @@ GskVulkanImage * gsk_vulkan_renderer_ref_texture_image (GskVulk
GskTexture *texture,
GskVulkanUploader *uploader);
+typedef struct {
+ float x, y, width, height;
+} GskRectangle;
+
+GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
+ GskVulkanUploader *uploader,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ GskRectangle *glyph_rects,
+ int *num_glyphs);
+
G_END_DECLS
#endif /* __GSK_VULKAN_RENDERER_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]