31 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator giter =
33 if (giter !=
glyphs.end()) {
41 std::ifstream is(path);
49 }
catch (boost::exception &be) {
61 std::codecvt_utf8<char32_t>,
64 for (; iter != bias.
end(); ++iter) {
66 if (iter->first.length() <= 4) {
68 std::u32string u32 = conv.from_bytes(iter->first);
70 if (u32.length() == 1) {
71 std::lock_guard<duds::general::Spinlock> lock(
block);
72 glyphs[u32[0]] = iter->second;
79 std::lock_guard<duds::general::Spinlock> lock(
block);
84 std::lock_guard<duds::general::Spinlock> lock(
block);
89 std::lock_guard<duds::general::Spinlock> lock(
block);
90 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator
92 if (iter ==
glyphs.end()) {
101 std::lock_guard<duds::general::Spinlock> lock(
block);
102 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator
104 if (iter ==
glyphs.end()) {
117 for (char32_t check : {
'8',
'M',
'q',
'y' }) {
126 std::lock_guard<duds::general::Spinlock> lock(
block);
127 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator iter =
129 return iter->second->dimensions();
160 typedef std::vector<LineDimensions>
DimVec;
165 static std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t >
conv;
169 std::u32string text32 = conv.from_bytes(text);
170 return render(text32, flags);
178 gv.reserve(text.size());
188 std::u32string::const_iterator titer = text.cbegin();
189 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator giter;
190 for (; titer != text.cend(); ++titer) {
192 if (*titer ==
'\n') {
194 maxline = std::max(maxline, lineDims.back().chars);
198 lineDims.back().dim.w = md.
w * lineDims.back().chars;
203 id.w = std::max(
id.w, lineDims.back().dim.w);
207 id.h += lineDims.back().dim.h;
215 std::lock_guard<duds::general::Spinlock> lock(
block);
216 giter =
glyphs.find(*titer);
218 if (giter ==
glyphs.end()) {
221 gv.emplace_back(glyph.get());
224 gv.push_back(giter->second.get());
229 lineDims.back().dim.
w += gd.
w;
230 md.
w = std::max(md.
w, gd.
w);
231 lineDims.back().dim.h = std::max(lineDims.back().dim.h, gd.
h);
232 md.
h = std::max(md.
h, gd.
h);
233 ++lineDims.back().chars;
236 maxline = std::max(maxline, lineDims.back().chars);
242 lineDims.back().dim.w = md.
w * lineDims.back().chars;
245 id.w = std::max(
id.w, lineDims.back().dim.w);
248 id.w = maxline * md.
w;
253 id.h += lineDims.back().dim.h;
256 id.h = md.
h * lineDims.size();
269 DimVec::iterator diter = lineDims.begin();
270 ImageVec::iterator viter = gv.begin();
273 for (; diter != lineDims.end(); ++diter) {
275 if (flags & FixedWidth) {
276 diter->dim.w = md.
w * diter->chars;
278 if (!(flags & VariableHeight)) {
283 il.
x = (
id.w - diter->dim.w) / 2;
285 il.
x =
id.w - diter->dim.w;
290 for (
int loop = diter->chars; loop > 0; ++viter, --loop) {
296 if (flags & FixedWidth) {
297 loc.
x += (md.
w - gd.
w) / 2;
299 }
else if (flags & FixedWidthPerLine) {
300 adv = diter->dim.w / diter->chars;
301 loc.
x += (adv - gd.
w) / 2;
303 bis->write(*viter, loc, gd);
308 il.
y += diter->dim.h;
312 }
catch (boost::exception &be) {
313 be <<
String(conv.to_bytes(text));
319 std::u32string text32 = conv.from_bytes(text);
327 std::lock_guard<duds::general::Spinlock> lock(
block);
328 for (
auto c : text) {
330 std::unordered_map<char32_t, ConstBppImageSptr>::const_iterator giter =
334 if (giter ==
glyphs.end()) {
338 glyph = giter->second;
341 dim.
h = std::max(dim.
h, glyph->height());
345 dim.
w = std::max(dim.
w, glyph->width());
348 dim.
w += glyph->width();
355 dim.
w = dim.
w * text.size();
358 }
catch (boost::exception &be) {
359 be <<
String(conv.to_bytes(text));
iterator begin()
Parses the first image in the stream and returns an iterator to that data.
constexpr LineDimensions()
Ensure all fields start with zeros.
void add(char32_t gc, const ConstBppImageSptr &img)
Adds or replaces a glyph in the font.
ImageDimensions lineDimensions(const std::string &text, Flags flags=Flags::Zero())
Returns the dimensions of a single-line string without the overhead of rendering the string...
Stores a location within an image.
ConstBppImageSptr tryGet(char32_t gc)
Returns the glyph of the specified character code.
std::int16_t y
Vertical coordinate.
static constexpr Flags AlignRight
Align each line to the right.
std::int16_t x
Horizontal coordinate.
std::shared_ptr< const BppImage > ConstBppImageSptr
An input iterator that will parse and supply image data from the stream.
constexpr ImageDimensions maxExtent(const ImageDimensions &dim) const
Returns new dimensions that are minimally large enough to fit this dimension and the given dimension...
move_impl move(unsigned int c, unsigned int r)
Display stream manipulator that moves the display cursor to the given location.
static constexpr Flags AlignMask
All alignment flags.
The base class for errors resulting from the attempt to read an image archive stream or file...
std::vector< LineDimensions > DimVec
Information on each line of text to render.
int chars
Number of characters in the line.
static constexpr iterator end()
Returns the end iterator.
boost::error_info< struct Info_ImageArcFileName, std::string > ImageArchiveFileName
The name of the image archive file involved in an ImageArchiveStreamError.
static constexpr Flags AlignCenter
Center each line in the resulting image.
Stores the dimensions of an image.
static constexpr Flags FixedWidthPerLine
Compute fixed width individually for each line, so each line may have a different width per glyph...
boost::error_info< struct Info_String, std::string > String
A string, like one requested for rendering in a specific font.
void readHeader()
Parses the headers used in BppImageArchive files.
static constexpr Flags FixedWidth
All glyphs rendered with the same width using the maximum width of the glyphs used in the string...
std::shared_ptr< BppImage > BppImageSptr
duds::general::Spinlock block
Used for thread safety.
virtual ConstBppImageSptr renderGlyph(char32_t gc)
Called to render the requested glyph when it is not present in the glyphs map.
std::vector< const BppImage * > ImageVec
Used to hold all the glyphs needed to render a string.
static std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > conv
String converter; UTF-8 to/from UTF-32.
static constexpr Flags VariableHeight
Each line will have the height of its tallest glyph rather than the tallest glyph of the entire strin...
Provides an input iterator to a sequence of named bit-per-pixel images read from an input stream...
ImageDimensions estimatedMaxCharacterSize()
Returns a somewhat decent estimate of the largest size of a character without actually inspecting all...
ImageDimensions dim
Minimum dimensions for the line.
duds::general::BitFlags< struct BppFontRenderingFlags > Flags
Option flags that affect how text is rendered.
void load(const std::string &path)
Loads glyphs from an image archive in the specified file.
static std::shared_ptr< BppImage > make(const ImageDimensions &id)
Convenience function to make a shared pointer to an image using the BppImage(const ImageDimensions &)...
General graphics related code.
static constexpr Flags AlignLeft
Align each line to the left.
boost::error_info< struct Info_Character, char32_t > Character
A character, like one requested for rendering in a specific font.
BppImageSptr render(const std::string &text, Flags flags=AlignLeft)
Renders the given text using this object's font.
std::unordered_map< char32_t, ConstBppImageSptr > glyphs
The glyph images keyed by character.
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
const ConstBppImageSptr & get(char32_t gc)
Returns the glyph of the specified character code.
A glyph required to render a string is not availble in the font.