commit 3413eed
Michael Forney
·
2014-01-31 12:26:13 +0000 UTC
parent f5b2b47
nouveau: Implement text rendering
1 files changed,
+73,
-1
+73,
-1
1@@ -124,6 +124,13 @@ static inline void nv_add_dwords_va(struct nouveau_pushbuf * push,
2 nv_add_dword(push, va_arg(dwords, uint32_t));
3 }
4
5+static inline void nv_add_data(struct nouveau_pushbuf * push,
6+ void * data, uint32_t count)
7+{
8+ memcpy(push->cur, data, count * 4);
9+ push->cur += count;
10+}
11+
12 static uint32_t nvc0_format(uint32_t format)
13 {
14 switch (format)
15@@ -488,7 +495,72 @@ void renderer_draw_text(struct wld_renderer * base,
16 int32_t x, int32_t y, const char * text, int32_t length,
17 struct wld_extents * extents)
18 {
19- /* TODO: Implement */
20+ struct nouveau_renderer * renderer = nouveau_renderer(base);
21+ uint32_t format;
22+ int ret;
23+ struct glyph * glyph;
24+ FT_UInt glyph_index;
25+ uint32_t c, count;
26+ int32_t origin_x = x;
27+
28+ if (!ensure_space(renderer->pushbuf, 17))
29+ return;
30+
31+ format = nvc0_format(renderer->target->base.format);
32+
33+ nouveau_bufctx_reset(renderer->bufctx, 0);
34+ nvc0_2d_use_buffer(renderer, renderer->target,
35+ NV50_2D_DST_FORMAT, format);
36+ nvc0_2d_inline(renderer->pushbuf, NV50_2D_SIFC_BITMAP_ENABLE, 1);
37+ nvc0_2d(renderer->pushbuf, NV50_2D_SIFC_BITMAP_FORMAT, 6,
38+ NV50_2D_SIFC_BITMAP_FORMAT_I1,
39+ 0, /* SIFC_FORMAT */
40+ NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE,
41+ 0, color, /* SIFC_BITMAP_COLOR_BIT0, SIFC_BITMAP_COLOR_BIT1 */
42+ 0 /* SIFC_BITMAP_WRITE_BIT0_ENABLE */
43+ );
44+ nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
45+
46+ if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
47+ return;
48+
49+ while ((ret = FcUtf8ToUcs4((FcChar8 *) text, &c, length)) > 0 && c != '\0')
50+ {
51+ text += ret;
52+ length -= ret;
53+ glyph_index = FT_Get_Char_Index(font->face, c);
54+
55+ if (!font_ensure_glyph(font, glyph_index))
56+ continue;
57+
58+ glyph = font->glyphs[glyph_index];
59+
60+ if (glyph->bitmap.width == 0 || glyph->bitmap.rows == 0)
61+ goto advance;
62+
63+ count = (glyph->bitmap.pitch * glyph->bitmap.rows + 3) / 4;
64+
65+ if (!ensure_space(renderer->pushbuf, 12 + count))
66+ return;
67+
68+ nvc0_2d(renderer->pushbuf, NV50_2D_SIFC_WIDTH, 10,
69+ /* Use the pitch instead of width to ensure the correct
70+ * alignment is used. */
71+ glyph->bitmap.pitch * 8, glyph->bitmap.rows,
72+ 0, 1, 0, 1,
73+ 0, origin_x + glyph->x, 0, y + glyph->y);
74+ nv_add_dword(renderer->pushbuf,
75+ nvc0_command(NVC0_COMMAND_TYPE_NON_INCREASING,
76+ NVC0_SUBCHANNEL_2D,
77+ NV50_2D_SIFC_DATA, count));
78+ nv_add_data(renderer->pushbuf, glyph->bitmap.buffer, count);
79+
80+ advance:
81+ origin_x += glyph->advance;
82+ }
83+
84+ if (extents)
85+ extents->advance = origin_x - x;
86 }
87
88 void renderer_flush(struct wld_renderer * base)