Skip to content

Commit 863bdba

Browse files
committed
Make thread-safe using a mutex lock, and suggest alternatives for real multi-threaded text drawing (issue #475).
1 parent 37f2ca1 commit 863bdba

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

CImg.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52685,6 +52685,9 @@ namespace cimg_library {
5268552685
defining the background color (0 means 'transparent').
5268652686
\param opacity Drawing opacity.
5268752687
\param font_height Height of the text font (exact match for 13,32,64,128, interpolated otherwise).
52688+
\note To ensure thread-safety, this function uses mutex lock. For real multi-threading drawing of text,
52689+
use another version of `CImg<T>::draw_text()` with argument `font`, that must be a copy of what is returned
52690+
by `CImgList<T>::font()`.
5268852691
**/
5268952692
template<typename tc1, typename tc2>
5269052693
CImg<T>& draw_text(const int x0, const int y0,
@@ -52694,8 +52697,10 @@ namespace cimg_library {
5269452697
if (!font_height) return *this;
5269552698
CImg<charT> tmp(2048);
5269652699
std::va_list ap; va_start(ap,font_height); cimg_vsnprintf(tmp,tmp._width,text,ap); va_end(ap);
52700+
cimg::mutex(15);
5269752701
const CImgList<ucharT>& font = CImgList<ucharT>::font(font_height,true);
5269852702
_draw_text(x0,y0,tmp,foreground_color,background_color,opacity,font,true);
52703+
cimg::mutex(15,0);
5269952704
return *this;
5270052705
}
5270152706

@@ -68732,6 +68737,7 @@ namespace cimg_library {
6873268737
/**
6873368738
\param font_height Height of the desired font (exact match for 13,23,53,103).
6873468739
\param is_variable_width Decide if the font has a variable (\c true) or fixed (\c false) width.
68740+
\note Beware, the returned reference is valid only until the next call to this function!
6873568741
**/
6873668742
static const CImgList<ucharT>& font(const unsigned int requested_height, const bool is_variable_width=true) {
6873768743
if (!requested_height) return CImgList<ucharT>::const_empty();
@@ -68810,18 +68816,18 @@ namespace cimg_library {
6881068816
}
6881168817

6881268818
// Find optimal font cache location to return.
68813-
static CImgList<ucharT> fonts[16];
68814-
static bool is_variable_widths[16] = {};
68819+
static CImgList<ucharT> fonts[32];
68820+
static bool is_variable_widths[32] = {};
6881568821
ind = ~0U;
68816-
for (int i = 0; i<16; ++i)
68822+
for (int i = 0; i<32; ++i)
6881768823
if (!fonts[i] || (is_variable_widths[i]==is_variable_width && requested_height==fonts[i][0]._height)) {
6881868824
ind = (unsigned int)i; break; // Found empty slot or cached font
6881968825
}
6882068826
if (ind==~0U) { // No empty slots nor existing font in cache
6882168827
fonts->assign();
68822-
std::memmove((void*)fonts,(void*)(fonts + 1),15*sizeof(CImgList<ucharT>));
68823-
std::memmove(is_variable_widths,is_variable_widths + 1,15*sizeof(bool));
68824-
std::memset((void*)(fonts + (ind=15)),0,sizeof(CImgList<ucharT>)); // Free a slot in cache for new font
68828+
std::memmove((void*)fonts,(void*)(fonts + 1),31*sizeof(CImgList<ucharT>));
68829+
std::memmove(is_variable_widths,is_variable_widths + 1,31*sizeof(bool));
68830+
std::memset((void*)(fonts + (ind=31)),0,sizeof(CImgList<ucharT>)); // Free a slot in cache for new font
6882568831
}
6882668832
CImgList<ucharT> &font = fonts[ind];
6882768833

0 commit comments

Comments
 (0)