commit 6c07136
shrub
·
2026-02-01 18:24:41 +0000 UTC
parent 8990a83
init
M
font.c
+3,
-2
1@@ -172,7 +172,8 @@ font_ensure_glyph(struct font *font, FT_UInt glyph_index)
2 if (!glyph)
3 return false;
4
5- FT_Load_Glyph(font->face, glyph_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO);
6+ FT_Load_Glyph(font->face, glyph_index,
7+ FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL);
8
9 FT_Bitmap_New(&glyph->bitmap);
10
11@@ -217,7 +218,7 @@ wld_font_text_extents_n(struct wld_font *font_base,
12
13 extents->advance = 0;
14
15- while ((ret = FcUtf8ToUcs4((FcChar8 *)text, &c, length) > 0) && c != '\0') {
16+ while ((ret = FcUtf8ToUcs4((FcChar8 *)text, &c, length)) > 0 && c != '\0') {
17 length -= ret;
18 text += ret;
19 glyph_index = FT_Get_Char_Index(font->face, c);
M
intel.c
+24,
-2
1@@ -29,6 +29,7 @@
2
3 #include <i915_drm.h>
4 #include <intel_bufmgr.h>
5+#include <string.h>
6 #include <unistd.h>
7
8 struct intel_context {
9@@ -57,6 +58,20 @@ IMPL(intel_context, wld_context)
10 IMPL(intel_renderer, wld_renderer)
11 IMPL(intel_buffer, wld_buffer)
12
13+static void
14+pack_gray_row_to_mono(uint8_t *dst, const uint8_t *src, uint32_t width)
15+{
16+ uint32_t x, bytes_per_row;
17+
18+ bytes_per_row = (width + 7) / 8;
19+ memset(dst, 0, bytes_per_row);
20+
21+ for (x = 0; x < width; ++x) {
22+ if (src[x] >= 128)
23+ dst[x / 8] |= 0x80 >> (x & 7);
24+ }
25+}
26+
27 /**** DRM driver ****/
28 bool
29 driver_device_supported(uint32_t vendor_id, uint32_t device_id)
30@@ -315,8 +330,15 @@ renderer_draw_text(struct wld_renderer *base,
31
32 /* XY_TEXT_IMMEDIATE requires a pitch with no extra bytes */
33 for (row = 0; row < glyph->bitmap.rows; ++row) {
34- memcpy(byte, glyph->bitmap.buffer + (row * glyph->bitmap.pitch),
35- (glyph->bitmap.width + 7) / 8);
36+ const uint8_t *src = glyph->bitmap.buffer +
37+ (row * glyph->bitmap.pitch);
38+ uint32_t bytes_per_row = (glyph->bitmap.width + 7) / 8;
39+
40+ if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
41+ memcpy(byte, src, bytes_per_row);
42+ } else {
43+ pack_gray_row_to_mono(byte, src, glyph->bitmap.width);
44+ }
45 byte += (glyph->bitmap.width + 7) / 8;
46 }
47
+60,
-12
1@@ -34,6 +34,7 @@
2 #include "pixman.h"
3
4 #include <nouveau.h>
5+#include <string.h>
6 #include <sys/mman.h>
7
8 enum nv_architecture {
9@@ -75,6 +76,20 @@ IMPL(nouveau_context, wld_context)
10 IMPL(nouveau_renderer, wld_renderer)
11 IMPL(nouveau_buffer, wld_buffer)
12
13+static void
14+pack_gray_row_to_mono(uint8_t *dst, const uint8_t *src, uint32_t width)
15+{
16+ uint32_t x, bytes_per_row;
17+
18+ bytes_per_row = (width + 7) / 8;
19+ memset(dst, 0, bytes_per_row);
20+
21+ for (x = 0; x < width; ++x) {
22+ if (src[x] >= 128)
23+ dst[x / 8] |= 0x80 >> (x & 7);
24+ }
25+}
26+
27 /**** DRM driver ****/
28 bool
29 driver_device_supported(uint32_t vendor_id, uint32_t device_id)
30@@ -594,22 +609,55 @@ renderer_draw_text(struct wld_renderer *base,
31 if (glyph->bitmap.width == 0 || glyph->bitmap.rows == 0)
32 goto advance;
33
34- count = (glyph->bitmap.pitch * glyph->bitmap.rows + 3) / 4;
35+ if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
36+ count = (glyph->bitmap.pitch * glyph->bitmap.rows + 3) / 4;
37+ } else {
38+ uint32_t bytes_per_row = (glyph->bitmap.width + 7) / 8;
39+ count = (bytes_per_row * glyph->bitmap.rows + 3) / 4;
40+ }
41
42 if (!ensure_space(renderer->pushbuf, 12 + count))
43 return;
44
45- nvc0_2d(renderer->pushbuf, G80_2D_SIFC_WIDTH, 10,
46- /* Use the pitch instead of width to ensure the correct
47- * alignment is used. */
48- glyph->bitmap.pitch * 8, glyph->bitmap.rows,
49- 0, 1, 0, 1,
50- 0, origin_x + glyph->x, 0, y + glyph->y);
51- nv_add_dword(renderer->pushbuf,
52- nvc0_command(GF100_COMMAND_TYPE_NON_INCREASING,
53- GF100_SUBCHANNEL_2D,
54- G80_2D_SIFC_DATA, count));
55- nv_add_data(renderer->pushbuf, glyph->bitmap.buffer, count);
56+ if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
57+ nvc0_2d(renderer->pushbuf, G80_2D_SIFC_WIDTH, 10,
58+ /* Use the pitch instead of width to ensure the correct
59+ * alignment is used. */
60+ glyph->bitmap.pitch * 8, glyph->bitmap.rows,
61+ 0, 1, 0, 1,
62+ 0, origin_x + glyph->x, 0, y + glyph->y);
63+ nv_add_dword(renderer->pushbuf,
64+ nvc0_command(GF100_COMMAND_TYPE_NON_INCREASING,
65+ GF100_SUBCHANNEL_2D,
66+ G80_2D_SIFC_DATA, count));
67+ nv_add_data(renderer->pushbuf, glyph->bitmap.buffer, count);
68+ } else {
69+ uint32_t bytes_per_row = (glyph->bitmap.width + 7) / 8;
70+ uint32_t row;
71+ uint8_t *mono = malloc(bytes_per_row * glyph->bitmap.rows);
72+ uint8_t *dst = mono;
73+
74+ if (!mono)
75+ return;
76+
77+ for (row = 0; row < glyph->bitmap.rows; ++row) {
78+ const uint8_t *src = glyph->bitmap.buffer +
79+ (row * glyph->bitmap.pitch);
80+ pack_gray_row_to_mono(dst, src, glyph->bitmap.width);
81+ dst += bytes_per_row;
82+ }
83+
84+ nvc0_2d(renderer->pushbuf, G80_2D_SIFC_WIDTH, 10,
85+ bytes_per_row * 8, glyph->bitmap.rows,
86+ 0, 1, 0, 1,
87+ 0, origin_x + glyph->x, 0, y + glyph->y);
88+ nv_add_dword(renderer->pushbuf,
89+ nvc0_command(GF100_COMMAND_TYPE_NON_INCREASING,
90+ GF100_SUBCHANNEL_2D,
91+ G80_2D_SIFC_DATA, count));
92+ nv_add_data(renderer->pushbuf, mono, count);
93+ free(mono);
94+ }
95
96 advance:
97 origin_x += glyph->advance;
M
pixman.c
+55,
-21
1@@ -24,6 +24,8 @@
2 #include "pixman.h"
3 #include "wld-private.h"
4
5+#include <string.h>
6+
7 #define PIXMAN_COLOR(c) \
8 { \
9 .alpha = ((c >> 24) & 0xff) * 0x101, \
10@@ -344,6 +346,58 @@ reverse(uint8_t byte)
11 return byte;
12 }
13
14+static pixman_image_t *
15+glyph_bitmap_to_pixman_image(struct glyph *glyph)
16+{
17+ FT_Bitmap *bitmap = &glyph->bitmap;
18+ pixman_image_t *image;
19+ uint8_t *src, *dst;
20+ uint32_t row, byte_index, bytes_per_row, pitch;
21+
22+ switch (bitmap->pixel_mode) {
23+ case FT_PIXEL_MODE_MONO:
24+ image = pixman_image_create_bits(PIXMAN_a1, bitmap->width,
25+ bitmap->rows, NULL, bitmap->pitch);
26+ if (!image)
27+ return NULL;
28+
29+ pitch = pixman_image_get_stride(image);
30+ bytes_per_row = (bitmap->width + 7) / 8;
31+ src = bitmap->buffer;
32+ dst = (uint8_t *)pixman_image_get_data(image);
33+
34+ for (row = 0; row < bitmap->rows; ++row) {
35+ /* Pixman's A1 format expects the bits in the opposite order
36+ * that Freetype gives us. */
37+ for (byte_index = 0; byte_index < bytes_per_row; ++byte_index)
38+ dst[byte_index] = reverse(src[byte_index]);
39+
40+ dst += pitch;
41+ src += bitmap->pitch;
42+ }
43+ return image;
44+ case FT_PIXEL_MODE_GRAY:
45+ image = pixman_image_create_bits(PIXMAN_a8, bitmap->width,
46+ bitmap->rows, NULL, 0);
47+ if (!image)
48+ return NULL;
49+
50+ pitch = pixman_image_get_stride(image);
51+ src = bitmap->buffer;
52+ dst = (uint8_t *)pixman_image_get_data(image);
53+
54+ for (row = 0; row < bitmap->rows; ++row) {
55+ memset(dst, 0, pitch);
56+ memcpy(dst, src, bitmap->width);
57+ dst += pitch;
58+ src += bitmap->pitch;
59+ }
60+ return image;
61+ default:
62+ return NULL;
63+ }
64+}
65+
66 void
67 renderer_draw_text(struct wld_renderer *base,
68 struct font *font, uint32_t color,
69@@ -385,32 +439,12 @@ renderer_draw_text(struct wld_renderer *base,
70 /* If we don't have the glyph in our cache, do some conversions to make
71 * pixman happy, and then insert it. */
72 if (!glyphs[index].glyph) {
73- uint8_t *src, *dst;
74- uint32_t row, byte_index, bytes_per_row, pitch;
75 pixman_image_t *image;
76- FT_Bitmap *bitmap;
77-
78- bitmap = &glyph->bitmap;
79- image = pixman_image_create_bits(PIXMAN_a1, bitmap->width, bitmap->rows, NULL, bitmap->pitch);
80+ image = glyph_bitmap_to_pixman_image(glyph);
81
82 if (!image)
83 goto advance;
84
85- pitch = pixman_image_get_stride(image);
86- bytes_per_row = (bitmap->width + 7) / 8;
87- src = bitmap->buffer;
88- dst = (uint8_t *)pixman_image_get_data(image);
89-
90- for (row = 0; row < bitmap->rows; ++row) {
91- /* Pixman's A1 format expects the bits in the opposite order
92- * that Freetype gives us. Sigh... */
93- for (byte_index = 0; byte_index < bytes_per_row; ++byte_index)
94- dst[byte_index] = reverse(src[byte_index]);
95-
96- dst += pitch;
97- src += bitmap->pitch;
98- }
99-
100 /* Insert the glyph into the cache. */
101 pixman_glyph_cache_freeze(renderer->glyph_cache);
102 glyphs[index].glyph = pixman_glyph_cache_insert(renderer->glyph_cache, font, glyph,