1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #include <svtools/fontsubstconfig.hxx>
28 #include <svl/svarray.hxx>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/uno/Any.hxx>
31 #include <com/sun/star/uno/Sequence.hxx>
32 #include <tools/debug.hxx>
33 
34 #include <vcl/outdev.hxx>
35 #include <rtl/logfile.hxx>
36 
37 using namespace utl;
38 using namespace rtl;
39 using namespace com::sun::star;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::beans;
42 
43 #define C2U(cChar) OUString::createFromAscii(cChar)
44 
45 const sal_Char cReplacement[] = "Replacement";
46 const sal_Char cFontPairs[] = "FontPairs";
47 
48 const sal_Char cReplaceFont[] 	= "ReplaceFont";
49 const sal_Char cSubstituteFont[]= "SubstituteFont";
50 const sal_Char cOnScreenOnly[] 	= "OnScreenOnly";
51 const sal_Char cAlways[] 		= "Always";
52 
53 //-----------------------------------------------------------------------------
54 typedef SubstitutionStruct* SubstitutionStructPtr;
55 SV_DECL_PTRARR_DEL(SubstitutionStructArr, SubstitutionStructPtr, 2, 2)
56 SV_IMPL_PTRARR(SubstitutionStructArr, SubstitutionStructPtr);
57 //-----------------------------------------------------------------------------
58 struct SvtFontSubstConfig_Impl
59 {
60 	SubstitutionStructArr	aSubstArr;
61 };
62 /* -----------------------------18.01.01 12:04--------------------------------
63 
64  ---------------------------------------------------------------------------*/
SvtFontSubstConfig()65 SvtFontSubstConfig::SvtFontSubstConfig() :
66 	ConfigItem(C2U("Office.Common/Font/Substitution")),
67 	bIsEnabled(sal_False),
68 	pImpl(new SvtFontSubstConfig_Impl)
69 {
70 	RTL_LOGFILE_CONTEXT(aLog, "svtools SvtFontSubstConfig::SvtFontSubstConfig()");
71 
72 	Sequence<OUString> aNames(1);
73 	aNames.getArray()[0] = C2U(cReplacement);
74 	Sequence<Any> aValues = GetProperties(aNames);
75 	DBG_ASSERT(aValues.getConstArray()[0].hasValue(), "no value available");
76 	if(aValues.getConstArray()[0].hasValue())
77 		bIsEnabled = *(sal_Bool*)aValues.getConstArray()[0].getValue();
78 
79 	OUString sPropPrefix(C2U(cFontPairs));
80     Sequence<OUString> aNodeNames = GetNodeNames(sPropPrefix, CONFIG_NAME_LOCAL_PATH);
81 	const OUString* pNodeNames = aNodeNames.getConstArray();
82 	Sequence<OUString> aPropNames(aNodeNames.getLength() * 4);
83 	OUString* pNames = aPropNames.getArray();
84 	sal_Int32 nName = 0;
85 	sPropPrefix += C2U("/");
86 	sal_Int32 nNode;
87 	for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
88 	{
89 		OUString sStart(sPropPrefix);
90 		sStart += pNodeNames[nNode];
91 		sStart += C2U("/");
92 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cReplaceFont);
93 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cSubstituteFont);
94 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cAlways);
95 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cOnScreenOnly);
96 	}
97 	Sequence<Any> aNodeValues = GetProperties(aPropNames);
98 	const Any* pNodeValues = aNodeValues.getConstArray();
99 	nName = 0;
100 	for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
101 	{
102 		SubstitutionStructPtr pInsert = new SubstitutionStruct;
103 		pNodeValues[nName++] >>= pInsert->sFont;
104 		pNodeValues[nName++] >>= pInsert->sReplaceBy;
105 		pInsert->bReplaceAlways = *(sal_Bool*)pNodeValues[nName++].getValue();
106 		pInsert->bReplaceOnScreenOnly = *(sal_Bool*)pNodeValues[nName++].getValue();
107 		pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
108 	}
109 }
110 /* -----------------------------18.01.01 12:06--------------------------------
111 
112  ---------------------------------------------------------------------------*/
~SvtFontSubstConfig()113 SvtFontSubstConfig::~SvtFontSubstConfig()
114 {
115 	delete pImpl;
116 }
117 /*-- 18.01.01 12:08:00---------------------------------------------------
118 
119   -----------------------------------------------------------------------*/
Notify(const com::sun::star::uno::Sequence<rtl::OUString> &)120 void SvtFontSubstConfig::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
121 {
122 }
123 
Commit()124 void SvtFontSubstConfig::Commit()
125 {
126 	Sequence<OUString> aNames(1);
127 	aNames.getArray()[0] = C2U(cReplacement);
128 	Sequence<Any> aValues(1);
129 	aValues.getArray()[0].setValue(&bIsEnabled, ::getBooleanCppuType());
130 	PutProperties(aNames, aValues);
131 
132 	OUString sNode(C2U(cFontPairs));
133 	if(!pImpl->aSubstArr.Count())
134 		ClearNodeSet(sNode);
135 	else
136 	{
137 		Sequence<PropertyValue> aSetValues(4 * pImpl->aSubstArr.Count());
138 		PropertyValue* pSetValues = aSetValues.getArray();
139 		sal_Int32 nSetValue = 0;
140 
141 		const OUString sReplaceFont(C2U(cReplaceFont));
142 		const OUString sSubstituteFont(C2U(cSubstituteFont));
143 		const OUString sAlways(C2U(cAlways));
144 		const OUString sOnScreenOnly(C2U(cOnScreenOnly));
145 
146 		const uno::Type& rBoolType = ::getBooleanCppuType();
147 		for(sal_uInt16 i = 0; i < pImpl->aSubstArr.Count(); i++)
148 		{
149 			OUString sPrefix(sNode);
150 			sPrefix += C2U("/_");
151 			sPrefix += OUString::valueOf((sal_Int32)i);
152 			sPrefix += C2U("/");
153 
154 			SubstitutionStructPtr pSubst = pImpl->aSubstArr[i];
155 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sReplaceFont;
156 			pSetValues[nSetValue++].Value <<= pSubst->sFont;
157 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sSubstituteFont;
158 			pSetValues[nSetValue++].Value <<= pSubst->sReplaceBy;
159 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sAlways;
160 			pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceAlways, rBoolType);
161 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sOnScreenOnly;
162 			pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceOnScreenOnly, rBoolType);
163 		}
164 		ReplaceSetProperties(sNode, aSetValues);
165 	}
166 }
167 /*-- 18.01.01 12:08:00---------------------------------------------------
168 
169   -----------------------------------------------------------------------*/
SubstitutionCount() const170 sal_Int32 SvtFontSubstConfig::SubstitutionCount() const
171 {
172 	return pImpl->aSubstArr.Count();
173 }
174 /*-- 18.01.01 12:08:00---------------------------------------------------
175 
176   -----------------------------------------------------------------------*/
ClearSubstitutions()177 void SvtFontSubstConfig::ClearSubstitutions()
178 {
179 	pImpl->aSubstArr.DeleteAndDestroy(0, pImpl->aSubstArr.Count());
180 }
181 /*-- 18.01.01 12:08:00---------------------------------------------------
182 
183   -----------------------------------------------------------------------*/
GetSubstitution(sal_Int32 nPos)184 const SubstitutionStruct* SvtFontSubstConfig::GetSubstitution(sal_Int32 nPos)
185 {
186 	DBG_ASSERT(nPos >= 0 && nPos < pImpl->aSubstArr.Count(), "illegal array index");
187 	if(nPos >= 0 && nPos < pImpl->aSubstArr.Count())
188 		return pImpl->aSubstArr[(sal_uInt16)nPos];
189 	return 0;
190 }
191 /*-- 18.01.01 12:08:01---------------------------------------------------
192 
193   -----------------------------------------------------------------------*/
AddSubstitution(const SubstitutionStruct & rToAdd)194 void SvtFontSubstConfig::AddSubstitution(const SubstitutionStruct& rToAdd)
195 {
196 	SubstitutionStructPtr pInsert = new SubstitutionStruct(rToAdd);
197 	pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
198 }
199 
Apply()200 void SvtFontSubstConfig::Apply()
201 {
202 	OutputDevice::BeginFontSubstitution();
203 
204 	// Alte Substitution entfernen
205 	sal_uInt16 nOldCount = OutputDevice::GetFontSubstituteCount();
206 
207 	while (nOldCount)
208 		OutputDevice::RemoveFontSubstitute(--nOldCount);
209 
210 	// Neue Substitution einlesen
211     sal_Int32 nCount = IsEnabled() ? SubstitutionCount() : 0;
212 
213 	for (sal_Int32  i = 0; i < nCount; i++)
214 	{
215 	    sal_uInt16 nFlags = 0;
216 		const SubstitutionStruct* pSubs = GetSubstitution(i);
217 		if(pSubs->bReplaceAlways)
218 			nFlags |= FONT_SUBSTITUTE_ALWAYS;
219 		if(pSubs->bReplaceOnScreenOnly)
220 			nFlags |= FONT_SUBSTITUTE_SCREENONLY;
221 		OutputDevice::AddFontSubstitute( String(pSubs->sFont), String(pSubs->sReplaceBy), nFlags );
222     }
223 
224 	OutputDevice::EndFontSubstitution();
225 }
226