Merge patch series "video: Enhancements related to truetype and console"
Simon Glass <sjg@chromium.org> says: This series includes some precursor patches needed for forthcoming expo enhancements. - truetype support for multiple lines - make white-on-black a runtime option - support drawing a rectangle
This commit is contained in:
@@ -131,6 +131,7 @@
|
|||||||
font-size = <30>;
|
font-size = <30>;
|
||||||
menu-inset = <3>;
|
menu-inset = <3>;
|
||||||
menuitem-gap-y = <1>;
|
menuitem-gap-y = <1>;
|
||||||
|
white-on-black;
|
||||||
};
|
};
|
||||||
|
|
||||||
cedit-theme {
|
cedit-theme {
|
||||||
|
@@ -194,7 +194,7 @@ int expo_render(struct expo *exp)
|
|||||||
u32 colour;
|
u32 colour;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
back = CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK) ? VID_BLACK : VID_WHITE;
|
back = vid_priv->white_on_black ? VID_BLACK : VID_WHITE;
|
||||||
colour = video_index_to_colour(vid_priv, back);
|
colour = video_index_to_colour(vid_priv, back);
|
||||||
ret = video_fill(dev, colour);
|
ret = video_fill(dev, colour);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
10
boot/scene.c
10
boot/scene.c
@@ -298,7 +298,7 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = vidconsole_measure(scn->expo->cons, txt->font_name,
|
ret = vidconsole_measure(scn->expo->cons, txt->font_name,
|
||||||
txt->font_size, str, &bbox);
|
txt->font_size, str, -1, &bbox, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("mea", ret);
|
return log_msg_ret("mea", ret);
|
||||||
if (widthp)
|
if (widthp)
|
||||||
@@ -330,8 +330,9 @@ static void scene_render_background(struct scene_obj *obj, bool box_only)
|
|||||||
enum colour_idx fore, back;
|
enum colour_idx fore, back;
|
||||||
uint inset = theme->menu_inset;
|
uint inset = theme->menu_inset;
|
||||||
|
|
||||||
|
vid_priv = dev_get_uclass_priv(dev);
|
||||||
/* draw a background for the object */
|
/* draw a background for the object */
|
||||||
if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
|
if (vid_priv->white_on_black) {
|
||||||
fore = VID_DARK_GREY;
|
fore = VID_DARK_GREY;
|
||||||
back = VID_WHITE;
|
back = VID_WHITE;
|
||||||
} else {
|
} else {
|
||||||
@@ -344,7 +345,6 @@ static void scene_render_background(struct scene_obj *obj, bool box_only)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
vidconsole_push_colour(cons, fore, back, &old);
|
vidconsole_push_colour(cons, fore, back, &old);
|
||||||
vid_priv = dev_get_uclass_priv(dev);
|
|
||||||
video_fill_part(dev, label_bbox.x0 - inset, label_bbox.y0 - inset,
|
video_fill_part(dev, label_bbox.x0 - inset, label_bbox.y0 - inset,
|
||||||
label_bbox.x1 + inset, label_bbox.y1 + inset,
|
label_bbox.x1 + inset, label_bbox.y1 + inset,
|
||||||
vid_priv->colour_fg);
|
vid_priv->colour_fg);
|
||||||
@@ -408,7 +408,8 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
|
|||||||
struct vidconsole_colour old;
|
struct vidconsole_colour old;
|
||||||
enum colour_idx fore, back;
|
enum colour_idx fore, back;
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
|
vid_priv = dev_get_uclass_priv(dev);
|
||||||
|
if (vid_priv->white_on_black) {
|
||||||
fore = VID_BLACK;
|
fore = VID_BLACK;
|
||||||
back = VID_WHITE;
|
back = VID_WHITE;
|
||||||
} else {
|
} else {
|
||||||
@@ -416,7 +417,6 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
|
|||||||
back = VID_BLACK;
|
back = VID_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
vid_priv = dev_get_uclass_priv(dev);
|
|
||||||
if (obj->flags & SCENEOF_POINT) {
|
if (obj->flags & SCENEOF_POINT) {
|
||||||
vidconsole_push_colour(cons, fore, back, &old);
|
vidconsole_push_colour(cons, fore, back, &old);
|
||||||
video_fill_part(dev, x - theme->menu_inset, y,
|
video_fill_part(dev, x - theme->menu_inset, y,
|
||||||
|
@@ -359,6 +359,24 @@ void console_puts_select_stderr(bool serial_only, const char *s)
|
|||||||
console_puts_select(stderr, serial_only, s);
|
console_puts_select(stderr, serial_only, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int console_printf_select_stderr(bool serial_only, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[CONFIG_SYS_PBSIZE];
|
||||||
|
va_list args;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
/* For this to work, buf must be larger than anything we ever want to
|
||||||
|
* print.
|
||||||
|
*/
|
||||||
|
ret = vscnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
console_puts_select_stderr(serial_only, buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void console_puts(int file, const char *s)
|
static void console_puts(int file, const char *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
* Copyright (c) 2016 Google, Inc
|
* Copyright (c) 2016 Google, Inc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY UCLASS_VIDEO
|
||||||
|
|
||||||
#include <abuf.h>
|
#include <abuf.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
@@ -488,10 +490,12 @@ static int console_truetype_backspace(struct udevice *dev)
|
|||||||
|
|
||||||
static int console_truetype_entry_start(struct udevice *dev)
|
static int console_truetype_entry_start(struct udevice *dev)
|
||||||
{
|
{
|
||||||
|
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
|
||||||
struct console_tt_priv *priv = dev_get_priv(dev);
|
struct console_tt_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
/* A new input line has start, so clear our history */
|
/* A new input line has start, so clear our history */
|
||||||
priv->pos_ptr = 0;
|
priv->pos_ptr = 0;
|
||||||
|
vc_priv->last_ch = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -733,14 +737,18 @@ static int truetype_select_font(struct udevice *dev, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int truetype_measure(struct udevice *dev, const char *name, uint size,
|
static int truetype_measure(struct udevice *dev, const char *name, uint size,
|
||||||
const char *text, struct vidconsole_bbox *bbox)
|
const char *text, int pixel_limit,
|
||||||
|
struct vidconsole_bbox *bbox, struct alist *lines)
|
||||||
{
|
{
|
||||||
struct console_tt_metrics *met;
|
struct console_tt_metrics *met;
|
||||||
|
struct vidconsole_mline mline;
|
||||||
|
const char *s, *last_space;
|
||||||
|
int width, last_width;
|
||||||
stbtt_fontinfo *font;
|
stbtt_fontinfo *font;
|
||||||
int lsb, advance;
|
int lsb, advance;
|
||||||
const char *s;
|
int start;
|
||||||
int width;
|
int limit;
|
||||||
int last;
|
int lastch;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = get_metrics(dev, name, size, &met);
|
ret = get_metrics(dev, name, size, &met);
|
||||||
@@ -751,27 +759,85 @@ static int truetype_measure(struct udevice *dev, const char *name, uint size,
|
|||||||
if (!*text)
|
if (!*text)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
limit = -1;
|
||||||
|
if (pixel_limit != -1)
|
||||||
|
limit = tt_ceil((double)pixel_limit / met->scale);
|
||||||
|
|
||||||
font = &met->font;
|
font = &met->font;
|
||||||
width = 0;
|
width = 0;
|
||||||
for (last = 0, s = text; *s; s++) {
|
bbox->y1 = 0;
|
||||||
|
bbox->x1 = 0;
|
||||||
|
start = 0;
|
||||||
|
last_space = NULL;
|
||||||
|
last_width = 0;
|
||||||
|
for (lastch = 0, s = text; *s; s++) {
|
||||||
|
int neww;
|
||||||
int ch = *s;
|
int ch = *s;
|
||||||
|
|
||||||
/* Used kerning to fine-tune the position of this character */
|
if (ch == ' ') {
|
||||||
if (last)
|
/*
|
||||||
width += stbtt_GetCodepointKernAdvance(font, last, ch);
|
* store the position and width so we can use it again
|
||||||
|
* if we need to word-wrap
|
||||||
|
*/
|
||||||
|
last_space = s;
|
||||||
|
last_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
/* First get some basic metrics about this character */
|
/* First get some basic metrics about this character */
|
||||||
stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
|
stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
|
||||||
|
neww = width + advance;
|
||||||
|
|
||||||
width += advance;
|
/* Use kerning to fine-tune the position of this character */
|
||||||
last = ch;
|
if (lastch)
|
||||||
|
neww += stbtt_GetCodepointKernAdvance(font, lastch, ch);
|
||||||
|
lastch = ch;
|
||||||
|
|
||||||
|
/* see if we need to start a new line */
|
||||||
|
if (ch == '\n' || (limit != -1 && neww >= limit)) {
|
||||||
|
if (ch != '\n' && last_space) {
|
||||||
|
s = last_space;
|
||||||
|
width = last_width;
|
||||||
|
}
|
||||||
|
last_space = NULL;
|
||||||
|
mline.bbox.x0 = 0;
|
||||||
|
mline.bbox.y0 = bbox->y1;
|
||||||
|
mline.bbox.x1 = tt_ceil((double)width * met->scale);
|
||||||
|
bbox->x1 = max(bbox->x1, mline.bbox.x1);
|
||||||
|
bbox->y1 += met->font_size;
|
||||||
|
mline.bbox.y1 = bbox->y1;
|
||||||
|
mline.bbox.valid = true;
|
||||||
|
mline.start = start;
|
||||||
|
mline.len = (s - text) - start;
|
||||||
|
if (lines && !alist_add(lines, mline))
|
||||||
|
return log_msg_ret("ttm", -ENOMEM);
|
||||||
|
log_debug("line x1 %d y0 %d y1 %d start %d len %d text '%.*s'\n",
|
||||||
|
mline.bbox.x1, mline.bbox.y0, mline.bbox.y1,
|
||||||
|
mline.start, mline.len, mline.len, text + mline.start);
|
||||||
|
|
||||||
|
start = s - text;
|
||||||
|
start++;
|
||||||
|
lastch = 0;
|
||||||
|
neww = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = neww;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add the final line */
|
||||||
|
mline.bbox.x0 = 0;
|
||||||
|
mline.bbox.y0 = bbox->y1;
|
||||||
|
mline.bbox.x1 = tt_ceil((double)width * met->scale);
|
||||||
|
bbox->y1 += met->font_size;
|
||||||
|
mline.bbox.y1 = bbox->y1;
|
||||||
|
mline.start = start;
|
||||||
|
mline.len = (s - text) - start;
|
||||||
|
if (lines && !alist_add(lines, mline))
|
||||||
|
return log_msg_ret("ttM", -ENOMEM);
|
||||||
|
|
||||||
bbox->valid = true;
|
bbox->valid = true;
|
||||||
bbox->x0 = 0;
|
bbox->x0 = 0;
|
||||||
bbox->y0 = 0;
|
bbox->y0 = 0;
|
||||||
bbox->x1 = tt_ceil((double)width * met->scale);
|
bbox->x1 = max(bbox->x1, mline.bbox.x1);
|
||||||
bbox->y1 = met->font_size;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -127,6 +127,9 @@ void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y)
|
|||||||
priv->xcur_frac = VID_TO_POS(x);
|
priv->xcur_frac = VID_TO_POS(x);
|
||||||
priv->xstart_frac = priv->xcur_frac;
|
priv->xstart_frac = priv->xcur_frac;
|
||||||
priv->ycur = y;
|
priv->ycur = y;
|
||||||
|
|
||||||
|
/* make sure not to kern against the previous character */
|
||||||
|
priv->last_ch = 0;
|
||||||
vidconsole_entry_start(dev);
|
vidconsole_entry_start(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,12 +511,14 @@ int vidconsole_put_char(struct udevice *dev, char ch)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vidconsole_put_string(struct udevice *dev, const char *str)
|
int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s, *end = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (s = str; *s; s++) {
|
if (maxlen != -1)
|
||||||
|
end = str + maxlen;
|
||||||
|
for (s = str; *s && (maxlen == -1 || s < end); s++) {
|
||||||
ret = vidconsole_put_char(dev, *s);
|
ret = vidconsole_put_char(dev, *s);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -522,11 +527,19 @@ int vidconsole_put_string(struct udevice *dev, const char *str)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vidconsole_put_string(struct udevice *dev, const char *str)
|
||||||
|
{
|
||||||
|
return vidconsole_put_stringn(dev, str, -1);
|
||||||
|
}
|
||||||
|
|
||||||
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
|
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
|
||||||
{
|
{
|
||||||
struct udevice *dev = sdev->priv;
|
struct udevice *dev = sdev->priv;
|
||||||
|
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (priv->quiet)
|
||||||
|
return;
|
||||||
ret = vidconsole_put_char(dev, ch);
|
ret = vidconsole_put_char(dev, ch);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -544,8 +557,11 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
|
|||||||
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
|
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
|
||||||
{
|
{
|
||||||
struct udevice *dev = sdev->priv;
|
struct udevice *dev = sdev->priv;
|
||||||
|
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (priv->quiet)
|
||||||
|
return;
|
||||||
ret = vidconsole_put_string(dev, s);
|
ret = vidconsole_put_string(dev, s);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -608,14 +624,17 @@ int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
|
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
|
||||||
const char *text, struct vidconsole_bbox *bbox)
|
const char *text, int limit,
|
||||||
|
struct vidconsole_bbox *bbox, struct alist *lines)
|
||||||
{
|
{
|
||||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||||
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
|
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (ops->measure) {
|
if (ops->measure) {
|
||||||
ret = ops->measure(dev, name, size, text, bbox);
|
if (lines)
|
||||||
|
alist_empty(lines);
|
||||||
|
ret = ops->measure(dev, name, size, text, limit, bbox, lines);
|
||||||
if (ret != -ENOSYS)
|
if (ret != -ENOSYS)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -784,3 +803,10 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
|
|||||||
y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1);
|
y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1);
|
||||||
vidconsole_set_cursor_pos(dev, x, y);
|
vidconsole_set_cursor_pos(dev, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vidconsole_set_quiet(struct udevice *dev, bool quiet)
|
||||||
|
{
|
||||||
|
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
|
||||||
|
priv->quiet = quiet;
|
||||||
|
}
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#ifdef CONFIG_SANDBOX
|
#ifdef CONFIG_SANDBOX
|
||||||
#include <asm/sdl.h>
|
#include <asm/sdl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "vidconsole_internal.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Theory of operation:
|
* Theory of operation:
|
||||||
@@ -216,6 +217,40 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
|
||||||
|
int width, u32 colour)
|
||||||
|
{
|
||||||
|
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
int pbytes = VNBYTES(priv->bpix);
|
||||||
|
void *start, *line;
|
||||||
|
int pixels = x1 - x0;
|
||||||
|
int row;
|
||||||
|
|
||||||
|
start = priv->fb + y0 * priv->line_length;
|
||||||
|
start += x0 * pbytes;
|
||||||
|
line = start;
|
||||||
|
for (row = y0; row < y1; row++) {
|
||||||
|
void *ptr = line;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < width; i++)
|
||||||
|
fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
|
||||||
|
if (row < y0 + width || row >= y1 - width) {
|
||||||
|
for (i = 0; i < pixels - width * 2; i++)
|
||||||
|
fill_pixel_and_goto_next(&ptr, colour, pbytes,
|
||||||
|
pbytes);
|
||||||
|
} else {
|
||||||
|
ptr += (pixels - width * 2) * pbytes;
|
||||||
|
}
|
||||||
|
for (i = 0; i < width; i++)
|
||||||
|
fill_pixel_and_goto_next(&ptr, colour, pbytes, pbytes);
|
||||||
|
line += priv->line_length;
|
||||||
|
}
|
||||||
|
video_damage(dev, x0, y0, x1 - x0, y1 - y0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int video_reserve_from_bloblist(struct video_handoff *ho)
|
int video_reserve_from_bloblist(struct video_handoff *ho)
|
||||||
{
|
{
|
||||||
if (!ho->fb || ho->size == 0)
|
if (!ho->fb || ho->size == 0)
|
||||||
@@ -345,7 +380,7 @@ void video_set_default_colors(struct udevice *dev, bool invert)
|
|||||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||||
int fore, back;
|
int fore, back;
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
|
if (priv->white_on_black) {
|
||||||
/* White is used when switching to bold, use light gray here */
|
/* White is used when switching to bold, use light gray here */
|
||||||
fore = VID_LIGHT_GRAY;
|
fore = VID_LIGHT_GRAY;
|
||||||
back = VID_BLACK;
|
back = VID_BLACK;
|
||||||
@@ -481,6 +516,7 @@ int video_sync(struct udevice *vid, bool force)
|
|||||||
video_flush_dcache(vid, true);
|
video_flush_dcache(vid, true);
|
||||||
|
|
||||||
#if defined(CONFIG_VIDEO_SANDBOX_SDL)
|
#if defined(CONFIG_VIDEO_SANDBOX_SDL)
|
||||||
|
/* to see the copy framebuffer, use priv->copy_fb */
|
||||||
sandbox_sdl_sync(priv->fb);
|
sandbox_sdl_sync(priv->fb);
|
||||||
#endif
|
#endif
|
||||||
priv->last_sync = get_timer(0);
|
priv->last_sync = get_timer(0);
|
||||||
@@ -582,6 +618,18 @@ static void video_idle(struct cyclic_info *cyc)
|
|||||||
video_sync_all();
|
video_sync_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void video_set_white_on_black(struct udevice *dev, bool white_on_black)
|
||||||
|
{
|
||||||
|
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
|
||||||
|
if (priv->white_on_black != white_on_black) {
|
||||||
|
priv->white_on_black = white_on_black;
|
||||||
|
video_set_default_colors(dev, false);
|
||||||
|
|
||||||
|
video_clear(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up the display ready for use */
|
/* Set up the display ready for use */
|
||||||
static int video_post_probe(struct udevice *dev)
|
static int video_post_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
@@ -624,6 +672,8 @@ static int video_post_probe(struct udevice *dev)
|
|||||||
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
|
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
|
||||||
priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
|
priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
|
||||||
|
|
||||||
|
priv->white_on_black = CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK);
|
||||||
|
|
||||||
/* Set up colors */
|
/* Set up colors */
|
||||||
video_set_default_colors(dev, false);
|
video_set_default_colors(dev, false);
|
||||||
|
|
||||||
|
@@ -169,6 +169,21 @@ int console_announce_r(void);
|
|||||||
*/
|
*/
|
||||||
void console_puts_select_stderr(bool serial_only, const char *s);
|
void console_puts_select_stderr(bool serial_only, const char *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* console_printf_select_stderr() - Output a formatted string to selected devs
|
||||||
|
*
|
||||||
|
* This writes to stderr only. It is useful for outputting errors. Note that it
|
||||||
|
* uses its own buffer, separate from the print buffer, to allow printing
|
||||||
|
* messages within console/stdio code
|
||||||
|
*
|
||||||
|
* @serial_only: true to output only to serial, false to output to everything
|
||||||
|
* else
|
||||||
|
* @fmt: Printf format string, followed by format arguments
|
||||||
|
* Return: number of characters written
|
||||||
|
*/
|
||||||
|
int console_printf_select_stderr(bool serial_only, const char *fmt, ...)
|
||||||
|
__attribute__ ((format (__printf__, 2, 3)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* console_clear() - Clear the console
|
* console_clear() - Clear the console
|
||||||
*
|
*
|
||||||
|
45
include/test/video.h
Normal file
45
include/test/video.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Google, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TEST_VIDEO_H
|
||||||
|
#define __TEST_VIDEO_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct udevice;
|
||||||
|
struct unit_test_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video_compress_fb() - Compress the frame buffer and return its size
|
||||||
|
*
|
||||||
|
* We want to write tests which perform operations on the video console and
|
||||||
|
* check that the frame buffer ends up with the correct contents. But it is
|
||||||
|
* painful to store 'known good' images for comparison with the frame
|
||||||
|
* buffer. As an alternative, we can compress the frame buffer and check the
|
||||||
|
* size of the compressed data. This provides a pretty good level of
|
||||||
|
* certainty and the resulting tests need only check a single value.
|
||||||
|
*
|
||||||
|
* @uts: Test state
|
||||||
|
* @dev: Video device
|
||||||
|
* @use_copy: Use copy frame buffer if available
|
||||||
|
* Return: compressed size of the frame buffer, or -ve on error
|
||||||
|
*/
|
||||||
|
int video_compress_fb(struct unit_test_state *uts, struct udevice *dev,
|
||||||
|
bool use_copy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check_copy_frame_buffer() - Compare main frame buffer to copy
|
||||||
|
*
|
||||||
|
* If the copy frame buffer is enabled, this compares it to the main
|
||||||
|
* frame buffer. Normally they should have the same contents after a
|
||||||
|
* sync.
|
||||||
|
*
|
||||||
|
* @uts: Test state
|
||||||
|
* @dev: Video device
|
||||||
|
* Return: 0, or -ve on error
|
||||||
|
*/
|
||||||
|
int video_check_copy_fb(struct unit_test_state *uts, struct udevice *dev);
|
||||||
|
|
||||||
|
#endif
|
@@ -100,6 +100,7 @@ enum video_format {
|
|||||||
* @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color)
|
* @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color)
|
||||||
* @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color)
|
* @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color)
|
||||||
* @last_sync: Monotonic time of last video sync
|
* @last_sync: Monotonic time of last video sync
|
||||||
|
* @white_on_black: Use a black background
|
||||||
*/
|
*/
|
||||||
struct video_priv {
|
struct video_priv {
|
||||||
/* Things set up by the driver: */
|
/* Things set up by the driver: */
|
||||||
@@ -131,6 +132,7 @@ struct video_priv {
|
|||||||
u8 fg_col_idx;
|
u8 fg_col_idx;
|
||||||
u8 bg_col_idx;
|
u8 bg_col_idx;
|
||||||
ulong last_sync;
|
ulong last_sync;
|
||||||
|
bool white_on_black;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,7 +249,7 @@ int video_fill(struct udevice *dev, u32 colour);
|
|||||||
/**
|
/**
|
||||||
* video_fill_part() - Erase a region
|
* video_fill_part() - Erase a region
|
||||||
*
|
*
|
||||||
* Erase a rectangle of the display within the given bounds.
|
* Erase a rectangle on the display within the given bounds
|
||||||
*
|
*
|
||||||
* @dev: Device to update
|
* @dev: Device to update
|
||||||
* @xstart: X start position in pixels from the left
|
* @xstart: X start position in pixels from the left
|
||||||
@@ -260,6 +262,23 @@ int video_fill(struct udevice *dev, u32 colour);
|
|||||||
int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
|
int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
|
||||||
int yend, u32 colour);
|
int yend, u32 colour);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video_draw_box() - Draw a box
|
||||||
|
*
|
||||||
|
* Draw a rectangle on the display within the given bounds
|
||||||
|
*
|
||||||
|
* @dev: Device to update
|
||||||
|
* @x0: X start position in pixels from the left
|
||||||
|
* @y0: Y start position in pixels from the top
|
||||||
|
* @x1: X end position in pixels from the left
|
||||||
|
* @y1: Y end position in pixels from the top
|
||||||
|
* @width: width in pixels
|
||||||
|
* @colour: Value to write
|
||||||
|
* Return: 0 if OK, -ENOSYS if the display depth is not supported
|
||||||
|
*/
|
||||||
|
int video_draw_box(struct udevice *dev, int x0, int y0, int x1, int y1,
|
||||||
|
int width, u32 colour);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* video_sync() - Sync a device's frame buffer with its hardware
|
* video_sync() - Sync a device's frame buffer with its hardware
|
||||||
*
|
*
|
||||||
@@ -346,6 +365,16 @@ void video_set_flush_dcache(struct udevice *dev, bool flush);
|
|||||||
*/
|
*/
|
||||||
void video_set_default_colors(struct udevice *dev, bool invert);
|
void video_set_default_colors(struct udevice *dev, bool invert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video_set_white_on_black() - Change the setting for white-on-black
|
||||||
|
*
|
||||||
|
* This does nothing if the setting is already the same.
|
||||||
|
*
|
||||||
|
* @dev: video device
|
||||||
|
* @white_on_black: true to use white-on-black, false for black-on-white
|
||||||
|
*/
|
||||||
|
void video_set_white_on_black(struct udevice *dev, bool white_on_black);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* video_default_font_height() - Get the default font height
|
* video_default_font_height() - Get the default font height
|
||||||
*
|
*
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#ifndef __video_console_h
|
#ifndef __video_console_h
|
||||||
#define __video_console_h
|
#define __video_console_h
|
||||||
|
|
||||||
|
#include <alist.h>
|
||||||
#include <video.h>
|
#include <video.h>
|
||||||
|
|
||||||
struct abuf;
|
struct abuf;
|
||||||
@@ -52,6 +53,7 @@ enum {
|
|||||||
* @row_saved: Saved Y position in pixels (0=top)
|
* @row_saved: Saved Y position in pixels (0=top)
|
||||||
* @escape_buf: Buffer to accumulate escape sequence
|
* @escape_buf: Buffer to accumulate escape sequence
|
||||||
* @utf8_buf: Buffer to accumulate UTF-8 byte sequence
|
* @utf8_buf: Buffer to accumulate UTF-8 byte sequence
|
||||||
|
* @quiet: Suppress all output from stdio
|
||||||
*/
|
*/
|
||||||
struct vidconsole_priv {
|
struct vidconsole_priv {
|
||||||
struct stdio_dev sdev;
|
struct stdio_dev sdev;
|
||||||
@@ -76,6 +78,7 @@ struct vidconsole_priv {
|
|||||||
int col_saved;
|
int col_saved;
|
||||||
char escape_buf[32];
|
char escape_buf[32];
|
||||||
char utf8_buf[5];
|
char utf8_buf[5];
|
||||||
|
bool quiet;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,6 +122,19 @@ struct vidconsole_bbox {
|
|||||||
int y1;
|
int y1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vidconsole_mline - Holds information about a line of measured text
|
||||||
|
*
|
||||||
|
* @bbox: Bounding box of the line, assuming it starts at 0,0
|
||||||
|
* @start: String index of the first character in the line
|
||||||
|
* @len: Number of characters in the line
|
||||||
|
*/
|
||||||
|
struct vidconsole_mline {
|
||||||
|
struct vidconsole_bbox bbox;
|
||||||
|
int start;
|
||||||
|
int len;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct vidconsole_ops - Video console operations
|
* struct vidconsole_ops - Video console operations
|
||||||
*
|
*
|
||||||
@@ -228,18 +244,26 @@ struct vidconsole_ops {
|
|||||||
int (*select_font)(struct udevice *dev, const char *name, uint size);
|
int (*select_font)(struct udevice *dev, const char *name, uint size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* measure() - Measure the bounds of some text
|
* measure() - Measure the bounding box of some text
|
||||||
*
|
*
|
||||||
* @dev: Device to adjust
|
* The text can include newlines
|
||||||
|
*
|
||||||
|
* @dev: Console device to use
|
||||||
* @name: Font name to use (NULL to use default)
|
* @name: Font name to use (NULL to use default)
|
||||||
* @size: Font size to use (0 to use default)
|
* @size: Font size to use (0 to use default)
|
||||||
* @text: Text to measure
|
* @text: Text to measure
|
||||||
|
* @limit: Width limit for each line, or -1 if none
|
||||||
* @bbox: Returns bounding box of text, assuming it is positioned
|
* @bbox: Returns bounding box of text, assuming it is positioned
|
||||||
* at 0,0
|
* at 0,0
|
||||||
|
* @lines: If non-NULL, this must be an alist of
|
||||||
|
* struct vidconsole_mline inited by caller. A separate
|
||||||
|
* record is added for each line of text
|
||||||
|
*
|
||||||
* Returns: 0 on success, -ENOENT if no such font
|
* Returns: 0 on success, -ENOENT if no such font
|
||||||
*/
|
*/
|
||||||
int (*measure)(struct udevice *dev, const char *name, uint size,
|
int (*measure)(struct udevice *dev, const char *name, uint size,
|
||||||
const char *text, struct vidconsole_bbox *bbox);
|
const char *text, int limit,
|
||||||
|
struct vidconsole_bbox *bbox, struct alist *lines);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nominal() - Measure the expected width of a line of text
|
* nominal() - Measure the expected width of a line of text
|
||||||
@@ -320,19 +344,27 @@ int vidconsole_get_font(struct udevice *dev, int seq,
|
|||||||
*/
|
*/
|
||||||
int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
|
int vidconsole_select_font(struct udevice *dev, const char *name, uint size);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* vidconsole_measure() - Measuring the bounding box of some text
|
* vidconsole_measure() - Measure the bounding box of some text
|
||||||
*
|
*
|
||||||
* @dev: Console device to use
|
* The text can include newlines
|
||||||
* @name: Font name, NULL for default
|
*
|
||||||
* @size: Font size, ignored if @name is NULL
|
* @dev: Device to adjust
|
||||||
* @text: Text to measure
|
* @name: Font name to use (NULL to use default)
|
||||||
* @bbox: Returns nounding box of text
|
* @size: Font size to use (0 to use default)
|
||||||
* Returns: 0 if OK, -ve on error
|
* @text: Text to measure
|
||||||
|
* @limit: Width limit for each line, or -1 if none
|
||||||
|
* @bbox: Returns bounding box of text, assuming it is positioned
|
||||||
|
* at 0,0
|
||||||
|
* @lines: If non-NULL, this must be an alist of
|
||||||
|
* struct vidconsole_mline inited by caller. The list is emptied
|
||||||
|
* and then a separate record is added for each line of text
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -ENOENT if no such font
|
||||||
*/
|
*/
|
||||||
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
|
int vidconsole_measure(struct udevice *dev, const char *name, uint size,
|
||||||
const char *text, struct vidconsole_bbox *bbox);
|
const char *text, int limit,
|
||||||
|
struct vidconsole_bbox *bbox, struct alist *lines);
|
||||||
/**
|
/**
|
||||||
* vidconsole_nominal() - Measure the expected width of a line of text
|
* vidconsole_nominal() - Measure the expected width of a line of text
|
||||||
*
|
*
|
||||||
@@ -469,6 +501,23 @@ int vidconsole_entry_start(struct udevice *dev);
|
|||||||
*/
|
*/
|
||||||
int vidconsole_put_char(struct udevice *dev, char ch);
|
int vidconsole_put_char(struct udevice *dev, char ch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vidconsole_put_stringn() - Output part of a string to the current console pos
|
||||||
|
*
|
||||||
|
* Outputs part of a string to the console and advances the cursor. This
|
||||||
|
* function handles wrapping to new lines and scrolling the console. Special
|
||||||
|
* characters are handled also: \n, \r, \b and \t.
|
||||||
|
*
|
||||||
|
* The device always starts with the cursor at position 0,0 (top left). It
|
||||||
|
* can be adjusted manually using vidconsole_position_cursor().
|
||||||
|
*
|
||||||
|
* @dev: Device to adjust
|
||||||
|
* @str: String to write
|
||||||
|
* @maxlen: Maximum chars to output, or -1 for all
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vidconsole_put_string() - Output a string to the current console position
|
* vidconsole_put_string() - Output a string to the current console position
|
||||||
*
|
*
|
||||||
@@ -537,4 +586,12 @@ void vidconsole_list_fonts(struct udevice *dev);
|
|||||||
*/
|
*/
|
||||||
int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
|
int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vidconsole_set_quiet() - Select whether the console should output stdio
|
||||||
|
*
|
||||||
|
* @dev: vidconsole device
|
||||||
|
* @quiet: true to suppress stdout/stderr output, false to enable it
|
||||||
|
*/
|
||||||
|
void vidconsole_set_quiet(struct udevice *dev, bool quiet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
352
test/dm/video.c
352
test/dm/video.c
@@ -17,8 +17,10 @@
|
|||||||
#include <asm/sdl.h>
|
#include <asm/sdl.h>
|
||||||
#include <dm/test.h>
|
#include <dm/test.h>
|
||||||
#include <dm/uclass-internal.h>
|
#include <dm/uclass-internal.h>
|
||||||
|
#include <test/lib.h>
|
||||||
#include <test/test.h>
|
#include <test/test.h>
|
||||||
#include <test/ut.h>
|
#include <test/ut.h>
|
||||||
|
#include <test/video.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These tests use the standard sandbox frame buffer, the resolution of which
|
* These tests use the standard sandbox frame buffer, the resolution of which
|
||||||
@@ -44,24 +46,8 @@ static int dm_test_video_base(struct unit_test_state *uts)
|
|||||||
}
|
}
|
||||||
DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
DM_TEST(dm_test_video_base, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
||||||
|
|
||||||
/**
|
int video_compress_fb(struct unit_test_state *uts, struct udevice *dev,
|
||||||
* compress_frame_buffer() - Compress the frame buffer and return its size
|
bool use_copy)
|
||||||
*
|
|
||||||
* We want to write tests which perform operations on the video console and
|
|
||||||
* check that the frame buffer ends up with the correct contents. But it is
|
|
||||||
* painful to store 'known good' images for comparison with the frame
|
|
||||||
* buffer. As an alternative, we can compress the frame buffer and check the
|
|
||||||
* size of the compressed data. This provides a pretty good level of
|
|
||||||
* certainty and the resulting tests need only check a single value.
|
|
||||||
*
|
|
||||||
* @uts: Test state
|
|
||||||
* @dev: Video device
|
|
||||||
* @use_copy: Use copy frame buffer if available
|
|
||||||
* Return: compressed size of the frame buffer, or -ve on error
|
|
||||||
*/
|
|
||||||
static int compress_frame_buffer(struct unit_test_state *uts,
|
|
||||||
struct udevice *dev,
|
|
||||||
bool use_copy)
|
|
||||||
{
|
{
|
||||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||||
uint destlen;
|
uint destlen;
|
||||||
@@ -86,19 +72,7 @@ static int compress_frame_buffer(struct unit_test_state *uts,
|
|||||||
return destlen;
|
return destlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int video_check_copy_fb(struct unit_test_state *uts, struct udevice *dev)
|
||||||
* check_copy_frame_buffer() - Compare main frame buffer to copy
|
|
||||||
*
|
|
||||||
* If the copy frame buffer is enabled, this compares it to the main
|
|
||||||
* frame buffer. Normally they should have the same contents after a
|
|
||||||
* sync.
|
|
||||||
*
|
|
||||||
* @uts: Test state
|
|
||||||
* @dev: Video device
|
|
||||||
* Return: 0, or -ve on error
|
|
||||||
*/
|
|
||||||
static int check_copy_frame_buffer(struct unit_test_state *uts,
|
|
||||||
struct udevice *dev)
|
|
||||||
{
|
{
|
||||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
|
||||||
@@ -174,31 +148,31 @@ static int dm_test_video_text(struct unit_test_state *uts)
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
vidconsole_putc_xy(con, 0, 0, 'a');
|
vidconsole_putc_xy(con, 0, 0, 'a');
|
||||||
ut_asserteq(79, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(79, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
vidconsole_putc_xy(con, 0, 0, ' ');
|
vidconsole_putc_xy(con, 0, 0, ' ');
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
||||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||||
ut_asserteq(273, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(273, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
vidconsole_set_row(con, 0, WHITE);
|
vidconsole_set_row(con, 0, WHITE);
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
||||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||||
ut_asserteq(273, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(273, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -216,31 +190,31 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts)
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
ut_assertok(vidconsole_select_font(con, "12x22", 0));
|
ut_assertok(vidconsole_select_font(con, "12x22", 0));
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
vidconsole_putc_xy(con, 0, 0, 'a');
|
vidconsole_putc_xy(con, 0, 0, 'a');
|
||||||
ut_asserteq(89, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(89, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
vidconsole_putc_xy(con, 0, 0, ' ');
|
vidconsole_putc_xy(con, 0, 0, ' ');
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
||||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||||
ut_asserteq(363, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(363, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
vidconsole_set_row(con, 0, WHITE);
|
vidconsole_set_row(con, 0, WHITE);
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
||||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||||
ut_asserteq(363, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(363, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -257,8 +231,8 @@ static int dm_test_video_chars(struct unit_test_state *uts)
|
|||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
ut_asserteq(466, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(466, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -279,24 +253,24 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
|
|||||||
/* reference clear: */
|
/* reference clear: */
|
||||||
video_clear(con->parent);
|
video_clear(con->parent);
|
||||||
video_sync(con->parent, false);
|
video_sync(con->parent, false);
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* test clear escape sequence: [2J */
|
/* test clear escape sequence: [2J */
|
||||||
vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
|
vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* test set-cursor: [%d;%df */
|
/* test set-cursor: [%d;%df */
|
||||||
vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
|
vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
|
||||||
ut_asserteq(143, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(143, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* test colors (30-37 fg color, 40-47 bg color) */
|
/* test colors (30-37 fg color, 40-47 bg color) */
|
||||||
vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
|
vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
|
||||||
vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
|
vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
|
||||||
ut_asserteq(272, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(272, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -328,28 +302,28 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* Check display wrap */
|
/* Check display wrap */
|
||||||
for (i = 0; i < 120; i++)
|
for (i = 0; i < 120; i++)
|
||||||
vidconsole_put_char(con, 'A' + i % 50);
|
vidconsole_put_char(con, 'A' + i % 50);
|
||||||
ut_asserteq(wrap_size, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(wrap_size, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* Check display scrolling */
|
/* Check display scrolling */
|
||||||
for (i = 0; i < SCROLL_LINES; i++) {
|
for (i = 0; i < SCROLL_LINES; i++) {
|
||||||
vidconsole_put_char(con, 'A' + i % 50);
|
vidconsole_put_char(con, 'A' + i % 50);
|
||||||
vidconsole_put_char(con, '\n');
|
vidconsole_put_char(con, '\n');
|
||||||
}
|
}
|
||||||
ut_asserteq(scroll_size, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(scroll_size, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/* If we scroll enough, the screen becomes blank again */
|
/* If we scroll enough, the screen becomes blank again */
|
||||||
for (i = 0; i < SCROLL_LINES; i++)
|
for (i = 0; i < SCROLL_LINES; i++)
|
||||||
vidconsole_put_char(con, '\n');
|
vidconsole_put_char(con, '\n');
|
||||||
ut_asserteq(46, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(46, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -423,8 +397,8 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(1368, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -443,8 +417,8 @@ static int dm_test_video_bmp8(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(1247, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -467,8 +441,8 @@ static int dm_test_video_bmp16(struct unit_test_state *uts)
|
|||||||
&src_len));
|
&src_len));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
||||||
ut_asserteq(3700, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(3700, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -491,8 +465,8 @@ static int dm_test_video_bmp24(struct unit_test_state *uts)
|
|||||||
&src_len));
|
&src_len));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
||||||
ut_asserteq(3656, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(3656, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -515,8 +489,8 @@ static int dm_test_video_bmp24_32(struct unit_test_state *uts)
|
|||||||
&src_len));
|
&src_len));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, dst, 0, 0, false));
|
||||||
ut_asserteq(6827, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(6827, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -534,8 +508,8 @@ static int dm_test_video_bmp32(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(2024, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -551,8 +525,8 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(1368, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(1368, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -571,8 +545,8 @@ static int dm_test_video_comp_bmp32(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(2024, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(2024, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -591,8 +565,8 @@ static int dm_test_video_comp_bmp8(struct unit_test_state *uts)
|
|||||||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||||
|
|
||||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||||
ut_asserteq(1247, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(1247, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -607,8 +581,9 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
ut_asserteq(12174, compress_frame_buffer(uts, dev, false));
|
vidconsole_put_stringn(con, test_string, 30);
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_asserteq(13184, video_compress_fb(uts, dev, false));
|
||||||
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -629,8 +604,8 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
ut_asserteq(34287, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(34287, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -651,8 +626,8 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
|
|||||||
ut_assertok(video_get_nologo(uts, &dev));
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
ut_asserteq(29471, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(29471, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -690,8 +665,8 @@ static int dm_test_video_copy(struct unit_test_state *uts)
|
|||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
|
|
||||||
ut_asserteq(6678, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(6678, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Secretly clear the hardware frame buffer, but in a different
|
* Secretly clear the hardware frame buffer, but in a different
|
||||||
@@ -715,8 +690,8 @@ static int dm_test_video_copy(struct unit_test_state *uts)
|
|||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
vidconsole_put_string(con, test_string);
|
vidconsole_put_string(con, test_string);
|
||||||
video_sync(dev, true);
|
video_sync(dev, true);
|
||||||
ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(7589, video_compress_fb(uts, dev, false));
|
||||||
ut_asserteq(7704, compress_frame_buffer(uts, dev, true));
|
ut_asserteq(7704, video_compress_fb(uts, dev, true));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -771,9 +746,180 @@ static int dm_test_video_damage(struct unit_test_state *uts)
|
|||||||
ut_asserteq(0, priv->damage.xend);
|
ut_asserteq(0, priv->damage.xend);
|
||||||
ut_asserteq(0, priv->damage.yend);
|
ut_asserteq(0, priv->damage.yend);
|
||||||
|
|
||||||
ut_asserteq(7339, compress_frame_buffer(uts, dev, false));
|
ut_asserteq(7339, video_compress_fb(uts, dev, false));
|
||||||
ut_assertok(check_copy_frame_buffer(uts, dev));
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
DM_TEST(dm_test_video_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/* Test font measurement */
|
||||||
|
static int dm_test_font_measure(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
const char *test_string = "There is always much\nto be said for not "
|
||||||
|
"attempting more than you can do and for making a certainty of "
|
||||||
|
"what you try. But this principle, like others in life and "
|
||||||
|
"war, has its exceptions.";
|
||||||
|
const struct vidconsole_mline *line;
|
||||||
|
struct vidconsole_bbox bbox;
|
||||||
|
struct video_priv *priv;
|
||||||
|
struct udevice *dev, *con;
|
||||||
|
const int limit = 0x320;
|
||||||
|
struct alist lines;
|
||||||
|
int nl;
|
||||||
|
|
||||||
|
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||||
|
priv = dev_get_uclass_priv(dev);
|
||||||
|
ut_asserteq(1366, priv->xsize);
|
||||||
|
ut_asserteq(768, priv->ysize);
|
||||||
|
|
||||||
|
/* this is using the Nimbus font with size of 18 pixels */
|
||||||
|
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||||
|
vidconsole_position_cursor(con, 0, 0);
|
||||||
|
alist_init_struct(&lines, struct vidconsole_mline);
|
||||||
|
ut_assertok(vidconsole_measure(con, NULL, 0, test_string, -1, &bbox,
|
||||||
|
&lines));
|
||||||
|
ut_asserteq(0, bbox.x0);
|
||||||
|
ut_asserteq(0, bbox.y0);
|
||||||
|
ut_asserteq(0x3ea, bbox.x1);
|
||||||
|
ut_asserteq(0x24, bbox.y1);
|
||||||
|
ut_asserteq(2, lines.count);
|
||||||
|
|
||||||
|
nl = strchr(test_string, '\n') - test_string;
|
||||||
|
|
||||||
|
line = alist_get(&lines, 0, struct vidconsole_mline);
|
||||||
|
ut_assertnonnull(line);
|
||||||
|
ut_asserteq(0, line->bbox.x0);
|
||||||
|
ut_asserteq(0, line->bbox.y0);
|
||||||
|
ut_asserteq(0x8c, line->bbox.x1);
|
||||||
|
ut_asserteq(0x12, line->bbox.y1);
|
||||||
|
ut_asserteq(0, line->start);
|
||||||
|
ut_asserteq(20, line->len);
|
||||||
|
ut_asserteq(nl, line->len);
|
||||||
|
|
||||||
|
line++;
|
||||||
|
ut_asserteq(0x0, line->bbox.x0);
|
||||||
|
ut_asserteq(0x12, line->bbox.y0);
|
||||||
|
ut_asserteq(0x3ea, line->bbox.x1);
|
||||||
|
ut_asserteq(0x24, line->bbox.y1);
|
||||||
|
ut_asserteq(21, line->start);
|
||||||
|
ut_asserteq(nl + 1, line->start);
|
||||||
|
ut_asserteq(163, line->len);
|
||||||
|
ut_asserteq(strlen(test_string + nl + 1), line->len);
|
||||||
|
|
||||||
|
/* now use a limit on the width */
|
||||||
|
ut_assertok(vidconsole_measure(con, NULL, 0, test_string, limit, &bbox,
|
||||||
|
&lines));
|
||||||
|
ut_asserteq(0, bbox.x0);
|
||||||
|
ut_asserteq(0, bbox.y0);
|
||||||
|
ut_asserteq(0x31e, bbox.x1);
|
||||||
|
ut_asserteq(0x36, bbox.y1);
|
||||||
|
ut_asserteq(3, lines.count);
|
||||||
|
|
||||||
|
nl = strchr(test_string, '\n') - test_string;
|
||||||
|
|
||||||
|
line = alist_get(&lines, 0, struct vidconsole_mline);
|
||||||
|
ut_assertnonnull(line);
|
||||||
|
ut_asserteq(0, line->bbox.x0);
|
||||||
|
ut_asserteq(0, line->bbox.y0);
|
||||||
|
ut_asserteq(0x8c, line->bbox.x1);
|
||||||
|
ut_asserteq(0x12, line->bbox.y1);
|
||||||
|
ut_asserteq(0, line->start);
|
||||||
|
ut_asserteq(20, line->len);
|
||||||
|
ut_asserteq(nl, line->len);
|
||||||
|
printf("line0 '%.*s'\n", line->len, test_string + line->start);
|
||||||
|
ut_asserteq_strn("There is always much",
|
||||||
|
test_string + line->start);
|
||||||
|
|
||||||
|
line++;
|
||||||
|
ut_asserteq(0x0, line->bbox.x0);
|
||||||
|
ut_asserteq(0x12, line->bbox.y0);
|
||||||
|
ut_asserteq(0x31e, line->bbox.x1);
|
||||||
|
ut_asserteq(0x24, line->bbox.y1);
|
||||||
|
ut_asserteq(21, line->start);
|
||||||
|
ut_asserteq(nl + 1, line->start);
|
||||||
|
ut_asserteq(129, line->len);
|
||||||
|
printf("line1 '%.*s'\n", line->len, test_string + line->start);
|
||||||
|
ut_asserteq_strn("to be said for not attempting more than you can do "
|
||||||
|
"and for making a certainty of what you try. But this "
|
||||||
|
"principle, like others in",
|
||||||
|
test_string + line->start);
|
||||||
|
|
||||||
|
line++;
|
||||||
|
ut_asserteq(0x0, line->bbox.x0);
|
||||||
|
ut_asserteq(0x24, line->bbox.y0);
|
||||||
|
ut_asserteq(0xc8, line->bbox.x1);
|
||||||
|
ut_asserteq(0x36, line->bbox.y1);
|
||||||
|
ut_asserteq(21 + 130, line->start);
|
||||||
|
ut_asserteq(33, line->len);
|
||||||
|
printf("line2 '%.*s'\n", line->len, test_string + line->start);
|
||||||
|
ut_asserteq_strn("life and war, has its exceptions.",
|
||||||
|
test_string + line->start);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* all characters should be accounted for, except the newline and the
|
||||||
|
* space which is consumed in the wordwrap
|
||||||
|
*/
|
||||||
|
ut_asserteq(strlen(test_string) - 2,
|
||||||
|
line[-2].len + line[-1].len + line->len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_font_measure, UTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/* Test silencing the video console */
|
||||||
|
static int dm_test_video_silence(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *dev, *con;
|
||||||
|
struct stdio_dev *sdev;
|
||||||
|
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* use the old console device from before when dm_test_pre_run() was
|
||||||
|
* called, since that is what is in stdio / console
|
||||||
|
*/
|
||||||
|
sdev = stdio_get_by_name("vidconsole");
|
||||||
|
ut_assertnonnull(sdev);
|
||||||
|
con = sdev->priv;
|
||||||
|
ut_assertok(vidconsole_clear_and_reset(con));
|
||||||
|
ut_unsilence_console(uts);
|
||||||
|
|
||||||
|
printf("message 1: console\n");
|
||||||
|
vidconsole_put_string(con, "message 1: video\n");
|
||||||
|
|
||||||
|
vidconsole_set_quiet(con, true);
|
||||||
|
printf("second message: console\n");
|
||||||
|
vidconsole_put_string(con, "second message: video\n");
|
||||||
|
|
||||||
|
vidconsole_set_quiet(con, false);
|
||||||
|
printf("final message: console\n");
|
||||||
|
vidconsole_put_string(con, "final message: video\n");
|
||||||
|
|
||||||
|
ut_asserteq(3892, video_compress_fb(uts, dev, false));
|
||||||
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_video_silence, UTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/* test drawing a box */
|
||||||
|
static int dm_test_video_box(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct video_priv *priv;
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
ut_assertok(video_get_nologo(uts, &dev));
|
||||||
|
priv = dev_get_uclass_priv(dev);
|
||||||
|
video_draw_box(dev, 100, 100, 200, 200, 3,
|
||||||
|
video_index_to_colour(priv, VID_LIGHT_BLUE));
|
||||||
|
video_draw_box(dev, 300, 100, 400, 200, 1,
|
||||||
|
video_index_to_colour(priv, VID_MAGENTA));
|
||||||
|
video_draw_box(dev, 500, 100, 600, 200, 20,
|
||||||
|
video_index_to_colour(priv, VID_LIGHT_RED));
|
||||||
|
ut_asserteq(133, video_compress_fb(uts, dev, false));
|
||||||
|
ut_assertok(video_check_copy_fb(uts, dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_video_box, UTF_SCAN_FDT);
|
||||||
|
Reference in New Issue
Block a user