#include "GuiPainter.h"
+#include "ColorCache.h"
#include "GuiApplication.h"
+#include "GuiFontLoader.h"
#include "GuiFontMetrics.h"
#include "GuiImage.h"
-
-#include "GuiApplication.h"
#include "qt_helpers.h"
-#include "debug.h"
+#include "FontInfo.h"
#include "Language.h"
#include "LyXRC.h"
-#include "support/unicode.h"
+#include "insets/Inset.h"
+
+#include "support/lassert.h"
+#include "support/debug.h"
#include <QPixmapCache>
#include <QTextLayout>
#define USE_PIXMAP_CACHE 1
#endif
-using std::endl;
-using std::string;
-
+using namespace std;
namespace lyx {
namespace frontend {
void GuiPainter::leaveMonochromeMode()
{
- BOOST_ASSERT(!monochrome_min_.empty());
+ LASSERT(!monochrome_min_.empty(), /**/);
monochrome_min_.pop();
monochrome_max_.pop();
}
FontInfo smallfont(f);
smallfont.decSize().decSize().setShape(UP_SHAPE);
- QFont const & qfont = guiApp->guiFontLoader().get(f);
- QFont const & qsmallfont = guiApp->guiFontLoader().get(smallfont);
+ QFont const & qfont = getFont(f);
+ QFont const & qsmallfont = getFont(smallfont);
setQPainterPen(computeColor(f.realColor()));
int textwidth = 0;
str = ' ' + str;
#endif
- GuiFontInfo & fi = guiApp->guiFontLoader().fontinfo(f);
+ QFont const & ff = getFont(f);
+ GuiFontMetrics const & fm = getFontMetrics(f);
int textwidth;
// Here we use the font width cache instead of
// textwidth = fontMetrics().width(str);
// because the above is awfully expensive on MacOSX
- textwidth = fi.metrics->width(s);
+ textwidth = fm.width(s);
if (f.underbar() == FONT_ON)
underline(f, x, y, textwidth);
if (s.size() == 1 && str[0].unicode() == 0x00ad) {
setQPainterPen(computeColor(f.realColor()));
QTextLayout adsymbol(str);
- adsymbol.setFont(fi.font);
+ adsymbol.setFont(ff);
adsymbol.beginLayout();
QTextLine line = adsymbol.createLine();
line.setNumColumns(1);
// don't use the pixmap cache,
// draw directly onto the painting device
setQPainterPen(computeColor(f.realColor()));
- if (font() != fi.font)
- setFont(fi.font);
- // We need to draw the text as LTR as we use our own bidi code.
- setLayoutDirection(Qt::LeftToRight);
+ if (font() != ff)
+ setFont(ff);
// We need to draw the text as LTR as we use our own bidi code.
setLayoutDirection(Qt::LeftToRight);
drawText(x, y, str);
- //LYXERR(Debug::PAINTING) << "draw " << std::string(str.toUtf8())
- // << " at " << x << "," << y << std::endl;
+ //LYXERR(Debug::PAINTING, "draw " << string(str.toUtf8())
+ // << " at " << x << "," << y);
return textwidth;
}
// Only the left bearing of the first character is important
// as we always write from left to right, even for
// right-to-left languages.
- int const lb = std::min(fi.metrics->lbearing(s[0]), 0);
- int const mA = fi.metrics->maxAscent();
+ int const lb = min(fm.lbearing(s[0]), 0);
+ int const mA = fm.maxAscent();
if (!QPixmapCache::find(key, pm)) {
// Only the right bearing of the last character is
// important as we always write from left to right,
// even for right-to-left languages.
- int const rb = fi.metrics->rbearing(s[s.size()-1]);
+ int const rb = fm.rbearing(s[s.size()-1]);
int const w = textwidth + rb - lb;
- int const mD = fi.metrics->maxDescent();
+ int const mD = fm.maxDescent();
int const h = mA + mD;
pm = QPixmap(w, h);
pm.fill(Qt::transparent);
GuiPainter p(&pm);
p.setQPainterPen(computeColor(f.realColor()));
- if (p.font() != fi.font)
- p.setFont(fi.font);
+ if (p.font() != ff)
+ p.setFont(ff);
// We need to draw the text as LTR as we use our own bidi code.
p.setLayoutDirection(Qt::LeftToRight);
p.drawText(-lb, mA, str);
QPixmapCache::insert(key, pm);
- //LYXERR(Debug::PAINTING) << "h=" << h << " mA=" << mA << " mD=" << mD
+ //LYXERR(Debug::PAINTING, "h=" << h << " mA=" << mA << " mD=" << mD
// << " w=" << w << " lb=" << lb << " tw=" << textwidth
- // << " rb=" << rb << endl;
+ // << " rb=" << rb);
}
// Draw the cached pixmap.
drawPixmap(x + lb, y - mA, pm);
}
+static int max(int a, int b) { return a > b ? a : b; }
+
+
+void GuiPainter::button(int x, int y, int w, int h, bool mouseHover)
+{
+ if (mouseHover)
+ fillRectangle(x, y, w, h, Color_buttonhoverbg);
+ else
+ fillRectangle(x, y, w, h, Color_buttonbg);
+ buttonFrame(x, y, w, h);
+}
+
+
+void GuiPainter::buttonFrame(int x, int y, int w, int h)
+{
+ line(x, y, x, y + h - 1, Color_buttonframe);
+ line(x - 1 + w, y, x - 1 + w, y + h - 1, Color_buttonframe);
+ line(x, y - 1, x - 1 + w, y - 1, Color_buttonframe);
+ line(x, y + h - 1, x - 1 + w, y + h - 1, Color_buttonframe);
+}
+
+
+void GuiPainter::rectText(int x, int y, docstring const & str,
+ FontInfo const & font, ColorCode back, ColorCode frame)
+{
+ int width;
+ int ascent;
+ int descent;
+
+ FontMetrics const & fm = theFontMetrics(font);
+ fm.rectText(str, width, ascent, descent);
+
+ if (back != Color_none)
+ fillRectangle(x + 1, y - ascent + 1, width - 1,
+ ascent + descent - 1, back);
+
+ if (frame != Color_none)
+ rectangle(x, y - ascent, width, ascent + descent, frame);
+
+ text(x + 3, y, str, font);
+}
+
+
+void GuiPainter::buttonText(int x, int y, docstring const & str,
+ FontInfo const & font, bool mouseHover)
+{
+ int width;
+ int ascent;
+ int descent;
+
+ FontMetrics const & fm = theFontMetrics(font);
+ fm.buttonText(str, width, ascent, descent);
+
+ static int const d = Inset::TEXT_TO_INSET_OFFSET / 2;
+
+ button(x + d, y - ascent, width - d, descent + ascent, mouseHover);
+ text(x + Inset::TEXT_TO_INSET_OFFSET, y, str, font);
+}
+
+
+int GuiPainter::preeditText(int x, int y, char_type c,
+ FontInfo const & font, preedit_style style)
+{
+ FontInfo temp_font = font;
+ FontMetrics const & fm = theFontMetrics(font);
+ int ascent = fm.maxAscent();
+ int descent = fm.maxDescent();
+ int height = ascent + descent;
+ int width = fm.width(c);
+
+ switch (style) {
+ case preedit_default:
+ // default unselecting mode.
+ fillRectangle(x, y - height + 1, width, height, Color_background);
+ dashedUnderline(font, x, y - descent + 1, width);
+ break;
+ case preedit_selecting:
+ // We are in selecting mode: white text on black background.
+ fillRectangle(x, y - height + 1, width, height, Color_black);
+ temp_font.setColor(Color_white);
+ break;
+ case preedit_cursor:
+ // The character comes with a cursor.
+ fillRectangle(x, y - height + 1, width, height, Color_background);
+ underline(font, x, y - descent + 1, width);
+ break;
+ }
+ text(x, y - descent + 1, c, temp_font);
+
+ return width;
+}
+
+
+void GuiPainter::underline(FontInfo const & f, int x, int y, int width)
+{
+ FontMetrics const & fm = theFontMetrics(f);
+
+ int const below = max(fm.maxDescent() / 2, 2);
+ int const height = max((fm.maxDescent() / 4) - 1, 1);
+
+ if (height < 2)
+ line(x, y + below, x + width, y + below, f.color());
+ else
+ fillRectangle(x, y + below, width, below + height, f.color());
+}
+
+
+void GuiPainter::dashedUnderline(FontInfo const & f, int x, int y, int width)
+{
+ FontMetrics const & fm = theFontMetrics(f);
+
+ int const below = max(fm.maxDescent() / 2, 2);
+ int height = max((fm.maxDescent() / 4) - 1, 1);
+
+ if (height >= 2)
+ height += below;
+
+ for (int n = 0; n != height; ++n)
+ line(x, y + below + n, x + width, y + below + n, f.color(), line_onoffdash);
+}
+
} // namespace frontend
} // namespace lyx