I'm a bit pissed off with the way we handle fonts and strings. It seems to me that we are duplicating code in the inset metrics and draw functions. Only in the very inner block of code do things differ, one ascertaining the width of the string in this particular font and the other calling the painter with this info.
As an example, I append the code from render_graphic.C to print out a diagnostic message. It seems to me that this mess could be avoided if we had some container that could contain both the string and the font information. Indeed, the STL stream classes do something very similar. I can imagine code like: void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const { if (!image_ready) lyx::rendered_stringstream rss; create_message(rss); dim.wid = std::max(50, rss.width() + 15); } } RenderGraphic::draw(PainterInfo & pi, int x, int y) const { if (!image_ready) lyx::rendered_stringstream rss; create_message(rss); pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6, y - 4, rss); } } where the magical helper function contained code like: void RenderGraphic::create_message(lyx::rendered_stringstream & rss) { rss << setFont(mi.base.font) << setFamily(LyXFont::SANS_FAMILY); string const justname = OnlyFilename(params_.filename); if (!justname.empty()) { rss << setSize(LyXFont::SIZE_FOOTNOTE) << justname; } string const msg = statusMessage(loader_.status()); if (!msg.empty()) { rss << setSize(LyXFont::SIZE_TINY) << msg; } } Is this just a wild flight of fancy, or does anybody else think that it's a sensible proposal? Regards, Angus ps, current code follows... void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const { bool image_ready = ...; if (image_ready) { ...; } else { int font_width = 0; LyXFont msgFont(mi.base.font); msgFont.setFamily(LyXFont::SANS_FAMILY); string const justname = OnlyFilename(params_.filename); if (!justname.empty()) { msgFont.setSize(LyXFont::SIZE_FOOTNOTE); font_width = font_metrics::width(justname, msgFont); } string const msg = statusMessage(loader_.status()); if (!msg.empty()) { msgFont.setSize(LyXFont::SIZE_TINY); font_width = std::max(font_width, font_metrics::width(msg, msgFont)); } dim.wid = std::max(50, font_width + 15); } dim_ = dim; } void RenderGraphic::draw(PainterInfo & pi, int x, int y) const { bool image_ready = ...; if (image_ready) { ...; } else { pi.pain.rectangle(x + InsetOld::TEXT_TO_INSET_OFFSET, y - dim_.asc, dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET, dim_.asc + dim_.des, LColor::foreground); // Print the file name. LyXFont msgFont = pi.base.font; msgFont.setFamily(LyXFont::SANS_FAMILY); string const justname = OnlyFilename(params_.filename); if (!justname.empty()) { msgFont.setSize(LyXFont::SIZE_FOOTNOTE); pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6, y - font_metrics::maxAscent(msgFont) - 4, justname, msgFont); } // Print the message. string const msg = statusMessage(loader_.status()); if (!msg.empty()) { msgFont.setSize(LyXFont::SIZE_TINY); pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6, y - 4, msg, msgFont); } } }