mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
common/font: add scaled_font_buffer_create_for_titlebar()
Co-authored-by: tokyo4j <hrak1529@gmail.com>
This commit is contained in:
parent
3ca7adace0
commit
54b236e027
4 changed files with 76 additions and 18 deletions
|
|
@ -1,6 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef LABWC_FONT_H
|
||||
#define LABWC_FONT_H
|
||||
|
||||
#include <cairo.h>
|
||||
#include <pango/pango-font.h>
|
||||
|
||||
struct lab_data_buffer;
|
||||
|
|
@ -36,14 +38,15 @@ void font_get_buffer_size(int max_width, const char *text, struct font *font,
|
|||
* font_buffer_create - Create ARGB8888 lab_data_buffer using pango
|
||||
* @buffer: buffer pointer
|
||||
* @max_width: max allowable width; will be ellipsized if longer
|
||||
* @height: buffer height or -1 to compute from font
|
||||
* @text: text to be generated as texture
|
||||
* @font: font description
|
||||
* @color: foreground color in rgba format
|
||||
* @bg_color: background color in rgba format
|
||||
* @bg_pattern: background pattern
|
||||
*/
|
||||
void font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
||||
const char *text, struct font *font, const float *color,
|
||||
const float *bg_color, double scale);
|
||||
int height, const char *text, struct font *font, const float *color,
|
||||
cairo_pattern_t *bg_pattern, double scale);
|
||||
|
||||
/**
|
||||
* font_finish - free some font related resources
|
||||
|
|
|
|||
|
|
@ -20,6 +20,16 @@ struct scaled_font_buffer {
|
|||
float bg_color[4];
|
||||
struct font font;
|
||||
struct scaled_scene_buffer *scaled_buffer;
|
||||
|
||||
/*
|
||||
* The following fields are used only for the titlebar, where
|
||||
* the font buffer can be rendered with a pattern background to
|
||||
* support gradients. In this case, the font buffer is also
|
||||
* padded to a fixed height (with the text centered vertically)
|
||||
* in order to align the pattern with the rest of the titlebar.
|
||||
*/
|
||||
int fixed_height;
|
||||
cairo_pattern_t *bg_pattern; /* overrides bg_color if set */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -33,6 +43,17 @@ struct scaled_font_buffer {
|
|||
*/
|
||||
struct scaled_font_buffer *scaled_font_buffer_create(struct wlr_scene_tree *parent);
|
||||
|
||||
/**
|
||||
* Create an auto scaling font buffer for titlebar text.
|
||||
* The font buffer takes a new reference to bg_pattern.
|
||||
*
|
||||
* @param fixed_height Fixed height for the buffer (logical pixels)
|
||||
* @param bg_pattern Background pattern (solid color or gradient)
|
||||
*/
|
||||
struct scaled_font_buffer *
|
||||
scaled_font_buffer_create_for_titlebar(struct wlr_scene_tree *parent,
|
||||
int fixed_height, cairo_pattern_t *bg_pattern);
|
||||
|
||||
/**
|
||||
* Update an existing auto scaling font buffer.
|
||||
*
|
||||
|
|
@ -44,6 +65,9 @@ struct scaled_font_buffer *scaled_font_buffer_create(struct wlr_scene_tree *pare
|
|||
* - truncated = buffer->width == max_width
|
||||
* - text_changed = strcmp(old_text, new_text)
|
||||
* - font and color the same
|
||||
*
|
||||
* bg_color is ignored for font buffers created with
|
||||
* scaled_font_buffer_create_for_titlebar().
|
||||
*/
|
||||
void scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
||||
int max_width, struct font *font, const float *color,
|
||||
|
|
|
|||
|
|
@ -86,15 +86,18 @@ font_get_buffer_size(int max_width, const char *text, struct font *font,
|
|||
|
||||
void
|
||||
font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
||||
const char *text, struct font *font, const float *color,
|
||||
const float *bg_color, double scale)
|
||||
int height, const char *text, struct font *font, const float *color,
|
||||
cairo_pattern_t *bg_pattern, double scale)
|
||||
{
|
||||
if (string_null_or_empty(text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
font_get_buffer_size(max_width, text, font, &width, &height);
|
||||
int width, computed_height;
|
||||
font_get_buffer_size(max_width, text, font, &width, &computed_height);
|
||||
if (height <= 0) {
|
||||
height = computed_height;
|
||||
}
|
||||
|
||||
*buffer = buffer_create_cairo(width, height, scale);
|
||||
if (!*buffer) {
|
||||
|
|
@ -114,18 +117,16 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
|||
* buffer unfilled (completely transparent) since the background
|
||||
* is already rendered by the scene element underneath. In this
|
||||
* case we have to disable subpixel rendering.
|
||||
*
|
||||
* Note: the 0.999 cutoff was chosen to be greater than 254/255
|
||||
* (about 0.996) but leave some margin for rounding errors.
|
||||
*/
|
||||
bool opaque_bg = (bg_color[3] > 0.999f);
|
||||
bool opaque_bg = is_pattern_opaque(bg_pattern);
|
||||
if (opaque_bg) {
|
||||
set_cairo_color(cairo, bg_color);
|
||||
cairo_set_source(cairo, bg_pattern);
|
||||
cairo_paint(cairo);
|
||||
}
|
||||
|
||||
set_cairo_color(cairo, color);
|
||||
cairo_move_to(cairo, 0, 0);
|
||||
/* center vertically if height was explicitly specified */
|
||||
cairo_move_to(cairo, 0, (height - computed_height) / 2);
|
||||
|
||||
PangoLayout *layout = pango_cairo_create_layout(cairo);
|
||||
pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include "buffer.h"
|
||||
#include "common/font.h"
|
||||
#include "common/graphic-helpers.h"
|
||||
#include "common/mem.h"
|
||||
#include "common/scaled-scene-buffer.h"
|
||||
#include "common/scaled-font-buffer.h"
|
||||
|
|
@ -17,15 +18,23 @@ _create_buffer(struct scaled_scene_buffer *scaled_buffer, double scale)
|
|||
{
|
||||
struct lab_data_buffer *buffer = NULL;
|
||||
struct scaled_font_buffer *self = scaled_buffer->data;
|
||||
cairo_pattern_t *bg_pattern = self->bg_pattern;
|
||||
cairo_pattern_t *solid_bg_pattern = NULL;
|
||||
|
||||
if (!bg_pattern) {
|
||||
solid_bg_pattern = color_to_pattern(self->bg_color);
|
||||
bg_pattern = solid_bg_pattern;
|
||||
}
|
||||
|
||||
/* Buffer gets free'd automatically along the backing wlr_buffer */
|
||||
font_buffer_create(&buffer, self->max_width, self->text,
|
||||
&self->font, self->color, self->bg_color, scale);
|
||||
font_buffer_create(&buffer, self->max_width, self->height, self->text,
|
||||
&self->font, self->color, bg_pattern, scale);
|
||||
|
||||
if (!buffer) {
|
||||
wlr_log(WLR_ERROR, "font_buffer_create() failed");
|
||||
}
|
||||
|
||||
zfree_pattern(solid_bg_pattern);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +46,7 @@ _destroy(struct scaled_scene_buffer *scaled_buffer)
|
|||
|
||||
zfree(self->text);
|
||||
zfree(self->font.name);
|
||||
zfree_pattern(self->bg_pattern);
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +64,9 @@ _equal(struct scaled_scene_buffer *scaled_buffer_a,
|
|||
&& a->font.slant == b->font.slant
|
||||
&& a->font.weight == b->font.weight
|
||||
&& !memcmp(a->color, b->color, sizeof(a->color))
|
||||
&& !memcmp(a->bg_color, b->bg_color, sizeof(a->bg_color));
|
||||
&& !memcmp(a->bg_color, b->bg_color, sizeof(a->bg_color))
|
||||
&& a->fixed_height == b->fixed_height
|
||||
&& a->bg_pattern == b->bg_pattern;
|
||||
}
|
||||
|
||||
static const struct scaled_scene_buffer_impl impl = {
|
||||
|
|
@ -82,6 +94,18 @@ scaled_font_buffer_create(struct wlr_scene_tree *parent)
|
|||
return self;
|
||||
}
|
||||
|
||||
struct scaled_font_buffer *
|
||||
scaled_font_buffer_create_for_titlebar(struct wlr_scene_tree *parent,
|
||||
int fixed_height, cairo_pattern_t *bg_pattern)
|
||||
{
|
||||
struct scaled_font_buffer *self = scaled_font_buffer_create(parent);
|
||||
if (self) {
|
||||
self->fixed_height = fixed_height;
|
||||
self->bg_pattern = cairo_pattern_reference(bg_pattern);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
||||
int max_width, struct font *font, const float *color,
|
||||
|
|
@ -109,8 +133,11 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
|||
memcpy(self->bg_color, bg_color, sizeof(self->bg_color));
|
||||
|
||||
/* Calculate the size of font buffer and request re-rendering */
|
||||
int computed_height;
|
||||
font_get_buffer_size(self->max_width, self->text, &self->font,
|
||||
&self->width, &self->height);
|
||||
&self->width, &computed_height);
|
||||
self->height = (self->fixed_height > 0) ?
|
||||
self->fixed_height : computed_height;
|
||||
scaled_scene_buffer_request_update(self->scaled_buffer,
|
||||
self->width, self->height);
|
||||
}
|
||||
|
|
@ -120,8 +147,11 @@ scaled_font_buffer_set_max_width(struct scaled_font_buffer *self, int max_width)
|
|||
{
|
||||
self->max_width = max_width;
|
||||
|
||||
int computed_height;
|
||||
font_get_buffer_size(self->max_width, self->text, &self->font,
|
||||
&self->width, &self->height);
|
||||
&self->width, &computed_height);
|
||||
self->height = (self->fixed_height > 0) ?
|
||||
self->fixed_height : computed_height;
|
||||
scaled_scene_buffer_request_update(self->scaled_buffer,
|
||||
self->width, self->height);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue