mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-14 11:34:58 +00:00
Font: split cairo context and surface creation into their own functions
This will allow us to more easily experiment with cairo in other places. See #10007 for an example.
This commit is contained in:
parent
49564ed86c
commit
b0fca37cbc
49
src/font/cairo.hpp
Normal file
49
src/font/cairo.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright (C) 2025 - 2025
|
||||
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdl/point.hpp"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <memory>
|
||||
|
||||
namespace cairo
|
||||
{
|
||||
using surface_ptr = std::unique_ptr<cairo_surface_t, void(*)(cairo_surface_t*)>;
|
||||
using context_ptr = std::unique_ptr<cairo_t, void(*)(cairo_t*)>;
|
||||
|
||||
/** Color format for cairo surfaces. Should be equivalent to the format used by SDL. */
|
||||
constexpr cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
surface_ptr create_surface(uint8_t* buffer, const point& size)
|
||||
{
|
||||
const auto& [width, height] = size;
|
||||
const int stride = cairo_format_stride_for_width(format, width);
|
||||
|
||||
return {
|
||||
cairo_image_surface_create_for_data(buffer, format, width, height, stride),
|
||||
cairo_surface_destroy
|
||||
};
|
||||
}
|
||||
|
||||
context_ptr create_context(const surface_ptr& surf)
|
||||
{
|
||||
return {
|
||||
cairo_create(surf.get()),
|
||||
cairo_destroy
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace cairo
|
|
@ -18,6 +18,7 @@
|
|||
#include "font/text.hpp"
|
||||
|
||||
#include "font/attributes.hpp"
|
||||
#include "font/cairo.hpp"
|
||||
#include "font/font_config.hpp"
|
||||
|
||||
#include "font/pango/escape.hpp"
|
||||
|
@ -710,20 +711,20 @@ static void from_cairo_format(uint32_t & c)
|
|||
|
||||
void pango_text::render(PangoLayout& layout, const SDL_Rect& viewport, const unsigned stride)
|
||||
{
|
||||
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
uint8_t* buffer = &surface_buffer_[0];
|
||||
|
||||
std::unique_ptr<cairo_surface_t, std::function<void(cairo_surface_t*)>> cairo_surface(
|
||||
cairo_image_surface_create_for_data(buffer, format, viewport.w, viewport.h, stride), cairo_surface_destroy);
|
||||
std::unique_ptr<cairo_t, std::function<void(cairo_t*)>> cr(cairo_create(cairo_surface.get()), cairo_destroy);
|
||||
auto cairo_surface = cairo::create_surface(buffer, point{ viewport.w, viewport.h }); // TODO: use rect::size
|
||||
auto cairo_context = cairo::create_context(cairo_surface);
|
||||
|
||||
if(cairo_status(cr.get()) == CAIRO_STATUS_INVALID_SIZE) {
|
||||
// Convenience pointer
|
||||
cairo_t* cr = cairo_context.get();
|
||||
|
||||
if(cairo_status(cr) == CAIRO_STATUS_INVALID_SIZE) {
|
||||
throw std::length_error("Text is too long to render");
|
||||
}
|
||||
|
||||
// The top-left of the text, which can be outside the area to be rendered
|
||||
cairo_move_to(cr.get(), -viewport.x, -viewport.y);
|
||||
cairo_move_to(cr, -viewport.x, -viewport.y);
|
||||
|
||||
//
|
||||
// TODO: the outline may be slightly cut off around certain text if it renders too
|
||||
|
@ -736,27 +737,27 @@ void pango_text::render(PangoLayout& layout, const SDL_Rect& viewport, const uns
|
|||
//
|
||||
if(add_outline_) {
|
||||
// Add a path to the cairo context tracing the current text.
|
||||
pango_cairo_layout_path(cr.get(), &layout);
|
||||
pango_cairo_layout_path(cr, &layout);
|
||||
|
||||
// Set color for background outline (black).
|
||||
cairo_set_source_rgba(cr.get(), 0.0, 0.0, 0.0, 1.0);
|
||||
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
cairo_set_line_join(cr.get(), CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_set_line_width(cr.get(), 3.0); // Adjust as necessary
|
||||
cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
|
||||
cairo_set_line_width(cr, 3.0); // Adjust as necessary
|
||||
|
||||
// Stroke path to draw outline.
|
||||
cairo_stroke(cr.get());
|
||||
cairo_stroke(cr);
|
||||
}
|
||||
|
||||
// Set main text color.
|
||||
cairo_set_source_rgba(cr.get(),
|
||||
cairo_set_source_rgba(cr,
|
||||
foreground_color_.r / 255.0,
|
||||
foreground_color_.g / 255.0,
|
||||
foreground_color_.b / 255.0,
|
||||
foreground_color_.a / 255.0
|
||||
);
|
||||
|
||||
pango_cairo_show_layout(cr.get(), &layout);
|
||||
pango_cairo_show_layout(cr, &layout);
|
||||
}
|
||||
|
||||
surface pango_text::create_surface()
|
||||
|
|
Loading…
Reference in New Issue
Block a user