]> git.lyx.org Git - features.git/commitdiff
This commit fixes the following bug:
authorAbdelrazak Younes <younes@lyx.org>
Fri, 1 Dec 2006 16:12:24 +0000 (16:12 +0000)
committerAbdelrazak Younes <younes@lyx.org>
Fri, 1 Dec 2006 16:12:24 +0000 (16:12 +0000)
http://bugzilla.lyx.org/show_bug.cgi?id=2900

The only drawback is that it requires about 20Mo extra-memory when loading the UserGuide. If it turns out to be too much, we can switch to a QHash based solution instead of a table.

* dimension.[Ch]:
  - Dimension(LyXFont const, char_typec): new ctor
  - set(LyXFont const & font, char_type c): new method.

* frontends/FontMetrics.h:
  - width(char_type): is now a pure virtual method.

* GuiFontMetrics:
  - CharMetrics: new structure;
  - the metrics cache now also cache ascent and descent. This is especially useful for mathed.

* MathSupport.[Ch]:
  - mathed_char_dim(): deleted. We now use Dimension::set() directly instead.

* rowpainter.C: fixe empty space.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16124 a592a061-630c-0410-9148-cb99ea01b6c8

14 files changed:
src/dimension.C
src/dimension.h
src/frontends/FontMetrics.h
src/frontends/NoGuiFontMetrics.h
src/frontends/qt4/GuiFontMetrics.C
src/frontends/qt4/GuiFontMetrics.h
src/mathed/InsetMathBrace.C
src/mathed/InsetMathChar.C
src/mathed/InsetMathDelim.C
src/mathed/InsetMathDots.C
src/mathed/MathData.C
src/mathed/MathSupport.C
src/mathed/MathSupport.h
src/rowpainter.C

index c7cbdbc9374e21e2cf4646155d1721e972ffab42..847fdd71f5b24c316bd649fd7910633854f08de1 100644 (file)
@@ -36,4 +36,12 @@ void Dimension::clear(LyXFont const & font)
 }
 
 
+void Dimension::set(LyXFont const & font, char_type c)
+{
+       frontend::FontMetrics const & fm = theFontMetrics(font);
+       des = fm.descent(c);
+       asc = fm.ascent(c);
+       wid = fm.width(c);
+}
+
 } // namespace lyx
index bf42106de0bb986e8fc5449b4a7b1fb7f5777d9b..26bd71064b9d1c8a518649436a2841ffa48b36c5 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef DIMENSION_H
 #define DIMENSION_H
 
+#include "support/types.h"
 
 namespace lyx {
 
@@ -25,6 +26,8 @@ public:
        /// initialize data
        Dimension(int w, int a, int d) : wid(w), asc(a), des(d) {}
 
+       Dimension(LyXFont const & font, char_type c) { set(font, c); }
+
        Dimension & operator=(Dimension const & dim) {
                wid = dim.wid;
                asc = dim.asc;
@@ -35,8 +38,11 @@ public:
        void operator+=(Dimension const & dim);
        /// set to empty box
        void clear() { wid = asc = des = 0; }
-       /// set to empty box suitble for given font
+       /// set to empty box suitble for given font.
        void clear(LyXFont const & font);
+       /// set to a char dimensions for a given font.
+       void set(LyXFont const & font, char_type c);
+
        /// get height
        int height() const { return asc + des; }
        /// get ascent
index 829b5cec1f156230b89210de0c067835e6779782..20c7808f9f8b45d098897fb9740c761f58df190a 100644 (file)
@@ -58,6 +58,8 @@ public:
        virtual int maxAscent() const = 0;
        /// return the maximum descent of the font
        virtual int maxDescent() const = 0;
+       /// return the width of the char in the font
+       virtual int width(char_type c) const = 0;
        /// return the ascent of the char in the font
        virtual int ascent(char_type c) const = 0;
        /// return the descent of the char in the font
@@ -103,13 +105,6 @@ public:
                return (rbearing(c) - lbearing(c)) / 2;
        }
 
-       /// return the width of the char in the font
-       inline int width(char_type c) const
-       {
-               char_type tmp[2] = { c, L'\0'};
-               return width(tmp, 1);
-       }
-
        /// return the width of the string in the font
        inline int width(docstring const & s) const
        {
index 6bbdcaed10ec05d40042c791192f5b8a4258be4d..5faaf685f805dbbca47f7e6c19b5a355e98184ba 100644 (file)
@@ -31,6 +31,8 @@ public:
 
        virtual int maxDescent() const { return 1; }
        
+       virtual int width(char_type) const { return 1; }
+
        virtual int ascent(char_type) const { return 1; }
        
        int descent(char_type) const { return 1; }
index d1ed0ecea854108bd61b293bb2edbd171b7ce40b..a10381096fdf4683098d373359ce2251ce58b01a 100644 (file)
@@ -19,9 +19,6 @@
 
 #include "support/unicode.h"
 
-using lyx::char_type;
-using lyx::docstring;
-
 using std::string;
 
 namespace lyx {
@@ -32,8 +29,11 @@ GuiFontMetrics::GuiFontMetrics(QFont const & font)
 : metrics_(font), smallcaps_metrics_(font), smallcaps_shape_(false)
 {
 #ifdef USE_LYX_FONTCACHE
-  for (int i = 0; i != 65536; ++i)
-    widthcache_[i] = -1;
+ for (int i = 0; i != 65536; ++i) {
+        metrics_cache_[i].width = -1000;
+        metrics_cache_[i].ascent = -1000;
+        metrics_cache_[i].descent = -1000;
+ }
 #endif
 }
 
@@ -58,20 +58,6 @@ int GuiFontMetrics::maxDescent() const
 }
 
 
-int GuiFontMetrics::ascent(char_type c) const
-{
-       QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
-       return -r.top();
-}
-
-
-int GuiFontMetrics::descent(char_type c) const
-{
-       QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
-       return r.bottom() + 1;
-}
-
-
 int GuiFontMetrics::lbearing(char_type c) const
 {
        return metrics_.leftBearing(ucs4_to_qchar(c));
@@ -110,19 +96,18 @@ int GuiFontMetrics::width(char_type const * s, size_t ls) const
        // casts in reality.
 
        if (ls == 1 && !smallcaps_shape_) {
-               QChar const c = ucs4_to_qchar(s[0]);
-               return width(c.unicode());
+               return width(s[0]);
        }
 
-       QString ucs2;
-       ucs4_to_qstring(s, ls, ucs2);
-
-       if (smallcaps_shape_)
+       if (smallcaps_shape_) {
+               QString ucs2;
+               ucs4_to_qstring(s, ls, ucs2);
                return smallcapsWidth(ucs2);
+       }
 
        int w = 0;
        for (unsigned int i = 0; i < ls; ++i)
-               w += width(ucs2[i].unicode());
+               w += width(s[i]);
 
        return w;
 }
@@ -178,14 +163,64 @@ void GuiFontMetrics::buttonText(docstring const & str,
        descent = metrics_.descent() + d;
 }
 
-#ifdef USE_LYX_FONTCACHE
-int GuiFontMetrics::width(unsigned short val) const
+#ifndef USE_LYX_FONTCACHE
+
+int GuiFontMetrics::ascent(char_type c) const
 {
-       if (widthcache_[val] == -1)
-               widthcache_[val] = metrics_.width(QChar(val));
-       return widthcache_[val];
+       QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
+       return -r.top();
 }
-#endif
 
+
+int GuiFontMetrics::descent(char_type c) const
+{
+       QRect const & r = metrics_.boundingRect(ucs4_to_qchar(c));
+       return r.bottom() + 1;
+}
+
+#else
+
+void GuiFontMetrics::fillCache(unsigned short val) const
+{
+       QRect const & r = metrics_.boundingRect(QChar(val));
+       metrics_cache_[val].descent = r.bottom() + 1;
+       metrics_cache_[val].ascent = -r.top();
+       // We could as well compute the width but this is not really
+       // needed for now as it is done directly in width() below.
+       //metrics_cache_[val].width = metrics_.width(QChar(val));
+}
+
+
+int GuiFontMetrics::width(char_type c) const
+{
+       unsigned short val = static_cast<unsigned short>(c);
+       if (metrics_cache_[val].width == -1000)
+               metrics_cache_[val].width = metrics_.width(QChar(val));
+
+       return metrics_cache_[val].width;
+}
+
+
+int GuiFontMetrics::ascent(char_type c) const
+{
+       unsigned short val = static_cast<unsigned short>(c);
+       if (metrics_cache_[val].ascent == -1000)
+               fillCache(val);
+
+       return metrics_cache_[val].ascent;
 }
+
+
+int GuiFontMetrics::descent(char_type c) const
+{
+       unsigned short val = static_cast<unsigned short>(c);
+       if (metrics_cache_[val].descent == -1000)
+               fillCache(val);
+
+       return metrics_cache_[val].descent;
 }
+
+#endif
+
+} // frontend
+} // lyx
index 194c8f828d33df7a25ce99fedbb6036a4fa10e79..d310741cc33c00facdd7ce40a4d7d611b93ea3f3 100644 (file)
 namespace lyx {
 namespace frontend {
 
+struct CharMetrics
+{
+       int width;
+       int ascent;
+       int descent;
+};
+
+
 class GuiFontMetrics: public FontMetrics
 {
 public:
@@ -38,17 +46,24 @@ public:
 
        virtual int maxAscent() const;
        virtual int maxDescent() const;
-       virtual int ascent(lyx::char_type c) const;
-       int descent(lyx::char_type c) const;
-       virtual int lbearing(lyx::char_type c) const;
-       virtual int rbearing(lyx::char_type c) const;
-       virtual int width(lyx::char_type const * s, size_t n) const;
-       virtual int signedWidth(lyx::docstring const & s) const;
-       virtual void rectText(lyx::docstring const & str,
+#ifndef USE_LYX_FONTCACHE
+       virtual int width(char_type c) const {
+               return metrics_.width(QChar(static_cast<short int>(c)));
+       }
+#else
+       virtual int width(char_type c) const;
+#endif
+       virtual int ascent(char_type c) const;
+       virtual int descent(char_type c) const;
+       virtual int lbearing(char_type c) const;
+       virtual int rbearing(char_type c) const;
+       virtual int width(char_type const * s, size_t n) const;
+       virtual int signedWidth(docstring const & s) const;
+       virtual void rectText(docstring const & str,
                int & width,
                int & ascent,
                int & descent) const;
-       virtual void buttonText(lyx::docstring const & str,
+       virtual void buttonText(docstring const & str,
                int & width,
                int & ascent,
                int & descent) const;
@@ -64,16 +79,16 @@ private:
 
        bool smallcaps_shape_;
 
-#ifndef USE_LYX_FONTCACHE
-       /// Return pixel width for the given unicode char
-       int width(unsigned short val) const { return metrics_.width(QChar(val)); }
-
-#else
-       /// Return pixel width for the given unicode char
-       int width(unsigned short val) const;
-
+#ifdef USE_LYX_FONTCACHE
+       /// fill in \c metrics_cache_ at specified value.
+       void fillCache(unsigned short val) const;
        /// Cache of char widths
-       mutable int widthcache_[65536];
+       /** This cache adds 20Mo of memory to the LyX executable when
+       * loading UserGuide.lyx which contains a good number of fonts. If
+       * this turns out to be too much, we can switch to a \c QHash based
+       * solution.
+       **/
+       mutable CharMetrics metrics_cache_[65536];
 #endif // USE_LYX_FONTCACHE
 };
 
index 736a47250ae86c903604d2ddb19da481904859ea..acae12e684ba0a86c9b2adec8c703437aa01f304 100644 (file)
@@ -46,8 +46,7 @@ auto_ptr<InsetBase> InsetMathBrace::doClone() const
 bool InsetMathBrace::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        cell(0).metrics(mi);
-       Dimension t;
-       mathed_char_dim(mi.base.font, '{', t);
+       Dimension t(mi.base.font, '{');
        dim.asc = max(cell(0).ascent(), t.asc);
        dim.des = max(cell(0).descent(), t.des);
        dim.wid = cell(0).width() + 2 * t.wid;
@@ -63,8 +62,7 @@ void InsetMathBrace::draw(PainterInfo & pi, int x, int y) const
 {
        LyXFont font = pi.base.font;
        font.setColor(LColor::latex);
-       Dimension t;
-       mathed_char_dim(font, '{', t);
+       Dimension t(font, '{');
        pi.pain.text(x, y, '{', font);
        cell(0).draw(pi, x + t.wid, y);
        pi.pain.text(x + t.wid + cell(0).width(), y, '}', font);
index aadcbc06cc6501bc7f35a64ad13b48556fae9654..004fb2283d1ab0e573908d12b895563d1014d0d1 100644 (file)
@@ -62,15 +62,15 @@ bool InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
 #if 1
        if (char_ == '=' && has_math_fonts) {
                FontSetChanger dummy(mi.base, "cmr");
-               mathed_char_dim(mi.base.font, char_, dim);
+               dim.set(mi.base.font, char_);
        } else if ((char_ == '>' || char_ == '<') && has_math_fonts) {
                FontSetChanger dummy(mi.base, "cmm");
-               mathed_char_dim(mi.base.font, char_, dim);
+               dim.set(mi.base.font, char_);
        } else if (!slanted(char_) && mi.base.fontname == "mathnormal") {
                ShapeChanger dummy(mi.base.font, LyXFont::UP_SHAPE);
-               mathed_char_dim(mi.base.font, char_, dim);
+               dim.set(mi.base.font, char_);
        } else {
-               mathed_char_dim(mi.base.font, char_, dim);
+               dim.set(mi.base.font, char_);
        }
        int const em = mathed_char_width(mi.base.font, 'M');
        if (isBinaryOp(char_))
@@ -79,7 +79,7 @@ bool InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
                dim.wid += static_cast<int>(0.1667*em+0.5);
 #else
        whichFont(font_, code_, mi);
-       mathed_char_dim(font_, char_, dim);
+       dim.set(font_, char_);
        if (isBinaryOp(char_, code_))
                width_ += 2 * theFontMetrics(font_).width(' ');
        lyxerr << "InsetMathChar::metrics: " << dim << endl;
index f74b81e3bb78f35913271fcf96a4397f199fdab4..2805ac986394fed32319878f02a2845f6ee95718 100644 (file)
@@ -75,7 +75,7 @@ bool InsetMathDelim::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        cell(0).metrics(mi);
        Dimension t;
-       mathed_char_dim(mi.base.font, 'I', t);
+       t.set(mi.base.font, 'I');
        int h0 = (t.asc + t.des) / 2;
        int a0 = max(cell(0).ascent(), t.asc)   - h0;
        int d0 = max(cell(0).descent(), t.des)  + h0;
index 5178aa64325b0070e214c9357b659a199d3d63f7..3f87f29f53927263b6ec91702e813c8756330ec9 100644 (file)
@@ -37,7 +37,7 @@ auto_ptr<InsetBase> InsetMathDots::doClone() const
 
 bool InsetMathDots::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       mathed_char_dim(mi.base.font, 'M', dim);
+       dim.set(mi.base.font, 'M');
        dh_ = 0;
        if (key_->name == "cdots" || key_->name == "dotsb"
                        || key_->name == "dotsm" || key_->name == "dotsi")
index f36bf570bad919c183f11d5802c3446f326735ab..06dd9db4d1503d3fab5457880835b130ad59454d 100644 (file)
@@ -241,7 +241,7 @@ bool isInside(DocIterator const & it, MathArray const & ar,
 
 void MathArray::metrics(MetricsInfo & mi) const
 {
-       mathed_char_dim(mi.base.font, 'I', dim_);
+       dim_.set(mi.base.font, 'I');
 
        if (empty())
                return;
index 333ddaa7c0578d3b096f0e3fc3dac9458ef11996..ff35c7c527dbdabd36f57851732a8a987bc851b0 100644 (file)
@@ -367,15 +367,6 @@ deco_struct const * search_deco(docstring const & name)
 } // namespace anon
 
 
-void mathed_char_dim(LyXFont const & font, char_type c, Dimension & dim)
-{
-       frontend::FontMetrics const & fm = theFontMetrics(font);
-       dim.des = fm.descent(c);
-       dim.asc = fm.ascent(c);
-       dim.wid = fm.width(c);
-}
-
-
 int mathed_char_width(LyXFont const & font, char_type c)
 {
        return theFontMetrics(font).width(c);
index a1396e2338eb8ce06f42a943ce0542cdce69116a..d872b371f90ce7716e4832b51fdb135c756b3d7c 100644 (file)
@@ -28,7 +28,6 @@ class MathAtom;
 class InsetMath;
 
 
-void mathed_char_dim(LyXFont const &, char_type c, Dimension & dim);
 int mathed_char_width(LyXFont const &, char_type c);
 
 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
index 6074cd07b950f0e61f8c7bb5ad589bd1b43c3e12..5b83338af96882b38422430198f471fa20605688 100644 (file)
@@ -949,7 +949,7 @@ void paintPar
                        rp.paintChangeBar();
                        if (rit == rb)
                                rp.paintFirst();
-                       rp.paintText();
+                       rp.paintText();
                        if (rit + 1 == re)
                                rp.paintLast();
                }