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