Add support for blitting characters. An instance of struct font_desc stores the the character shapes. The blitting source pixmap contains a reference to a character's glyph, which can then be blitted to the destination. drm_pixmap_init_from_font_desc() sets up the pixmap. struct drm_pixmap; drm_pixmap_init_from_font_desc(&drm_pixmap, font_desc, font_data, 'c'); drm_fb_blit(..., &pixmap, ...); // blits the character 'c' To blit a string of characters, drm_pixmap_set_font_char() updates the character's value. struct drm_pixmap; const char *str = "Hello world!" drm_pixmap_init_from_font_desc(&drm_pixmap, font_desc, font_data, '\0'); while (*str) { drm_pixmap_set_font_char(&pixmap, font_data, *str); drm_fb_blit(..., &pixmap, ...); // blits *str ++str; } Further helpers can be build from these primitives. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/drm_format_helper.c | 27 +++++++++++++++++++++++++++ include/drm/drm_format_helper.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 6b80be55cc5c0..ed90745f4d9fb 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -8,6 +8,7 @@ * (at your option) any later version. */ +#include <linux/font.h> #include <linux/io.h> #include <linux/iosys-map.h> #include <linux/module.h> @@ -181,6 +182,32 @@ void drm_pixmap_init_from_framebuffer(struct drm_pixmap *pix, const struct drm_f } EXPORT_SYMBOL(drm_pixmap_init_from_framebuffer); +void drm_pixmap_init_from_font_desc(struct drm_pixmap *pix, const struct font_desc *font, + const struct iosys_map *data, int c) +{ + const struct drm_rect clip = DRM_RECT_INIT(0, 0, font->width, font->height); + const struct drm_format_info *format = drm_format_info(DRM_FORMAT_C1); + const unsigned int pitches[DRM_FORMAT_MAX_PLANES] = { + drm_format_info_min_pitch(format, 0, font->width), + }; + struct iosys_map cdata[DRM_FORMAT_MAX_PLANES] = { + IOSYS_MAP_INIT_OFFSET(&data[0], c * font->height * pitches[0]), + }; + + drm_pixmap_init(pix, format, cdata, pitches, &clip); +} +EXPORT_SYMBOL(drm_pixmap_init_from_font_desc); + +void drm_pixmap_set_font_char(struct drm_pixmap *pix, const struct iosys_map *data, int c) +{ + unsigned int height = drm_rect_height(&pix->clip); + size_t i; + + for (i = 0; i < pix->format->num_planes; ++i) + pix->data[i] = IOSYS_MAP_INIT_OFFSET(&data[i], c * height * pix->pitches[i]); +} +EXPORT_SYMBOL(drm_pixmap_set_font_char); + static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, const void *src, unsigned long src_pitch, unsigned long src_pixsize, const struct drm_rect *src_clip, bool src_cached_hint, diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index a78360e229a45..098e6f8412465 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -14,6 +14,7 @@ struct drm_device; struct drm_framebuffer; +struct font_desc; /** * struct drm_format_conv_state - Stores format-conversion state @@ -93,6 +94,9 @@ struct drm_pixmap { void drm_pixmap_init_from_framebuffer(struct drm_pixmap *pix, const struct drm_framebuffer *fb, const struct iosys_map *data, const struct drm_rect *clip); +void drm_pixmap_init_from_font_desc(struct drm_pixmap *pix, const struct font_desc *font, + const struct iosys_map *data, int c); +void drm_pixmap_set_font_char(struct drm_pixmap *pix, const struct iosys_map *data, int c); unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, const struct drm_rect *clip); -- 2.43.0