LibreOffice Module starmath (master) 1
symbol.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <symbol.hxx>
21#include <utility.hxx>
22#include <cfgitem.hxx>
23#include <smmod.hxx>
24#include <sal/log.hxx>
25#include <osl/diagnose.h>
26
27
29 m_aName(OUString("unknown")),
30 m_aSetName(OUString("unknown")),
31 m_cChar('\0'),
32 m_bPredefined(false)
33{
37}
38
39
40SmSym::SmSym(const SmSym& rSymbol)
41{
42 *this = rSymbol;
43}
44
45
46SmSym::SmSym(const OUString& rName, const vcl::Font& rFont, sal_UCS4 cChar,
47 const OUString& rSet, bool bIsPredefined)
48{
49 m_aName = m_aExportName = rName;
50
51 m_aFace = rFont;
54
55 m_cChar = cChar;
57 m_bPredefined = bIsPredefined;
58}
59
60
62{
63 m_aName = rSymbol.m_aName;
65 m_cChar = rSymbol.m_cChar;
66 m_aFace = rSymbol.m_aFace;
67 m_aSetName = rSymbol.m_aSetName;
69
70 SM_MOD()->GetSymbolManager().SetModified(true);
71
72 return *this;
73}
74
75
76bool SmSym::IsEqualInUI( const SmSym& rSymbol ) const
77{
78 return m_aName == rSymbol.m_aName &&
79 m_aFace == rSymbol.m_aFace &&
80 m_cChar == rSymbol.m_cChar;
81}
82
83/**************************************************************************/
84
85
87{
88 m_bModified = false;
89}
90
91
93{
94 m_aSymbols = rSymbolSetManager.m_aSymbols;
95 m_bModified = true;
96}
97
98
100{
101}
102
103
105{
106 m_aSymbols = rSymbolSetManager.m_aSymbols;
107 m_bModified = true;
108 return *this;
109}
110
111
112SmSym *SmSymbolManager::GetSymbolByName(const OUString& rSymbolName)
113{
114 SmSym *pRes = nullptr;
115 SymbolMap_t::iterator aIt( m_aSymbols.find( rSymbolName ) );
116 if (aIt != m_aSymbols.end())
117 pRes = &aIt->second;
118 return pRes;
119}
120
121
123{
124 SymbolPtrVec_t aRes;
125 aRes.reserve(m_aSymbols.size());
126 for (const auto& rEntry : m_aSymbols)
127 aRes.push_back( &rEntry.second );
128// OSL_ENSURE( sSymbols.size() == m_aSymbols.size(), "number of symbols mismatch " );
129 return aRes;
130}
131
132
133bool SmSymbolManager::AddOrReplaceSymbol( const SmSym &rSymbol, bool bForceChange )
134{
135 bool bAdded = false;
136
137 const OUString& aSymbolName( rSymbol.GetName() );
138 if (!aSymbolName.isEmpty() && !rSymbol.GetSymbolSetName().isEmpty())
139 {
140 const SmSym *pFound = GetSymbolByName( aSymbolName );
141 const bool bSymbolConflict = pFound && !pFound->IsEqualInUI( rSymbol );
142
143 // avoid having the same symbol name twice but with different symbols in use
144 if (!pFound || bForceChange)
145 {
146 m_aSymbols[ aSymbolName ] = rSymbol;
147 bAdded = true;
148 }
149 else if (bSymbolConflict)
150 {
151 // TODO: to solve this a document owned symbol manager would be required ...
152 SAL_WARN("starmath", "symbol conflict, different symbol with same name found!");
153 // symbols in all formulas. A copy of the global one would be needed here
154 // and then the new symbol has to be forcefully applied. This would keep
155 // the current formula intact but will leave the set of symbols in the
156 // global symbol manager somewhat to chance.
157 }
158
159 OSL_ENSURE( bAdded, "failed to add symbol" );
160 if (bAdded)
161 m_bModified = true;
162 OSL_ENSURE( bAdded || (pFound && !bSymbolConflict), "AddOrReplaceSymbol: unresolved symbol conflict" );
163 }
164
165 return bAdded;
166}
167
168
169void SmSymbolManager::RemoveSymbol( const OUString & rSymbolName )
170{
171 if (!rSymbolName.isEmpty())
172 {
173 size_t nOldSize = m_aSymbols.size();
174 m_aSymbols.erase( rSymbolName );
175 m_bModified = nOldSize != m_aSymbols.size();
176 }
177}
178
179
180std::set< OUString > SmSymbolManager::GetSymbolSetNames() const
181{
182 std::set< OUString > aRes;
183 for (const auto& rEntry : m_aSymbols)
184 aRes.insert( rEntry.second.GetSymbolSetName() );
185 return aRes;
186}
187
188
189SymbolPtrVec_t SmSymbolManager::GetSymbolSet( std::u16string_view rSymbolSetName )
190{
191 SymbolPtrVec_t aRes;
192 if (!rSymbolSetName.empty())
193 {
194 for (const auto& rEntry : m_aSymbols)
195 {
196 if (rEntry.second.GetSymbolSetName() == rSymbolSetName)
197 aRes.push_back( &rEntry.second );
198 }
199 }
200 return aRes;
201}
202
203
205{
206 std::vector< SmSym > aSymbols;
207 SmMathConfig &rCfg = *SM_MOD()->GetConfig();
208 rCfg.GetSymbols( aSymbols );
209 size_t nSymbolCount = aSymbols.size();
210
211 m_aSymbols.clear();
212 for (size_t i = 0; i < nSymbolCount; ++i)
213 {
214 const SmSym &rSym = aSymbols[i];
215 OSL_ENSURE( !rSym.GetName().isEmpty(), "symbol without name!" );
216 if (!rSym.GetName().isEmpty())
217 AddOrReplaceSymbol( rSym );
218 }
219 m_bModified = true;
220
221 if (0 == nSymbolCount)
222 {
223 SAL_WARN("starmath", "no symbol set found");
224 m_bModified = false;
225 }
226
227 // now add a %i... symbol to the 'iGreek' set for every symbol found in the 'Greek' set.
228 const OUString aGreekSymbolSetName(SmLocalizedSymbolData::GetUiSymbolSetName(u"Greek"));
229 const SymbolPtrVec_t aGreekSymbols( GetSymbolSet( aGreekSymbolSetName ) );
230 OUString aSymbolSetName = "i" + aGreekSymbolSetName;
231 size_t nSymbols = aGreekSymbols.size();
232 for (size_t i = 0; i < nSymbols; ++i)
233 {
234 // make the new symbol a copy but with ITALIC_NORMAL, and add it to iGreek
235 const SmSym &rSym = *aGreekSymbols[i];
236 vcl::Font aFont( rSym.GetFace() );
237 OSL_ENSURE( aFont.GetItalic() == ITALIC_NONE, "expected Font with ITALIC_NONE, failed." );
238 aFont.SetItalic( ITALIC_NORMAL );
239 OUString aSymbolName = "i" + rSym.GetName();
240 SmSym aSymbol( aSymbolName, aFont, rSym.GetCharacter(),
241 aSymbolSetName, true /*bIsPredefined*/ );
242
243 AddOrReplaceSymbol( aSymbol );
244 }
245}
246
248{
249 if (!m_bModified)
250 return;
251
252 SmMathConfig &rCfg = *SM_MOD()->GetConfig();
253
254 // prepare to skip symbols from iGreek on saving
255 OUString aSymbolSetName = "i" +
257
258 SymbolPtrVec_t aTmp( GetSymbols() );
259 std::vector< SmSym > aSymbols;
260 for (const SmSym* i : aTmp)
261 {
262 // skip symbols from iGreek set since those symbols always get added
263 // by computational means in SmSymbolManager::Load
264 if (i->GetSymbolSetName() != aSymbolSetName)
265 aSymbols.push_back( *i );
266 }
267 rCfg.SetSymbols( aSymbols );
268
269 m_bModified = false;
270}
271
272
273/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetSymbols(const std::vector< SmSym > &rNewSymbols)
Definition: cfgitem.cxx:520
void GetSymbols(std::vector< SmSym > &rSymbols) const
Definition: cfgitem.cxx:506
Definition: symbol.hxx:37
SmSym & operator=(const SmSym &rSymbol)
Definition: symbol.cxx:61
OUString m_aExportName
Definition: symbol.hxx:41
OUString m_aSetName
Definition: symbol.hxx:42
const OUString & GetSymbolSetName() const
Definition: symbol.hxx:59
const OUString & GetName() const
Definition: symbol.hxx:56
sal_UCS4 m_cChar
Definition: symbol.hxx:43
SmFace m_aFace
Definition: symbol.hxx:39
OUString m_aName
Definition: symbol.hxx:40
sal_UCS4 GetCharacter() const
Definition: symbol.hxx:55
const vcl::Font & GetFace() const
Definition: symbol.hxx:54
SmSym()
Definition: symbol.cxx:28
bool IsEqualInUI(const SmSym &rSymbol) const
Definition: symbol.cxx:76
bool m_bPredefined
Definition: symbol.hxx:44
SymbolPtrVec_t GetSymbolSet(std::u16string_view rSymbolSetName)
Definition: symbol.cxx:189
bool AddOrReplaceSymbol(const SmSym &rSymbol, bool bForceChange=false)
Definition: symbol.cxx:133
SymbolMap_t m_aSymbols
Definition: symbol.hxx:77
void RemoveSymbol(const OUString &rSymbolName)
Definition: symbol.cxx:169
SmSym * GetSymbolByName(const OUString &rSymbolName)
Definition: symbol.cxx:112
std::set< OUString > GetSymbolSetNames() const
Definition: symbol.cxx:180
bool m_bModified
Definition: symbol.hxx:78
SymbolPtrVec_t GetSymbols() const
Definition: symbol.cxx:122
SmSymbolManager & operator=(const SmSymbolManager &rSymbolSetManager)
Definition: symbol.cxx:104
void SetTransparent(bool bTransparent)
FontItalic GetItalic()
void SetItalic(FontItalic)
void SetAlignment(TextAlign)
float u
ITALIC_NORMAL
ITALIC_NONE
ALIGN_BASELINE
#define SAL_WARN(area, stream)
OUString GetUiSymbolSetName(std::u16string_view rExportName)
Definition: smmod.cxx:80
int i
OUString m_aName
static SfxItemSet & rSet
#define SM_MOD()
Definition: smmod.hxx:98
std::vector< const SmSym * > SymbolPtrVec_t
Definition: symbol.hxx:71
sal_uInt32 sal_UCS4