[vte] draw: Move struct unistr_info into FontInfo class
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] draw: Move struct unistr_info into FontInfo class
- Date: Mon, 1 Jun 2020 20:50:47 +0000 (UTC)
commit 9c9d9a44c045b16685061fc0380bcc2d86634011
Author: Christian Persch <chpe src gnome org>
Date: Mon Jun 1 22:48:43 2020 +0200
draw: Move struct unistr_info into FontInfo class
src/vtedraw.cc | 213 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 104 insertions(+), 109 deletions(-)
---
diff --git a/src/vtedraw.cc b/src/vtedraw.cc
index e2efc245..f19dca02 100644
--- a/src/vtedraw.cc
+++ b/src/vtedraw.cc
@@ -86,7 +86,7 @@ _vte_double_equal(double a,
* later. It uses three different internal representations and respectively
* three drawing paths:
*
- * - COVERAGE_USE_CAIRO_GLYPH:
+ * - Coverage::USE_CAIRO_GLYPH:
* Keeping a single glyph index and a cairo scaled-font. This is the
* fastest way to draw text as it bypasses Pango completely and allows
* for stuffing multiple glyphs into a single cairo_show_glyphs() request
@@ -96,7 +96,7 @@ _vte_double_equal(double a,
* than 99% of the cases. Only exceptional cases fall through to the
* other two methods.
*
- * - COVERAGE_USE_PANGO_GLYPH_STRING:
+ * - Coverage::USE_PANGO_GLYPH_STRING:
* Keeping a pango glyphstring and a pango font. This is slightly slower
* than the previous case as drawing each glyph goes through pango
* separately and causes a separate cairo_show_glyphs() call. This method
@@ -104,7 +104,7 @@ _vte_double_equal(double a,
* character all use a single font. This is the method used for hexboxes
* and "empty" characters like U+200C ZERO WIDTH NON-JOINER for example.
*
- * - COVERAGE_USE_PANGO_LAYOUT_LINE:
+ * - Coverage::USE_PANGO_LAYOUT_LINE:
* Keeping a pango layout line. This method is used only in the very
* weird and exceptional case that a single vteunistr uses more than one
* font to be drawn. This happens for example if some diacretics is not
@@ -135,7 +135,7 @@ _vte_double_equal(double a,
* When initializing a font info struct we measure a string consisting of all
* ASCII letters and some other ASCII characters. Since we have a shaped pango
* layout at hand, we walk over it and cache unistr font info for the ASCII
- * letters if we can do that easily using COVERAGE_USE_CAIRO_GLYPH. This
+ * letters if we can do that easily using Coverage::USE_CAIRO_GLYPH. This
* means that we precache all ASCII letters without any extra pango shaping
* involved.
*/
@@ -157,82 +157,6 @@ _vte_double_equal(double a,
*/
#define MAX_RUN_LENGTH 100
-
-enum unistr_coverage {
- /* in increasing order of speed */
- COVERAGE_UNKNOWN = 0, /* we don't know about the character yet */
- COVERAGE_USE_PANGO_LAYOUT_LINE, /* use a PangoLayoutLine for the character */
- COVERAGE_USE_PANGO_GLYPH_STRING, /* use a PangoGlyphString for the character */
- COVERAGE_USE_CAIRO_GLYPH /* use a cairo_glyph_t for the character */
-};
-
-union unistr_font_info {
- /* COVERAGE_USE_PANGO_LAYOUT_LINE */
- struct {
- PangoLayoutLine *line;
- } using_pango_layout_line;
- /* COVERAGE_USE_PANGO_GLYPH_STRING */
- struct {
- PangoFont *font;
- PangoGlyphString *glyph_string;
- } using_pango_glyph_string;
- /* COVERAGE_USE_CAIRO_GLYPH */
- struct {
- cairo_scaled_font_t *scaled_font;
- unsigned int glyph_index;
- } using_cairo_glyph;
-};
-
-struct unistr_info {
- guchar coverage;
- guchar has_unknown_chars;
- guint16 width;
- union unistr_font_info ufi;
-};
-
-static struct unistr_info *
-unistr_info_create (void)
-{
- return g_slice_new0 (struct unistr_info);
-}
-
-static void
-unistr_info_finish (struct unistr_info *uinfo)
-{
- union unistr_font_info *ufi = &uinfo->ufi;
-
- switch (uinfo->coverage) {
- default:
- case COVERAGE_UNKNOWN:
- break;
- case COVERAGE_USE_PANGO_LAYOUT_LINE:
- /* we hold a manual reference on layout */
- g_object_unref (ufi->using_pango_layout_line.line->layout);
- ufi->using_pango_layout_line.line->layout = NULL;
- pango_layout_line_unref (ufi->using_pango_layout_line.line);
- ufi->using_pango_layout_line.line = NULL;
- break;
- case COVERAGE_USE_PANGO_GLYPH_STRING:
- if (ufi->using_pango_glyph_string.font)
- g_object_unref (ufi->using_pango_glyph_string.font);
- ufi->using_pango_glyph_string.font = NULL;
- pango_glyph_string_free (ufi->using_pango_glyph_string.glyph_string);
- ufi->using_pango_glyph_string.glyph_string = NULL;
- break;
- case COVERAGE_USE_CAIRO_GLYPH:
- cairo_scaled_font_destroy (ufi->using_cairo_glyph.scaled_font);
- ufi->using_cairo_glyph.scaled_font = NULL;
- break;
- }
-}
-
-static void
-unistr_info_destroy (struct unistr_info *uinfo)
-{
- unistr_info_finish (uinfo);
- g_slice_free (struct unistr_info, uinfo);
-}
-
guint _vte_draw_get_style(gboolean bold, gboolean italic) {
guint style = 0;
if (bold)
@@ -297,13 +221,83 @@ public:
this);
}
- struct unistr_info *get_unistr_info(vteunistr c);
+ struct UnistrInfo {
+ enum class Coverage : uint8_t {
+ /* in increasing order of speed */
+ UNKNOWN = 0u, /* we don't know about the character yet */
+ USE_PANGO_LAYOUT_LINE, /* use a PangoLayoutLine for the character */
+ USE_PANGO_GLYPH_STRING, /* use a PangoGlyphString for the character */
+ USE_CAIRO_GLYPH /* use a cairo_glyph_t for the character */
+ };
+
+ uint8_t m_coverage{uint8_t(Coverage::UNKNOWN)};
+ uint8_t has_unknown_chars;
+ uint16_t width;
+
+ inline constexpr Coverage coverage() const noexcept { return Coverage{m_coverage}; }
+ inline constexpr void set_coverage(Coverage coverage) { m_coverage = uint8_t(coverage); }
+
+ // FIXME: use std::variant<std::monostate, RefPtr<PangoLayoutLine>, ...> ?
+ union unistr_font_info {
+ /* Coverage::USE_PANGO_LAYOUT_LINE */
+ struct {
+ PangoLayoutLine *line;
+ } using_pango_layout_line;
+ /* Coverage::USE_PANGO_GLYPH_STRING */
+ struct {
+ PangoFont *font;
+ PangoGlyphString *glyph_string;
+ } using_pango_glyph_string;
+ /* Coverage::USE_CAIRO_GLYPH */
+ struct {
+ cairo_scaled_font_t *scaled_font;
+ unsigned int glyph_index;
+ } using_cairo_glyph;
+ } m_ufi;
+
+ UnistrInfo() noexcept = default;
+
+ ~UnistrInfo() noexcept
+ {
+ switch (coverage()) {
+ default:
+ case Coverage::UNKNOWN:
+ break;
+ case Coverage::USE_PANGO_LAYOUT_LINE:
+ /* we hold a manual reference on layout */
+ g_object_unref (m_ufi.using_pango_layout_line.line->layout);
+ m_ufi.using_pango_layout_line.line->layout = NULL;
+ pango_layout_line_unref (m_ufi.using_pango_layout_line.line);
+ m_ufi.using_pango_layout_line.line = NULL;
+ break;
+ case Coverage::USE_PANGO_GLYPH_STRING:
+ if (m_ufi.using_pango_glyph_string.font)
+ g_object_unref (m_ufi.using_pango_glyph_string.font);
+ m_ufi.using_pango_glyph_string.font = NULL;
+ pango_glyph_string_free (m_ufi.using_pango_glyph_string.glyph_string);
+ m_ufi.using_pango_glyph_string.glyph_string = NULL;
+ break;
+ case Coverage::USE_CAIRO_GLYPH:
+ cairo_scaled_font_destroy (m_ufi.using_cairo_glyph.scaled_font);
+ m_ufi.using_cairo_glyph.scaled_font = NULL;
+ break;
+ }
+ }
+
+ }; // struct UnistrInfo
+
+ UnistrInfo *get_unistr_info(vteunistr c);
inline constexpr int width() const { return m_width; }
inline constexpr int height() const { return m_height; }
inline constexpr int ascent() const { return m_ascent; }
private:
+ static void unistr_info_destroy(UnistrInfo* uinfo)
+ {
+ delete uinfo;
+ }
+
static gboolean destroy_delayed_cb(void* that)
{
auto info = reinterpret_cast<FontInfo*>(that);
@@ -314,7 +308,7 @@ private:
mutable int m_ref_count{1};
- struct unistr_info* find_unistr_info(vteunistr c);
+ UnistrInfo* find_unistr_info(vteunistr c);
void cache_ascii();
void measure_font();
guint m_destroy_timeout{0}; /* only used when ref_count == 0 */
@@ -323,7 +317,9 @@ private:
vte::glib::RefPtr<PangoLayout> m_layout{};
/* cache of character info */
- struct unistr_info m_ascii_unistr_info[128];
+ // FIXME: use std::array<UnistrInfo, 128>
+ UnistrInfo m_ascii_unistr_info[128];
+ // FIXME: use std::unordered_map<vteunistr, UnistrInfo>
GHashTable* m_other_unistr_info{nullptr};
/* cell metrics as taken from the font, not yet scaled by cell_{width,height}_scale */
@@ -332,6 +328,7 @@ private:
int m_ascent{0};
/* reusable string for UTF-8 conversion */
+ // FIXME: use std::string
GString* m_string{nullptr};
#ifdef VTE_DEBUG
@@ -356,7 +353,7 @@ private:
}; // class FontInfo
-struct unistr_info *
+FontInfo::UnistrInfo*
FontInfo::find_unistr_info(vteunistr c)
{
if (G_LIKELY (c < G_N_ELEMENTS(m_ascii_unistr_info)))
@@ -365,11 +362,11 @@ FontInfo::find_unistr_info(vteunistr c)
if (G_UNLIKELY (m_other_unistr_info == nullptr))
m_other_unistr_info = g_hash_table_new_full(nullptr, nullptr, nullptr,
(GDestroyNotify)unistr_info_destroy);
- auto uinfo = (struct unistr_info *)g_hash_table_lookup(m_other_unistr_info, GINT_TO_POINTER (c));
+ auto uinfo = reinterpret_cast<UnistrInfo*>(g_hash_table_lookup(m_other_unistr_info,
GINT_TO_POINTER(c)));
if (G_LIKELY (uinfo))
return uinfo;
- uinfo = unistr_info_create ();
+ uinfo = new UnistrInfo{};
g_hash_table_insert(m_other_unistr_info, GINT_TO_POINTER (c), uinfo);
return uinfo;
}
@@ -422,8 +419,6 @@ FontInfo::cache_ascii()
more;
more = pango_glyph_item_iter_next_cluster (&iter))
{
- struct unistr_info *uinfo;
- union unistr_font_info *ufi;
PangoGlyphGeometry *geometry;
PangoGlyph glyph;
vteunistr c;
@@ -449,23 +444,23 @@ FontInfo::cache_ascii()
if (!(glyph <= 0xFFFF) || (geometry->x_offset | geometry->y_offset) != 0)
continue;
- uinfo = find_unistr_info(c);
- if (G_UNLIKELY (uinfo->coverage != COVERAGE_UNKNOWN))
+ auto uinfo = find_unistr_info(c);
+ if (G_UNLIKELY (uinfo->coverage() != UnistrInfo::Coverage::UNKNOWN))
continue;
- ufi = &uinfo->ufi;
+ auto ufi = &uinfo->m_ufi;
uinfo->width = PANGO_PIXELS_CEIL (geometry->width);
uinfo->has_unknown_chars = false;
- uinfo->coverage = COVERAGE_USE_CAIRO_GLYPH;
+ uinfo->set_coverage(UnistrInfo::Coverage::USE_CAIRO_GLYPH);
ufi->using_cairo_glyph.scaled_font = cairo_scaled_font_reference (scaled_font);
ufi->using_cairo_glyph.glyph_index = glyph;
#ifdef VTE_DEBUG
m_coverage_count[0]++;
- m_coverage_count[uinfo->coverage]++;
+ m_coverage_count[(unsigned)uinfo->coverage()]++;
#endif
}
@@ -529,6 +524,7 @@ FontInfo::FontInfo(PangoContext *context)
"vtepangocairo: %p allocating FontInfo\n",
(void*)this);
+ // FIXME: placement new
memset(m_ascii_unistr_info, 0, sizeof(m_ascii_unistr_info));
m_layout = vte::glib::take_ref(pango_layout_new(context));
@@ -568,7 +564,7 @@ FontInfo::~FontInfo()
g_string_free(m_string, true);
for (i = 0; i < G_N_ELEMENTS(m_ascii_unistr_info); i++)
- unistr_info_finish(&m_ascii_unistr_info[i]);
+ m_ascii_unistr_info[i].~UnistrInfo();
if (m_other_unistr_info) {
g_hash_table_destroy(m_other_unistr_info);
@@ -706,18 +702,17 @@ FontInfo::create_for_widget(GtkWidget* widget,
return create_for_screen(screen, desc, language);
}
-struct unistr_info *
+FontInfo::UnistrInfo*
FontInfo::get_unistr_info(vteunistr c)
{
- union unistr_font_info *ufi;
PangoRectangle logical;
PangoLayoutLine *line;
auto uinfo = find_unistr_info(c);
- if (G_LIKELY (uinfo->coverage != COVERAGE_UNKNOWN))
+ if (G_LIKELY (uinfo->coverage() != UnistrInfo::Coverage::UNKNOWN))
return uinfo;
- ufi = &uinfo->ufi;
+ auto ufi = &uinfo->m_ufi;
g_string_set_size(m_string, 0);
_vte_unistr_append_to_string(c, m_string);
@@ -732,7 +727,7 @@ FontInfo::get_unistr_info(vteunistr c)
/* we use PangoLayoutRun rendering unless there is exactly one run in the line. */
if (G_UNLIKELY (!line || !line->runs || line->runs->next))
{
- uinfo->coverage = COVERAGE_USE_PANGO_LAYOUT_LINE;
+ uinfo->set_coverage(UnistrInfo::Coverage::USE_PANGO_LAYOUT_LINE);
ufi->using_pango_layout_line.line = pango_layout_line_ref (line);
/* we hold a manual reference on layout. pango currently
@@ -755,7 +750,7 @@ FontInfo::get_unistr_info(vteunistr c)
cairo_scaled_font_t *scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont
*) pango_font);
if (scaled_font) {
- uinfo->coverage = COVERAGE_USE_CAIRO_GLYPH;
+ uinfo->set_coverage(UnistrInfo::Coverage::USE_CAIRO_GLYPH);
ufi->using_cairo_glyph.scaled_font = cairo_scaled_font_reference
(scaled_font);
ufi->using_cairo_glyph.glyph_index = glyph_string->glyphs[0].glyph;
@@ -763,8 +758,8 @@ FontInfo::get_unistr_info(vteunistr c)
}
/* use pango fast path otherwise */
- if (G_UNLIKELY (uinfo->coverage == COVERAGE_UNKNOWN)) {
- uinfo->coverage = COVERAGE_USE_PANGO_GLYPH_STRING;
+ if (G_UNLIKELY (uinfo->coverage() == UnistrInfo::Coverage::UNKNOWN)) {
+ uinfo->set_coverage(UnistrInfo::Coverage::USE_PANGO_GLYPH_STRING);
ufi->using_pango_glyph_string.font = pango_font ? (PangoFont *)g_object_ref
(pango_font) : NULL;
ufi->using_pango_glyph_string.glyph_string = pango_glyph_string_copy (glyph_string);
@@ -776,7 +771,7 @@ FontInfo::get_unistr_info(vteunistr c)
#ifdef VTE_DEBUG
m_coverage_count[0]++;
- m_coverage_count[uinfo->coverage]++;
+ m_coverage_count[uinfo->m_coverage]++;
#endif
return uinfo;
@@ -2110,7 +2105,7 @@ DrawingContext::draw_text_internal(TextRequest* requests,
}
auto uinfo = font->get_unistr_info(c);
- union unistr_font_info *ufi = &uinfo->ufi;
+ auto ufi = &uinfo->m_ufi;
int x, y, ye;
get_char_edges(c, requests[i].columns, style, x, ye /* unused */);
@@ -2119,23 +2114,23 @@ DrawingContext::draw_text_internal(TextRequest* requests,
* baselines, we offset by the normal font's ascent here. (Bug 137.) */
y = requests[i].y + m_char_spacing.top + m_fonts[VTE_DRAW_NORMAL]->ascent();
- switch (uinfo->coverage) {
+ switch (uinfo->coverage()) {
default:
- case COVERAGE_UNKNOWN:
+ case FontInfo::UnistrInfo::Coverage::UNKNOWN:
g_assert_not_reached ();
break;
- case COVERAGE_USE_PANGO_LAYOUT_LINE:
+ case FontInfo::UnistrInfo::Coverage::USE_PANGO_LAYOUT_LINE:
cairo_move_to(m_cr, x, y);
pango_cairo_show_layout_line(m_cr,
ufi->using_pango_layout_line.line);
break;
- case COVERAGE_USE_PANGO_GLYPH_STRING:
+ case FontInfo::UnistrInfo::Coverage::USE_PANGO_GLYPH_STRING:
cairo_move_to(m_cr, x, y);
pango_cairo_show_glyph_string(m_cr,
ufi->using_pango_glyph_string.font,
ufi->using_pango_glyph_string.glyph_string);
break;
- case COVERAGE_USE_CAIRO_GLYPH:
+ case FontInfo::UnistrInfo::Coverage::USE_CAIRO_GLYPH:
if (last_scaled_font != ufi->using_cairo_glyph.scaled_font || n_cr_glyphs ==
MAX_RUN_LENGTH) {
if (n_cr_glyphs) {
cairo_set_scaled_font(m_cr, last_scaled_font);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]