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 */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
#ifndef LABWC_FONT_H
|
#ifndef LABWC_FONT_H
|
||||||
#define LABWC_FONT_H
|
#define LABWC_FONT_H
|
||||||
|
|
||||||
|
#include <cairo.h>
|
||||||
#include <pango/pango-font.h>
|
#include <pango/pango-font.h>
|
||||||
|
|
||||||
struct lab_data_buffer;
|
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
|
* font_buffer_create - Create ARGB8888 lab_data_buffer using pango
|
||||||
* @buffer: buffer pointer
|
* @buffer: buffer pointer
|
||||||
* @max_width: max allowable width; will be ellipsized if longer
|
* @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
|
* @text: text to be generated as texture
|
||||||
* @font: font description
|
* @font: font description
|
||||||
* @color: foreground color in rgba format
|
* @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,
|
void font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
||||||
const char *text, struct font *font, const float *color,
|
int height, const char *text, struct font *font, const float *color,
|
||||||
const float *bg_color, double scale);
|
cairo_pattern_t *bg_pattern, double scale);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* font_finish - free some font related resources
|
* font_finish - free some font related resources
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,16 @@ struct scaled_font_buffer {
|
||||||
float bg_color[4];
|
float bg_color[4];
|
||||||
struct font font;
|
struct font font;
|
||||||
struct scaled_scene_buffer *scaled_buffer;
|
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);
|
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.
|
* 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
|
* - truncated = buffer->width == max_width
|
||||||
* - text_changed = strcmp(old_text, new_text)
|
* - text_changed = strcmp(old_text, new_text)
|
||||||
* - font and color the same
|
* - 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,
|
void scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
||||||
int max_width, struct font *font, const float *color,
|
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
|
void
|
||||||
font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
||||||
const char *text, struct font *font, const float *color,
|
int height, const char *text, struct font *font, const float *color,
|
||||||
const float *bg_color, double scale)
|
cairo_pattern_t *bg_pattern, double scale)
|
||||||
{
|
{
|
||||||
if (string_null_or_empty(text)) {
|
if (string_null_or_empty(text)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width, height;
|
int width, computed_height;
|
||||||
font_get_buffer_size(max_width, text, font, &width, &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);
|
*buffer = buffer_create_cairo(width, height, scale);
|
||||||
if (!*buffer) {
|
if (!*buffer) {
|
||||||
|
|
@ -114,18 +117,16 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
|
||||||
* buffer unfilled (completely transparent) since the background
|
* buffer unfilled (completely transparent) since the background
|
||||||
* is already rendered by the scene element underneath. In this
|
* is already rendered by the scene element underneath. In this
|
||||||
* case we have to disable subpixel rendering.
|
* 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) {
|
if (opaque_bg) {
|
||||||
set_cairo_color(cairo, bg_color);
|
cairo_set_source(cairo, bg_pattern);
|
||||||
cairo_paint(cairo);
|
cairo_paint(cairo);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_cairo_color(cairo, color);
|
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);
|
PangoLayout *layout = pango_cairo_create_layout(cairo);
|
||||||
pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
|
pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "common/font.h"
|
#include "common/font.h"
|
||||||
|
#include "common/graphic-helpers.h"
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "common/scaled-scene-buffer.h"
|
#include "common/scaled-scene-buffer.h"
|
||||||
#include "common/scaled-font-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 lab_data_buffer *buffer = NULL;
|
||||||
struct scaled_font_buffer *self = scaled_buffer->data;
|
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 */
|
/* Buffer gets free'd automatically along the backing wlr_buffer */
|
||||||
font_buffer_create(&buffer, self->max_width, self->text,
|
font_buffer_create(&buffer, self->max_width, self->height, self->text,
|
||||||
&self->font, self->color, self->bg_color, scale);
|
&self->font, self->color, bg_pattern, scale);
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
wlr_log(WLR_ERROR, "font_buffer_create() failed");
|
wlr_log(WLR_ERROR, "font_buffer_create() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zfree_pattern(solid_bg_pattern);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,6 +46,7 @@ _destroy(struct scaled_scene_buffer *scaled_buffer)
|
||||||
|
|
||||||
zfree(self->text);
|
zfree(self->text);
|
||||||
zfree(self->font.name);
|
zfree(self->font.name);
|
||||||
|
zfree_pattern(self->bg_pattern);
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +64,9 @@ _equal(struct scaled_scene_buffer *scaled_buffer_a,
|
||||||
&& a->font.slant == b->font.slant
|
&& a->font.slant == b->font.slant
|
||||||
&& a->font.weight == b->font.weight
|
&& a->font.weight == b->font.weight
|
||||||
&& !memcmp(a->color, b->color, sizeof(a->color))
|
&& !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 = {
|
static const struct scaled_scene_buffer_impl impl = {
|
||||||
|
|
@ -82,6 +94,18 @@ scaled_font_buffer_create(struct wlr_scene_tree *parent)
|
||||||
return self;
|
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
|
void
|
||||||
scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
|
||||||
int max_width, struct font *font, const float *color,
|
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));
|
memcpy(self->bg_color, bg_color, sizeof(self->bg_color));
|
||||||
|
|
||||||
/* Calculate the size of font buffer and request re-rendering */
|
/* Calculate the size of font buffer and request re-rendering */
|
||||||
|
int computed_height;
|
||||||
font_get_buffer_size(self->max_width, self->text, &self->font,
|
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,
|
scaled_scene_buffer_request_update(self->scaled_buffer,
|
||||||
self->width, self->height);
|
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;
|
self->max_width = max_width;
|
||||||
|
|
||||||
|
int computed_height;
|
||||||
font_get_buffer_size(self->max_width, self->text, &self->font,
|
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,
|
scaled_scene_buffer_request_update(self->scaled_buffer,
|
||||||
self->width, self->height);
|
self->width, self->height);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue