mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Merge branch 'betterspacing'
The purpose of this branch is to improve the spacing in math equations * do not use hardcoded pixel values, but math units that depend on zoom and dpi. This should be good for HiDPI systems. * implement as much as possible the math typesetting algorithm described in Appendix G of the TeXbook. One typical example of the spacing algorithm is that ``-a'' has no spacing, contrary to ``a + b''. This reflects the unitary/binary minus that will indeed happen in typeset output. Together with the better character substitution that has already been implemented by Guillaume, we get a nice improvement of mathed looks. What makes this code complicated is that it handles macros properly: the spacing inside the macro will depend on the values of the arguments and the elements that are before and after the macro. As a result, many definitions in lib/symbols are now just copy/pasted from the relevant sty file. In particular, it is now possible to make use of \mathrel, \mathbin, etc. macros to specify spacing. This merge is a starting point. Remaining work includes * proper handling of sub/superscript nucleus and of font-changing insets (as is done in the TeX algorithm). * proper typesetting of fractions Thanks to Guillaume for extensive testing.
This commit is contained in:
commit
f643ae7007
90
lib/symbols
90
lib/symbols
@ -300,8 +300,7 @@ spadesuit cmsy 127 170 mathord ♠
|
||||
# We define lyxnot as mathrel in order to have proper alignment
|
||||
lyxnot cmsy 54 47 mathrel / hiddensymbol
|
||||
iffont cmsy
|
||||
# 10mu is the extra space added to relation operators
|
||||
\def\not{\lyxnot\kern-20mu}
|
||||
\def\not{\lyxnot\mathrel{\kern-11mu}}
|
||||
else
|
||||
\def\not{\kern4mu\lyxnot\kern-19mu}
|
||||
endif
|
||||
@ -669,7 +668,7 @@ hslash msb 125 0 mathord ℏ
|
||||
hbar msb 126 0 mathord ℏ
|
||||
backepsilon msb 127 0 mathrel ϶
|
||||
|
||||
lyxbar cmsy 161 0 mathord — hiddensymbol
|
||||
lyxbar cmsy 161 0 mathrel — hiddensymbol
|
||||
lyxminus cmsy 161 0 mathbin — hiddensymbol
|
||||
lyxplus cmr 43 43 mathbin + hiddensymbol
|
||||
lyxeq cmr 61 61 mathord = hiddensymbol
|
||||
@ -795,7 +794,7 @@ APLup wasy 0 0 x x
|
||||
APLdown wasy 70 0 x x
|
||||
APLinput wasy 125 0 x x
|
||||
APLcomment wasy 127 0 x x
|
||||
\def\APLinv{\div\kern-17.9mu\APLbox} wasysym
|
||||
\def\APLinv{\mathord{\div\kern-13.9mu\APLbox}} wasysym
|
||||
APLuparrowbox wasy 110 0 x ⍐
|
||||
APLdownarrowbox wasy 111 0 x ⍗
|
||||
APLleftarrowbox wasy 112 0 x ⍇
|
||||
@ -976,15 +975,15 @@ bignplus stmry 112 0 mathop x stmaryrd # caution: named hugenpl
|
||||
#Largerrbracketbot stmry 126 0 mathclose x stmaryrd # only in the font, not the .sty caution: named Hugerrbracketbot in the font
|
||||
#rrbracketex stmry 127 0 mathclose x stmaryrd # only in the font, not the .sty caution: named Hugerrbracketex in the font
|
||||
|
||||
\def\varcopyright{c\kern-14mu\varbigcirc} stmaryrd
|
||||
\def\longarrownot{\kern5.5mu\arrownot\kern-5.5mu} stmaryrd
|
||||
\def\Longarrownot{\kern5.5mu\Arrownot\kern-5.5mu} stmaryrd
|
||||
\def\Mapsto{\Mapstochar\kern-9mu\Rightarrow} stmaryrd
|
||||
\def\varcopyright{\mathord{c\kern-11mu\varbigcirc}} stmaryrd
|
||||
\def\longarrownot{\mathrel{\kern5.5mu}\arrownot\mathrel{\kern-5.5mu}} stmaryrd
|
||||
\def\Longarrownot{\mathrel{\kern5.5mu}\Arrownot\mathrel{\kern-5.5mu}} stmaryrd
|
||||
\def\Mapsto{\Mapstochar\mathrel{\kern-2mu}\Rightarrow} stmaryrd
|
||||
\def\mapsfrom{\leftarrow\kern-9mu\mapsfromchar} stmaryrd
|
||||
\def\Mapsfrom{\Leftarrow\kern-9mu\Mapsfromchar} stmaryrd
|
||||
\def\Longmapsto{\Mapstochar\kern-7mu\Longrightarrow} stmaryrd
|
||||
\def\longmapsfrom{\longleftarrow\kern-7mu\mapsfromchar} stmaryrd
|
||||
\def\Longmapsfrom{\Longleftarrow\kern-7mu\Mapsfromchar} stmaryrd
|
||||
\def\Longmapsto{\Mapstochar\Longrightarrow} stmaryrd
|
||||
\def\longmapsfrom{\longleftarrow\mapsfromchar} stmaryrd
|
||||
\def\Longmapsfrom{\Longleftarrow\mathrel{\kern1mu}\Mapsfromchar} stmaryrd
|
||||
|
||||
# symbols from the mhchem package, all of them are equivalent to a math symbol
|
||||
# mhchem is not loaded because these commands can only be used inside
|
||||
@ -1115,21 +1114,21 @@ pod lyxblacktext 0 0 func x amsmath
|
||||
|
||||
|
||||
# mathtools.sty
|
||||
vcentcolon cmr 58 58 mathrel : mathtools
|
||||
ordinarycolon cmr 58 58 mathrel : mathtools
|
||||
\def\dblcolon{\vcentcolon\kern-10.9mu\vcentcolon} mathrel :: mathtools
|
||||
\def\coloneqq{\vcentcolon\kern-11.2mu=} mathrel ≔ mathtools
|
||||
\def\Coloneqq{\dblcolon\kern-11.2mu=} mathrel ::= mathtools
|
||||
\def\coloneq{\vcentcolon\kern-11.2mu-} mathrel :- mathtools
|
||||
\def\Coloneq{\dblcolon\kern-11.2mu-} mathrel ::- mathtools
|
||||
\def\eqqcolon{=\kern-11.2mu\vcentcolon} mathrel ≕ mathtools
|
||||
\def\Eqqcolon{=\kern-11.2mu\dblcolon} mathrel =:: mathtools
|
||||
\def\eqcolon{-\kern-11.2mu\vcentcolon} mathrel -: mathtools
|
||||
\def\Eqcolon{-\kern-11.2mu\dblcolon} mathrel -:: mathtools
|
||||
\def\colonapprox{\vcentcolon\kern-11.2mu\approx} mathrel :≈ mathtools
|
||||
\def\Colonapprox{\dblcolon\kern-11.2mu\approx} mathrel ::≈ mathtools
|
||||
\def\colonsim{\vcentcolon\kern-11.2mu\sim} mathrel :∼ mathtools
|
||||
\def\Colonsim{\dblcolon\kern-11.2mu\sim} mathrel ::∼ mathtools
|
||||
vcentcolon cmr 58 58 mathrel : mathtools
|
||||
ordinarycolon cmr 58 58 mathrel : mathtools
|
||||
\def\dblcolon{\vcentcolon\mathrel{\kern-0.9mu}\vcentcolon} mathrel :: mathtools
|
||||
\def\coloneqq{\vcentcolon\mathrel{\kern-1.2mu}=} mathrel ≔ mathtools
|
||||
\def\Coloneqq{\dblcolon\mathrel{\kern-1.2mu}=} mathrel ::= mathtools
|
||||
\def\coloneq{\vcentcolon\mathrel{\kern-1.2mu}\mathrel{-}} mathrel :- mathtools
|
||||
\def\Coloneq{\dblcolon\mathrel{\kern-1.2mu}\mathrel{-}} mathrel ::- mathtools
|
||||
\def\eqqcolon{=\mathrel{\kern-1.2mu}\vcentcolon} mathrel ≕ mathtools
|
||||
\def\Eqqcolon{=\mathrel{\kern-1.2mu}\dblcolon} mathrel =:: mathtools
|
||||
\def\eqcolon{\mathrel{-}\mathrel{\kern-1.2mu}\vcentcolon} mathrel -: mathtools
|
||||
\def\Eqcolon{\mathrel{-}\mathrel{\kern-1.2mu}\dblcolon} mathrel -:: mathtools
|
||||
\def\colonapprox{\vcentcolon\mathrel{\kern-1.2mu}\approx} mathrel :≈ mathtools
|
||||
\def\Colonapprox{\dblcolon\mathrel{\kern-1.2mu}\approx} mathrel ::≈ mathtools
|
||||
\def\colonsim{\vcentcolon\mathrel{\kern-1.2mu}\sim} mathrel :∼ mathtools
|
||||
\def\Colonsim{\dblcolon\mathrel{\kern-1.2mu}\sim} mathrel ::∼ mathtools
|
||||
|
||||
|
||||
#
|
||||
@ -1144,50 +1143,53 @@ ordinarycolon cmr 58 58 mathrel : mathtools
|
||||
\def\notin{\not\in} mathrel ∉
|
||||
\def\slash{/}
|
||||
|
||||
\def\longleftrightarrow{\leftarrow\kern-12.5mu\rightarrow}
|
||||
\def\Longleftrightarrow{\Leftarrow\kern-12.5mu\Rightarrow}
|
||||
\def\iff{\Leftarrow\kern-12.5mu\Rightarrow}
|
||||
\def\joinrel{\mathrel{\kern-3mu}}
|
||||
\def\relbar{\lyxbar}
|
||||
\def\Relbar{\mathrel{=}}
|
||||
\def\longleftrightarrow{\leftarrow\joinrel\rightarrow}
|
||||
\def\Longleftrightarrow{\Leftarrow\joinrel\Rightarrow}
|
||||
\def\iff{\Leftarrow\joinrel\Rightarrow}
|
||||
\def\doteq{\stackrel{\cdot}{=}}
|
||||
|
||||
iffont cmsy
|
||||
\def\longrightarrow{\lyxbar\kern-11mu\rightarrow} mathrel ⟶
|
||||
\def\longleftarrow{\leftarrow\kern-11mu\lyxbar} mathrel ⟵
|
||||
\def\Longrightarrow{\lyxeq\kern-9.5mu\Rightarrow} mathrel ⟹
|
||||
\def\Longleftarrow{\Leftarrow\kern-9.5mu\lyxeq} mathrel ⟸
|
||||
\def\longrightarrow{\relbar\joinrel\rightarrow} mathrel ⟶
|
||||
\def\longleftarrow{\leftarrow\joinrel\relbar} mathrel ⟵
|
||||
\def\Longrightarrow{\Relbar\joinrel\Rightarrow} mathrel ⟹
|
||||
\def\Longleftarrow{\Leftarrow\joinrel\Relbar} mathrel ⟸
|
||||
\def\implies{\Longrightarrow} mathrel ⟹ amsmath
|
||||
\def\impliedby{\Longleftarrow} mathrel ⟸ amsmath
|
||||
\def\mapsto{\mapstochar\kern-9mu\rightarrow} mathrel ↤
|
||||
\def\longmapsto{\mapstochar\kern-6mu\lyxbar\kern-11mu\rightarrow} mathrel ⟻
|
||||
\def\models{\vert\kern-3mu\lyxeq} mathrel ⊨
|
||||
\def\mapsto{\mapstochar\mathrel{\kern-2mu}\rightarrow} mathrel ↤
|
||||
\def\longmapsto{\mapstochar\joinrel\relbar\joinrel\rightarrow} mathrel ⟻
|
||||
\def\models{\mathrel{\vert}\joinrel\Relbar} mathrel ⊨
|
||||
else
|
||||
\def\implies{=>} mathrel ⟹ amsmath
|
||||
\def\impliedby{<=} mathrel ⟸ amsmath
|
||||
endif
|
||||
iffont cmm
|
||||
\def\hookrightarrow{\lhook\kern-12mu\rightarrow} mathrel ↪
|
||||
\def\hookleftarrow{\leftarrow\kern-12mu\rhook} mathrel ↩
|
||||
\def\bowtie{\triangleright\kern-10mu\triangleleft} mathrel ⋈
|
||||
\def\hookrightarrow{\lhook\joinrel\rightarrow} mathrel ↪
|
||||
\def\hookleftarrow{\leftarrow\joinrel\rhook} mathrel ↩
|
||||
\def\bowtie{\mathrel\triangleright\joinrel\mathrel\triangleleft} mathrel ⋈
|
||||
endif
|
||||
iffont msa
|
||||
\def\dashrightarrow{\lyxdabar\lyxdabar\lyxright} mathrel ⤏ amssymb
|
||||
\def\dashleftarrow{\lyxleft\lyxdabar\lyxdabar} mathrel ⤎ amssymb
|
||||
\def\dashrightarrow{\mathrel{\lyxdabar\lyxdabar\lyxright}} mathrel ⤏ amssymb
|
||||
\def\dashleftarrow{\mathrel{\lyxleft\lyxdabar\lyxdabar}} mathrel ⤎ amssymb
|
||||
else
|
||||
\def\dashrightarrow{- - \rightarrow} mathrel ⤏ amssymb
|
||||
\def\dashleftarrow{\leftarrow{} - -} mathrel ⤎ amssymb
|
||||
endif
|
||||
\def\dasharrow{\dashrightarrow} mathrel ⤏ amssymb
|
||||
iffont msb
|
||||
\def\Join{\ltimes\kern-22mu\rtimes} amssymb
|
||||
\def\Join{\mathrel{\ltimes\kern-13.5mu\rtimes}} amssymb
|
||||
else
|
||||
\def\Join{|x|} amssymb
|
||||
endif
|
||||
# Fixme: latin-1 chars in text file
|
||||
# FIXME: UTF-8 chars in text file
|
||||
\def\AA{\AA}{Å} textmode Å amstext,lyxmathsym
|
||||
\def\O{\O}{Ø} textmode Ø amstext,lyxmathsym
|
||||
|
||||
iffont cmsy
|
||||
# The \sim is placed too high...
|
||||
\def\cong{\stackrel{_\sim}{=}} mathrel ≅
|
||||
\def\cong{\stackrel{\sim}{=}} mathrel ≅
|
||||
lyxsurd cmsy 112 0 mathord √
|
||||
\def\surd{^\lyxsurd} mathord √
|
||||
\def\textdegree{\kern-1mu^{\circ}\kern-4mu} textmode ° textcomp,amstext,lyxmathsym
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
void operator+=(Dimension const & dim);
|
||||
/// set to empty box
|
||||
void clear() { wid = asc = des = 0; }
|
||||
/// check if box is empty
|
||||
bool empty() const { return wid == 0 && asc == 0 && wid == 0; }
|
||||
/// get height
|
||||
int height() const { return asc + des; }
|
||||
/// get ascent
|
||||
|
@ -403,6 +403,7 @@ SOURCEFILESMATHED = \
|
||||
mathed/InsetMathCancelto.cpp \
|
||||
mathed/InsetMathCases.cpp \
|
||||
mathed/InsetMathChar.cpp \
|
||||
mathed/InsetMathClass.cpp \
|
||||
mathed/InsetMathColor.cpp \
|
||||
mathed/InsetMathComment.cpp \
|
||||
mathed/InsetMathDecoration.cpp \
|
||||
@ -447,16 +448,18 @@ SOURCEFILESMATHED = \
|
||||
mathed/InsetMathXArrow.cpp \
|
||||
mathed/InsetMathXYMatrix.cpp \
|
||||
mathed/InsetMathDiagram.cpp \
|
||||
mathed/MacroTable.cpp \
|
||||
mathed/MathAtom.cpp \
|
||||
mathed/MathAutoCorrect.cpp \
|
||||
mathed/MathClass.cpp \
|
||||
mathed/MathData.cpp \
|
||||
mathed/MathExtern.cpp \
|
||||
mathed/MathFactory.cpp \
|
||||
mathed/MathMacro.cpp \
|
||||
mathed/MathMacroArgument.cpp \
|
||||
mathed/MacroTable.cpp \
|
||||
mathed/MathMacroTemplate.cpp \
|
||||
mathed/MathParser.cpp \
|
||||
mathed/MathRow.cpp \
|
||||
mathed/MathStream.cpp \
|
||||
mathed/MathSupport.cpp \
|
||||
mathed/TextPainter.cpp
|
||||
@ -473,6 +476,7 @@ HEADERFILESMATHED = \
|
||||
mathed/InsetMathCancelto.h \
|
||||
mathed/InsetMathCases.h \
|
||||
mathed/InsetMathChar.h \
|
||||
mathed/InsetMathClass.h \
|
||||
mathed/InsetMathColor.h \
|
||||
mathed/InsetMathComment.h \
|
||||
mathed/InsetMathDelim.h \
|
||||
@ -518,6 +522,7 @@ HEADERFILESMATHED = \
|
||||
mathed/InsetMathDiagram.h \
|
||||
mathed/MathAtom.h \
|
||||
mathed/MathAutoCorrect.h \
|
||||
mathed/MathClass.h \
|
||||
mathed/MathData.h \
|
||||
mathed/MathCompletionList.h \
|
||||
mathed/MathExtern.h \
|
||||
@ -528,6 +533,7 @@ HEADERFILESMATHED = \
|
||||
mathed/MathMacroTemplate.h \
|
||||
mathed/MathParser.h \
|
||||
mathed/MathParser_flags.h \
|
||||
mathed/MathRow.h \
|
||||
mathed/ReplaceData.h \
|
||||
mathed/MathStream.h \
|
||||
mathed/MathSupport.h \
|
||||
|
@ -38,8 +38,8 @@ namespace lyx {
|
||||
|
||||
MetricsBase::MetricsBase(BufferView * b, FontInfo f, int w)
|
||||
: bv(b), font(move(f)), style(LM_ST_TEXT), fontname("mathnormal"),
|
||||
textwidth(w), solid_line_thickness_(1), solid_line_offset_(1),
|
||||
dotted_line_thickness_(1)
|
||||
textwidth(w), macro_nesting(0),
|
||||
solid_line_thickness_(1), solid_line_offset_(1), dotted_line_thickness_(1)
|
||||
{
|
||||
if (lyxrc.zoom >= 200) {
|
||||
// derive the line thickness from zoom factor
|
||||
|
@ -65,6 +65,8 @@ public:
|
||||
std::string fontname;
|
||||
/// This is the width available in pixels
|
||||
int textwidth;
|
||||
/// count wether the current mathdata is nested in macro(s)
|
||||
int macro_nesting;
|
||||
|
||||
/// Temporarily change a full font.
|
||||
Changer changeFontSet(std::string const & font, bool cond = true);
|
||||
|
@ -235,6 +235,8 @@ enum InsetCode {
|
||||
///
|
||||
IPADECO_CODE,
|
||||
///
|
||||
MATH_CLASS_CODE,
|
||||
///
|
||||
INSET_CODE_SIZE
|
||||
};
|
||||
|
||||
|
@ -13,15 +13,18 @@
|
||||
|
||||
#include "InsetMath.h"
|
||||
#include "MathData.h"
|
||||
#include "MathRow.h"
|
||||
#include "MathStream.h"
|
||||
|
||||
#include "MetricsInfo.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstream.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/textutils.h"
|
||||
|
||||
#include "support/lassert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -49,6 +52,52 @@ MathData const & InsetMath::cell(idx_type) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMath::mathClass() const
|
||||
{
|
||||
return MC_ORD;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
||||
{
|
||||
MathRow::Element e(MathRow::INSET, mi);
|
||||
e.inset = this;
|
||||
e.mclass = mathClass();
|
||||
mrow.push_back(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InsetMath::metricsMarkers(MetricsInfo & mi, Dimension & dim,
|
||||
int framesize) const
|
||||
{
|
||||
if (!mi.base.macro_nesting)
|
||||
Inset::metricsMarkers(dim, framesize);
|
||||
}
|
||||
|
||||
|
||||
void InsetMath::metricsMarkers2(MetricsInfo & mi, Dimension & dim,
|
||||
int framesize) const
|
||||
{
|
||||
if (!mi.base.macro_nesting)
|
||||
Inset::metricsMarkers2(dim, framesize);
|
||||
}
|
||||
|
||||
|
||||
void InsetMath::drawMarkers(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
if (!pi.base.macro_nesting)
|
||||
Inset::drawMarkers(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetMath::drawMarkers2(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
if (!pi.base.macro_nesting)
|
||||
Inset::drawMarkers2(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InsetMath::dump() const
|
||||
{
|
||||
lyxerr << "---------------------------------------------" << endl;
|
||||
|
@ -13,6 +13,8 @@
|
||||
#ifndef MATH_INSET_H
|
||||
#define MATH_INSET_H
|
||||
|
||||
#include "MathClass.h"
|
||||
|
||||
#include "insets/Inset.h"
|
||||
|
||||
|
||||
@ -51,7 +53,10 @@ inclusion in the "real LyX insets" FormulaInset and FormulaMacroInset.
|
||||
|
||||
*/
|
||||
|
||||
class Cursor;
|
||||
class OutputParams;
|
||||
class MetricsInfo;
|
||||
|
||||
class InsetMathArray;
|
||||
class InsetMathAMSArray;
|
||||
class InsetMathBrace;
|
||||
@ -70,7 +75,6 @@ class InsetMathSpace;
|
||||
class InsetMathSpecialChar;
|
||||
class InsetMathSymbol;
|
||||
class InsetMathUnknown;
|
||||
|
||||
class InsetMathRef;
|
||||
|
||||
class HtmlStream;
|
||||
@ -85,7 +89,7 @@ class WriteStream;
|
||||
class MathData;
|
||||
class MathMacroTemplate;
|
||||
class MathMacro;
|
||||
class Cursor;
|
||||
class MathRow;
|
||||
class TextPainter;
|
||||
class TextMetricsInfo;
|
||||
class ReplaceData;
|
||||
@ -160,14 +164,22 @@ public:
|
||||
virtual InsetMathRef * asRefInset() { return 0; }
|
||||
virtual InsetMathSpecialChar const * asSpecialCharInset() const { return 0; }
|
||||
|
||||
/// The class of the math object (used primarily for spacing)
|
||||
virtual MathClass mathClass() const;
|
||||
/// Add this inset to a math row. Return true if contents got added
|
||||
virtual bool addToMathRow(MathRow &, MetricsInfo & mi) const;
|
||||
|
||||
/// draw four angular markers
|
||||
void drawMarkers(PainterInfo & pi, int x, int y) const;
|
||||
/// draw two angular markers
|
||||
void drawMarkers2(PainterInfo & pi, int x, int y) const;
|
||||
/// add space for markers
|
||||
void metricsMarkers(MetricsInfo & mi, Dimension & dim, int framesize = 1) const;
|
||||
/// add space for markers
|
||||
void metricsMarkers2(MetricsInfo & mi, Dimension & dim, int framesize = 1) const;
|
||||
|
||||
/// identifies things that can get scripts
|
||||
virtual bool isScriptable() const { return false; }
|
||||
/// identifies a binary operators (used for spacing)
|
||||
virtual bool isMathBin() const { return false; }
|
||||
/// identifies relational operators (used for spacing and splitting equations)
|
||||
virtual bool isMathRel() const { return false; }
|
||||
/// identifies punctuation (used for spacing)
|
||||
virtual bool isMathPunct() const { return false; }
|
||||
/// will this get written as a single block in {..}
|
||||
virtual bool extraBraces() const { return false; }
|
||||
|
||||
|
@ -51,7 +51,7 @@ void InsetMathBoldSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
//Changer dummy = mi.base.changeFontSet("mathbf");
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
++dim.wid; // for 'double stroke'
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ void InsetMathBox::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Changer dummy = mi.base.changeFontSet("textnormal");
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ void InsetMathFBox::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Changer dummy = mi.base.changeFontSet("textnormal");
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
|
||||
metricsMarkers2(mi, dim, 3); // 1 pixel space, 1 frame, 1 space
|
||||
}
|
||||
|
||||
|
||||
@ -246,7 +246,7 @@ void InsetMathMakebox::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des += 1;
|
||||
}
|
||||
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
@ -360,7 +360,7 @@ InsetMathBoxed::InsetMathBoxed(Buffer * buf)
|
||||
void InsetMathBoxed::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
|
||||
metricsMarkers2(mi, dim, 3); // 1 pixel space, 1 frame, 1 space
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ void InsetMathBrace::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc = max(dim0.asc, t.asc);
|
||||
dim.des = max(dim0.des, t.des);
|
||||
dim.wid = dim0.width() + 2 * t.wid;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ Inset * InsetMathCancel::clone() const
|
||||
void InsetMathCancel::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void InsetMathCancelto::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc = max(dim0.ascent() + 2, dim0.ascent() + dim1.ascent()) + 2 + 8;
|
||||
dim.des = max(dim0.descent() - 2, dim1.descent()) + 2;
|
||||
dim.wid = dim0.width() + dim1.width() + 10;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -121,8 +121,6 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim = fm.dimension(char_);
|
||||
kerning_ = fm.rbearing(char_) - dim.wid;
|
||||
}
|
||||
if (mathfont && isMathPunct())
|
||||
dim.wid += mathed_thinmuskip(mi.base.font);
|
||||
}
|
||||
|
||||
|
||||
@ -266,22 +264,19 @@ void InsetMathChar::htmlize(HtmlStream & ms) const
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathBin() const
|
||||
MathClass InsetMathChar::mathClass() const
|
||||
{
|
||||
return subst_ && subst_->extra == "mathbin";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathRel() const
|
||||
{
|
||||
return subst_ && subst_->extra == "mathrel";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathPunct() const
|
||||
{
|
||||
return support::contains(",;", static_cast<char>(char_))
|
||||
|| (subst_ && subst_->extra == "mathpunct");
|
||||
// this information comes from fontmath.ltx in LaTeX source.
|
||||
char const ch = static_cast<char>(char_);
|
||||
if (subst_)
|
||||
return string_to_class(subst_->extra);
|
||||
else if (support::contains(",;", ch))
|
||||
return MC_PUNCT;
|
||||
else if (support::contains("([", ch))
|
||||
return MC_OPEN;
|
||||
else if (support::contains(")]!?", ch))
|
||||
return MC_CLOSE;
|
||||
else return MC_ORD;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,11 +51,7 @@ public:
|
||||
///
|
||||
char_type getChar() const { return char_; }
|
||||
///
|
||||
bool isMathBin() const;
|
||||
///
|
||||
bool isMathRel() const;
|
||||
///
|
||||
bool isMathPunct() const;
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_CHAR_CODE; }
|
||||
|
||||
|
57
src/mathed/InsetMathClass.cpp
Normal file
57
src/mathed/InsetMathClass.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* \file InsetMathClass.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author André Pönitz
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "InsetMathClass.h"
|
||||
|
||||
#include "support/docstream.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
InsetMathClass::InsetMathClass(Buffer * buf, MathClass mc)
|
||||
: InsetMathNest(buf, 1), math_class_(mc)
|
||||
{}
|
||||
|
||||
|
||||
Inset * InsetMathClass::clone() const
|
||||
{
|
||||
return new InsetMathClass(*this);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathClass::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathClass::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
cell(0).draw(pi, x + 1, y);
|
||||
drawMarkers(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
docstring InsetMathClass::name() const
|
||||
{
|
||||
return class_to_string(math_class_);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathClass::infoize(odocstream & os) const
|
||||
{
|
||||
os << name() << " ";
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
50
src/mathed/InsetMathClass.h
Normal file
50
src/mathed/InsetMathClass.h
Normal file
@ -0,0 +1,50 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file InsetMathClass.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author André Pönitz
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef MATH_CLASSINSET_H
|
||||
#define MATH_CLASSINSET_H
|
||||
|
||||
#include "MathClass.h"
|
||||
|
||||
#include "InsetMathNest.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
/// Support for LaTeX's \\mathxxx class-changing commands
|
||||
|
||||
class InsetMathClass : public InsetMathNest {
|
||||
public:
|
||||
///
|
||||
InsetMathClass(Buffer * buf, MathClass);
|
||||
///
|
||||
docstring name() const;
|
||||
///
|
||||
MathClass mathClass() const { return math_class_; }
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
void infoize(odocstream & os) const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_CLASS_CODE; }
|
||||
|
||||
private:
|
||||
virtual Inset * clone() const;
|
||||
///
|
||||
MathClass math_class_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
#endif
|
@ -49,7 +49,7 @@ Inset * InsetMathColor::clone() const
|
||||
void InsetMathColor::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ Inset * InsetMathComment::clone() const
|
||||
void InsetMathComment::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,7 +122,7 @@ void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des += dh_ + 2;
|
||||
}
|
||||
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ void InsetMathDelim::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dw_ = 8;
|
||||
if (dw_ < 4)
|
||||
dw_ = 4;
|
||||
dim.wid = dim0.width() + 2 * dw_ + 2 * mathed_thinmuskip(mi.base.font);
|
||||
dim.wid = dim0.width() + 2 * dw_;
|
||||
dim.asc = max(a0, d0) + h0;
|
||||
dim.des = max(a0, d0) - h0;
|
||||
}
|
||||
@ -125,10 +125,9 @@ void InsetMathDelim::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
Dimension const dim = dimension(*pi.base.bv);
|
||||
int const b = y - dim.asc;
|
||||
int const skip = mathed_thinmuskip(pi.base.font);
|
||||
cell(0).draw(pi, x + dw_ + skip, y);
|
||||
mathed_draw_deco(pi, x + skip, b, dw_, dim.height(), left_);
|
||||
mathed_draw_deco(pi, x + dim.width() - dw_ - skip,
|
||||
cell(0).draw(pi, x + dw_, y);
|
||||
mathed_draw_deco(pi, x, b, dw_, dim.height(), left_);
|
||||
mathed_draw_deco(pi, x + dim.width() - dw_,
|
||||
b, dw_, dim.height(), right_);
|
||||
setPosCache(pi, x, y);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
InsetMathDelim * asDelimInset() { return this; }
|
||||
///
|
||||
InsetMathDelim const * asDelimInset() const { return this; }
|
||||
///
|
||||
MathClass mathClass() const { return MC_INNER; }
|
||||
/// is it (...)?
|
||||
bool isParenthesis() const;
|
||||
/// is it [...]?
|
||||
|
@ -41,7 +41,7 @@ void InsetMathEnsureMath::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
bool really_change_font = isTextFont(mi.base.fontname);
|
||||
Changer dummy = mi.base.changeFontSet("mathnormal", really_change_font);
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ Inset * InsetMathEnv::clone() const
|
||||
void InsetMathEnv::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,7 +86,7 @@ void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Changer dummy = mi.base.changeFontSet(font());
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ void InsetMathFontOld::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
|
||||
Changer dummy = mi.base.changeFontSet(fontname, really_change_font);
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,6 +123,31 @@ bool InsetMathFrac::idxBackward(Cursor & cur) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathFrac::mathClass() const
|
||||
{
|
||||
// Generalized fractions are of inner class (see The TeXbook, p. 292)
|
||||
// But stuff from the unit/nicefrac packages are not real fractions.
|
||||
MathClass mc = MC_ORD;
|
||||
switch (kind_) {
|
||||
case ATOP:
|
||||
case OVER:
|
||||
case FRAC:
|
||||
case DFRAC:
|
||||
case TFRAC:
|
||||
case CFRAC:
|
||||
case CFRACLEFT:
|
||||
case CFRACRIGHT:
|
||||
mc = MC_INNER;
|
||||
break;
|
||||
case NICEFRAC:
|
||||
case UNITFRAC:
|
||||
case UNIT:
|
||||
break;
|
||||
}
|
||||
return mc;
|
||||
}
|
||||
|
||||
|
||||
void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim0, dim1, dim2;
|
||||
@ -182,7 +207,7 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des = dim1.height() + 2 - 5;
|
||||
}
|
||||
}
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
@ -557,7 +582,7 @@ void InsetMathBinom::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc = dim0.height() + 4 + 5;
|
||||
dim.des = dim1.height() + 4 - 5;
|
||||
dim.wid = max(dim0.wid, dim1.wid) + 2 * dw(dim.height()) + 4;
|
||||
metricsMarkers2(dim);
|
||||
metricsMarkers2(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
///
|
||||
bool idxBackward(Cursor &) const;
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo &, int x, int y) const;
|
||||
@ -117,6 +119,8 @@ public:
|
||||
void write(WriteStream & os) const;
|
||||
///
|
||||
void normalize(NormalStream &) const;
|
||||
/// Generalized fractions are of inner class (see The TeXbook, p.292)
|
||||
MathClass mathClass() const { return MC_INNER; }
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
|
@ -588,7 +588,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
}
|
||||
*/
|
||||
dim.wid += leftMargin() + rightMargin();
|
||||
metricsMarkers2(dim);
|
||||
metricsMarkers2(mi, dim);
|
||||
// Cache the inset dimension.
|
||||
setDimCache(mi, dim);
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ namespace {
|
||||
size_t firstRelOp(MathData const & ar)
|
||||
{
|
||||
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
|
||||
if ((*it)->isMathRel())
|
||||
if ((*it)->mathClass() == MC_REL)
|
||||
return it - ar.begin();
|
||||
return ar.size();
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ void InsetMathLefteqn::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc += 2;
|
||||
dim.des += 2;
|
||||
dim.wid = 4;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ void InsetMathOverset::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.wid = max(dim0.width(), dim1.wid) + 4;
|
||||
dim.asc = dim1.asc + dim0.height() + 4;
|
||||
dim.des = dim1.des;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ Inset * InsetMathPhantom::clone() const
|
||||
void InsetMathPhantom::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void InsetMathRoot::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc = max(dim0.ascent() + 5, dim1.ascent()) + 2;
|
||||
dim.des = max(dim0.descent() - 5, dim1.descent()) + 2;
|
||||
dim.wid = dim0.width() + dim1.width() + 10;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -273,6 +273,19 @@ int InsetMathScript::nker(BufferView const * bv) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathScript::mathClass() const
|
||||
{
|
||||
// FIXME: this is a hack, since the class will not be correct if
|
||||
// the nucleus has several elements.
|
||||
// The correct implementation would require to linearize the nucleus.
|
||||
if (nuc().empty())
|
||||
return MC_ORD;
|
||||
else
|
||||
// return the class of last element since this is the one that counts.
|
||||
return nuc().back()->mathClass();
|
||||
}
|
||||
|
||||
|
||||
void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim0;
|
||||
@ -320,7 +333,7 @@ void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des = max(nd, des);
|
||||
} else
|
||||
dim.des = nd;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
///
|
||||
mode_type currentMode() const { return MATH_MODE; }
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
|
@ -221,7 +221,7 @@ void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
int nd = ndes(bv);
|
||||
int des = dyb(bv) + max(dimbl.descent(), dimbr.descent());
|
||||
dim.des = max(nd, des);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void InsetMathSize::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Changer dummy = mi.base.changeStyle(style_);
|
||||
cell(0).metrics(mi, dim);
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ void InsetMathSqrt::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc += 4;
|
||||
dim.des += 2;
|
||||
dim.wid += 12;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,6 +52,13 @@ bool InsetMathStackrel::idxUpDown(Cursor & cur, bool up) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathStackrel::mathClass() const
|
||||
{
|
||||
// FIXME: update this when/if \stackbin is supported
|
||||
return MC_REL;
|
||||
}
|
||||
|
||||
|
||||
void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim1;
|
||||
@ -70,7 +77,7 @@ void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc = dim1.ascent() + dim0.height() + 4;
|
||||
dim.des = dim1.descent();
|
||||
}
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
///
|
||||
bool idxUpDown(Cursor &, bool up) const;
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
@ -35,7 +37,7 @@ public:
|
||||
void mathmlize(MathStream &) const;
|
||||
///
|
||||
void htmlize(HtmlStream &) const;
|
||||
///
|
||||
///
|
||||
void validate(LaTeXFeatures &) const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_STACKREL_CODE; }
|
||||
|
@ -70,7 +70,7 @@ void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc += h_;
|
||||
dim.des -= h_;
|
||||
}
|
||||
// set striptable_
|
||||
// set scriptable_
|
||||
scriptable_ = false;
|
||||
if (mi.base.style == LM_ST_DISPLAY)
|
||||
if (sym_->inset == "cmex" || sym_->inset == "esint" ||
|
||||
@ -92,30 +92,21 @@ InsetMath::mode_type InsetMathSymbol::currentMode() const
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathBin() const
|
||||
{
|
||||
return sym_->extra == "mathbin";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathRel() const
|
||||
{
|
||||
return sym_->extra == "mathrel";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathPunct() const
|
||||
{
|
||||
return sym_->extra == "mathpunct";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isOrdAlpha() const
|
||||
{
|
||||
return sym_->extra == "mathord" || sym_->extra == "mathalpha";
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathSymbol::mathClass() const
|
||||
{
|
||||
if (sym_->extra == "func" || sym_->extra == "funclim")
|
||||
return MC_OP;
|
||||
MathClass const mc = string_to_class(sym_->extra);
|
||||
return (mc == MC_UNKNOWN) ? MC_ORD : mc;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isScriptable() const
|
||||
{
|
||||
return scriptable_;
|
||||
|
@ -40,11 +40,7 @@ public:
|
||||
///
|
||||
mode_type currentMode() const;
|
||||
///
|
||||
bool isMathRel() const;
|
||||
///
|
||||
bool isMathBin() const;
|
||||
///
|
||||
bool isMathPunct() const;
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
bool isOrdAlpha() const;
|
||||
/// do we take scripts?
|
||||
|
@ -40,7 +40,7 @@ void InsetMathUnderset::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.wid = max(dim0.width(), dim1.width()) + 4;
|
||||
dim.asc = dim1.ascent();
|
||||
dim.des = dim1.descent() + dim0.height() + 4;
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.wid = max(dim0.width(), dim1.width()) + 10;
|
||||
dim.asc = dim0.height() + 10;
|
||||
dim.des = dim1.height();
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
180
src/mathed/MathClass.cpp
Normal file
180
src/mathed/MathClass.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* \file MathClass.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "MathClass.h"
|
||||
#include "MathSupport.h"
|
||||
|
||||
#include "MetricsInfo.h"
|
||||
#include "FontInfo.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstring.h"
|
||||
#include "support/lassert.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
docstring const class_to_string(MathClass const mc)
|
||||
{
|
||||
string s;
|
||||
switch (mc) {
|
||||
case MC_ORD:
|
||||
s = "mathord";
|
||||
break;
|
||||
case MC_OP:
|
||||
s = "mathop";
|
||||
break;
|
||||
case MC_BIN:
|
||||
s = "mathbin";
|
||||
break;
|
||||
case MC_REL:
|
||||
s = "mathrel";
|
||||
break;
|
||||
case MC_OPEN:
|
||||
s = "mathopen";
|
||||
break;
|
||||
case MC_CLOSE:
|
||||
s = "mathclose";
|
||||
break;
|
||||
case MC_PUNCT:
|
||||
s = "mathpunct";
|
||||
break;
|
||||
case MC_INNER:
|
||||
s = "mathinner";
|
||||
break;
|
||||
case MC_UNKNOWN:
|
||||
LATTEST(false);
|
||||
s = "mathord";
|
||||
}
|
||||
return from_ascii(s);
|
||||
}
|
||||
|
||||
|
||||
MathClass string_to_class(docstring const &s)
|
||||
{
|
||||
if (s == "mathop")
|
||||
return MC_OP;
|
||||
else if (s == "mathbin")
|
||||
return MC_BIN;
|
||||
else if (s == "mathrel")
|
||||
return MC_REL;
|
||||
else if (s == "mathopen")
|
||||
return MC_OPEN;
|
||||
else if (s == "mathclose")
|
||||
return MC_CLOSE;
|
||||
else if (s == "mathpunct")
|
||||
return MC_PUNCT;
|
||||
else if (s == "mathinner")
|
||||
return MC_INNER;
|
||||
else if (s == "mathord")
|
||||
return MC_ORD;
|
||||
else
|
||||
return MC_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The TeXbook presents in Appendix G a set of 22 rules (!) explaining
|
||||
* how to typeset mathematic formulas. Of interest here are rules 5
|
||||
* and 6:
|
||||
|
||||
* 5. If the current item is a Bin atom, and if this was the first
|
||||
* atom in the list, or if the most recent previous atom was Bin,
|
||||
* Op, Rel, Open, or Punct, change the current Bin to Ord [and
|
||||
* continue with Rule 14. Otherwise continue with Rule 17]
|
||||
*
|
||||
* 6. If the current item is a Rel or Close or Punct atom, and if the
|
||||
* most recent previous atom was Bin, change that previous Bin to
|
||||
* Ord. [Continue with Rule 17.]
|
||||
*/
|
||||
void update_class(MathClass & mc, MathClass const prev, MathClass const next)
|
||||
{
|
||||
if (mc == MC_BIN
|
||||
&& (prev == MC_BIN || prev == MC_OP || prev == MC_OPEN
|
||||
|| prev == MC_PUNCT || prev == MC_REL
|
||||
|| next == MC_CLOSE || next == MC_PUNCT || next == MC_REL))
|
||||
mc = MC_ORD;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This table of spacing between two classes can be found p. 170 of
|
||||
* The TeXbook.
|
||||
*
|
||||
* The line is the class of the first class, and the column the second
|
||||
* class. The number encodes the spacing between the two atoms, as
|
||||
* follows
|
||||
*
|
||||
* + 0: no spacing
|
||||
* + 1: thin mu skip
|
||||
* + 2: med mu skip
|
||||
* + 3: thick mu skip
|
||||
* + 9: should never happen
|
||||
* + negative value: either 0 if the atom is in script or scriptscript mode,
|
||||
* or the spacing given by the absolute value.
|
||||
*/
|
||||
int pair_spc[MC_UNKNOWN][MC_UNKNOWN] = {
|
||||
// ORD OP BIN REL OPEN CLOSE PUNCT INNER
|
||||
{ 0, 1, -2, -3, 0, 0, 0, -1}, // ORD
|
||||
{ 1, 1, 9, -3, 0, 0, 0, -1}, // OP
|
||||
{ -2, -2, 9, 9, -2, 9, 9, -2}, // BIN
|
||||
{ -3, -3, 9, 0, -3, 0, 0, -3}, // REL
|
||||
{ 0, 0, 9, 0, 0, 0, 0, 0}, // OPEN
|
||||
{ 0, 1, -2, -3, 0, 0, 0, -1}, // CLOSE
|
||||
{ -1, -1, 9, -1, -1, -1, -1, -1}, // PUNCT
|
||||
{ -1, 1, -2, -3, -1, 0, -1, -1}, // INNER
|
||||
};
|
||||
|
||||
|
||||
int class_spacing(MathClass const mc1, MathClass const mc2,
|
||||
MetricsBase const & mb)
|
||||
{
|
||||
int spc_code = pair_spc[mc1][mc2];
|
||||
//lyxerr << class_to_string(mc1) << "+" << class_to_string(mc2)
|
||||
// << "=" << spc_code << " @" << mb.style << endl;
|
||||
if (spc_code < 0) {
|
||||
switch (mb.style) {
|
||||
case LM_ST_DISPLAY:
|
||||
case LM_ST_TEXT:
|
||||
spc_code = abs(spc_code);
|
||||
break;
|
||||
case LM_ST_SCRIPT:
|
||||
case LM_ST_SCRIPTSCRIPT:
|
||||
spc_code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int spc = 0;
|
||||
switch(spc_code) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
spc = mathed_thinmuskip(mb.font);
|
||||
break;
|
||||
case 2:
|
||||
spc = mathed_medmuskip(mb.font);
|
||||
break;
|
||||
case 3:
|
||||
spc = mathed_thickmuskip(mb.font);
|
||||
break;
|
||||
default:
|
||||
LYXERR0("Impossible pair of classes: (" << mc1 << ", " << mc2 << ")");
|
||||
LATTEST(false);
|
||||
}
|
||||
return spc;
|
||||
}
|
||||
|
||||
} // namespace lyx
|
69
src/mathed/MathClass.h
Normal file
69
src/mathed/MathClass.h
Normal file
@ -0,0 +1,69 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file MathClass.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef MATH_CLASS_H
|
||||
#define MATH_CLASS_H
|
||||
|
||||
#include "support/strfwd.h"
|
||||
|
||||
namespace lyx {
|
||||
|
||||
class MetricsBase;
|
||||
|
||||
/* The TeXbook, p. 158:
|
||||
*
|
||||
* There are thirteen kinds of atoms, each of which might act
|
||||
* differently in a formula; for example, ‘(’ is an Open atom because
|
||||
* it comes from an opening. Here is a complete list of the different
|
||||
* kinds:
|
||||
|
||||
* + Ord: an ordinary atom like ‘x’
|
||||
* + Op: a large operator atom like ‘\sum’
|
||||
* + Bin: a binary operation atom like ‘+’
|
||||
* + Rel: a relation atom like ‘=’
|
||||
* + Open: an opening atom like ‘(’
|
||||
* + Close: a closing atom like ‘)’
|
||||
* + Punct: a punctuation atom like ‘,’
|
||||
* + Inner: an inner atom like ‘\frac{1}{2}’
|
||||
* + Over: an overline atom like ‘\overline{x}’
|
||||
* + Under: an underline atom like ‘\underline{x}’
|
||||
* + Acc: an accented atom like ‘\hat{x}’
|
||||
* + Rad: a radical atom like ‘\sqrt{2}’
|
||||
* + Vcent: a vbox to be centered, produced by \vcenter.
|
||||
*
|
||||
* Over, Under, Acc, Rad and Vcent are not considered in the enum
|
||||
* below. The relvant elements will be considered as Ord.
|
||||
*/
|
||||
enum MathClass {
|
||||
MC_ORD,
|
||||
MC_OP,
|
||||
MC_BIN,
|
||||
MC_REL,
|
||||
MC_OPEN,
|
||||
MC_CLOSE,
|
||||
MC_PUNCT,
|
||||
MC_INNER,
|
||||
MC_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
MathClass string_to_class(docstring const &);
|
||||
|
||||
docstring const class_to_string(MathClass);
|
||||
|
||||
void update_class(MathClass & mc, MathClass const prev, MathClass const next);
|
||||
|
||||
int class_spacing(MathClass const mc1, MathClass const mc2,
|
||||
MetricsBase const & mb);
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif
|
@ -30,12 +30,10 @@
|
||||
|
||||
#include "mathed/InsetMathUnknown.h"
|
||||
|
||||
#include "frontends/FontMetrics.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstream.h"
|
||||
|
||||
#include "frontends/FontMetrics.h"
|
||||
#include "frontends/Painter.h"
|
||||
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
#include "support/lyxalgo.h"
|
||||
@ -218,6 +216,34 @@ void MathData::touch() const
|
||||
}
|
||||
|
||||
|
||||
bool MathData::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
||||
{
|
||||
bool has_contents = false;
|
||||
BufferView * bv = mi.base.bv;
|
||||
MathData * ar = const_cast<MathData*>(this);
|
||||
ar->updateMacros(&bv->cursor(), mi.macrocontext,
|
||||
InternalUpdate);
|
||||
|
||||
// FIXME: for completion, try to insert the relevant data in the
|
||||
// mathrow (like is done for text rows). We could add a pair of
|
||||
// InsetMathColor inset, but these come with extra spacing of
|
||||
// their own.
|
||||
DocIterator const & inlineCompletionPos = bv->inlineCompletionPos();
|
||||
bool const has_completion = inlineCompletionPos.inMathed()
|
||||
&& &inlineCompletionPos.cell() == this;
|
||||
size_t const compl_pos = has_completion ? inlineCompletionPos.pos() : 0;
|
||||
|
||||
for (size_t i = 0 ; i < size() ; ++i) {
|
||||
has_contents |= (*this)[i]->addToMathRow(mrow, mi);
|
||||
if (i + 1 == compl_pos) {
|
||||
mrow.back().compl_text = bv->inlineCompletion();
|
||||
mrow.back().compl_unique_to = bv->inlineCompletionUniqueChars();
|
||||
}
|
||||
}
|
||||
return has_contents;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
namespace {
|
||||
|
||||
@ -247,53 +273,18 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
mindes_ = (3 * xascent) / 4;
|
||||
slevel_ = (4 * xascent) / 5;
|
||||
sshift_ = xascent / 4;
|
||||
kerning_ = 0;
|
||||
|
||||
if (empty()) {
|
||||
// Cache the dimension.
|
||||
mi.base.bv->coordCache().arrays().add(this, dim);
|
||||
return;
|
||||
}
|
||||
MathRow mrow(mi, this);
|
||||
mrow_cache_[mi.base.bv] = mrow;
|
||||
mrow.metrics(mi, dim);
|
||||
kerning_ = mrow.kerning(mi.base.bv);
|
||||
|
||||
Cursor & cur = mi.base.bv->cursor();
|
||||
const_cast<MathData*>(this)->updateMacros(&cur, mi.macrocontext, InternalUpdate);
|
||||
|
||||
DocIterator const & inlineCompletionPos = mi.base.bv->inlineCompletionPos();
|
||||
MathData const * inlineCompletionData = 0;
|
||||
if (inlineCompletionPos.inMathed())
|
||||
inlineCompletionData = &inlineCompletionPos.cell();
|
||||
|
||||
dim.asc = 0;
|
||||
dim.wid = 0;
|
||||
Dimension d;
|
||||
CoordCache::Insets & coords = mi.base.bv->coordCache().insets();
|
||||
for (pos_type i = 0, n = size(); i != n; ++i) {
|
||||
MathAtom const & at = operator[](i);
|
||||
at->metrics(mi, d);
|
||||
coords.add(at.nucleus(), d);
|
||||
dim += d;
|
||||
if (i == n - 1)
|
||||
kerning_ = at->kerning(mi.base.bv);
|
||||
|
||||
// HACK to draw completion suggestion inline
|
||||
if (inlineCompletionData != this
|
||||
|| size_t(inlineCompletionPos.pos()) != i + 1)
|
||||
continue;
|
||||
|
||||
docstring const & completion = mi.base.bv->inlineCompletion();
|
||||
if (completion.length() == 0)
|
||||
continue;
|
||||
|
||||
FontInfo font = mi.base.font;
|
||||
augmentFont(font, "mathnormal");
|
||||
dim.wid += mathed_string_width(font, completion);
|
||||
}
|
||||
// Cache the dimension.
|
||||
mi.base.bv->coordCache().arrays().add(this, dim);
|
||||
}
|
||||
|
||||
|
||||
void MathData::draw(PainterInfo & pi, int x, int y) const
|
||||
void MathData::draw(PainterInfo & pi, int const x, int const y) const
|
||||
{
|
||||
//lyxerr << "MathData::draw: x: " << x << " y: " << y << endl;
|
||||
BufferView & bv = *pi.base.bv;
|
||||
@ -301,11 +292,6 @@ void MathData::draw(PainterInfo & pi, int x, int y) const
|
||||
|
||||
Dimension const & dim = bv.coordCache().getArrays().dim(this);
|
||||
|
||||
if (empty()) {
|
||||
pi.pain.rectangle(x, y - dim.ascent(), dim.width(), dim.height(), Color_mathline);
|
||||
return;
|
||||
}
|
||||
|
||||
// don't draw outside the workarea
|
||||
if (y + dim.descent() <= 0
|
||||
|| y - dim.ascent() >= bv.workHeight()
|
||||
@ -313,48 +299,8 @@ void MathData::draw(PainterInfo & pi, int x, int y) const
|
||||
|| x >= bv. workWidth())
|
||||
return;
|
||||
|
||||
DocIterator const & inlineCompletionPos = bv.inlineCompletionPos();
|
||||
MathData const * inlineCompletionData = 0;
|
||||
if (inlineCompletionPos.inMathed())
|
||||
inlineCompletionData = &inlineCompletionPos.cell();
|
||||
|
||||
CoordCache::Insets & coords = pi.base.bv->coordCache().insets();
|
||||
for (size_t i = 0, n = size(); i != n; ++i) {
|
||||
MathAtom const & at = operator[](i);
|
||||
coords.add(at.nucleus(), x, y);
|
||||
at->drawSelection(pi, x, y);
|
||||
at->draw(pi, x, y);
|
||||
x += coords.dim(at.nucleus()).wid;
|
||||
|
||||
// Is the inline completion here?
|
||||
if (inlineCompletionData != this
|
||||
|| size_t(inlineCompletionPos.pos()) != i + 1)
|
||||
continue;
|
||||
docstring const & completion = bv.inlineCompletion();
|
||||
if (completion.length() == 0)
|
||||
continue;
|
||||
FontInfo f = pi.base.font;
|
||||
augmentFont(f, "mathnormal");
|
||||
|
||||
// draw the unique and the non-unique completion part
|
||||
// Note: this is not time-critical as it is
|
||||
// only done once per screen.
|
||||
size_t uniqueTo = bv.inlineCompletionUniqueChars();
|
||||
docstring s1 = completion.substr(0, uniqueTo);
|
||||
docstring s2 = completion.substr(uniqueTo);
|
||||
|
||||
if (!s1.empty()) {
|
||||
f.setColor(Color_inlinecompletion);
|
||||
pi.pain.text(x, y, s1, f);
|
||||
x += mathed_string_width(f, s1);
|
||||
}
|
||||
|
||||
if (!s2.empty()) {
|
||||
f.setColor(Color_nonunique_inlinecompletion);
|
||||
pi.pain.text(x, y, s2, f);
|
||||
x += mathed_string_width(f, s2);
|
||||
}
|
||||
}
|
||||
MathRow const & mrow = mrow_cache_[pi.base.bv];
|
||||
mrow.draw(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,7 +16,9 @@
|
||||
#define MATH_DATA_H
|
||||
|
||||
#include "Dimension.h"
|
||||
|
||||
#include "MathAtom.h"
|
||||
#include "MathRow.h"
|
||||
|
||||
#include "OutputEnums.h"
|
||||
|
||||
@ -24,6 +26,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace lyx {
|
||||
@ -117,6 +120,10 @@ public:
|
||||
MathAtom & operator[](pos_type);
|
||||
/// checked read access
|
||||
MathAtom const & operator[](pos_type) const;
|
||||
|
||||
/// Add this array to a math row. Return true if contents got added
|
||||
bool addToMathRow(MathRow &, MetricsInfo & mi) const;
|
||||
|
||||
/// rebuild cached metrics information
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
@ -177,6 +184,9 @@ protected:
|
||||
mutable int kerning_;
|
||||
Buffer * buffer_;
|
||||
|
||||
/// cached object that describes typeset data
|
||||
mutable std::map<BufferView*, MathRow> mrow_cache_;
|
||||
|
||||
private:
|
||||
/// is this an exact match at this position?
|
||||
bool find1(MathData const & ar, size_type pos) const;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "InsetMathCancel.h"
|
||||
#include "InsetMathCancelto.h"
|
||||
#include "InsetMathCases.h"
|
||||
#include "InsetMathClass.h"
|
||||
#include "InsetMathColor.h"
|
||||
#include "InsetMathDecoration.h"
|
||||
#include "InsetMathDots.h"
|
||||
@ -662,10 +663,13 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf)
|
||||
return MathAtom(new InsetMathSpecialChar(s));
|
||||
if (s == " ")
|
||||
return MathAtom(new InsetMathSpace(" ", ""));
|
||||
|
||||
if (s == "regexp")
|
||||
return MathAtom(new InsetMathHull(buf, hullRegexp));
|
||||
|
||||
MathClass const mc = string_to_class(s);
|
||||
if (mc != MC_UNKNOWN)
|
||||
return MathAtom(new InsetMathClass(buf, mc));
|
||||
|
||||
return MathAtom(new MathMacro(buf, s));
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,49 @@ public:
|
||||
///
|
||||
InsetCode lyxCode() const { return ARGUMENT_PROXY_CODE; }
|
||||
///
|
||||
bool addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
||||
{
|
||||
// macro arguments are in macros
|
||||
LATTEST(mi.base.macro_nesting > 0);
|
||||
if (mi.base.macro_nesting == 1)
|
||||
mi.base.macro_nesting = 0;
|
||||
|
||||
MathRow::Element e_beg(MathRow::BEG_ARG, mi);
|
||||
e_beg.macro = mathMacro_;
|
||||
e_beg.ar = &mathMacro_->cell(idx_);
|
||||
mrow.push_back(e_beg);
|
||||
|
||||
mathMacro_->macro()->unlock();
|
||||
bool has_contents = mathMacro_->cell(idx_).addToMathRow(mrow, mi);
|
||||
mathMacro_->macro()->lock();
|
||||
|
||||
// if there was no contents, and the contents is editable,
|
||||
// then we insert a box instead.
|
||||
if (!has_contents && mi.base.macro_nesting == 0) {
|
||||
MathRow::Element e(MathRow::BOX, mi);
|
||||
e.color = Color_mathline;
|
||||
mrow.push_back(e);
|
||||
has_contents = true;
|
||||
}
|
||||
|
||||
if (mi.base.macro_nesting == 0)
|
||||
mi.base.macro_nesting = 1;
|
||||
|
||||
MathRow::Element e_end(MathRow::END_ARG, mi);
|
||||
e_end.macro = mathMacro_;
|
||||
e_end.ar = &mathMacro_->cell(idx_);
|
||||
|
||||
mrow.push_back(e_end);
|
||||
|
||||
return has_contents;
|
||||
}
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const {
|
||||
// macro arguments are in macros
|
||||
LATTEST(mi.base.macro_nesting > 0);
|
||||
if (mi.base.macro_nesting == 1)
|
||||
mi.base.macro_nesting = 0;
|
||||
|
||||
mathMacro_->macro()->unlock();
|
||||
mathMacro_->cell(idx_).metrics(mi, dim);
|
||||
|
||||
@ -77,6 +119,8 @@ public:
|
||||
def_.metrics(mi, dim);
|
||||
|
||||
mathMacro_->macro()->lock();
|
||||
if (mi.base.macro_nesting == 0)
|
||||
mi.base.macro_nesting = 1;
|
||||
}
|
||||
// write(), normalize(), infoize() and infoize2() are not needed since
|
||||
// MathMacro uses the definition and not the expanded cells.
|
||||
@ -94,6 +138,10 @@ public:
|
||||
void octave(OctaveStream & os) const { os << mathMacro_->cell(idx_); }
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const {
|
||||
LATTEST(pi.base.macro_nesting > 0);
|
||||
if (pi.base.macro_nesting == 1)
|
||||
pi.base.macro_nesting = 0;
|
||||
|
||||
if (mathMacro_->editMetrics(pi.base.bv)) {
|
||||
// The only way a ArgumentProxy can appear is in a cell of the
|
||||
// MathMacro. Moreover the cells are only drawn in the DISPLAY_FOLDED
|
||||
@ -111,6 +159,9 @@ public:
|
||||
def_.draw(pi, x, y);
|
||||
} else
|
||||
mathMacro_->cell(idx_).draw(pi, x, y);
|
||||
|
||||
if (pi.base.macro_nesting == 0)
|
||||
pi.base.macro_nesting = 1;
|
||||
}
|
||||
///
|
||||
size_t idx() const { return idx_; }
|
||||
@ -266,6 +317,45 @@ MathMacro::~MathMacro()
|
||||
}
|
||||
|
||||
|
||||
bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
||||
{
|
||||
// set edit mode for which we will have calculated row.
|
||||
// This is the same as what is done in metrics().
|
||||
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
||||
|
||||
if (displayMode() != MathMacro::DISPLAY_NORMAL
|
||||
|| d->editing_[mi.base.bv])
|
||||
return InsetMath::addToMathRow(mrow, mi);
|
||||
|
||||
MathRow::Element e_beg(MathRow::BEG_MACRO, mi);
|
||||
e_beg.macro = this;
|
||||
mrow.push_back(e_beg);
|
||||
|
||||
++mi.base.macro_nesting;
|
||||
|
||||
d->macro_->lock();
|
||||
bool has_contents = d->expanded_.addToMathRow(mrow, mi);
|
||||
d->macro_->unlock();
|
||||
|
||||
// if there was no contents and the array is editable, then we
|
||||
// insert a grey box instead.
|
||||
if (!has_contents && mi.base.macro_nesting == 1) {
|
||||
MathRow::Element e(MathRow::BOX, mi);
|
||||
e.color = Color_mathmacroblend;
|
||||
mrow.push_back(e);
|
||||
has_contents = true;
|
||||
}
|
||||
|
||||
--mi.base.macro_nesting;
|
||||
|
||||
MathRow::Element e_end(MathRow::END_MACRO, mi);
|
||||
e_end.macro = this;
|
||||
mrow.push_back(e_end);
|
||||
|
||||
return has_contents;
|
||||
}
|
||||
|
||||
|
||||
Inset * MathMacro::clone() const
|
||||
{
|
||||
MathMacro * copy = new MathMacro(*this);
|
||||
@ -344,7 +434,7 @@ bool MathMacro::editMode(BufferView const * bv) const {
|
||||
}
|
||||
|
||||
|
||||
MacroData const * MathMacro::macro()
|
||||
MacroData const * MathMacro::macro() const
|
||||
{
|
||||
return d->macro_;
|
||||
}
|
||||
@ -358,6 +448,9 @@ bool MathMacro::editMetrics(BufferView const * bv) const
|
||||
|
||||
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
// the macro contents is not editable (except the arguments)
|
||||
++mi.base.macro_nesting;
|
||||
|
||||
// set edit mode for which we will have calculated metrics. But only
|
||||
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
||||
|
||||
@ -371,7 +464,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.wid += bsdim.width() + 1;
|
||||
dim.asc = max(bsdim.ascent(), dim.ascent());
|
||||
dim.des = max(bsdim.descent(), dim.descent());
|
||||
metricsMarkers(dim);
|
||||
metricsMarkers(mi, dim);
|
||||
} else if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST
|
||||
&& d->editing_[mi.base.bv]) {
|
||||
// Macro will be edited in a old-style list mode here:
|
||||
@ -411,7 +504,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc += 1;
|
||||
dim.des += 1;
|
||||
dim.wid += 2;
|
||||
metricsMarkers2(dim);
|
||||
metricsMarkers2(mi, dim);
|
||||
} else {
|
||||
LBUFERR(d->macro_);
|
||||
|
||||
@ -446,6 +539,9 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// restore macro nesting
|
||||
--mi.base.macro_nesting;
|
||||
}
|
||||
|
||||
|
||||
@ -614,6 +710,9 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
|
||||
dim.height() - 2, Color_mathmacroframe);
|
||||
drawMarkers2(pi, expx, expy);
|
||||
} else {
|
||||
// the macro contents is not editable (except the arguments)
|
||||
++pi.base.macro_nesting;
|
||||
|
||||
bool drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX;
|
||||
bool upshape = currentMode() == TEXT_MODE;
|
||||
Changer dummy = pi.base.font.changeShape(upshape ? UP_SHAPE
|
||||
@ -648,8 +747,11 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
|
||||
} else
|
||||
d->expanded_.draw(pi, expx, expy);
|
||||
|
||||
--pi.base.macro_nesting;
|
||||
|
||||
if (!drawBox)
|
||||
drawMarkers(pi, x, y);
|
||||
|
||||
}
|
||||
|
||||
// edit mode changed?
|
||||
|
@ -37,6 +37,10 @@ public:
|
||||
///
|
||||
virtual MathMacro const * asMacro() const { return this; }
|
||||
///
|
||||
/// If the macro is in normal edit mode, dissolve its contents in
|
||||
/// the row. Otherwise, just insert the inset.
|
||||
bool addToMathRow(MathRow &, MetricsInfo & mi) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
/// draw selection background
|
||||
void drawSelection(PainterInfo & pi, int x, int y) const;
|
||||
@ -45,6 +49,8 @@ public:
|
||||
{ drawMarkers2(pi, x, y); }
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
/// was the macro in edit mode when computing metrics?
|
||||
bool editMetrics(BufferView const * bv) const;
|
||||
///
|
||||
int kerning(BufferView const * bv) const;
|
||||
/// get cursor position
|
||||
@ -117,6 +123,8 @@ public:
|
||||
///
|
||||
docstring name() const;
|
||||
///
|
||||
MacroData const * macro() const;
|
||||
///
|
||||
docstring macroName() const;
|
||||
///
|
||||
bool validName() const;
|
||||
@ -151,10 +159,6 @@ protected:
|
||||
/// attach arguments (maybe less than arity at the end of an MathData),
|
||||
/// including the optional ones (even if it can be empty here)
|
||||
void attachArguments(std::vector<MathData> const & args, size_t arity, int optionals);
|
||||
///
|
||||
MacroData const * macro();
|
||||
///
|
||||
bool editMetrics(BufferView const * bv) const;
|
||||
|
||||
private:
|
||||
///
|
||||
|
@ -269,7 +269,7 @@ Inset * InsetMathWrapper::clone() const
|
||||
void InsetMathWrapper::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
value_->metrics(mi, dim);
|
||||
//metricsMarkers2(dim);
|
||||
//metricsMarkers2(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
|
319
src/mathed/MathRow.cpp
Normal file
319
src/mathed/MathRow.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
/**
|
||||
* \file MathRow.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "MathRow.h"
|
||||
|
||||
#include "InsetMath.h"
|
||||
#include "MathClass.h"
|
||||
#include "MathData.h"
|
||||
#include "MathMacro.h"
|
||||
#include "MathSupport.h"
|
||||
|
||||
#include "BufferView.h"
|
||||
#include "CoordCache.h"
|
||||
#include "MetricsInfo.h"
|
||||
|
||||
#include "frontends/FontMetrics.h"
|
||||
#include "frontends/Painter.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstring.h"
|
||||
#include "support/lassert.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
MathRow::Element::Element(Type t, MetricsInfo &mi)
|
||||
: type(t), macro_nesting(mi.base.macro_nesting),
|
||||
inset(0), mclass(MC_ORD), before(0), after(0), compl_unique_to(0),
|
||||
macro(0), color(Color_red)
|
||||
{}
|
||||
|
||||
|
||||
MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
||||
{
|
||||
// First there is a dummy element of type "open"
|
||||
push_back(Element(BEGIN, mi));
|
||||
back().mclass = MC_OPEN;
|
||||
|
||||
// Then insert the MathData argument
|
||||
bool const has_contents = ar->addToMathRow(*this, mi);
|
||||
|
||||
// empty arrays are visible when they are editable
|
||||
// we reserve the necessary space anyway (even if nothing gets drawn)
|
||||
if (!has_contents) {
|
||||
Element e(BOX, mi);
|
||||
e.color = Color_mathline;
|
||||
push_back(e);
|
||||
}
|
||||
|
||||
// Finally there is a dummy element of type "close"
|
||||
push_back(Element(END, mi));
|
||||
back().mclass = MC_CLOSE;
|
||||
|
||||
/* Do spacing only in math mode. This test is a bit clumsy,
|
||||
* but it is used in other places for guessing the current mode.
|
||||
*/
|
||||
if (!isMathFont(mi.base.fontname))
|
||||
return;
|
||||
|
||||
// update classes
|
||||
for (int i = 1 ; i != static_cast<int>(elements_.size()) - 1 ; ++i) {
|
||||
if (elements_[i].type != INSET)
|
||||
continue;
|
||||
update_class(elements_[i].mclass, elements_[before(i)].mclass,
|
||||
elements_[after(i)].mclass);
|
||||
}
|
||||
|
||||
// set spacing
|
||||
// We go to the end to handle spacing at the end of equation
|
||||
for (int i = 1 ; i != static_cast<int>(elements_.size()) ; ++i) {
|
||||
if (elements_[i].type != INSET)
|
||||
continue;
|
||||
Element & bef = elements_[before(i)];
|
||||
int spc = class_spacing(bef.mclass, elements_[i].mclass, mi.base);
|
||||
bef.after = spc / 2;
|
||||
// this is better than spc / 2 to avoid rounding problems
|
||||
elements_[i].before = spc - spc / 2;
|
||||
}
|
||||
// Do not lose spacing allocated to extremities
|
||||
if (!elements_.empty()) {
|
||||
elements_[after(0)].before += elements_.front().after;
|
||||
elements_[before(elements_.size() - 1)].after += elements_.back().before;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MathRow::before(int i) const
|
||||
{
|
||||
do
|
||||
--i;
|
||||
while (elements_[i].type != BEGIN
|
||||
&& elements_[i].type != INSET);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int MathRow::after(int i) const
|
||||
{
|
||||
do
|
||||
++i;
|
||||
while (elements_[i].type != END
|
||||
&& elements_[i].type != INSET);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
dim.asc = 0;
|
||||
dim.wid = 0;
|
||||
// In order to compute the dimension of macros and their
|
||||
// arguments, it is necessary to keep track of them.
|
||||
map<MathMacro const *, Dimension> dim_macros;
|
||||
map<MathData const *, Dimension> dim_arrays;
|
||||
CoordCache & coords = mi.base.bv->coordCache();
|
||||
for (Element const & e : elements_) {
|
||||
Dimension d;
|
||||
mi.base.macro_nesting = e.macro_nesting;
|
||||
switch (e.type) {
|
||||
case BEGIN:
|
||||
case END:
|
||||
break;
|
||||
case INSET:
|
||||
e.inset->metrics(mi, d);
|
||||
d.wid += e.before + e.after;
|
||||
coords.insets().add(e.inset, d);
|
||||
break;
|
||||
case BEG_MACRO:
|
||||
e.macro->macro()->lock();
|
||||
// Add a macro to current list
|
||||
dim_macros[e.macro] = Dimension();
|
||||
break;
|
||||
case END_MACRO:
|
||||
LATTEST(dim_macros.find(e.macro) != dim_macros.end());
|
||||
e.macro->macro()->unlock();
|
||||
// Cache the dimension of the macro and remove it from
|
||||
// tracking map.
|
||||
coords.insets().add(e.macro, dim_macros[e.macro]);
|
||||
dim_macros.erase(e.macro);
|
||||
break;
|
||||
// This is basically like macros
|
||||
case BEG_ARG:
|
||||
if (e.macro)
|
||||
e.macro->macro()->unlock();
|
||||
dim_arrays[e.ar] = Dimension();
|
||||
break;
|
||||
case END_ARG:
|
||||
LATTEST(dim_arrays.find(e.ar) != dim_arrays.end());
|
||||
if (e.macro)
|
||||
e.macro->macro()->lock();
|
||||
coords.arrays().add(e.ar, dim_arrays[e.ar]);
|
||||
dim_arrays.erase(e.ar);
|
||||
break;
|
||||
case BOX:
|
||||
d = theFontMetrics(mi.base.font).dimension('I');
|
||||
d.wid += e.before + e.after;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!d.empty()) {
|
||||
dim += d;
|
||||
// Now add the dimension to current macros and arguments.
|
||||
for (auto & dim_macro : dim_macros)
|
||||
dim_macro.second += d;
|
||||
for (auto & dim_array : dim_arrays)
|
||||
dim_array.second += d;
|
||||
}
|
||||
|
||||
if (e.compl_text.empty())
|
||||
continue;
|
||||
FontInfo font = mi.base.font;
|
||||
augmentFont(font, "mathnormal");
|
||||
dim.wid += mathed_string_width(font, e.compl_text);
|
||||
}
|
||||
LATTEST(dim_macros.empty() && dim_arrays.empty());
|
||||
}
|
||||
|
||||
|
||||
void MathRow::draw(PainterInfo & pi, int x, int const y) const
|
||||
{
|
||||
CoordCache & coords = pi.base.bv->coordCache();
|
||||
for (Element const & e : elements_) {
|
||||
pi.base.macro_nesting = e.macro_nesting;
|
||||
switch (e.type) {
|
||||
case INSET: {
|
||||
// This is hackish: the math inset does not know that space
|
||||
// has been added before and after it; we alter its dimension
|
||||
// while it is drawing, because it relies on this value.
|
||||
Dimension const d = coords.insets().dim(e.inset);
|
||||
Dimension d2 = d;
|
||||
d2.wid -= e.before + e.after;
|
||||
coords.insets().add(e.inset, d2);
|
||||
e.inset->drawSelection(pi, x + e.before, y);
|
||||
e.inset->draw(pi, x + e.before, y);
|
||||
coords.insets().add(e.inset, x, y);
|
||||
coords.insets().add(e.inset, d);
|
||||
x += d.wid;
|
||||
break;
|
||||
}
|
||||
case BEG_MACRO:
|
||||
coords.insets().add(e.macro, x, y);
|
||||
break;
|
||||
case BEG_ARG:
|
||||
coords.arrays().add(e.ar, x, y);
|
||||
// if the macro is being edited, then the painter is in
|
||||
// monochrome mode.
|
||||
if (e.macro->editMetrics(pi.base.bv))
|
||||
pi.pain.leaveMonochromeMode();
|
||||
break;
|
||||
case END_ARG:
|
||||
if (e.macro->editMetrics(pi.base.bv))
|
||||
pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend);
|
||||
break;
|
||||
case BOX: {
|
||||
Dimension const d = theFontMetrics(pi.base.font).dimension('I');
|
||||
// the box is not visible in non-editable context (except for grey macro boxes).
|
||||
if (e.macro_nesting == 0 || e.color == Color_mathmacroblend)
|
||||
pi.pain.rectangle(x + e.before, y - d.ascent(),
|
||||
d.width(), d.height(), e.color);
|
||||
x += d.wid;
|
||||
break;
|
||||
}
|
||||
case BEGIN:
|
||||
case END:
|
||||
case END_MACRO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.compl_text.empty())
|
||||
continue;
|
||||
FontInfo f = pi.base.font;
|
||||
augmentFont(f, "mathnormal");
|
||||
|
||||
// draw the unique and the non-unique completion part
|
||||
// Note: this is not time-critical as it is
|
||||
// only done once per screen.
|
||||
docstring const s1 = e.compl_text.substr(0, e.compl_unique_to);
|
||||
docstring const s2 = e.compl_text.substr(e.compl_unique_to);
|
||||
|
||||
if (!s1.empty()) {
|
||||
f.setColor(Color_inlinecompletion);
|
||||
pi.pain.text(x, y, s1, f);
|
||||
x += mathed_string_width(f, s1);
|
||||
}
|
||||
if (!s2.empty()) {
|
||||
f.setColor(Color_nonunique_inlinecompletion);
|
||||
pi.pain.text(x, y, s2, f);
|
||||
x += mathed_string_width(f, s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MathRow::kerning(BufferView const * bv) const
|
||||
{
|
||||
if (elements_.empty())
|
||||
return 0;
|
||||
InsetMath const * inset = elements_[before(elements_.size() - 1)].inset;
|
||||
return inset ? inset->kerning(bv) : 0;
|
||||
}
|
||||
|
||||
|
||||
ostream & operator<<(ostream & os, MathRow::Element const & e)
|
||||
{
|
||||
switch (e.type) {
|
||||
case MathRow::BEGIN:
|
||||
os << "{";
|
||||
break;
|
||||
case MathRow::END:
|
||||
os << "}";
|
||||
break;
|
||||
case MathRow::INSET:
|
||||
os << "<" << e.before << "-"
|
||||
<< to_utf8(class_to_string(e.mclass))
|
||||
<< "-" << e.after << ">";
|
||||
break;
|
||||
case MathRow::BEG_MACRO:
|
||||
os << "\\" << to_utf8(e.macro->name()) << "[";
|
||||
break;
|
||||
case MathRow::END_MACRO:
|
||||
os << "]";
|
||||
break;
|
||||
case MathRow::BEG_ARG:
|
||||
os << "#(";
|
||||
break;
|
||||
case MathRow::END_ARG:
|
||||
os << ")";
|
||||
break;
|
||||
case MathRow::BOX:
|
||||
os << "@";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
ostream & operator<<(ostream & os, MathRow const & mrow)
|
||||
{
|
||||
for (MathRow::Element const & e : mrow)
|
||||
os << e << " ";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace lyx
|
145
src/mathed/MathRow.h
Normal file
145
src/mathed/MathRow.h
Normal file
@ -0,0 +1,145 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file MathRow.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef MATH_ROW_H
|
||||
#define MATH_ROW_H
|
||||
|
||||
#include "MathClass.h"
|
||||
|
||||
#include "ColorCode.h"
|
||||
|
||||
#include "support/docstring.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace lyx {
|
||||
|
||||
class BufferView;
|
||||
class Dimension;
|
||||
class MetricsInfo;
|
||||
class PainterInfo;
|
||||
|
||||
class InsetMath;
|
||||
class MathData;
|
||||
class MathMacro;
|
||||
|
||||
/*
|
||||
* While for editing purpose it is important that macros are counted
|
||||
* as a single element, this is not the case for display. To get the
|
||||
* spacing correct, it is necessary to dissolve all the macros that
|
||||
* can be, along with their arguments. Then one obtains a
|
||||
* representation of the MathData contents as a string of insets and
|
||||
* then spacing can be done properly.
|
||||
*
|
||||
* This is the purpose of the MathRow class.
|
||||
*/
|
||||
class MathRow
|
||||
{
|
||||
public:
|
||||
// What row elements can be
|
||||
enum Type {
|
||||
INSET, // this element is a plain inset
|
||||
BEG_MACRO, // a macro begins here
|
||||
END_MACRO, // a macro ends here
|
||||
BEG_ARG, // a macro argument begins here
|
||||
END_ARG, // a macro argument ends here
|
||||
BEGIN, // dummy element before row
|
||||
END, // dummy element after row
|
||||
BOX // an empty box
|
||||
};
|
||||
|
||||
// An elements, together with its spacing
|
||||
struct Element
|
||||
{
|
||||
///
|
||||
Element(Type t, MetricsInfo & mi);
|
||||
|
||||
/// Classifies the contents of the object
|
||||
Type type;
|
||||
/// count wether the current mathdata is nested in macro(s)
|
||||
int macro_nesting;
|
||||
|
||||
/// When type is INSET
|
||||
/// the math inset
|
||||
InsetMath const * inset;
|
||||
/// the class of the inset
|
||||
MathClass mclass;
|
||||
/// the spacing around the inset
|
||||
int before, after;
|
||||
// Non empty when there is a completion to draw
|
||||
docstring compl_text;
|
||||
// the number of characters forming the unique part.
|
||||
size_t compl_unique_to;
|
||||
|
||||
/// When type is BEG_MACRO, END_MACRO, BEG_ARG, END_ARG
|
||||
/// the math macro
|
||||
MathMacro const * macro;
|
||||
|
||||
// type is BEG_ARG, END_ARG
|
||||
MathData const * ar;
|
||||
|
||||
// type is BOX
|
||||
ColorCode color;
|
||||
};
|
||||
|
||||
///
|
||||
MathRow() {};
|
||||
///
|
||||
typedef std::vector<Element> Elements;
|
||||
///
|
||||
typedef Elements::iterator iterator;
|
||||
///
|
||||
typedef Elements::const_iterator const_iterator;
|
||||
///
|
||||
iterator begin() { return elements_.begin(); }
|
||||
///
|
||||
iterator end() { return elements_.end(); }
|
||||
///
|
||||
const_iterator begin() const { return elements_.begin(); }
|
||||
///
|
||||
const_iterator end() const { return elements_.end(); }
|
||||
//
|
||||
void push_back(Element const & e) { elements_.push_back(e); }
|
||||
//
|
||||
Element & back() { return elements_.back(); }
|
||||
|
||||
// create the math row by unwinding all macros in the MathData and
|
||||
// compute the spacings.
|
||||
MathRow(MetricsInfo & mi, MathData const * ar);
|
||||
|
||||
//
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
//
|
||||
void draw(PainterInfo & pi, int const x, int const y) const;
|
||||
|
||||
/// superscript kerning
|
||||
int kerning(BufferView const *) const;
|
||||
|
||||
private:
|
||||
// Index of the first inset element before position i
|
||||
int before(int i) const;
|
||||
// Index of the first inset element after position i
|
||||
int after(int i) const;
|
||||
|
||||
///
|
||||
Elements elements_;
|
||||
};
|
||||
|
||||
///
|
||||
std::ostream & operator<<(std::ostream & os, MathRow::Element const & elt);
|
||||
|
||||
///
|
||||
std::ostream & operator<<(std::ostream & os, MathRow const & mrow);
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif
|
@ -528,6 +528,9 @@ int mathed_font_em(FontInfo const & font)
|
||||
* punctuation, and is put around inner objects, except where these
|
||||
* are followed by a close or preceded by an open symbol, and except
|
||||
* if the other object is a large operator or a binary relation.
|
||||
*
|
||||
* See the file MathClass.cpp for a formal implementation of the rules
|
||||
* above.
|
||||
*/
|
||||
|
||||
int mathed_thinmuskip(FontInfo font)
|
||||
@ -671,13 +674,6 @@ void mathedSymbolDim(MetricsInfo & mi, Dimension & dim, latexkeys const * sym)
|
||||
std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
|
||||
Changer dummy = mi.base.changeFontSet(font);
|
||||
mathed_string_dim(mi.base.font, sym->draw, dim);
|
||||
// seperate things a bit
|
||||
if (sym->extra == "mathbin")
|
||||
dim.wid += 2 * mathed_medmuskip(mi.base.font);
|
||||
else if (sym->extra == "mathrel")
|
||||
dim.wid += 2 * mathed_thickmuskip(mi.base.font);
|
||||
else if (sym->extra == "mathpunct")
|
||||
dim.wid += mathed_thinmuskip(mi.base.font);
|
||||
}
|
||||
|
||||
|
||||
@ -693,10 +689,6 @@ void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
|
||||
sym->extra == "mathalpha" &&
|
||||
pi.base.fontname == "mathit";
|
||||
std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
|
||||
if (sym->extra == "mathbin")
|
||||
x += mathed_medmuskip(pi.base.font);
|
||||
else if (sym->extra == "mathrel")
|
||||
x += mathed_thickmuskip(pi.base.font);
|
||||
|
||||
Changer dummy = pi.base.changeFontSet(font);
|
||||
pi.draw(x, y, sym->draw);
|
||||
|
Loading…
Reference in New Issue
Block a user