tdf#158727 Support attribute leftvec leftharpoon in Math

. . . for improved RTL support

This includes wide variants for both wideleftvec and wideleftharpoon. OpenSymbol has been updated to include uni20D0 COMBINING LEFT HARPOON ABOVE and uni20D6 COMBINING LEFT ARROW ABOVE.

Change-Id: Id7f4ce2d3aad493a731f6b1be736c0aa8faa2027
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202922
Reviewed-by: Khaled Hosny <khaled@libreoffice.org>
Tested-by: Jenkins
This commit is contained in:
Neil S Patel
2026-03-29 05:26:59 +02:00
committed by Khaled Hosny
parent 4d3a291b5d
commit 2975a0bf92
15 changed files with 92 additions and 11 deletions
+43 -7
View File
@@ -1,10 +1,10 @@
SplineFontDB: 3.0
SplineFontDB: 3.2
FontName: OpenSymbol
FullName: OpenSymbol
FamilyName: OpenSymbol
Weight: Book
Copyright: (c) 2009 Sun Microsystems Inc.\nTHERE DOES NOT EXIST (c) 2011 Julien Nabet\nPRECEDES <-> DOES NOT SUCCEED (c) 2011 Olivier Hallot\nPRIME <-> TRIPLE PRIME (c) 2013 Mathias Hasselmann\nphi <-> phi1 (c) 2015 Khaled Hosny\n(c) 2016 Mike Kaganski\nzero, one, two, three, four, five, six, seven, eight, nine, question, underscore, copyright, registered, uni2215, angle, therefore, lozenge (c) 2010 Google Corporation\nuni20D1 (c) 2019 Takeshi Abe\nuniF030 <-> uniF039 (c) 2020 Ming Hua
Version: 102.12
Copyright: (c) 2009 Sun Microsystems Inc.\nTHERE DOES NOT EXIST (c) 2011 Julien Nabet\nPRECEDES <-> DOES NOT SUCCEED (c) 2011 Olivier Hallot\nPRIME <-> TRIPLE PRIME (c) 2013 Mathias Hasselmann\nphi <-> phi1 (c) 2015 Khaled Hosny\n(c) 2016 Mike Kaganski\nzero, one, two, three, four, five, six, seven, eight, nine, question, underscore, copyright, registered, uni2215, angle, therefore, lozenge (c) 2010 Google Corporation\nuni20D1 (c) 2019 Takeshi Abe\nuniF030 <-> uniF039 (c) 2020 Ming Hua\nuni20D6, uni20D0 (c) 2026 Neil Patel
Version: 102.13
ItalicAngle: 0
UnderlinePosition: -143
UnderlineWidth: 20
@@ -20,7 +20,7 @@ OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1144938807
ModificationTime: 1605567303
ModificationTime: 1774635515
PfmFamily: 81
TTFWeight: 400
TTFWidth: 5
@@ -775,16 +775,16 @@ ShortTable: maxp 16
EndShort
LangName: 1033 "" "" "Regular" "OpenSymbol"
GaspTable: 1 65535 2 0
Encoding: Original
Encoding: Custom
UnicodeInterp: none
NameList: Adobe Glyph List
DisplaySize: -72
AntiAlias: 1
FitToEm: 1
WinInfo: 0 34 12
WinInfo: 608 32 15
BeginPrivate: 0
EndPrivate
BeginChars: 1063 1063
BeginChars: 1065 1065
StartChar: Alpha
Encoding: 0 913 0
@@ -108814,5 +108814,41 @@ LayerCount: 2
Fore
Refer: 1040 57 N 1 0 0 1 0 0 2
EndChar
StartChar: uni20D6
Encoding: 1063 8406 1063
Width: 1056
Flags: W
HStem: 1313 112<84 672>
LayerCount: 2
Fore
SplineSet
958 1313 m 1,0,-1
370 1313 l 1,1,-1
411 1163 l 1,2,-1
30 1368 l 1,3,-1
411 1575 l 1,4,-1
370 1425 l 1,5,-1
958 1425 l 1,6,-1
958 1313 l 1,0,-1
EndSplineSet
EndChar
StartChar: uni20D0
Encoding: 1064 8400 1064
Width: 1056
Flags: WO
HStem: 1313 112<30 618>
LayerCount: 2
Fore
SplineSet
958 1313 m 1,0,-1
30 1313 l 1,1,-1
411 1575 l 1,2,-1
370 1425 l 1,3,-1
958 1425 l 1,4,-1
958 1313 l 1,0,-1
EndSplineSet
EndChar
EndChars
EndSplineFont
+1 -1
View File
@@ -1877,7 +1877,7 @@ public:
/** Attribute node
*
* Used to give an attribute to another node. Used for commands such as:
* UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHARPOON, WIDEHAT and WIDETILDE.
* UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDELVEC WIDEHARPOON, WIDELHARPOON, WIDEHAT and WIDETILDE.
*
* Children:<BR>
* 0: Attribute<BR>
+4
View File
@@ -190,7 +190,9 @@
#define RID_HATX_HELP NC_("RID_HATX_HELP", "Circumflex" )
#define RID_TILDEX_HELP NC_("RID_TILDEX_HELP", "Tilde" )
#define RID_VECX_HELP NC_("RID_VECX_HELP", "Vector Arrow" )
#define RID_LVECX_HELP NC_("RID_LVECX_HELP", "Left Vector Arrow" )
#define RID_HARPOONX_HELP NC_("RID_HARPOONX_HELP", "Harpoon" )
#define RID_LHARPOONX_HELP NC_("RID_LHARPOONX_HELP", "Left Harpoon" )
#define RID_UNDERLINEX_HELP NC_("RID_UNDERLINEX_HELP", "Line Below" )
#define RID_OVERLINEX_HELP NC_("RID_OVERLINEX_HELP", "Line Over" )
#define RID_OVERSTRIKEX_HELP NC_("RID_OVERSTRIKEX_HELP", "Line Through" )
@@ -302,7 +304,9 @@
#define RID_WIDEHATX_HELP NC_("RID_WIDEHATX_HELP", "Large Circumflex" )
#define RID_WIDETILDEX_HELP NC_("RID_WIDETILDEX_HELP", "Large Tilde" )
#define RID_WIDEVECX_HELP NC_("RID_WIDEVECX_HELP", "Large Vector Arrow" )
#define RID_WIDELVECX_HELP NC_("RID_WIDELVECX_HELP", "Large Left Vector Arrow" )
#define RID_WIDEHARPOONX_HELP NC_("RID_WIDEHARPOONX_HELP", "Large Harpoon" )
#define RID_WIDELHARPOONX_HELP NC_("RID_WIDELHARPOONX_HELP", "Large Left Harpoon" )
#define RID_HBAR_HELP NC_("RID_HBAR_HELP", "h Bar" )
#define RID_LAMBDABAR_HELP NC_("RID_LAMBDABAR_HELP", "Lambda Bar" )
#define RID_LEFTARROW_HELP NC_("RID_LEFTARROW_HELP", "Left Arrow" )
+4 -1
View File
@@ -177,7 +177,9 @@ inline constexpr OUString RID_UNDOFORMATNAME = u"Format"_ustr;
#define RID_HATX u"hat <?> "
#define RID_TILDEX u"tilde <?> "
#define RID_VECX u"vec <?> "
#define RID_LVECX u"leftvec <?> "
#define RID_HARPOONX u"harpoon <?> "
#define RID_LHARPOONX u"leftharpoon <?> "
#define RID_UNDERLINEX u"underline {<?>} "
#define RID_OVERLINEX u"overline {<?>} "
#define RID_OVERSTRIKEX u"overstrike {<?>} "
@@ -290,8 +292,9 @@ inline constexpr OUString RID_UNDOFORMATNAME = u"Format"_ustr;
#define RID_WIDEHATX u"widehat {<?>} "
#define RID_WIDETILDEX u"widetilde {<?>} "
#define RID_WIDEVECX u"widevec {<?>} "
// #define RID_OVERLEFTARROWX u"overleftarrow {<?>} "
#define RID_WIDELVECX u"wideleftvec {<?>} "
#define RID_WIDEHARPOONX u"wideharpoon {<?>} "
#define RID_WIDELHARPOONX u"wideleftharpoon {<?>} "
#define RID_HBAR u"hbar "
#define RID_LAMBDABAR u"lambdabar "
#define RID_LEFTARROW u"leftarrow "
+4 -2
View File
@@ -119,8 +119,10 @@ enum SmTokenType
TUNDERLINE, TOVERLINE, TOVERSTRIKE, TBAR, // Lines
TFIXED, TSANS, TSERIF, // Types
TACUTE, TGRAVE, THAT, TBREVE, // Accents
TWIDEVEC, TWIDEHARPOON, TWIDETILDE, TWIDEHAT, // Wide math
TVEC, THARPOON, TTILDE, TCIRCLE, // math
TWIDEVEC, TWIDELVEC, TWIDEHARPOON, TWIDELHARPOON,
TWIDETILDE, TWIDEHAT, // Wide math
TVEC, TLVEC, THARPOON, TLHARPOON,
TTILDE, TCIRCLE, // math
TCHECK,
TTEXT, TNUMBER, TCHARACTER, TIDENT, // Content type
// Brackets
+2
View File
@@ -152,7 +152,9 @@ sal_Unicode const MS_CIRCLE = 0x02DA;
sal_Unicode const MS_COMBCIRCLE = 0x030A;
sal_Unicode const MS_CHECK = 0x02C7;
sal_Unicode const MS_COMBCHECK = 0x030C;
sal_Unicode const MS_LHARPOON = 0x20D0;
sal_Unicode const MS_HARPOON = 0x20D1;
sal_Unicode const MS_LVEC = 0x20D6;
sal_Unicode const MS_VEC = 0x20D7;
sal_Unicode const MS_DOT = 0x02D9;
sal_Unicode const MS_DDOT = 0x00A8;
@@ -254,13 +254,17 @@ void Test::SimpleAttributes()
parseandparseagain("breve a", "Breve");
parseandparseagain("circle a", "Circle");
parseandparseagain("vec a", "Vector arrow");
parseandparseagain("leftvec a", "Left vector arrow");
parseandparseagain("harpoon a", "Harpoon");
parseandparseagain("leftharpoon a", "Left harpoon");
parseandparseagain("tilde a", "Tilde");
parseandparseagain("hat a", "Circumflex");
parseandparseagain("bar a", "Line above");
parseandparseagain("dot a", "Dot");
parseandparseagain("widevec abc", "Wide vector arrow");
parseandparseagain("wideleftvec abc", "Wide left vector arrow");
parseandparseagain("wideharpoon abc", "Wide harpoon");
parseandparseagain("wideleftharpoon abc", "Wide left harpoon");
parseandparseagain("widetilde abc", "Wide tilde");
parseandparseagain("widehat abc", "Wide circumflex");
parseandparseagain("ddot a", "Double dot");
@@ -366,13 +366,17 @@ const SmElementDescr s_a5AttributesList[] =
{RID_DDDOTX, RID_DDDOTX_HELP, {}, {}},
{RID_BARX, RID_BARX_HELP, {}, {}},
{RID_VECX, RID_VECX_HELP, {}, {}},
{RID_LVECX, RID_LVECX_HELP, {}, {}},
{RID_HARPOONX, RID_HARPOONX_HELP, {}, {}},
{RID_LHARPOONX, RID_LHARPOONX_HELP, {}, {}},
{RID_TILDEX, RID_TILDEX_HELP, {}, {}},
{RID_HATX, RID_HATX_HELP, {}, {}},
{RID_CHECKX, RID_CHECKX_HELP, {}, {}},
{},
{RID_WIDEVECX, RID_WIDEVECX_HELP, {}, {}},
{RID_WIDELVECX, RID_WIDELVECX_HELP, {}, {}},
{RID_WIDEHARPOONX, RID_WIDEHARPOONX_HELP, {}, {}},
{RID_WIDELHARPOONX, RID_WIDELHARPOONX_HELP, {}, {}},
{RID_WIDETILDEX, RID_WIDETILDEX_HELP, {}, {}},
{RID_WIDEHATX, RID_WIDEHATX_HELP, {}, {}},
{RID_OVERLINEX, RID_OVERLINEX_HELP, {}, {}},
+2
View File
@@ -1064,7 +1064,9 @@ void SmXMLExport::ExportAttributes(const SmNode* pNode, int nLevel)
case TWIDETILDE:
case TWIDEHAT:
case TWIDEVEC:
case TWIDELVEC:
case TWIDEHARPOON:
case TWIDELHARPOON:
{
// make these wide accents stretchy
AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
+4
View File
@@ -3141,11 +3141,13 @@ void MathType::HandleAttributes(SmNode *pNode,int nLevel)
//we have to drop them
nOldPending = StartTemplate(0x2f,0x01);
break;
case TWIDELVEC: //Not Exportable
case TCHECK: //Not Exportable
case TACUTE: //Not Exportable
case TGRAVE: //Not Exportable
case TCIRCLE: //Not Exportable
case TWIDEHARPOON: //Not Exportable
case TWIDELHARPOON: //Not Exportable
case TWIDETILDE: //Not Exportable
case TWIDEHAT: //Not Exportable
break;
@@ -3234,7 +3236,9 @@ void MathType::HandleAttributes(SmNode *pNode,int nLevel)
pS->WriteUChar( 20 );
break;
case TWIDEVEC:
case TWIDELVEC:
case TWIDEHARPOON:
case TWIDELHARPOON:
case TUNDERLINE:
case TWIDETILDE:
case TWIDEHAT:
+2
View File
@@ -208,7 +208,9 @@ void SmOoxmlExport::HandleAttribute( const SmAttributeNode* pNode, int nLevel )
case TWIDETILDE:
case TWIDEHAT:
case TWIDEHARPOON:
case TWIDELHARPOON:
case TWIDEVEC:
case TWIDELVEC:
case TBAR:
{
m_pSerializer->startElementNS(XML_m, XML_acc);
+6
View File
@@ -208,9 +208,15 @@ OUString SmOoxmlImport::handleAcc()
// shouldn't matter, but short above a longer expression doesn't look right
acc = "widevec";
break;
case MS_LVEC:
acc = "wideleftvec";
break;
case MS_HARPOON:
acc = "wideharpoon";
break;
case MS_LHARPOON:
acc = "wideleftharpoon";
break;
case MS_TILDE:
case MS_COMBTILDE:
acc = "widetilde";
+6
View File
@@ -140,6 +140,8 @@ constexpr SmTokenTableEntry aTokenTable[]
{ u"le"_ustr, TLE, MS_LE, TG::Relation, 0 },
{ u"left"_ustr, TLEFT, '\0', TG::NONE, 5 },
{ u"leftarrow"_ustr, TLEFTARROW, MS_LEFTARROW, TG::Standalone, 5 },
{ u"leftharpoon"_ustr, TLHARPOON, MS_LHARPOON, TG::Attribute, 5 },
{ u"leftvec"_ustr, TLVEC, MS_LVEC, TG::Attribute, 5 },
{ u"leslant"_ustr, TLESLANT, MS_LESLANT, TG::Relation, 0 },
{ u"lfloor"_ustr, TLFLOOR, MS_LFLOOR, TG::LBrace, 5 },
{ u"lim"_ustr, TLIM, '\0', TG::Oper, 5 },
@@ -258,6 +260,8 @@ constexpr SmTokenTableEntry aTokenTable[]
{ u"widebslash"_ustr, TWIDEBACKSLASH, MS_BACKSLASH, TG::Product, 0 },
{ u"wideharpoon"_ustr, TWIDEHARPOON, MS_HARPOON, TG::Attribute, 5 },
{ u"widehat"_ustr, TWIDEHAT, MS_HAT, TG::Attribute, 5 },
{ u"wideleftharpoon"_ustr, TWIDELHARPOON, MS_LHARPOON, TG::Attribute, 5 },
{ u"wideleftvec"_ustr, TWIDELVEC, MS_LVEC, TG::Attribute, 5 },
{ u"wideslash"_ustr, TWIDESLASH, MS_SLASH, TG::Product, 0 },
{ u"widetilde"_ustr, TWIDETILDE, MS_TILDE, TG::Attribute, 5 },
{ u"widevec"_ustr, TWIDEVEC, MS_VEC, TG::Attribute, 5 },
@@ -2163,7 +2167,9 @@ std::unique_ptr<SmStructureNode> SmParser5::DoAttribute()
break;
case TWIDEVEC:
case TWIDELVEC:
case TWIDEHARPOON:
case TWIDELHARPOON:
case TWIDEHAT:
case TWIDETILDE:
xAttr.reset(new SmMathSymbolNode(m_aCurToken));
+2
View File
@@ -104,7 +104,9 @@ void SmRtfExport::HandleAttribute(const SmAttributeNode* pNode, int nLevel)
case TWIDETILDE:
case TWIDEHAT:
case TWIDEHARPOON:
case TWIDELHARPOON:
case TWIDEVEC:
case TWIDELVEC:
case TBAR:
{
m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MACC " ");
@@ -167,12 +167,16 @@
<menu:menuitem menu:label="dddot a" menu:id=".uno:InsertCommandText?Text:string=dddot &lt;?&gt; "/>
<menu:menuitem menu:label="bar a" menu:id=".uno:InsertCommandText?Text:string=bar &lt;?&gt; "/>
<menu:menuitem menu:label="vec a" menu:id=".uno:InsertCommandText?Text:string=vec &lt;?&gt; "/>
<menu:menuitem menu:label="leftvec a" menu:id=".uno:InsertCommandText?Text:string=leftvec &lt;?&gt; "/>
<menu:menuitem menu:label="harpoon a" menu:id=".uno:InsertCommandText?Text:string=harpoon &lt;?&gt; "/>
<menu:menuitem menu:label="leftharpoon a" menu:id=".uno:InsertCommandText?Text:string=leftharpoon &lt;?&gt; "/>
<menu:menuitem menu:label="tilde a" menu:id=".uno:InsertCommandText?Text:string=tilde &lt;?&gt; "/>
<menu:menuitem menu:label="hat a" menu:id=".uno:InsertCommandText?Text:string=hat &lt;?&gt; "/>
<menu:menuseparator/>
<menu:menuitem menu:label="widevec abc" menu:id=".uno:InsertCommandText?Text:string=widevec {&lt;?&gt;} "/>
<menu:menuitem menu:label="wideleftvec abc" menu:id=".uno:InsertCommandText?Text:string=wideleftvec {&lt;?&gt;} "/>
<menu:menuitem menu:label="wideharpoon abc" menu:id=".uno:InsertCommandText?Text:string=wideharpoon {&lt;?&gt;} "/>
<menu:menuitem menu:label="wideleftharpoon abc" menu:id=".uno:InsertCommandText?Text:string=wideleftharpoon {&lt;?&gt;} "/>
<menu:menuitem menu:label="widetilde abc" menu:id=".uno:InsertCommandText?Text:string=widetilde {&lt;?&gt;} "/>
<menu:menuitem menu:label="widehat abc" menu:id=".uno:InsertCommandText?Text:string=widehat {&lt;?&gt;} "/>
<menu:menuitem menu:label="overline abc" menu:id=".uno:InsertCommandText?Text:string=overline {&lt;?&gt;} "/>