/src/libreoffice/svx/source/dialog/fntctrl.cxx
Line | Count | Source |
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 <sfx2/dialoghelper.hxx> |
21 | | #include <sfx2/viewsh.hxx> |
22 | | #include <sfx2/printer.hxx> |
23 | | #include <vcl/metric.hxx> |
24 | | #include <vcl/svapp.hxx> |
25 | | #include <vcl/settings.hxx> |
26 | | |
27 | | #include <com/sun/star/i18n/ScriptType.hpp> |
28 | | |
29 | | #include <vector> |
30 | | #include <optional> |
31 | | #include <svtools/colorcfg.hxx> |
32 | | #include <svtools/sampletext.hxx> |
33 | | |
34 | | #include <svx/fntctrl.hxx> |
35 | | #include <svx/svxids.hrc> |
36 | | |
37 | | // Item set includes |
38 | | #include <svl/itemset.hxx> |
39 | | #include <svl/itempool.hxx> |
40 | | #include <svl/stritem.hxx> |
41 | | #include <svl/cjkoptions.hxx> |
42 | | #include <svl/ctloptions.hxx> |
43 | | |
44 | | #include <editeng/editeng.hxx> |
45 | | #include <editeng/colritem.hxx> |
46 | | #include <editeng/fontitem.hxx> |
47 | | #include <editeng/editids.hrc> |
48 | | #include <editeng/postitem.hxx> |
49 | | #include <editeng/udlnitem.hxx> |
50 | | #include <editeng/crossedoutitem.hxx> |
51 | | #include <editeng/contouritem.hxx> |
52 | | #include <editeng/wghtitem.hxx> |
53 | | #include <editeng/fhgtitem.hxx> |
54 | | #include <editeng/shdditem.hxx> |
55 | | #include <editeng/escapementitem.hxx> |
56 | | #include <editeng/wrlmitem.hxx> |
57 | | #include <editeng/cmapitem.hxx> |
58 | | #include <editeng/kernitem.hxx> |
59 | | #include <editeng/brushitem.hxx> |
60 | | #include <editeng/emphasismarkitem.hxx> |
61 | | #include <editeng/charreliefitem.hxx> |
62 | | #include <editeng/charscaleitem.hxx> |
63 | | #include <editeng/langitem.hxx> |
64 | | |
65 | | //TODO: remove this and calculate off the actual size of text, not |
66 | | //an arbitrary number of characters |
67 | 0 | #define TEXT_WIDTH 80 |
68 | | |
69 | | |
70 | | // small helper functions to set fonts |
71 | | |
72 | | namespace |
73 | | { |
74 | | void scaleFontWidth(vcl::Font& rFont, vcl::RenderContext const & rRenderContext,tools::Long& n100PercentFont) |
75 | 0 | { |
76 | 0 | rFont.SetAverageFontWidth(0); |
77 | 0 | n100PercentFont = rRenderContext.GetFontMetric(rFont).GetAverageFontWidth(); |
78 | 0 | } |
79 | | |
80 | | void initFont(vcl::Font& rFont) |
81 | 0 | { |
82 | 0 | rFont.SetTransparent(true); |
83 | 0 | rFont.SetAlignment(ALIGN_BASELINE); |
84 | 0 | } |
85 | | |
86 | | void setFontSize(vcl::Font& rFont) |
87 | 0 | { |
88 | 0 | Size aSize(rFont.GetFontSize()); |
89 | 0 | aSize.setHeight( (aSize.Height() * 3) / 5 ); |
90 | 0 | aSize.setWidth( (aSize.Width() * 3) / 5 ); |
91 | 0 | rFont.SetFontSize(aSize); |
92 | 0 | } |
93 | | |
94 | | void calcFontHeightAnyAscent(vcl::RenderContext& rRenderContext, const vcl::Font& rFont, tools::Long& nHeight, tools::Long& nAscent) |
95 | 0 | { |
96 | 0 | if (!nHeight) |
97 | 0 | { |
98 | 0 | rRenderContext.SetFont(rFont); |
99 | 0 | FontMetric aMetric(rRenderContext.GetFontMetric()); |
100 | 0 | nHeight = aMetric.GetLineHeight(); |
101 | 0 | nAscent = aMetric.GetAscent(); |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | void setFont(const SvxFont& rNewFont, SvxFont& rImplFont) |
106 | 0 | { |
107 | 0 | rImplFont = rNewFont; |
108 | 0 | rImplFont.SetTransparent(true); |
109 | 0 | rImplFont.SetAlignment(ALIGN_BASELINE); |
110 | 0 | } |
111 | | |
112 | | /* |
113 | | * removes line feeds and carriage returns from string |
114 | | * returns if param is empty |
115 | | */ |
116 | | OUString removeCRLF(const OUString& rText) |
117 | 0 | { |
118 | 0 | return rText.replace(0xa, ' ').replace(0xd, ' ').trim(); |
119 | 0 | } |
120 | | |
121 | | struct ScriptInfo |
122 | | { |
123 | | tools::Long textWidth; |
124 | | SvtScriptType scriptType; |
125 | | sal_Int32 changePos; |
126 | | ScriptInfo(SvtScriptType scrptType, sal_Int32 position) |
127 | 0 | : textWidth(0) |
128 | 0 | , scriptType(scrptType) |
129 | 0 | , changePos(position) |
130 | 0 | { |
131 | 0 | } |
132 | | }; |
133 | | |
134 | | } // end anonymous namespace |
135 | | |
136 | | class FontPrevWin_Impl |
137 | | { |
138 | | friend class SvxFontPrevWindow; |
139 | | |
140 | | SvxFont maFont; |
141 | | VclPtr<Printer> mpPrinter; |
142 | | bool mbDelPrinter; |
143 | | |
144 | | std::vector<ScriptInfo> maScriptChanges; |
145 | | SvxFont maCJKFont; |
146 | | SvxFont maCTLFont; |
147 | | OUString maText; |
148 | | OUString maScriptText; |
149 | | std::optional<Color> mxColor; |
150 | | std::optional<Color> mxBackColor; |
151 | | std::optional<Color> mxTextLineColor; |
152 | | std::optional<Color> mxOverlineColor; |
153 | | tools::Long mnAscent; |
154 | | sal_Unicode mcStartBracket; |
155 | | sal_Unicode mcEndBracket; |
156 | | |
157 | | tools::Long mn100PercentFontWidth; // initial -1 -> not set yet |
158 | | tools::Long mn100PercentFontWidthCJK; |
159 | | tools::Long mn100PercentFontWidthCTL; |
160 | | sal_uInt16 mnFontWidthScale; |
161 | | |
162 | | bool mbSelection : 1; |
163 | | bool mbGetSelection : 1; |
164 | | bool mbTwoLines : 1; |
165 | | bool mbUseFontNameAsText : 1; |
166 | | bool mbTextInited : 1; |
167 | | |
168 | | bool m_bCJKEnabled; |
169 | | bool m_bCTLEnabled; |
170 | | |
171 | | |
172 | | public: |
173 | | FontPrevWin_Impl() : |
174 | 0 | mpPrinter(nullptr), |
175 | 0 | mbDelPrinter(false), |
176 | 0 | mnAscent(0), |
177 | 0 | mcStartBracket(0), |
178 | 0 | mcEndBracket(0), |
179 | 0 | mnFontWidthScale(100), |
180 | 0 | mbSelection(false), |
181 | 0 | mbGetSelection(false), |
182 | 0 | mbTwoLines(false), |
183 | 0 | mbUseFontNameAsText(false), |
184 | 0 | mbTextInited(false) |
185 | 0 | { |
186 | 0 | m_bCJKEnabled = SvtCJKOptions::IsAnyEnabled(); |
187 | 0 | m_bCTLEnabled = SvtCTLOptions::IsCTLFontEnabled(); |
188 | 0 | mxBackColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; |
189 | 0 | Invalidate100PercentFontWidth(); |
190 | 0 | } |
191 | | |
192 | | ~FontPrevWin_Impl() |
193 | 0 | { |
194 | 0 | if (mbDelPrinter) |
195 | 0 | mpPrinter.disposeAndClear(); |
196 | 0 | } |
197 | | |
198 | | void CheckScript(); |
199 | | Size CalcTextSize(vcl::RenderContext& rRenderContext, OutputDevice const * pPrinter, const SvxFont& rFont); |
200 | | void DrawPrev(vcl::RenderContext& rRenderContext, Printer* pPrinter, Point& rPt, const SvxFont& rFont); |
201 | | |
202 | | bool SetFontWidthScale(sal_uInt16 nScaleInPercent); |
203 | | inline void Invalidate100PercentFontWidth(); |
204 | | inline bool Is100PercentFontWidthValid() const; |
205 | | void ScaleFontWidth(vcl::RenderContext const & rRenderContext); |
206 | | // scales rNonCJKFont and aCJKFont depending on nFontWidthScale and |
207 | | // sets the 100%-Font-Widths |
208 | | }; |
209 | | |
210 | | inline void FontPrevWin_Impl::Invalidate100PercentFontWidth() |
211 | 0 | { |
212 | 0 | mn100PercentFontWidth = mn100PercentFontWidthCJK = mn100PercentFontWidthCTL = -1; |
213 | 0 | } |
214 | | |
215 | | inline bool FontPrevWin_Impl::Is100PercentFontWidthValid() const |
216 | 0 | { |
217 | 0 | DBG_ASSERT( ( mn100PercentFontWidth == -1 && mn100PercentFontWidthCJK == -1 ) || |
218 | 0 | ( mn100PercentFontWidth != -1 && mn100PercentFontWidthCJK != -1 ) || |
219 | 0 | ( mn100PercentFontWidth == -1 && mn100PercentFontWidthCTL == -1 ) || |
220 | 0 | ( mn100PercentFontWidth != -1 && mn100PercentFontWidthCTL != -1 ), |
221 | 0 | "*FontPrevWin_Impl::Is100PercentFontWidthValid(): 100PercentFontWidth's not synchronous" ); |
222 | 0 | return mn100PercentFontWidth != -1; |
223 | 0 | } |
224 | | |
225 | | /* |
226 | | * evaluates the scripttypes of the actual string. |
227 | | * Afterwards the positions of script change are notified in aScriptChg, |
228 | | * the scripttypes in aScriptType. |
229 | | * The aTextWidth array will be filled with zero. |
230 | | */ |
231 | | void FontPrevWin_Impl::CheckScript() |
232 | 0 | { |
233 | 0 | assert(!maText.isEmpty()); // must have a preview text here! |
234 | 0 | if (maText == maScriptText) |
235 | 0 | { |
236 | 0 | return; // already initialized |
237 | 0 | } |
238 | | |
239 | 0 | maScriptText = maText; |
240 | 0 | maScriptChanges.clear(); |
241 | |
|
242 | 0 | auto aEditEngine = EditEngine(nullptr); |
243 | 0 | aEditEngine.SetText(maScriptText); |
244 | |
|
245 | 0 | auto aScript = aEditEngine.GetScriptType({ 0, 0, 0, 0 }); |
246 | 0 | for (sal_Int32 i = 1; i <= maScriptText.getLength(); i++) |
247 | 0 | { |
248 | 0 | auto aNextScript = aEditEngine.GetScriptType({ 0, i, 0, i }); |
249 | 0 | if (aNextScript != aScript) |
250 | 0 | maScriptChanges.emplace_back(aScript, i - 1); |
251 | 0 | if (i == maScriptText.getLength()) |
252 | 0 | maScriptChanges.emplace_back(aScript, i); |
253 | 0 | aScript = aNextScript; |
254 | 0 | } |
255 | 0 | } |
256 | | |
257 | | /* |
258 | | * Size FontPrevWin_Impl::CalcTextSize(..) |
259 | | * fills the aTextWidth array with the text width of every part |
260 | | * of the actual string without a script change inside. |
261 | | * For Latin parts the given rFont will be used, |
262 | | * for Asian parts the aCJKFont. |
263 | | * The returned size contains the whole string. |
264 | | * The member nAscent is calculated to the maximal ascent of all used fonts. |
265 | | */ |
266 | | |
267 | | Size FontPrevWin_Impl::CalcTextSize(vcl::RenderContext& rRenderContext, OutputDevice const * _pPrinter, const SvxFont& rInFont) |
268 | 0 | { |
269 | 0 | SvtScriptType aScript; |
270 | 0 | sal_uInt16 nIdx = 0; |
271 | 0 | sal_Int32 nStart = 0; |
272 | 0 | sal_Int32 nEnd; |
273 | 0 | size_t nCnt = maScriptChanges.size(); |
274 | |
|
275 | 0 | if (nCnt) |
276 | 0 | { |
277 | 0 | nEnd = maScriptChanges[nIdx].changePos; |
278 | 0 | aScript = maScriptChanges[nIdx].scriptType; |
279 | 0 | } |
280 | 0 | else |
281 | 0 | { |
282 | 0 | nEnd = maText.getLength(); |
283 | 0 | aScript = SvtScriptType::LATIN; |
284 | 0 | } |
285 | 0 | tools::Long nTxtWidth = 0; |
286 | 0 | tools::Long nCJKHeight = 0; |
287 | 0 | tools::Long nCTLHeight = 0; |
288 | 0 | tools::Long nHeight = 0; |
289 | 0 | mnAscent = 0; |
290 | 0 | tools::Long nCJKAscent = 0; |
291 | 0 | tools::Long nCTLAscent = 0; |
292 | |
|
293 | 0 | do |
294 | 0 | { |
295 | 0 | const SvxFont& rFont = (aScript == SvtScriptType::ASIAN) ? |
296 | 0 | maCJKFont : |
297 | 0 | ((aScript == SvtScriptType::COMPLEX) ? |
298 | 0 | maCTLFont : |
299 | 0 | rInFont); |
300 | 0 | tools::Long nWidth = rFont.GetTextSize(*_pPrinter, maText, nStart, nEnd - nStart).Width(); |
301 | 0 | if (nIdx >= maScriptChanges.size()) |
302 | 0 | break; |
303 | | |
304 | 0 | maScriptChanges[nIdx++].textWidth = nWidth; |
305 | 0 | nTxtWidth += nWidth; |
306 | |
|
307 | 0 | switch (aScript) |
308 | 0 | { |
309 | 0 | case SvtScriptType::ASIAN: |
310 | 0 | calcFontHeightAnyAscent(rRenderContext, maCJKFont, nCJKHeight, nCJKAscent); |
311 | 0 | break; |
312 | 0 | case SvtScriptType::COMPLEX: |
313 | 0 | calcFontHeightAnyAscent(rRenderContext, maCTLFont, nCTLHeight, nCTLAscent); |
314 | 0 | break; |
315 | 0 | default: |
316 | 0 | calcFontHeightAnyAscent(rRenderContext, rFont, nHeight, mnAscent); |
317 | 0 | } |
318 | | |
319 | 0 | if (nEnd < maText.getLength() && nIdx < nCnt) |
320 | 0 | { |
321 | 0 | nStart = nEnd; |
322 | 0 | nEnd = maScriptChanges[nIdx].changePos; |
323 | 0 | aScript = maScriptChanges[nIdx].scriptType; |
324 | 0 | } |
325 | 0 | else |
326 | 0 | break; |
327 | 0 | } |
328 | 0 | while(true); |
329 | | |
330 | 0 | nHeight -= mnAscent; |
331 | 0 | nCJKHeight -= nCJKAscent; |
332 | 0 | nCTLHeight -= nCTLAscent; |
333 | |
|
334 | 0 | if (nHeight < nCJKHeight) |
335 | 0 | nHeight = nCJKHeight; |
336 | |
|
337 | 0 | if (mnAscent < nCJKAscent) |
338 | 0 | mnAscent = nCJKAscent; |
339 | |
|
340 | 0 | if (nHeight < nCTLHeight) |
341 | 0 | nHeight = nCTLHeight; |
342 | |
|
343 | 0 | if (mnAscent < nCTLAscent) |
344 | 0 | mnAscent = nCTLAscent; |
345 | |
|
346 | 0 | nHeight += mnAscent; |
347 | |
|
348 | 0 | Size aTxtSize(nTxtWidth, nHeight); |
349 | 0 | return aTxtSize; |
350 | 0 | } |
351 | | |
352 | | /* |
353 | | * void FontPrevWin_Impl::DrawPrev(..) |
354 | | * calls SvxFont::DrawPrev(..) for every part of the string without a script |
355 | | * change inside, for Asian parts the aCJKFont will be used, otherwise the |
356 | | * given rFont. |
357 | | */ |
358 | | |
359 | | void FontPrevWin_Impl::DrawPrev(vcl::RenderContext& rRenderContext, Printer* _pPrinter, Point &rPt, const SvxFont& rInFont) |
360 | 0 | { |
361 | 0 | vcl::Font aOldFont = _pPrinter->GetFont(); |
362 | 0 | SvtScriptType aScript; |
363 | 0 | sal_uInt16 nIdx = 0; |
364 | 0 | sal_Int32 nStart = 0; |
365 | 0 | sal_Int32 nEnd; |
366 | 0 | size_t nCnt = maScriptChanges.size(); |
367 | |
|
368 | 0 | if (nCnt) |
369 | 0 | { |
370 | 0 | nEnd = maScriptChanges[nIdx].changePos; |
371 | 0 | aScript = maScriptChanges[nIdx].scriptType; |
372 | 0 | } |
373 | 0 | else |
374 | 0 | { |
375 | 0 | nEnd = maText.getLength(); |
376 | 0 | aScript = SvtScriptType::LATIN; |
377 | 0 | } |
378 | 0 | do |
379 | 0 | { |
380 | 0 | const SvxFont& rFont = (aScript == SvtScriptType::ASIAN) |
381 | 0 | ? maCJKFont |
382 | 0 | : ((aScript == SvtScriptType::COMPLEX) |
383 | 0 | ? maCTLFont |
384 | 0 | : rInFont); |
385 | 0 | _pPrinter->SetFont(rFont); |
386 | |
|
387 | 0 | rFont.DrawPrev(&rRenderContext, _pPrinter, rPt, maText, nStart, nEnd - nStart); |
388 | |
|
389 | 0 | rPt.AdjustX(maScriptChanges[nIdx++].textWidth); |
390 | 0 | if (nEnd < maText.getLength() && nIdx < nCnt) |
391 | 0 | { |
392 | 0 | nStart = nEnd; |
393 | 0 | nEnd = maScriptChanges[nIdx].changePos; |
394 | 0 | aScript = maScriptChanges[nIdx].scriptType; |
395 | 0 | } |
396 | 0 | else |
397 | 0 | break; |
398 | 0 | } |
399 | 0 | while(true); |
400 | 0 | _pPrinter->SetFont(aOldFont); |
401 | 0 | } |
402 | | |
403 | | |
404 | | bool FontPrevWin_Impl::SetFontWidthScale(sal_uInt16 nScale) |
405 | 0 | { |
406 | 0 | if (mnFontWidthScale != nScale) |
407 | 0 | { |
408 | 0 | mnFontWidthScale = nScale; |
409 | 0 | return true; |
410 | 0 | } |
411 | | |
412 | 0 | return false; |
413 | 0 | } |
414 | | |
415 | | void FontPrevWin_Impl::ScaleFontWidth(vcl::RenderContext const & rOutDev) |
416 | 0 | { |
417 | 0 | if (!Is100PercentFontWidthValid()) |
418 | 0 | { |
419 | 0 | scaleFontWidth(maFont, rOutDev, mn100PercentFontWidth); |
420 | 0 | scaleFontWidth(maCJKFont, rOutDev, mn100PercentFontWidthCJK); |
421 | 0 | scaleFontWidth(maCTLFont, rOutDev, mn100PercentFontWidthCTL); |
422 | 0 | } |
423 | |
|
424 | 0 | maFont.SetAverageFontWidth(mn100PercentFontWidth * mnFontWidthScale / 100); |
425 | 0 | maCJKFont.SetAverageFontWidth(mn100PercentFontWidthCJK * mnFontWidthScale / 100); |
426 | 0 | maCTLFont.SetAverageFontWidth(mn100PercentFontWidthCTL * mnFontWidthScale / 100); |
427 | 0 | } |
428 | | |
429 | | static bool GetWhich (const SfxItemSet& rSet, sal_uInt16 nSlot, sal_uInt16& rWhich) |
430 | 0 | { |
431 | 0 | rWhich = rSet.GetPool()->GetWhichIDFromSlotID(nSlot); |
432 | 0 | return rSet.GetItemState(rWhich) >= SfxItemState::DEFAULT; |
433 | 0 | } |
434 | | |
435 | | static void SetPrevFont(const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont) |
436 | 0 | { |
437 | 0 | sal_uInt16 nWhich; |
438 | 0 | if (GetWhich(rSet, nSlot, nWhich)) |
439 | 0 | { |
440 | 0 | const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rSet.Get(nWhich)); |
441 | 0 | rFont.SetFamily(rFontItem.GetFamily()); |
442 | 0 | rFont.SetFamilyName(rFontItem.GetFamilyName()); |
443 | 0 | rFont.SetPitch(rFontItem.GetPitch()); |
444 | 0 | rFont.SetCharSet(rFontItem.GetCharSet()); |
445 | 0 | rFont.SetStyleName(rFontItem.GetStyleName()); |
446 | 0 | } |
447 | 0 | } |
448 | | |
449 | | static void SetPrevFontStyle( const SfxItemSet& rSet, sal_uInt16 nPosture, sal_uInt16 nWeight, SvxFont& rFont ) |
450 | 0 | { |
451 | 0 | sal_uInt16 nWhich; |
452 | 0 | if( GetWhich( rSet, nPosture, nWhich ) ) |
453 | 0 | { |
454 | 0 | const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>( rSet.Get( nWhich ) ); |
455 | 0 | rFont.SetItalic( rItem.GetValue() != ITALIC_NONE ? ITALIC_NORMAL : ITALIC_NONE ); |
456 | 0 | } |
457 | |
|
458 | 0 | if( GetWhich( rSet, nWeight, nWhich ) ) |
459 | 0 | { |
460 | 0 | const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>( rSet.Get( nWhich ) ); |
461 | 0 | rFont.SetWeight( rItem.GetValue() != WEIGHT_NORMAL ? WEIGHT_BOLD : WEIGHT_NORMAL ); |
462 | 0 | } |
463 | 0 | } |
464 | | |
465 | | static void SetPrevFontEscapement(SvxFont& rFont, sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc) |
466 | 0 | { |
467 | 0 | rFont.SetPropr(nProp); |
468 | 0 | rFont.SetProprRel(nEscProp); |
469 | 0 | rFont.SetEscapement(nEsc); |
470 | 0 | } |
471 | | |
472 | | void SvxFontPrevWindow::ApplySettings(vcl::RenderContext& rRenderContext) |
473 | 0 | { |
474 | 0 | Color aBgColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; |
475 | 0 | Color aFgColor = svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR, false).nColor; |
476 | 0 | if (aFgColor == COL_AUTO) |
477 | 0 | aFgColor = aBgColor.IsDark() ? COL_WHITE : COL_BLACK; |
478 | 0 | rRenderContext.SetBackground(aBgColor); |
479 | 0 | rRenderContext.SetTextColor(aFgColor); |
480 | 0 | } |
481 | | |
482 | | void SvxFontPrevWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
483 | 0 | { |
484 | 0 | CustomWidgetController::SetDrawingArea(pDrawingArea); |
485 | 0 | Size aPrefSize(getPreviewStripSize(pDrawingArea->get_ref_device())); |
486 | 0 | pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height()); |
487 | |
|
488 | 0 | pImpl.reset(new FontPrevWin_Impl); |
489 | 0 | SfxViewShell* pSh = SfxViewShell::Current(); |
490 | |
|
491 | 0 | if (pSh) |
492 | 0 | pImpl->mpPrinter = pSh->GetPrinter(); |
493 | |
|
494 | 0 | if (!pImpl->mpPrinter) |
495 | 0 | { |
496 | 0 | pImpl->mpPrinter = VclPtr<Printer>::Create(); |
497 | 0 | pImpl->mbDelPrinter = true; |
498 | 0 | } |
499 | 0 | initFont(pImpl->maFont); |
500 | 0 | initFont(pImpl->maCJKFont); |
501 | 0 | initFont(pImpl->maCTLFont); |
502 | |
|
503 | 0 | Invalidate(); |
504 | 0 | } |
505 | | |
506 | | SvxFontPrevWindow::SvxFontPrevWindow() |
507 | 0 | { |
508 | 0 | } |
509 | | |
510 | | SvxFontPrevWindow::~SvxFontPrevWindow() |
511 | 0 | { |
512 | 0 | } |
513 | | |
514 | | SvxFont& SvxFontPrevWindow::GetCTLFont() |
515 | 0 | { |
516 | 0 | return pImpl->maCTLFont; |
517 | 0 | } |
518 | | |
519 | | SvxFont& SvxFontPrevWindow::GetCJKFont() |
520 | 0 | { |
521 | 0 | return pImpl->maCJKFont; |
522 | 0 | } |
523 | | |
524 | | SvxFont& SvxFontPrevWindow::GetFont() |
525 | 0 | { |
526 | 0 | pImpl->Invalidate100PercentFontWidth(); // because the user might change the size |
527 | 0 | return pImpl->maFont; |
528 | 0 | } |
529 | | |
530 | | const SvxFont& SvxFontPrevWindow::GetFont() const |
531 | 0 | { |
532 | 0 | return pImpl->maFont; |
533 | 0 | } |
534 | | |
535 | | void SvxFontPrevWindow::SetPreviewText( const OUString& rString ) |
536 | 0 | { |
537 | 0 | pImpl->maText = rString; |
538 | 0 | pImpl->mbTextInited = true; |
539 | 0 | } |
540 | | |
541 | | void SvxFontPrevWindow::SetFontNameAsPreviewText() |
542 | 0 | { |
543 | 0 | pImpl->mbUseFontNameAsText = true; |
544 | 0 | } |
545 | | |
546 | | void SvxFontPrevWindow::SetFont( const SvxFont& rNormalOutFont, const SvxFont& rCJKOutFont, const SvxFont& rCTLFont ) |
547 | 0 | { |
548 | 0 | setFont(rNormalOutFont, pImpl->maFont); |
549 | 0 | setFont(rCJKOutFont, pImpl->maCJKFont); |
550 | 0 | setFont(rCTLFont, pImpl->maCTLFont); |
551 | |
|
552 | 0 | pImpl->Invalidate100PercentFontWidth(); |
553 | 0 | Invalidate(); |
554 | 0 | } |
555 | | |
556 | | void SvxFontPrevWindow::SetColor(const Color &rColor) |
557 | 0 | { |
558 | 0 | pImpl->mxColor = rColor; |
559 | 0 | Invalidate(); |
560 | 0 | } |
561 | | |
562 | | void SvxFontPrevWindow::ResetColor() |
563 | 0 | { |
564 | 0 | pImpl->mxColor.reset(); |
565 | 0 | Invalidate(); |
566 | 0 | } |
567 | | |
568 | | void SvxFontPrevWindow::SetTextLineColor(const Color &rColor) |
569 | 0 | { |
570 | 0 | pImpl->mxTextLineColor = rColor; |
571 | 0 | Invalidate(); |
572 | 0 | } |
573 | | |
574 | | void SvxFontPrevWindow::SetOverlineColor(const Color &rColor) |
575 | 0 | { |
576 | 0 | pImpl->mxOverlineColor = rColor; |
577 | 0 | Invalidate(); |
578 | 0 | } |
579 | | |
580 | | void SvxFontPrevWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) |
581 | 0 | { |
582 | 0 | auto popIt = rRenderContext.ScopedPush(vcl::PushFlags::ALL); |
583 | 0 | rRenderContext.SetMapMode(MapMode(MapUnit::MapTwip)); |
584 | |
|
585 | 0 | ApplySettings(rRenderContext); |
586 | 0 | rRenderContext.Erase(); |
587 | |
|
588 | 0 | Printer* pPrinter = pImpl->mpPrinter; |
589 | 0 | const SvxFont& rFont = pImpl->maFont; |
590 | 0 | const SvxFont& rCJKFont = pImpl->maCJKFont; |
591 | 0 | const SvxFont& rCTLFont = pImpl->maCTLFont; |
592 | |
|
593 | 0 | if (!IsEnabled()) |
594 | 0 | { |
595 | 0 | const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); |
596 | 0 | const Size aLogSize(rRenderContext.GetOutputSize()); |
597 | |
|
598 | 0 | tools::Rectangle aRect(Point(0, 0), aLogSize); |
599 | 0 | rRenderContext.SetLineColor(); |
600 | 0 | rRenderContext.SetFillColor(rStyleSettings.GetWindowColor()); |
601 | 0 | rRenderContext.DrawRect(aRect); |
602 | 0 | } |
603 | 0 | else |
604 | 0 | { |
605 | 0 | if (!pImpl->mbSelection && !pImpl->mbTextInited) |
606 | 0 | { |
607 | 0 | using namespace css::i18n::ScriptType; |
608 | |
|
609 | 0 | SfxViewShell* pSh = SfxViewShell::Current(); |
610 | |
|
611 | 0 | if (pSh && !pImpl->mbGetSelection && !pImpl->mbUseFontNameAsText) |
612 | 0 | { |
613 | 0 | pImpl->maText = removeCRLF(pSh->GetSelectionText(/*bCompleteWords*/false, /*bOnlyASample*/true)); |
614 | 0 | pImpl->mbGetSelection = true; |
615 | 0 | pImpl->mbSelection = !(pImpl->maText.isEmpty()); |
616 | 0 | } |
617 | |
|
618 | 0 | if (!pImpl->mbSelection || pImpl->mbUseFontNameAsText) |
619 | 0 | { |
620 | | //If we're showing multiple sample texts, then they're all |
621 | | //sample texts. If only showing Latin, continue to use |
622 | | //the fontname as the preview |
623 | 0 | if ((pImpl->m_bCJKEnabled) || (pImpl->m_bCTLEnabled)) |
624 | 0 | pImpl->maText = makeRepresentativeTextForFont(LATIN, rFont); |
625 | 0 | else |
626 | 0 | pImpl->maText = rFont.GetFamilyName(); |
627 | |
|
628 | 0 | if (pImpl->m_bCJKEnabled) |
629 | 0 | { |
630 | 0 | if (!pImpl->maText.isEmpty()) |
631 | 0 | pImpl->maText += " "; |
632 | 0 | pImpl->maText += makeRepresentativeTextForFont(ASIAN, rCJKFont); |
633 | |
|
634 | 0 | } |
635 | 0 | if (pImpl->m_bCTLEnabled) |
636 | 0 | { |
637 | 0 | if (!pImpl->maText.isEmpty()) |
638 | 0 | pImpl->maText += " "; |
639 | 0 | pImpl->maText += makeRepresentativeTextForFont(COMPLEX, rCTLFont); |
640 | 0 | } |
641 | 0 | } |
642 | |
|
643 | 0 | if (pImpl->maText.isEmpty()) |
644 | 0 | { // fdo#58427: still no text? let's try that one... |
645 | 0 | pImpl->maText = makeRepresentativeTextForFont(LATIN, rFont); |
646 | 0 | } |
647 | |
|
648 | 0 | pImpl->maText = removeCRLF(pImpl->maText); |
649 | |
|
650 | 0 | if (pImpl->maText.getLength() > (TEXT_WIDTH - 1)) |
651 | 0 | { |
652 | 0 | const sal_Int32 nSpaceIdx = pImpl->maText.indexOf(" ", TEXT_WIDTH); |
653 | 0 | if (nSpaceIdx != -1) |
654 | 0 | pImpl->maText = pImpl->maText.copy(0, nSpaceIdx); |
655 | 0 | else |
656 | 0 | pImpl->maText = pImpl->maText.copy(0, (TEXT_WIDTH - 1)); |
657 | 0 | } |
658 | 0 | } |
659 | | |
660 | | // calculate text width scaling |
661 | 0 | pImpl->ScaleFontWidth(rRenderContext); |
662 | |
|
663 | 0 | pImpl->CheckScript(); |
664 | 0 | Size aTxtSize = pImpl->CalcTextSize(rRenderContext, pPrinter, rFont); |
665 | |
|
666 | 0 | const Size aLogSize(rRenderContext.GetOutputSize()); |
667 | |
|
668 | 0 | tools::Long nX = aLogSize.Width() / 2 - aTxtSize.Width() / 2; |
669 | 0 | tools::Long nY = aLogSize.Height() / 2 - aTxtSize.Height() / 2; |
670 | |
|
671 | 0 | if (nY + pImpl->mnAscent > aLogSize.Height()) |
672 | 0 | nY = aLogSize.Height() - pImpl->mnAscent; |
673 | |
|
674 | 0 | if (pImpl->mxBackColor) |
675 | 0 | { |
676 | 0 | tools::Rectangle aRect(Point(0, 0), aLogSize); |
677 | 0 | Color aLineCol = rRenderContext.GetLineColor(); |
678 | 0 | Color aFillCol = rRenderContext.GetFillColor(); |
679 | 0 | rRenderContext.SetLineColor(); |
680 | 0 | rRenderContext.SetFillColor(*pImpl->mxBackColor); |
681 | 0 | rRenderContext.DrawRect(aRect); |
682 | 0 | rRenderContext.SetLineColor(aLineCol); |
683 | 0 | rRenderContext.SetFillColor(aFillCol); |
684 | 0 | } |
685 | 0 | if (pImpl->mxColor) |
686 | 0 | { |
687 | 0 | tools::Rectangle aRect(Point(nX, nY), aTxtSize); |
688 | 0 | Color aLineCol = rRenderContext.GetLineColor(); |
689 | 0 | Color aFillCol = rRenderContext.GetFillColor(); |
690 | 0 | rRenderContext.SetLineColor(); |
691 | 0 | rRenderContext.SetFillColor(*pImpl->mxColor); |
692 | 0 | rRenderContext.DrawRect(aRect); |
693 | 0 | rRenderContext.SetLineColor(aLineCol); |
694 | 0 | rRenderContext.SetFillColor(aFillCol); |
695 | 0 | } |
696 | |
|
697 | 0 | if (pImpl->mxTextLineColor) |
698 | 0 | { |
699 | 0 | rRenderContext.SetTextLineColor(*pImpl->mxTextLineColor); |
700 | 0 | } |
701 | |
|
702 | 0 | if (pImpl->mxOverlineColor) |
703 | 0 | { |
704 | 0 | rRenderContext.SetOverlineColor(*pImpl->mxOverlineColor); |
705 | 0 | } |
706 | |
|
707 | 0 | tools::Long nStdAscent = pImpl->mnAscent; |
708 | 0 | nY += nStdAscent; |
709 | |
|
710 | 0 | if (IsTwoLines()) |
711 | 0 | { |
712 | 0 | SvxFont aSmallFont(rFont); |
713 | 0 | Size aOldSize = pImpl->maCJKFont.GetFontSize(); |
714 | 0 | setFontSize(aSmallFont); |
715 | 0 | setFontSize(pImpl->maCJKFont); |
716 | |
|
717 | 0 | tools::Long nStartBracketWidth = 0; |
718 | 0 | tools::Long nEndBracketWidth = 0; |
719 | 0 | tools::Long nTextWidth = 0; |
720 | 0 | if (pImpl->mcStartBracket) |
721 | 0 | { |
722 | 0 | OUString sBracket(pImpl->mcStartBracket); |
723 | 0 | nStartBracketWidth = rFont.GetTextSize(*pPrinter, sBracket).Width(); |
724 | 0 | } |
725 | 0 | if (pImpl->mcEndBracket) |
726 | 0 | { |
727 | 0 | OUString sBracket(pImpl->mcEndBracket); |
728 | 0 | nEndBracketWidth = rFont.GetTextSize(*pPrinter, sBracket).Width(); |
729 | 0 | } |
730 | 0 | nTextWidth = pImpl->CalcTextSize(rRenderContext, pPrinter, aSmallFont).Width(); |
731 | 0 | tools::Long nResultWidth = nStartBracketWidth; |
732 | 0 | nResultWidth += nEndBracketWidth; |
733 | 0 | nResultWidth += nTextWidth; |
734 | |
|
735 | 0 | tools::Long _nX = (aLogSize.Width() - nResultWidth) / 2; |
736 | 0 | rRenderContext.DrawLine(Point(0, nY), Point(_nX, nY)); |
737 | 0 | rRenderContext.DrawLine(Point(_nX + nResultWidth, nY), Point(aLogSize.Width(), nY)); |
738 | |
|
739 | 0 | tools::Long nSmallAscent = pImpl->mnAscent; |
740 | 0 | tools::Long nOffset = (nStdAscent - nSmallAscent) / 2; |
741 | |
|
742 | 0 | if (pImpl->mcStartBracket) |
743 | 0 | { |
744 | 0 | OUString sBracket(pImpl->mcStartBracket); |
745 | 0 | rFont.DrawPrev(&rRenderContext, pPrinter, Point(_nX, nY - nOffset - 4), sBracket); |
746 | 0 | _nX += nStartBracketWidth; |
747 | 0 | } |
748 | |
|
749 | 0 | Point aTmpPoint1(_nX, nY - nSmallAscent - 2); |
750 | 0 | Point aTmpPoint2(_nX, nY); |
751 | 0 | pImpl->DrawPrev(rRenderContext, pPrinter, aTmpPoint1, aSmallFont); |
752 | 0 | pImpl->DrawPrev(rRenderContext, pPrinter, aTmpPoint2, aSmallFont); |
753 | |
|
754 | 0 | _nX += nTextWidth; |
755 | 0 | if (pImpl->mcEndBracket) |
756 | 0 | { |
757 | 0 | Point aTmpPoint( _nX + 1, nY - nOffset - 4); |
758 | 0 | OUString sBracket(pImpl->mcEndBracket); |
759 | 0 | rFont.DrawPrev(&rRenderContext, pPrinter, aTmpPoint, sBracket); |
760 | 0 | } |
761 | 0 | pImpl->maCJKFont.SetFontSize(aOldSize); |
762 | 0 | } |
763 | 0 | else |
764 | 0 | { |
765 | |
|
766 | 0 | Color aLineCol = rRenderContext.GetLineColor(); |
767 | |
|
768 | 0 | if (rFont.GetColor() == COL_TRANSPARENT) |
769 | 0 | rRenderContext.SetLineColor(); |
770 | 0 | else if (!rRenderContext.HasAlpha() && rFont.GetColor().IsTransparent()) |
771 | 0 | rRenderContext.SetLineColor(::Color(rFont.GetColor().GetRed(), rFont.GetColor().GetGreen(), |
772 | 0 | rFont.GetColor().GetBlue())); |
773 | 0 | else |
774 | 0 | rRenderContext.SetLineColor(rFont.GetColor()); |
775 | 0 | rRenderContext.DrawLine(Point(0, nY), Point(nX, nY)); |
776 | 0 | rRenderContext.DrawLine(Point(nX + aTxtSize.Width(), nY), Point(aLogSize.Width(), nY)); |
777 | 0 | rRenderContext.SetLineColor(aLineCol); |
778 | |
|
779 | 0 | Point aTmpPoint(nX, nY); |
780 | 0 | pImpl->DrawPrev(rRenderContext, pPrinter, aTmpPoint, rFont); |
781 | 0 | } |
782 | 0 | } |
783 | 0 | } |
784 | | |
785 | | bool SvxFontPrevWindow::IsTwoLines() const |
786 | 0 | { |
787 | 0 | return pImpl->mbTwoLines; |
788 | 0 | } |
789 | | |
790 | | void SvxFontPrevWindow::SetTwoLines(bool bSet) |
791 | 0 | { |
792 | 0 | pImpl->mbTwoLines = bSet; |
793 | 0 | } |
794 | | |
795 | | void SvxFontPrevWindow::SetBrackets(sal_Unicode cStart, sal_Unicode cEnd) |
796 | 0 | { |
797 | 0 | pImpl->mcStartBracket = cStart; |
798 | 0 | pImpl->mcEndBracket = cEnd; |
799 | 0 | } |
800 | | |
801 | | void SvxFontPrevWindow::SetFontWidthScale( sal_uInt16 n ) |
802 | 0 | { |
803 | 0 | if (pImpl->SetFontWidthScale(n)) |
804 | 0 | Invalidate(); |
805 | 0 | } |
806 | | |
807 | | void SvxFontPrevWindow::AutoCorrectFontColor() |
808 | 0 | { |
809 | 0 | Color aColor(COL_AUTO); |
810 | 0 | if ( pImpl->mxBackColor ) aColor = *pImpl->mxBackColor; |
811 | 0 | const bool bIsDark(aColor.IsDark()); |
812 | |
|
813 | 0 | aColor = pImpl->maFont.GetColor(); |
814 | 0 | if (aColor == COL_AUTO) |
815 | 0 | pImpl->maFont.SetColor( bIsDark ? COL_WHITE : COL_BLACK ); |
816 | 0 | aColor = pImpl->maCJKFont.GetColor(); |
817 | 0 | if (aColor == COL_AUTO) |
818 | 0 | pImpl->maCJKFont.SetColor( bIsDark ? COL_WHITE : COL_BLACK ); |
819 | 0 | aColor = pImpl->maCTLFont.GetColor(); |
820 | 0 | if (aColor == COL_AUTO) |
821 | 0 | pImpl->maCTLFont.SetColor( bIsDark ? COL_WHITE : COL_BLACK ); |
822 | 0 | } |
823 | | |
824 | | void SvxFontPrevWindow::SetFontSize( const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont ) |
825 | 0 | { |
826 | 0 | sal_uInt16 nWhich; |
827 | 0 | tools::Long nH; |
828 | 0 | if (GetWhich(rSet, nSlot, nWhich)) |
829 | 0 | { |
830 | 0 | nH = OutputDevice::LogicToLogic(static_cast<const SvxFontHeightItem&>(rSet.Get(nWhich)).GetHeight(), |
831 | 0 | rSet.GetPool()->GetMetric(nWhich), |
832 | 0 | MapUnit::MapTwip); |
833 | 0 | } |
834 | 0 | else |
835 | 0 | nH = 240;// as default 12pt |
836 | |
|
837 | 0 | rFont.SetFontSize(Size(0, nH)); |
838 | 0 | } |
839 | | |
840 | | void SvxFontPrevWindow::SetFontLang(const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont) |
841 | 0 | { |
842 | 0 | sal_uInt16 nWhich; |
843 | 0 | LanguageType nLang; |
844 | 0 | if( GetWhich( rSet, nSlot, nWhich ) ) |
845 | 0 | nLang = static_cast<const SvxLanguageItem&>(rSet.Get(nWhich)).GetLanguage(); |
846 | 0 | else |
847 | 0 | nLang = LANGUAGE_NONE; |
848 | 0 | rFont.SetLanguage(nLang); |
849 | 0 | } |
850 | | |
851 | | void SvxFontPrevWindow::SetFromItemSet(const SfxItemSet &rSet, bool bPreviewBackgroundToCharacter) |
852 | 0 | { |
853 | 0 | sal_uInt16 nWhich; |
854 | 0 | SvxFont& rFont = GetFont(); |
855 | 0 | SvxFont& rCJKFont = GetCJKFont(); |
856 | 0 | SvxFont& rCTLFont = GetCTLFont(); |
857 | | |
858 | | // Preview string |
859 | 0 | if( GetWhich( rSet, SID_CHAR_DLG_PREVIEW_STRING, nWhich ) ) |
860 | 0 | { |
861 | 0 | const SfxStringItem& rItem = static_cast<const SfxStringItem&>( rSet.Get( nWhich ) ); |
862 | 0 | const OUString& aString = rItem.GetValue(); |
863 | 0 | if( !aString.isEmpty() ) |
864 | 0 | SetPreviewText( aString ); |
865 | 0 | else |
866 | 0 | SetFontNameAsPreviewText(); |
867 | 0 | } |
868 | | |
869 | | // Underline |
870 | 0 | FontLineStyle eUnderline; |
871 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_UNDERLINE, nWhich ) ) |
872 | 0 | { |
873 | 0 | const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>( rSet.Get( nWhich ) ); |
874 | 0 | eUnderline = rItem.GetValue(); |
875 | 0 | } |
876 | 0 | else |
877 | 0 | eUnderline = LINESTYLE_NONE; |
878 | |
|
879 | 0 | rFont.SetUnderline( eUnderline ); |
880 | 0 | rCJKFont.SetUnderline( eUnderline ); |
881 | 0 | rCTLFont.SetUnderline( eUnderline ); |
882 | | |
883 | | // Overline |
884 | 0 | FontLineStyle eOverline; |
885 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_OVERLINE, nWhich ) ) |
886 | 0 | { |
887 | 0 | const SvxOverlineItem& rItem = static_cast<const SvxOverlineItem&>( rSet.Get( nWhich ) ); |
888 | 0 | eOverline = rItem.GetValue(); |
889 | 0 | } |
890 | 0 | else |
891 | 0 | eOverline = LINESTYLE_NONE; |
892 | |
|
893 | 0 | rFont.SetOverline( eOverline ); |
894 | 0 | rCJKFont.SetOverline( eOverline ); |
895 | 0 | rCTLFont.SetOverline( eOverline ); |
896 | | |
897 | | // Strikeout |
898 | 0 | FontStrikeout eStrikeout; |
899 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_STRIKEOUT, nWhich ) ) |
900 | 0 | { |
901 | 0 | const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>( rSet.Get( nWhich ) ); |
902 | 0 | eStrikeout = rItem.GetValue(); |
903 | 0 | } |
904 | 0 | else |
905 | 0 | eStrikeout = STRIKEOUT_NONE; |
906 | |
|
907 | 0 | rFont.SetStrikeout( eStrikeout ); |
908 | 0 | rCJKFont.SetStrikeout( eStrikeout ); |
909 | 0 | rCTLFont.SetStrikeout( eStrikeout ); |
910 | | |
911 | | // WordLineMode |
912 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_WORDLINEMODE, nWhich ) ) |
913 | 0 | { |
914 | 0 | const SvxWordLineModeItem& rItem = static_cast<const SvxWordLineModeItem&>( rSet.Get( nWhich ) ); |
915 | 0 | rFont.SetWordLineMode( rItem.GetValue() ); |
916 | 0 | rCJKFont.SetWordLineMode( rItem.GetValue() ); |
917 | 0 | rCTLFont.SetWordLineMode( rItem.GetValue() ); |
918 | 0 | } |
919 | | |
920 | | // Emphasis |
921 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_EMPHASISMARK, nWhich ) ) |
922 | 0 | { |
923 | 0 | const SvxEmphasisMarkItem& rItem = static_cast<const SvxEmphasisMarkItem&>( rSet.Get( nWhich ) ); |
924 | 0 | FontEmphasisMark eMark = rItem.GetEmphasisMark(); |
925 | 0 | rFont.SetEmphasisMark( eMark ); |
926 | 0 | rCJKFont.SetEmphasisMark( eMark ); |
927 | 0 | rCTLFont.SetEmphasisMark( eMark ); |
928 | 0 | } |
929 | | |
930 | | // Relief |
931 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_RELIEF, nWhich ) ) |
932 | 0 | { |
933 | 0 | const SvxCharReliefItem& rItem = static_cast<const SvxCharReliefItem&>( rSet.Get( nWhich ) ); |
934 | 0 | FontRelief eFontRelief = rItem.GetValue(); |
935 | 0 | rFont.SetRelief( eFontRelief ); |
936 | 0 | rCJKFont.SetRelief( eFontRelief ); |
937 | 0 | rCTLFont.SetRelief( eFontRelief ); |
938 | 0 | } |
939 | | |
940 | | // Effects |
941 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_CASEMAP, nWhich ) ) |
942 | 0 | { |
943 | 0 | const SvxCaseMapItem& rItem = static_cast<const SvxCaseMapItem&>( rSet.Get( nWhich ) ); |
944 | 0 | SvxCaseMap eCaseMap = rItem.GetValue(); |
945 | 0 | rFont.SetCaseMap( eCaseMap ); |
946 | 0 | rCJKFont.SetCaseMap( eCaseMap ); |
947 | | // #i78474# small caps do not exist in CTL fonts |
948 | 0 | rCTLFont.SetCaseMap( eCaseMap == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaseMap ); |
949 | 0 | } |
950 | | |
951 | | // Outline |
952 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_CONTOUR, nWhich ) ) |
953 | 0 | { |
954 | 0 | const SvxContourItem& rItem = static_cast<const SvxContourItem&>( rSet.Get( nWhich ) ); |
955 | 0 | bool bOutline = rItem.GetValue(); |
956 | 0 | rFont.SetOutline( bOutline ); |
957 | 0 | rCJKFont.SetOutline( bOutline ); |
958 | 0 | rCTLFont.SetOutline( bOutline ); |
959 | 0 | } |
960 | | |
961 | | // Shadow |
962 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_SHADOWED, nWhich ) ) |
963 | 0 | { |
964 | 0 | const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>( rSet.Get( nWhich ) ); |
965 | 0 | bool bShadow = rItem.GetValue(); |
966 | 0 | rFont.SetShadow( bShadow ); |
967 | 0 | rCJKFont.SetShadow( bShadow ); |
968 | 0 | rCTLFont.SetShadow( bShadow ); |
969 | 0 | } |
970 | | |
971 | | // Background |
972 | 0 | bool bTransparent; |
973 | 0 | if( GetWhich( rSet, bPreviewBackgroundToCharacter ? SID_ATTR_BRUSH : SID_ATTR_BRUSH_CHAR, nWhich ) ) |
974 | 0 | { |
975 | 0 | const SvxBrushItem& rBrush = static_cast<const SvxBrushItem&>( rSet.Get( nWhich ) ); |
976 | 0 | const Color& rColor = rBrush.GetColor(); |
977 | 0 | bTransparent = rColor.IsTransparent(); |
978 | 0 | rFont.SetFillColor( rColor ); |
979 | 0 | rCJKFont.SetFillColor( rColor ); |
980 | 0 | rCTLFont.SetFillColor( rColor ); |
981 | 0 | } |
982 | 0 | else |
983 | 0 | bTransparent = true; |
984 | |
|
985 | 0 | rFont.SetTransparent( bTransparent ); |
986 | 0 | rCJKFont.SetTransparent( bTransparent ); |
987 | 0 | rCTLFont.SetTransparent( bTransparent ); |
988 | |
|
989 | 0 | if( !bPreviewBackgroundToCharacter ) |
990 | 0 | { |
991 | 0 | bool bBackColorFound = false; |
992 | 0 | if( GetWhich( rSet, SID_ATTR_BRUSH, nWhich ) ) |
993 | 0 | { |
994 | 0 | const SvxBrushItem& rBrush = static_cast<const SvxBrushItem&>( rSet.Get( nWhich ) ); |
995 | 0 | if (GPOS_NONE == rBrush.GetGraphicPos()) |
996 | 0 | { |
997 | 0 | const Color& rBrushColor = rBrush.GetColor(); |
998 | 0 | if (rBrushColor != COL_TRANSPARENT) |
999 | 0 | { |
1000 | 0 | pImpl->mxBackColor = rBrush.GetColor(); |
1001 | 0 | bBackColorFound = true; |
1002 | 0 | } |
1003 | 0 | } |
1004 | 0 | } |
1005 | 0 | if (!bBackColorFound) |
1006 | 0 | pImpl->mxBackColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; |
1007 | 0 | } |
1008 | | |
1009 | | // Font |
1010 | 0 | SetPrevFont( rSet, SID_ATTR_CHAR_FONT, rFont ); |
1011 | 0 | SetPrevFont( rSet, SID_ATTR_CHAR_CJK_FONT, rCJKFont ); |
1012 | 0 | SetPrevFont( rSet, SID_ATTR_CHAR_CTL_FONT, rCTLFont ); |
1013 | | |
1014 | | // Style |
1015 | 0 | SetPrevFontStyle( rSet, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, rFont ); |
1016 | 0 | SetPrevFontStyle( rSet, SID_ATTR_CHAR_CJK_POSTURE, SID_ATTR_CHAR_CJK_WEIGHT, rCJKFont ); |
1017 | 0 | SetPrevFontStyle( rSet, SID_ATTR_CHAR_CTL_POSTURE, SID_ATTR_CHAR_CTL_WEIGHT, rCTLFont ); |
1018 | | |
1019 | | // Size |
1020 | 0 | SetFontSize( rSet, SID_ATTR_CHAR_FONTHEIGHT, rFont ); |
1021 | 0 | SetFontSize( rSet, SID_ATTR_CHAR_CJK_FONTHEIGHT, rCJKFont ); |
1022 | 0 | SetFontSize( rSet, SID_ATTR_CHAR_CTL_FONTHEIGHT, rCTLFont ); |
1023 | | |
1024 | | // Language |
1025 | 0 | SetFontLang( rSet, SID_ATTR_CHAR_LANGUAGE, rFont ); |
1026 | 0 | SetFontLang( rSet, SID_ATTR_CHAR_CJK_LANGUAGE, rCJKFont ); |
1027 | 0 | SetFontLang( rSet, SID_ATTR_CHAR_CTL_LANGUAGE, rCTLFont ); |
1028 | | |
1029 | | // Color |
1030 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_COLOR, nWhich ) ) |
1031 | 0 | { |
1032 | 0 | const SvxColorItem& rItem = static_cast<const SvxColorItem&>( rSet.Get( nWhich ) ); |
1033 | 0 | Color aCol( rItem.GetValue() ); |
1034 | 0 | rFont.SetColor( aCol ); |
1035 | |
|
1036 | 0 | rCJKFont.SetColor( aCol ); |
1037 | 0 | rCTLFont.SetColor( aCol ); |
1038 | |
|
1039 | 0 | AutoCorrectFontColor(); // handle color COL_AUTO |
1040 | 0 | } |
1041 | | |
1042 | | // Kerning |
1043 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_KERNING, nWhich ) ) |
1044 | 0 | { |
1045 | 0 | const SvxKerningItem& rItem = static_cast<const SvxKerningItem&>( rSet.Get( nWhich ) ); |
1046 | 0 | short nKern = static_cast<short>(OutputDevice::LogicToLogic(rItem.GetValue(), rSet.GetPool()->GetMetric(nWhich), MapUnit::MapTwip)); |
1047 | 0 | rFont.SetFixKerning( nKern ); |
1048 | 0 | rCJKFont.SetFixKerning( nKern ); |
1049 | 0 | rCTLFont.SetFixKerning( nKern ); |
1050 | 0 | } |
1051 | | |
1052 | | // Escapement |
1053 | 0 | const sal_uInt8 nProp = 100; |
1054 | 0 | short nEsc; |
1055 | 0 | sal_uInt8 nEscProp; |
1056 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_ESCAPEMENT, nWhich ) ) |
1057 | 0 | { |
1058 | 0 | const SvxEscapementItem& rItem = static_cast<const SvxEscapementItem&>( rSet.Get( nWhich ) ); |
1059 | 0 | nEsc = rItem.GetEsc(); |
1060 | 0 | nEscProp = rItem.GetProportionalHeight(); |
1061 | |
|
1062 | 0 | if( nEsc == DFLT_ESC_AUTO_SUPER ) |
1063 | 0 | nEsc = DFLT_ESC_SUPER; |
1064 | 0 | else if( nEsc == DFLT_ESC_AUTO_SUB ) |
1065 | 0 | nEsc = DFLT_ESC_SUB; |
1066 | 0 | } |
1067 | 0 | else |
1068 | 0 | { |
1069 | 0 | nEsc = 0; |
1070 | 0 | nEscProp = 100; |
1071 | 0 | } |
1072 | 0 | SetPrevFontEscapement( rFont, nProp, nEscProp, nEsc ); |
1073 | 0 | SetPrevFontEscapement( rCJKFont, nProp, nEscProp, nEsc ); |
1074 | 0 | SetPrevFontEscapement( rCTLFont, nProp, nEscProp, nEsc ); |
1075 | | |
1076 | | // Font width scale |
1077 | 0 | if( GetWhich( rSet, SID_ATTR_CHAR_SCALEWIDTH, nWhich ) ) |
1078 | 0 | { |
1079 | 0 | const SvxCharScaleWidthItem&rItem = static_cast<const SvxCharScaleWidthItem&>( rSet.Get( nWhich ) ); |
1080 | 0 | SetFontWidthScale( rItem.GetValue() ); |
1081 | 0 | } |
1082 | |
|
1083 | 0 | Invalidate(); |
1084 | 0 | } |
1085 | | |
1086 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |