1 /* 2 * Copyright (C) 2003 Red Hat, Inc. 3 * Copyright © 2020 Christian Persch 4 * 5 * This library is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published 7 * by the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this library. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 #pragma once 20 21 #include <cstdint> 22 23 #include <memory> 24 25 #include <cairo.h> 26 27 #include <glib.h> 28 #include <gtk/gtk.h> 29 30 #include "cairo-glue.hh" 31 #include "fwd.hh" 32 #include "minifont.hh" 33 #include "vtetypes.hh" 34 #include "vteunistr.h" 35 36 namespace vte { 37 namespace view { 38 39 class DrawingContext { 40 public: 41 42 /* A request to draw a particular character spanning a given number of columns 43 at the given location. Unlike most APIs, (x,y) specifies the top-left 44 corner of the cell into which the character will be drawn instead of the 45 left end of the baseline. */ 46 struct TextRequest { 47 vteunistr c; 48 int16_t x, y, columns; 49 50 /* Char has RTL resolved directionality, mirror if mirrorable. */ 51 uint8_t mirror : 1; 52 53 /* Add box drawing chars to the set of mirrorable characters. */ 54 uint8_t box_mirror : 1; 55 }; 56 57 DrawingContext() noexcept = default; 58 ~DrawingContext(); 59 60 DrawingContext(DrawingContext const&) = delete; 61 DrawingContext(DrawingContext&&) = delete; 62 DrawingContext& operator=(DrawingContext const&) = delete; 63 DrawingContext& operator=(DrawingContext&&) = delete; 64 65 void set_cairo(cairo_t* cr) noexcept; cairo() const66 auto cairo() const noexcept { return m_cr; } 67 68 void clip(cairo_rectangle_int_t const* rect); 69 void unclip(); 70 71 void clear(int x, 72 int y, 73 int width, 74 int height, 75 vte::color::rgb const* color, 76 double alpha); 77 void clear_font_cache(); 78 void set_text_font(GtkWidget* widget, 79 PangoFontDescription const* fontdesc, 80 double cell_width_scale, 81 double cell_height_scale); 82 void get_text_metrics(int* cell_width, 83 int* cell_height, 84 int* char_ascent, 85 int* char_descent, 86 GtkBorder* char_spacing); 87 void get_char_edges(vteunistr c, 88 int columns, 89 uint32_t attr, 90 int& left, 91 int& right); 92 void draw_text(TextRequest* requests, 93 gsize n_requests, 94 uint32_t attr, 95 vte::color::rgb const* color, 96 double alpha); 97 bool draw_char(TextRequest* request, 98 uint32_t attr, 99 vte::color::rgb const* color, 100 double alpha); 101 bool has_char(vteunistr c, 102 uint32_t attr); 103 void fill_rectangle(int x, 104 int y, 105 int width, 106 int height, 107 vte::color::rgb const* color, 108 double alpha); 109 void draw_rectangle(int x, 110 int y, 111 int width, 112 int height, 113 vte::color::rgb const* color, 114 double alpha); 115 void draw_line(int x, 116 int y, 117 int xp, 118 int yp, 119 int line_width, 120 vte::color::rgb const *color, 121 double alpha); 122 123 void draw_undercurl(int x, 124 double y, 125 double line_width, 126 int count, 127 vte::color::rgb const* color, 128 double alpha); 129 cell_width() const130 auto cell_width() const noexcept { return m_cell_width; } cell_height() const131 auto cell_height() const noexcept { return m_cell_height; } 132 133 private: 134 void set_source_color_alpha (vte::color::rgb const* color, 135 double alpha); 136 void draw_graphic(vteunistr c, 137 uint32_t attr, 138 vte::color::rgb const* fg, 139 int x, 140 int y, 141 int font_width, 142 int columns, 143 int font_height); 144 void draw_text_internal(TextRequest* requests, 145 gsize n_requests, 146 uint32_t attr, 147 vte::color::rgb const* color, 148 double alpha); 149 150 // std::array<vte::base::RefPtr<FontInfo>, 4> m_fonts{}; 151 FontInfo* m_fonts[4]{nullptr, nullptr, nullptr, nullptr}; 152 int m_cell_width{1}; 153 int m_cell_height{1}; 154 GtkBorder m_char_spacing{1, 1, 1, 1}; 155 156 cairo_t *m_cr{nullptr}; // unowned 157 158 Minifont m_minifont{}; 159 160 /* Cache the undercurl's rendered look. */ 161 vte::Freeable<cairo_surface_t> m_undercurl_surface{}; 162 163 }; // class DrawingContext 164 165 } // namespace view 166 } // namespace vte 167 168 double 169 _vte_draw_get_undercurl_height(gint width, double line_width); 170 171 class _vte_draw_autoclip_t { 172 private: 173 vte::view::DrawingContext& m_draw; 174 public: _vte_draw_autoclip_t(vte::view::DrawingContext & draw,cairo_rectangle_int_t const * rect)175 _vte_draw_autoclip_t(vte::view::DrawingContext& draw, 176 cairo_rectangle_int_t const* rect) 177 : m_draw{draw} 178 { 179 m_draw.clip(rect); 180 } 181 ~_vte_draw_autoclip_t()182 ~_vte_draw_autoclip_t() 183 { 184 m_draw.unclip(); 185 } 186 }; 187