Skip to content

Commit 501848b

Browse files
committed
Merge branch 'no-global-cdtors'
* no-global-cdtors: LIB: remove unused function declaration LIB: document initialization for InstEncCache GLUI: TextRenderer: fixed signedness warning LV2: warn about global ctors / dtors VST: warn about global ctors / dtors CLAP: warn about global ctors / dtors TESTS: testisincos: avoid double<->float conversion in perf test LIB: move int_sincos_table to MathTables, avoid memory leak LIB: PolyPhaseInter: free memory when done LIB: IFFTSynthTable: free memory when done GLUI: TextRenderer: free memory when done GLUI: warn about global constructors / destructors when using clang++ GLUI: avoid global constructors / destructors for linux file dialog LIB: UtilsGlobal: avoid global constructors / destructors for utils LIB: warn about global constructors / destructors when using clang++ BUILD: setup global constructor / destructor warnings when using clang++ LIB: DebugGlobal: avoid global constructors / destructors for debugging LIB: NoiseDecoderGlobal: use anon namespace LIB: IFFTSynthGlobal: use anon namespace LIB: IFFTSynth: manage global state via Singleton LIB: NoiseDecoder: move global data to Singleton LIB: avoid global dtor in pugixml LIB: SKFilter: manage RTable via Singleton LIB: WavSetRepo: allow inlining Singleton instance getter LIB: LiveDecoder: maintain antialias filter table via Singleton LIB: FFT: manage global FFT state via Singleton LIB: Singleton: use std::atomic to avoid lock for reading ptr (performance) LIB: WavSetRepo: use new Singleton template LIB: Singleton: add template to create / destroy singleton like classes Merge branch 'freetype-font' * freetype-font: GLUI: TextRenderer: minor rename refactoring GLUI: TextRenderer: improve error handling code slightly GLUI: TextRenderer: reserve cached glyph bitmap before initialization GLUI: TextRenderer: use std::unique_ptr to free glyph cache entries GLUI: TextRenderer: reserve space for glyphs vector (performance) GLUI: DrawUtils: support Orientation::VERTICAL text using TextRenderer GLUI: TextRenderer: if DejaVu Sans is not available use sans-serif font GLUI: TextRenderer: fallback: locate font using fontconfig if necessary GLUI: TextRenderer: move implementation to its own .cc / .hh file GLUI: TextRenderer: don't crash if no font was loaded GLUI: TextRenderer: avoid FT_Get_Char_Index for cached glyphs GLUI: TextRenderer: use unordered_map for glyph_cache GLUI: TextRenderer: use int for Glyph advance_x (whole pixel offset) GLUI: TextRenderer: move memcpy offset computation out of the loop GLUI: DrawUtils: fix font size setup in TextRenderer GLUI: DrawUtils: no longer select cairo font on cr GLUI: TextRenderer: add a mutex GLUI: DrawUtils: port text_extents method to use TextRenderer GLUI: TextRenderer: move remaining text->surface code here GLUI: TextRenderer: move str -> glyphs conversion to its own function GLUI: TextRenderer: reset cache if UI scaling changed GLUI: TextRenderer: support different font caches for each size GLUI: TextRenderer: start to migrate text rendering to its own class GLUI: DrawUtils: implement FontExtents GLUI: DrawUtils: fix TextExtents computation for character _ (and similar) GLUI: DrawUtils: support computing TextExtents from bounding box GLUI: smuitest: support setting string for smuitest textperf GLUI: DrawUtils: merge text glyphs before masking (performance) GLUI: DrawUtils: move some code out of the inner loop GLUI: DrawUtils: add simple glyph cache for text rendering GLUI: DrawUtils: snap text to device pixels GLUI: smuitest: add text performance test GLUI: first prototype: use freetype for rendering fonts directly GLUI: TextRenderer: minor rename refactoring GLUI: TextRenderer: improve error handling code slightly GLUI: TextRenderer: reserve cached glyph bitmap before initialization GLUI: TextRenderer: use std::unique_ptr to free glyph cache entries GLUI: TextRenderer: reserve space for glyphs vector (performance) GLUI: DrawUtils: support Orientation::VERTICAL text using TextRenderer GLUI: TextRenderer: if DejaVu Sans is not available use sans-serif font GLUI: TextRenderer: fallback: locate font using fontconfig if necessary GLUI: TextRenderer: move implementation to its own .cc / .hh file GLUI: TextRenderer: don't crash if no font was loaded GLUI: TextRenderer: avoid FT_Get_Char_Index for cached glyphs GLUI: TextRenderer: use unordered_map for glyph_cache GLUI: TextRenderer: use int for Glyph advance_x (whole pixel offset) GLUI: TextRenderer: move memcpy offset computation out of the loop GLUI: DrawUtils: fix font size setup in TextRenderer GLUI: DrawUtils: no longer select cairo font on cr GLUI: TextRenderer: add a mutex GLUI: DrawUtils: port text_extents method to use TextRenderer GLUI: TextRenderer: move remaining text->surface code here GLUI: TextRenderer: move str -> glyphs conversion to its own function GLUI: TextRenderer: reset cache if UI scaling changed GLUI: TextRenderer: support different font caches for each size GLUI: TextRenderer: start to migrate text rendering to its own class GLUI: DrawUtils: implement FontExtents GLUI: DrawUtils: fix TextExtents computation for character _ (and similar) GLUI: DrawUtils: support computing TextExtents from bounding box GLUI: smuitest: support setting string for smuitest textperf GLUI: DrawUtils: merge text glyphs before masking (performance) GLUI: DrawUtils: move some code out of the inner loop GLUI: DrawUtils: add simple glyph cache for text rendering GLUI: DrawUtils: snap text to device pixels GLUI: smuitest: add text performance test GLUI: first prototype: use freetype for rendering fonts directly Signed-off-by: Stefan Westerfeld <[email protected]>
2 parents 7340d6c + f6aaff1 commit 501848b

34 files changed

+888
-277
lines changed

clap/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include $(top_srcdir)/Makefile.decl
22

3-
AM_CXXFLAGS += $(GLIB_CFLAGS) $(FFTW_CFLAGS) $(SNDFILE_CFLAGS) $(JACK_CFLAGS) $(CAIRO_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/glui $(CFLAG_VISIBILITY) -I$(top_srcdir)/3rdparty
3+
AM_CXXFLAGS += $(GLIB_CFLAGS) $(FFTW_CFLAGS) $(SNDFILE_CFLAGS) $(JACK_CFLAGS) $(CAIRO_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/glui $(CFLAG_VISIBILITY) -I$(top_srcdir)/3rdparty $(WARN_GLOBAL_CDTORS)
44

55
spectmorph_clapdir = $(libdir)/clap
66

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,11 @@ MC_PROG_CC_SUPPORTS_OPTION([-Wall], [
432432
if test "x$compiler_is_clang" = "xyes"; then
433433
AM_CFLAGS="$AM_CFLAGS -Wno-vla-cxx-extension"
434434
AM_CXXFLAGS="$AM_CXXFLAGS -Wno-vla-cxx-extension"
435+
WARN_GLOBAL_CDTORS="-Wglobal-constructors -Wexit-time-destructors"
436+
else
437+
WARN_GLOBAL_CDTORS=""
435438
fi
439+
AC_SUBST(WARN_GLOBAL_CDTORS)
436440

437441
MC_PROG_CC_SUPPORTS_OPTION([-fPIC], [
438442
AM_CFLAGS="$AM_CFLAGS -fPIC"

glui/Makefile.am

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SMSRCS = smwidget.cc smwindow.cc smmorphplanview.cc smmorphplanwindow.cc \
3434
smdrawutils.cc smrenameopwindow.cc smmorphwavsourceview.cc \
3535
smtimer.cc smshortcut.cc smparamlabel.cc smeventloop.cc \
3636
sminsteditwindow.cc smlineedit.cc smmorphkeytrackview.cc \
37-
smmorphcurvewidget.cc smmorphenvelopeview.cc
37+
smmorphcurvewidget.cc smmorphenvelopeview.cc smtextrenderer.cc
3838

3939
SMHDRS = smlabel.hh smslider.hh smwidget.hh smwindow.hh smframe.hh \
4040
smcombobox.hh smdrawutils.hh smscrollbar.hh smmenubar.hh \
@@ -54,22 +54,23 @@ SMHDRS = smlabel.hh smslider.hh smwidget.hh smwindow.hh smframe.hh \
5454
smvoicestatus.hh smpathdialog.hh smloadstereodialog.hh \
5555
smbankeditwindow.hh smcreatebankwindow.hh smclickablelabel.hh \
5656
sminsteditvolume.hh smvumeter.hh smvolumeresetdialog.hh \
57-
smmorphkeytrackview.hh smmorphcurvewidget.hh smmorphenvelopeview.hh
57+
smmorphkeytrackview.hh smmorphcurvewidget.hh smmorphenvelopeview.hh \
58+
smtextrenderer.hh
5859

5960
libspectmorphglui_la_SOURCES = $(SMSRCS) $(SMHDRS)
6061
libspectmorphglui_la_CXXFLAGS = $(AM_CXXFLAGS)
6162
libspectmorphglui_la_LIBADD = $(SPECTMORPH_LIBS) $(PUGL_LIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(GLIB_LIBS)
6263
libspectmorphglui_la_LDFLAGS = -no-undefined $(PUGL_LDFLAGS)
6364
libspectmorphglui_la_LIBTOOLFLAGS = --tag CXX
6465

65-
AM_CXXFLAGS += $(GLIB_CFLAGS) $(FFTW_CFLAGS) $(SNDFILE_CFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/src -I$(top_srcdir)/glui -DPUGL_HAVE_GL -DPUGL_HAVE_CAIRO -I$(top_srcdir)/vst
66+
AM_CXXFLAGS += $(GLIB_CFLAGS) $(FFTW_CFLAGS) $(SNDFILE_CFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/src -I$(top_srcdir)/glui -DPUGL_HAVE_GL -DPUGL_HAVE_CAIRO -I$(top_srcdir)/vst $(WARN_GLOBAL_CDTORS)
6667

6768
smuitest_SOURCES = smuitest.cc
68-
smuitest_LDADD = libspectmorphglui.la $(SPECTMORPH_LIBS) $(GLIB_LIBS) $(CAIRO_LIBS) $(PUGL_LIBS)
69+
smuitest_LDADD = libspectmorphglui.la $(SPECTMORPH_LIBS) $(FREETYPE_LIBS) $(GLIB_LIBS) $(CAIRO_LIBS) $(PUGL_LIBS)
6970
smuitest_LDFLAGS = $(PUGL_LDFLAGS)
7071

7172
smscrolltest_SOURCES = smscrolltest.cc
72-
smscrolltest_LDADD = libspectmorphglui.la $(SPECTMORPH_LIBS) $(GLIB_LIBS) $(CAIRO_LIBS) $(PUGL_LIBS)
73+
smscrolltest_LDADD = libspectmorphglui.la $(SPECTMORPH_LIBS) $(FREETYPE_LIBS) $(GLIB_LIBS) $(CAIRO_LIBS) $(PUGL_LIBS)
7374
smscrolltest_LDFLAGS = $(PUGL_LDFLAGS)
7475

7576
noinst_PROGRAMS = smuitest smscrolltest

glui/smdrawutils.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ DrawUtils::static_text_width (Window *window, const string& text)
3838
return w;
3939
}
4040

41-
cairo_text_extents_t
41+
TextExtents
4242
DrawUtils::static_text_extents (Window *window, const string& text)
4343
{
4444
cairo_surface_t *dummy = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0);

glui/smdrawutils.hh

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl-2.1.html
22

3-
#ifndef SPECTMORPH_DRAWUTILS_HH
4-
#define SPECTMORPH_DRAWUTILS_HH
3+
#pragma once
54

65
#include "smwidget.hh"
6+
#include "smtextrenderer.hh"
77

88
namespace SpectMorph
99
{
@@ -86,55 +86,106 @@ struct DrawUtils
8686
TextAlign align = TextAlign::LEFT, Orientation orientation = Orientation::HORIZONTAL)
8787
{
8888
// draw label
89+
90+
#if DEBUG_EXTENTS
8991
cairo_set_font_size (cr, 11.0);
9092
select_font_face (bold);
9193

92-
cairo_font_extents_t font_extents;
93-
cairo_font_extents (cr, &font_extents);
94+
cairo_font_extents_t font_extents_cairo;
95+
cairo_font_extents (cr, &font_extents_cairo);
96+
97+
cairo_text_extents_t extents_cairo;
98+
cairo_text_extents (cr, text.c_str(), &extents_cairo);
99+
#endif
100+
101+
cairo_save (cr);
102+
103+
cairo_matrix_t mat;
104+
cairo_get_matrix (cr, &mat);
105+
106+
double s = (mat.xx + mat.yy) / 2;
94107

95-
cairo_text_extents_t extents;
96-
cairo_text_extents (cr, text.c_str(), &extents);
108+
TextExtents extents;
109+
FontExtents font_extents;
110+
111+
cairo_surface_t *text_surface = TextRenderer::the()->text_to_surface (s, bold, text, &font_extents, &extents, TextRenderer::Mode::RENDER_SURFACE);
112+
113+
#if (DEBUG_EXTENTS)
114+
printf ("\n");
115+
printf ("x_bearing %f %f\n", extents.x_bearing, extents_cairo.x_bearing);
116+
printf ("y_bearing %f %f\n", extents.y_bearing, extents_cairo.y_bearing);
117+
printf ("width %f %f\n", extents.width, extents_cairo.width);
118+
printf ("height %f %f\n", extents.height, extents_cairo.height);
119+
printf ("x_advance %f %f\n", extents.x_advance, extents_cairo.x_advance);
120+
// printf ("y_advance %f %f\n", extents.y_advance, extents_cairo.y_advance);
121+
printf ("\n");
122+
printf ("ascent %f %f\n", font_extents.ascent, font_extents_cairo.ascent);
123+
printf ("descent %f %f\n", font_extents.descent, font_extents_cairo.descent);
124+
printf ("height %f %f\n", font_extents.height, font_extents_cairo.height);
125+
printf ("max_x_advance %f %f\n", font_extents.max_x_advance, font_extents_cairo.max_x_advance);
126+
// printf ("max_y_advance %f %f\n", font_extents.max_y_advance, font_extents_cairo.max_y_advance);
127+
#endif
97128

98129
if (orientation == Orientation::HORIZONTAL)
99130
{
100131
double fy = y + height / 2 - font_extents.descent + font_extents.height / 2;
101132
switch (align)
102133
{
103-
case TextAlign::LEFT: cairo_move_to (cr, x, fy);
134+
case TextAlign::LEFT: cairo_translate (cr, x, fy);
104135
break;
105-
case TextAlign::CENTER: cairo_move_to (cr, x + (width / 2) - extents.x_bearing - extents.width / 2, fy);
136+
case TextAlign::CENTER: cairo_translate (cr, x + (width / 2) - extents.x_bearing - extents.width / 2, fy);
106137
break;
107-
case TextAlign::RIGHT: cairo_move_to (cr, x + width - extents.x_bearing - extents.width, fy);
138+
case TextAlign::RIGHT: cairo_translate (cr, x + width - extents.x_bearing - extents.width, fy);
108139
break;
109140
}
110-
cairo_show_text (cr, text.c_str());
111141
}
112142
else
113143
{
114144
double fx = x + width / 2 + font_extents.height / 2 - font_extents.descent;
115145
switch (align)
116146
{
117-
case TextAlign::LEFT: cairo_move_to (cr, fx, y + height);
147+
case TextAlign::LEFT: cairo_translate (cr, fx, y + height);
118148
break;
119-
case TextAlign::CENTER: cairo_move_to (cr, fx, y + height / 2 + extents.x_bearing + extents.width / 2);
149+
case TextAlign::CENTER: cairo_translate (cr, fx, y + height / 2 + extents.x_bearing + extents.width / 2);
120150
break;
121-
case TextAlign::RIGHT: cairo_move_to (cr, fx, y + extents.x_bearing + extents.width);
151+
case TextAlign::RIGHT: cairo_translate (cr, fx, y + extents.x_bearing + extents.width);
122152
break;
123-
}
124-
cairo_save (cr);
125-
cairo_rotate (cr, -M_PI / 2);
126-
cairo_show_text (cr, text.c_str());
127-
cairo_restore (cr);
153+
}
128154
}
155+
// use simple matrix (no scaling) for drawing text_surface
156+
cairo_get_matrix (cr, &mat);
157+
mat.xx = 1.0;
158+
mat.yy = 1.0;
159+
mat.xy = 0.0;
160+
mat.yx = 0.0;
161+
cairo_set_matrix (cr, &mat);
162+
163+
if (orientation == Orientation::VERTICAL)
164+
cairo_rotate (cr, -M_PI / 2);
165+
166+
double ux = extents.x_bearing * s, uy = extents.y_bearing * s;
167+
168+
// snap to integer device pixels
169+
cairo_user_to_device (cr, &ux, &uy);
170+
ux = round (ux);
171+
uy = round (uy);
172+
cairo_device_to_user (cr, &ux, &uy);
173+
174+
cairo_mask_surface (cr, text_surface, ux, uy);
175+
cairo_surface_destroy (text_surface);
176+
177+
cairo_restore (cr);
129178
}
130-
cairo_text_extents_t
179+
TextExtents
131180
text_extents (const std::string& text)
132181
{
133-
cairo_set_font_size (cr, 11.0);
134-
select_font_face (bold);
182+
cairo_matrix_t mat;
183+
cairo_get_matrix (cr, &mat);
184+
double s = (mat.xx + mat.yy) / 2;
185+
TextExtents extents;
186+
187+
TextRenderer::the()->text_to_surface (s, bold, text, nullptr, &extents, TextRenderer::Mode::EXTENTS_ONLY);
135188

136-
cairo_text_extents_t extents;
137-
cairo_text_extents (cr, text.c_str(), &extents);
138189
return extents;
139190
}
140191
double
@@ -149,10 +200,7 @@ struct DrawUtils
149200
}
150201
void select_font_face (bool bold);
151202
static double static_text_width (Window *window, const std::string& text); /* static version: without instance */
152-
static cairo_text_extents_t static_text_extents (Window *window, const std::string& text); /* static version: without instance */
203+
static TextExtents static_text_extents (Window *window, const std::string& text); /* static version: without instance */
153204
};
154205

155206
}
156-
157-
#endif
158-

glui/smlineedit.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ LineEdit::draw (const DrawEvent& devent)
8080
auto prefix = text32.substr (0, i);
8181
string b4 = to_utf8 (prefix);
8282

83-
cairo_text_extents_t extents = du.text_extents (b4);
83+
TextExtents extents = du.text_extents (b4);
8484
prefix_x.push_back (10 + extents.x_advance + 1);
8585
}
8686
if (select_start >= 0 && select_start != cursor_pos)

glui/smlinuxfiledialog.cc

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "smlistbox.hh"
1010
#include "smcheckbox.hh"
1111
#include "smmessagebox.hh"
12+
#include "smmain.hh"
1213
#include <glib/gstdio.h>
1314
#include <map>
1415

@@ -62,7 +63,33 @@ class FileDialogWindow : public Window
6263
string default_ext;
6364
map<string, FileDialogFormats::Format> filter_map;
6465

65-
static string last_start_directory;
66+
struct Global
67+
{
68+
string last_start_directory;
69+
std::mutex mutex;
70+
static Global *
71+
the()
72+
{
73+
static Singleton<Global> singleton;
74+
return singleton.ptr();
75+
}
76+
};
77+
78+
void
79+
set_last_start_directory (const string& s)
80+
{
81+
Global *g = Global::the();
82+
std::lock_guard lg (g->mutex);
83+
g->last_start_directory = s;
84+
}
85+
string
86+
last_start_directory()
87+
{
88+
Global *g = Global::the();
89+
std::lock_guard lg (g->mutex);
90+
91+
return g->last_start_directory;
92+
}
6693
public:
6794
FileDialogWindow (Window *parent_window, bool open, const string& title, const FileDialogFormats& formats, LinuxFileDialog *lfd) :
6895
Window (*parent_window->event_loop(), title, 480, 320, 0, false, parent_window->native_window()),
@@ -176,8 +203,8 @@ class FileDialogWindow : public Window
176203
grid.add_widget (root_button, 1, yoffset, 6, 3);
177204
yoffset += 3;
178205

179-
if (last_start_directory != "" && can_read_dir (last_start_directory))
180-
read_directory (last_start_directory);
206+
if (last_start_directory() != "" && can_read_dir (last_start_directory()))
207+
read_directory (last_start_directory());
181208
else
182209
read_directory (g_get_home_dir());
183210
}
@@ -216,7 +243,7 @@ class FileDialogWindow : public Window
216243
/* open dialog is easy */
217244
if (is_open_dialog)
218245
{
219-
last_start_directory = current_directory;
246+
set_last_start_directory (current_directory);
220247
lfd->signal_file_selected (path);
221248
return;
222249
}
@@ -245,14 +272,14 @@ class FileDialogWindow : public Window
245272
{
246273
if (save_changes)
247274
{
248-
last_start_directory = current_directory;
275+
set_last_start_directory (current_directory);
249276
lfd->signal_file_selected (path);
250277
}
251278
});
252279
}
253280
else
254281
{
255-
last_start_directory = current_directory;
282+
set_last_start_directory (current_directory);
256283
lfd->signal_file_selected (path);
257284
}
258285
}
@@ -351,8 +378,6 @@ class FileDialogWindow : public Window
351378
}
352379
};
353380

354-
string FileDialogWindow::last_start_directory;
355-
356381
}
357382

358383
LinuxFileDialog::LinuxFileDialog (Window *window, bool open, const string& title, const FileDialogFormats& formats)

0 commit comments

Comments
 (0)