diff --git a/src/Changes.cpp b/src/Changes.cpp index 877c3f1042..97596b4b92 100644 --- a/src/Changes.cpp +++ b/src/Changes.cpp @@ -19,6 +19,7 @@ #include "BufferParams.h" #include "Encoding.h" #include "LaTeXFeatures.h" +#include "MetricsInfo.h" #include "OutputParams.h" #include "Paragraph.h" #include "TocBackend.h" @@ -30,6 +31,8 @@ #include "support/mutex.h" #include "frontends/alert.h" +#include "frontends/FontMetrics.h" +#include "frontends/Painter.h" #include @@ -37,6 +40,9 @@ using namespace std; namespace lyx { +using frontend::Painter; +using frontend::FontMetrics; + /* * Class Change has a changetime field that specifies the exact time at which * a specific change was made. The change time is used as a guidance for the @@ -545,6 +551,46 @@ void Changes::updateBuffer(Buffer const & buf) } +void Change::paintCue(PainterInfo & pi, double const x1, double const y, + double const x2, FontInfo const & font) const +{ + if (!changed()) + return; + // Calculate 1/3 height of font + FontMetrics const & fm = theFontMetrics(font); + int const y_bar = deleted() ? y - fm.maxAscent() / 3 + : y + 2 * pi.base.solidLineOffset() + pi.base.solidLineThickness(); + pi.pain.line(int(x1), y_bar, int(x2), y_bar, color(), + Painter::line_solid, pi.base.solidLineThickness()); +} + + +void Change::paintCue(PainterInfo & pi, double const x1, double const y1, + double const x2, double const y2) const +{ + /* + * y1 / + * / + * / + * / + * / + * y2 /_____ + * x1 x2 + */ + double y = 0; + switch(type) { + case UNCHANGED: + return; + case INSERTED: + y = y2; + break; + case DELETED: + y = y1; + break; + } + pi.pain.line(x1, y2, x2, y, color(), Painter::line_solid, + pi.base.solidLineThickness()); +} } // namespace lyx diff --git a/src/Changes.h b/src/Changes.h index 1d55b03b54..96383967b9 100644 --- a/src/Changes.h +++ b/src/Changes.h @@ -32,6 +32,8 @@ class AuthorList; class Buffer; class DocIterator; class OutputParams; +class PainterInfo; +class FontInfo; class Change { public: @@ -64,6 +66,20 @@ public: /// Is this change made by the current author ? bool currentAuthor() const { return author == 0; } + /// Paint under- or strike-through line + /// + /// Text : underline or strike through + /// \param x1 begin + /// \param x2 end + /// \param y baseline + void paintCue(PainterInfo & pi, double const x1, double const y, + double const x2, FontInfo const & font) const; + /// Box : line below or diagonal + /// \param x1,y1 top-left corner + /// \param x2,y2 bottom-right corner + void paintCue(PainterInfo & pi, double const x1, double const y1, + double const x2, double const y2) const; + Type type; int author; diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp index 3808da6a24..3353a7d3e6 100644 --- a/src/MetricsInfo.cpp +++ b/src/MetricsInfo.cpp @@ -12,6 +12,7 @@ #include "BufferView.h" #include "ColorSet.h" +#include "LyXRC.h" #include "MetricsInfo.h" #include "insets/Inset.h" @@ -36,15 +37,33 @@ namespace lyx { ///////////////////////////////////////////////////////////////////////// MetricsBase::MetricsBase() - : bv(0), font(), style(LM_ST_TEXT), fontname("mathnormal"), - textwidth(0) -{} + : bv(0), font(), style(LM_ST_TEXT), fontname("mathnormal"), textwidth(0), + solid_line_thickness_(1), solid_line_offset_(1), dotted_line_thickness_(1) +{ + if (lyxrc.zoom >= 200) { + // derive the line thickness from zoom factor + // the zoom is given in percent + // (increase thickness at 250%, 450% etc.) + solid_line_thickness_ = (lyxrc.zoom + 50) / 200; + // adjust line_offset_ too + solid_line_offset_ = 1 + solid_line_thickness_ / 2; + } + if (lyxrc.zoom >= 100) { + // derive the line thickness from zoom factor + // the zoom is given in percent + // (increase thickness at 150%, 250% etc.) + dotted_line_thickness_ = (lyxrc.zoom + 50) / 100; + } +} -MetricsBase::MetricsBase(BufferView * b, FontInfo const & f, int w) - : bv(b), font(f), style(LM_ST_TEXT), fontname("mathnormal"), - textwidth(w) -{} +MetricsBase::MetricsBase(BufferView * b, FontInfo f, int w) + : MetricsBase() +{ + bv = b; + font = f; + textwidth = w; +} Changer MetricsBase::changeFontSet(docstring const & name, bool cond) @@ -80,8 +99,8 @@ Changer MetricsBase::changeFontSet(char const * name, bool cond) // ///////////////////////////////////////////////////////////////////////// -MetricsInfo::MetricsInfo(BufferView * bv, FontInfo const & font, int textwidth, - MacroContext const & mc) +MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth, + MacroContext const & mc) : base(bv, font, textwidth), macrocontext(mc) {} diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h index 3f18724cb7..9a1fff47e5 100644 --- a/src/MetricsInfo.h +++ b/src/MetricsInfo.h @@ -54,7 +54,7 @@ public: /// MetricsBase(); /// - MetricsBase(BufferView * bv, FontInfo const & font, int textwidth); + MetricsBase(BufferView * bv, FontInfo font, int textwidth); /// the current view BufferView * bv; @@ -76,6 +76,16 @@ public: Changer changeFrac(bool cond = true); // Temporarily change the style to (script)script style Changer changeScript(bool cond = true); + /// + int solidLineThickness() const { return solid_line_thickness_; } + /// + int solidLineOffset() const { return solid_line_offset_; } + /// + int dottedLineThickness() const { return dotted_line_thickness_; } +private: + int solid_line_thickness_; + int solid_line_offset_; + int dotted_line_thickness_; }; @@ -88,7 +98,8 @@ public: /// MetricsInfo(); /// - MetricsInfo(BufferView * bv, FontInfo const & font, int textwidth, MacroContext const & mc); + MetricsInfo(BufferView * bv, FontInfo font, int textwidth, + MacroContext const & mc); /// MetricsBase base; diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index a2ff309347..5b3e6472ed 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -60,25 +60,8 @@ RowPainter::RowPainter(PainterInfo & pi, pars_(text.paragraphs()), row_(row), par_(text.paragraphs()[row.pit()]), pm_(text_metrics_.parMetrics(row.pit())), change_(pi_.change_), - xo_(x), yo_(y), width_(text_metrics_.width()), - solid_line_thickness_(1), solid_line_offset_(1), - dotted_line_thickness_(1) + xo_(x), yo_(y), width_(text_metrics_.width()) { - if (lyxrc.zoom >= 200) { - // derive the line thickness from zoom factor - // the zoom is given in percent - // (increase thickness at 250%, 450% etc.) - solid_line_thickness_ = (lyxrc.zoom + 50) / 200; - // adjust line_offset_ too - solid_line_offset_ = 1 + solid_line_thickness_ / 2; - } - if (lyxrc.zoom >= 100) { - // derive the line thickness from zoom factor - // the zoom is given in percent - // (increase thickness at 150%, 250% etc.) - dotted_line_thickness_ = (lyxrc.zoom + 50) / 100; - } - x_ = row_.left_margin + xo_; //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl; @@ -165,9 +148,10 @@ void RowPainter::paintForeignMark(Row::Element const & e) const return; int const desc = e.inset ? e.dim.descent() : 0; - int const y = yo_ + solid_line_offset_ + desc + solid_line_thickness_ / 2; + int const y = yo_ + pi_.base.solidLineOffset() + + desc + pi_.base.solidLineThickness() / 2; pi_.pain.line(int(x_), y, int(x_ + e.full_width()), y, Color_language, - Painter::line_solid, solid_line_thickness_); + Painter::line_solid, pi_.base.solidLineThickness()); } @@ -177,8 +161,8 @@ void RowPainter::paintMisspelledMark(Row::Element const & e) const // to avoid drawing at the same vertical offset FontMetrics const & fm = theFontMetrics(e.font); int const thickness = max(fm.lineWidth(), 2); - int const y = yo_ + solid_line_offset_ + solid_line_thickness_ - + (e.change.changed() ? solid_line_thickness_ + 1 : 0) + int const y = yo_ + pi_.base.solidLineOffset() + pi_.base.solidLineThickness() + + (e.change.changed() ? pi_.base.solidLineThickness() + 1 : 0) + 1 + thickness / 2; //FIXME: this could be computed only once, it is probably not costly. @@ -255,14 +239,7 @@ void RowPainter::paintStringAndSel(Row::Element const & e) const void RowPainter::paintChange(Row::Element const & e) const { - if (!e.change.changed()) - return; - // Calculate 1/3 height of font - FontMetrics const & fm = theFontMetrics(e.font); - int const y_bar = e.change.deleted() ? yo_ - fm.maxAscent() / 3 - : yo_ + 2 * solid_line_offset_ + solid_line_thickness_; - pi_.pain.line(int(x_), y_bar, int(x_ + e.full_width()), y_bar, - e.change.color(), Painter::line_solid, solid_line_thickness_); + e.change.paintCue(pi_, x_, yo_, x_ + e.full_width(), e.font.fontInfo()); } @@ -373,16 +350,17 @@ void RowPainter::paintAppendixStart(int y) const void RowPainter::paintTooLargeMarks(bool const left, bool const right) const { if (left) - pi_.pain.line(dotted_line_thickness_, yo_ - row_.ascent(), - dotted_line_thickness_, yo_ + row_.descent(), - Color_scroll, - Painter::line_onoffdash, dotted_line_thickness_); + pi_.pain.line(pi_.base.dottedLineThickness(), yo_ - row_.ascent(), + pi_.base.dottedLineThickness(), yo_ + row_.descent(), + Color_scroll, Painter::line_onoffdash, + pi_.base.dottedLineThickness()); if (right) { - int const wwidth = pi_.base.bv->workWidth() - dotted_line_thickness_; + int const wwidth = + pi_.base.bv->workWidth() - pi_.base.dottedLineThickness(); pi_.pain.line(wwidth, yo_ - row_.ascent(), wwidth, yo_ + row_.descent(), - Color_scroll, - Painter::line_onoffdash, dotted_line_thickness_); + Color_scroll, Painter::line_onoffdash, + pi_.base.dottedLineThickness()); } } @@ -611,8 +589,8 @@ void RowPainter::paintText() // The line that indicates word in a different language paintForeignMark(e); - // change tracking (not for insets that track their own changes) - if (e.type != Row::INSET || ! e.inset->canTrackChanges()) + // change tracking (not for insets that handle it themselves) + if (e.type != Row::INSET || ! e.inset->canPaintChange(*pi_.base.bv)) paintChange(e); x_ += e.full_width(); diff --git a/src/RowPainter.h b/src/RowPainter.h index 05ab57c51b..ca719bd228 100644 --- a/src/RowPainter.h +++ b/src/RowPainter.h @@ -97,9 +97,6 @@ private: int const yo_; // current baseline double x_; int width_; - int solid_line_thickness_; - int solid_line_offset_; - int dotted_line_thickness_; }; } // namespace lyx diff --git a/src/insets/Inset.h b/src/insets/Inset.h index cbcaf518a2..c450505ed2 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -352,6 +352,9 @@ public: /// does this contain text that can be change track marked in DVI? virtual bool canTrackChanges() const { return false; } + /// Will this inset paint its own change tracking status (in the parent + /// paragraph) or will it let RowPainter handle it? + virtual bool canPaintChange(BufferView const &) const { return false; } /// return true if the inset should be removed automatically virtual bool autoDelete() const; diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index 268b8f2043..294c826466 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -615,4 +615,21 @@ string InsetCollapsable::contextMenuName() const return "context-collapsable"; } + +bool InsetCollapsable::canPaintChange(BufferView const & bv) const +{ + switch (geometry(bv)) { + case Corners: + case SubLabel: + case ButtonOnly: + // these cases are handled by RowPainter since the inset is inline. + return false; + default: + break; + } + // TODO: implement the drawing in the remaining cases + return true; +} + + } // namespace lyx diff --git a/src/insets/InsetCollapsable.h b/src/insets/InsetCollapsable.h index ec23773123..35f6e8b530 100644 --- a/src/insets/InsetCollapsable.h +++ b/src/insets/InsetCollapsable.h @@ -127,6 +127,8 @@ public: /// and of course decoration(). Geometry geometry(BufferView const & bv) const; /// + bool canPaintChange(BufferView const & bv) const; + /// bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const; /// bool setMouseHover(BufferView const * bv, bool mouse_hover) const; diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index f57cbaea13..b23fc85b74 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -877,6 +877,8 @@ public: bool allowSpellCheck() const { return true; } /// bool canTrackChanges() const { return true; } + /// + bool canPaintChange(BufferView const &) const { return true; } /** returns false if, when outputing LaTeX, font changes should be closed before generating this inset. This is needed for insets that may contain several paragraphs */ diff --git a/src/insets/InsetText.h b/src/insets/InsetText.h index 52ea7afc7f..b42dce39ef 100644 --- a/src/insets/InsetText.h +++ b/src/insets/InsetText.h @@ -64,6 +64,8 @@ public: /// bool canTrackChanges() const { return true; } /// + bool canPaintChange(BufferView const &) const { return false; } + /// InsetText * asInsetText() { return this; } /// InsetText const * asInsetText() const { return this; }