1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
27 #include <com/sun/star/i18n/ScriptType.hpp>
32 #include <svtools/colorcfg.hxx>
33 #include <svtools/sampletext.hxx>
35 #include <svx/fntctrl.hxx>
36 #include <svx/svxids.hrc>
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>
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>
66 //TODO: remove this and calculate off the actual size of text, not
67 //an arbitrary number of characters
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::lang
;
74 // small helper functions to set fonts
78 void scaleFontWidth(vcl::Font
& rFont
, vcl::RenderContext
const & rRenderContext
,tools::Long
& n100PercentFont
)
80 rFont
.SetAverageFontWidth(0);
81 n100PercentFont
= rRenderContext
.GetFontMetric(rFont
).GetAverageFontWidth();
84 void initFont(vcl::Font
& rFont
)
86 rFont
.SetTransparent(true);
87 rFont
.SetAlignment(ALIGN_BASELINE
);
90 void setFontSize(vcl::Font
& rFont
)
92 Size
aSize(rFont
.GetFontSize());
93 aSize
.setHeight( (aSize
.Height() * 3) / 5 );
94 aSize
.setWidth( (aSize
.Width() * 3) / 5 );
95 rFont
.SetFontSize(aSize
);
98 void calcFontHeightAnyAscent(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
, tools::Long
& nHeight
, tools::Long
& nAscent
)
102 rRenderContext
.SetFont(rFont
);
103 FontMetric
aMetric(rRenderContext
.GetFontMetric());
104 nHeight
= aMetric
.GetLineHeight();
105 nAscent
= aMetric
.GetAscent();
109 void setFont(const SvxFont
& rNewFont
, SvxFont
& rImplFont
)
111 rImplFont
= rNewFont
;
112 rImplFont
.SetTransparent(true);
113 rImplFont
.SetAlignment(ALIGN_BASELINE
);
117 * removes line feeds and carriage returns from string
118 * returns if param is empty
120 OUString
removeCRLF(const OUString
& rText
)
122 return rText
.replace(0xa, ' ').replace(0xd, ' ').trim();
127 tools::Long textWidth
;
128 SvtScriptType scriptType
;
130 ScriptInfo(SvtScriptType scrptType
, sal_Int32 position
)
132 , scriptType(scrptType
)
133 , changePos(position
)
138 } // end anonymous namespace
140 class FontPrevWin_Impl
142 friend class SvxFontPrevWindow
;
145 VclPtr
<Printer
> mpPrinter
;
148 std::vector
<ScriptInfo
> maScriptChanges
;
152 OUString maScriptText
;
153 std::optional
<Color
> mxColor
;
154 std::optional
<Color
> mxBackColor
;
155 std::optional
<Color
> mxTextLineColor
;
156 std::optional
<Color
> mxOverlineColor
;
157 tools::Long mnAscent
;
158 sal_Unicode mcStartBracket
;
159 sal_Unicode mcEndBracket
;
161 tools::Long mn100PercentFontWidth
; // initial -1 -> not set yet
162 tools::Long mn100PercentFontWidthCJK
;
163 tools::Long mn100PercentFontWidthCTL
;
164 sal_uInt16 mnFontWidthScale
;
166 bool mbSelection
: 1;
167 bool mbGetSelection
: 1;
169 bool mbUseFontNameAsText
: 1;
170 bool mbTextInited
: 1;
183 mnFontWidthScale(100),
185 mbGetSelection(false),
187 mbUseFontNameAsText(false),
190 m_bCJKEnabled
= SvtCJKOptions::IsAnyEnabled();
191 m_bCTLEnabled
= SvtCTLOptions::IsCTLFontEnabled();
192 mxBackColor
= svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
;
193 Invalidate100PercentFontWidth();
199 mpPrinter
.disposeAndClear();
203 Size
CalcTextSize(vcl::RenderContext
& rRenderContext
, OutputDevice
const * pPrinter
, const SvxFont
& rFont
);
204 void DrawPrev(vcl::RenderContext
& rRenderContext
, Printer
* pPrinter
, Point
& rPt
, const SvxFont
& rFont
);
206 bool SetFontWidthScale(sal_uInt16 nScaleInPercent
);
207 inline void Invalidate100PercentFontWidth();
208 inline bool Is100PercentFontWidthValid() const;
209 void ScaleFontWidth(vcl::RenderContext
const & rRenderContext
);
210 // scales rNonCJKFont and aCJKFont depending on nFontWidthScale and
211 // sets the 100%-Font-Widths
214 inline void FontPrevWin_Impl::Invalidate100PercentFontWidth()
216 mn100PercentFontWidth
= mn100PercentFontWidthCJK
= mn100PercentFontWidthCTL
= -1;
219 inline bool FontPrevWin_Impl::Is100PercentFontWidthValid() const
221 DBG_ASSERT( ( mn100PercentFontWidth
== -1 && mn100PercentFontWidthCJK
== -1 ) ||
222 ( mn100PercentFontWidth
!= -1 && mn100PercentFontWidthCJK
!= -1 ) ||
223 ( mn100PercentFontWidth
== -1 && mn100PercentFontWidthCTL
== -1 ) ||
224 ( mn100PercentFontWidth
!= -1 && mn100PercentFontWidthCTL
!= -1 ),
225 "*FontPrevWin_Impl::Is100PercentFontWidthValid(): 100PercentFontWidth's not synchronous" );
226 return mn100PercentFontWidth
!= -1;
230 * evaluates the scripttypes of the actual string.
231 * Afterwards the positions of script change are notified in aScriptChg,
232 * the scripttypes in aScriptType.
233 * The aTextWidth array will be filled with zero.
235 void FontPrevWin_Impl::CheckScript()
237 assert(!maText
.isEmpty()); // must have a preview text here!
238 if (maText
== maScriptText
)
240 return; // already initialized
243 maScriptText
= maText
;
244 maScriptChanges
.clear();
246 auto aEditEngine
= EditEngine(nullptr);
247 aEditEngine
.SetText(maScriptText
);
249 auto aScript
= aEditEngine
.GetScriptType({ 0, 0, 0, 0 });
250 for (sal_Int32 i
= 1; i
<= maScriptText
.getLength(); i
++)
252 auto aNextScript
= aEditEngine
.GetScriptType({ 0, i
, 0, i
});
253 if (aNextScript
!= aScript
)
254 maScriptChanges
.emplace_back(aScript
, i
- 1);
255 if (i
== maScriptText
.getLength())
256 maScriptChanges
.emplace_back(aScript
, i
);
257 aScript
= aNextScript
;
262 * Size FontPrevWin_Impl::CalcTextSize(..)
263 * fills the aTextWidth array with the text width of every part
264 * of the actual string without a script change inside.
265 * For Latin parts the given rFont will be used,
266 * for Asian parts the aCJKFont.
267 * The returned size contains the whole string.
268 * The member nAscent is calculated to the maximal ascent of all used fonts.
271 Size
FontPrevWin_Impl::CalcTextSize(vcl::RenderContext
& rRenderContext
, OutputDevice
const * _pPrinter
, const SvxFont
& rInFont
)
273 SvtScriptType aScript
;
275 sal_Int32 nStart
= 0;
277 size_t nCnt
= maScriptChanges
.size();
281 nEnd
= maScriptChanges
[nIdx
].changePos
;
282 aScript
= maScriptChanges
[nIdx
].scriptType
;
286 nEnd
= maText
.getLength();
287 aScript
= SvtScriptType::LATIN
;
289 tools::Long nTxtWidth
= 0;
290 tools::Long nCJKHeight
= 0;
291 tools::Long nCTLHeight
= 0;
292 tools::Long nHeight
= 0;
294 tools::Long nCJKAscent
= 0;
295 tools::Long nCTLAscent
= 0;
299 const SvxFont
& rFont
= (aScript
== SvtScriptType::ASIAN
) ?
301 ((aScript
== SvtScriptType::COMPLEX
) ?
304 tools::Long nWidth
= rFont
.GetTextSize(*_pPrinter
, maText
, nStart
, nEnd
- nStart
).Width();
305 if (nIdx
>= maScriptChanges
.size())
308 maScriptChanges
[nIdx
++].textWidth
= nWidth
;
313 case SvtScriptType::ASIAN
:
314 calcFontHeightAnyAscent(rRenderContext
, maCJKFont
, nCJKHeight
, nCJKAscent
);
316 case SvtScriptType::COMPLEX
:
317 calcFontHeightAnyAscent(rRenderContext
, maCTLFont
, nCTLHeight
, nCTLAscent
);
320 calcFontHeightAnyAscent(rRenderContext
, rFont
, nHeight
, mnAscent
);
323 if (nEnd
< maText
.getLength() && nIdx
< nCnt
)
326 nEnd
= maScriptChanges
[nIdx
].changePos
;
327 aScript
= maScriptChanges
[nIdx
].scriptType
;
335 nCJKHeight
-= nCJKAscent
;
336 nCTLHeight
-= nCTLAscent
;
338 if (nHeight
< nCJKHeight
)
339 nHeight
= nCJKHeight
;
341 if (mnAscent
< nCJKAscent
)
342 mnAscent
= nCJKAscent
;
344 if (nHeight
< nCTLHeight
)
345 nHeight
= nCTLHeight
;
347 if (mnAscent
< nCTLAscent
)
348 mnAscent
= nCTLAscent
;
352 Size
aTxtSize(nTxtWidth
, nHeight
);
357 * void FontPrevWin_Impl::DrawPrev(..)
358 * calls SvxFont::DrawPrev(..) for every part of the string without a script
359 * change inside, for Asian parts the aCJKFont will be used, otherwise the
363 void FontPrevWin_Impl::DrawPrev(vcl::RenderContext
& rRenderContext
, Printer
* _pPrinter
, Point
&rPt
, const SvxFont
& rInFont
)
365 vcl::Font aOldFont
= _pPrinter
->GetFont();
366 SvtScriptType aScript
;
368 sal_Int32 nStart
= 0;
370 size_t nCnt
= maScriptChanges
.size();
374 nEnd
= maScriptChanges
[nIdx
].changePos
;
375 aScript
= maScriptChanges
[nIdx
].scriptType
;
379 nEnd
= maText
.getLength();
380 aScript
= SvtScriptType::LATIN
;
384 const SvxFont
& rFont
= (aScript
== SvtScriptType::ASIAN
)
386 : ((aScript
== SvtScriptType::COMPLEX
)
389 _pPrinter
->SetFont(rFont
);
391 rFont
.DrawPrev(&rRenderContext
, _pPrinter
, rPt
, maText
, nStart
, nEnd
- nStart
);
393 rPt
.AdjustX(maScriptChanges
[nIdx
++].textWidth
);
394 if (nEnd
< maText
.getLength() && nIdx
< nCnt
)
397 nEnd
= maScriptChanges
[nIdx
].changePos
;
398 aScript
= maScriptChanges
[nIdx
].scriptType
;
404 _pPrinter
->SetFont(aOldFont
);
408 bool FontPrevWin_Impl::SetFontWidthScale(sal_uInt16 nScale
)
410 if (mnFontWidthScale
!= nScale
)
412 mnFontWidthScale
= nScale
;
419 void FontPrevWin_Impl::ScaleFontWidth(vcl::RenderContext
const & rOutDev
)
421 if (!Is100PercentFontWidthValid())
423 scaleFontWidth(maFont
, rOutDev
, mn100PercentFontWidth
);
424 scaleFontWidth(maCJKFont
, rOutDev
, mn100PercentFontWidthCJK
);
425 scaleFontWidth(maCTLFont
, rOutDev
, mn100PercentFontWidthCTL
);
428 maFont
.SetAverageFontWidth(mn100PercentFontWidth
* mnFontWidthScale
/ 100);
429 maCJKFont
.SetAverageFontWidth(mn100PercentFontWidthCJK
* mnFontWidthScale
/ 100);
430 maCTLFont
.SetAverageFontWidth(mn100PercentFontWidthCTL
* mnFontWidthScale
/ 100);
433 static bool GetWhich (const SfxItemSet
& rSet
, sal_uInt16 nSlot
, sal_uInt16
& rWhich
)
435 rWhich
= rSet
.GetPool()->GetWhich(nSlot
);
436 return rSet
.GetItemState(rWhich
) >= SfxItemState::DEFAULT
;
439 static void SetPrevFont(const SfxItemSet
& rSet
, sal_uInt16 nSlot
, SvxFont
& rFont
)
442 if (GetWhich(rSet
, nSlot
, nWhich
))
444 const SvxFontItem
& rFontItem
= static_cast<const SvxFontItem
&>(rSet
.Get(nWhich
));
445 rFont
.SetFamily(rFontItem
.GetFamily());
446 rFont
.SetFamilyName(rFontItem
.GetFamilyName());
447 rFont
.SetPitch(rFontItem
.GetPitch());
448 rFont
.SetCharSet(rFontItem
.GetCharSet());
449 rFont
.SetStyleName(rFontItem
.GetStyleName());
453 static void SetPrevFontStyle( const SfxItemSet
& rSet
, sal_uInt16 nPosture
, sal_uInt16 nWeight
, SvxFont
& rFont
)
456 if( GetWhich( rSet
, nPosture
, nWhich
) )
458 const SvxPostureItem
& rItem
= static_cast<const SvxPostureItem
&>( rSet
.Get( nWhich
) );
459 rFont
.SetItalic( rItem
.GetValue() != ITALIC_NONE
? ITALIC_NORMAL
: ITALIC_NONE
);
462 if( GetWhich( rSet
, nWeight
, nWhich
) )
464 const SvxWeightItem
& rItem
= static_cast<const SvxWeightItem
&>( rSet
.Get( nWhich
) );
465 rFont
.SetWeight( rItem
.GetValue() != WEIGHT_NORMAL
? WEIGHT_BOLD
: WEIGHT_NORMAL
);
469 static void SetPrevFontEscapement(SvxFont
& rFont
, sal_uInt8 nProp
, sal_uInt8 nEscProp
, short nEsc
)
471 rFont
.SetPropr(nProp
);
472 rFont
.SetProprRel(nEscProp
);
473 rFont
.SetEscapement(nEsc
);
476 void SvxFontPrevWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
478 Color aBgColor
= svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
;
479 Color aFgColor
= svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR
, false).nColor
;
480 if (aFgColor
== COL_AUTO
)
481 aFgColor
= aBgColor
.IsDark() ? COL_WHITE
: COL_BLACK
;
482 rRenderContext
.SetBackground(aBgColor
);
483 rRenderContext
.SetTextColor(aFgColor
);
486 void SvxFontPrevWindow::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
488 CustomWidgetController::SetDrawingArea(pDrawingArea
);
489 Size
aPrefSize(getPreviewStripSize(pDrawingArea
->get_ref_device()));
490 pDrawingArea
->set_size_request(aPrefSize
.Width(), aPrefSize
.Height());
492 pImpl
.reset(new FontPrevWin_Impl
);
493 SfxViewShell
* pSh
= SfxViewShell::Current();
496 pImpl
->mpPrinter
= pSh
->GetPrinter();
498 if (!pImpl
->mpPrinter
)
500 pImpl
->mpPrinter
= VclPtr
<Printer
>::Create();
501 pImpl
->mbDelPrinter
= true;
503 initFont(pImpl
->maFont
);
504 initFont(pImpl
->maCJKFont
);
505 initFont(pImpl
->maCTLFont
);
510 SvxFontPrevWindow::SvxFontPrevWindow()
514 SvxFontPrevWindow::~SvxFontPrevWindow()
518 SvxFont
& SvxFontPrevWindow::GetCTLFont()
520 return pImpl
->maCTLFont
;
523 SvxFont
& SvxFontPrevWindow::GetCJKFont()
525 return pImpl
->maCJKFont
;
528 SvxFont
& SvxFontPrevWindow::GetFont()
530 pImpl
->Invalidate100PercentFontWidth(); // because the user might change the size
531 return pImpl
->maFont
;
534 const SvxFont
& SvxFontPrevWindow::GetFont() const
536 return pImpl
->maFont
;
539 void SvxFontPrevWindow::SetPreviewText( const OUString
& rString
)
541 pImpl
->maText
= rString
;
542 pImpl
->mbTextInited
= true;
545 void SvxFontPrevWindow::SetFontNameAsPreviewText()
547 pImpl
->mbUseFontNameAsText
= true;
550 void SvxFontPrevWindow::SetFont( const SvxFont
& rNormalOutFont
, const SvxFont
& rCJKOutFont
, const SvxFont
& rCTLFont
)
552 setFont(rNormalOutFont
, pImpl
->maFont
);
553 setFont(rCJKOutFont
, pImpl
->maCJKFont
);
554 setFont(rCTLFont
, pImpl
->maCTLFont
);
556 pImpl
->Invalidate100PercentFontWidth();
560 void SvxFontPrevWindow::SetColor(const Color
&rColor
)
562 pImpl
->mxColor
= rColor
;
566 void SvxFontPrevWindow::ResetColor()
568 pImpl
->mxColor
.reset();
572 void SvxFontPrevWindow::SetTextLineColor(const Color
&rColor
)
574 pImpl
->mxTextLineColor
= rColor
;
578 void SvxFontPrevWindow::SetOverlineColor(const Color
&rColor
)
580 pImpl
->mxOverlineColor
= rColor
;
584 void SvxFontPrevWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
586 rRenderContext
.Push(vcl::PushFlags::ALL
);
587 rRenderContext
.SetMapMode(MapMode(MapUnit::MapTwip
));
589 ApplySettings(rRenderContext
);
590 rRenderContext
.Erase();
592 Printer
* pPrinter
= pImpl
->mpPrinter
;
593 const SvxFont
& rFont
= pImpl
->maFont
;
594 const SvxFont
& rCJKFont
= pImpl
->maCJKFont
;
595 const SvxFont
& rCTLFont
= pImpl
->maCTLFont
;
599 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
600 const Size
aLogSize(rRenderContext
.GetOutputSize());
602 tools::Rectangle
aRect(Point(0, 0), aLogSize
);
603 rRenderContext
.SetLineColor();
604 rRenderContext
.SetFillColor(rStyleSettings
.GetWindowColor());
605 rRenderContext
.DrawRect(aRect
);
609 if (!pImpl
->mbSelection
&& !pImpl
->mbTextInited
)
611 using namespace css::i18n::ScriptType
;
613 SfxViewShell
* pSh
= SfxViewShell::Current();
615 if (pSh
&& !pImpl
->mbGetSelection
&& !pImpl
->mbUseFontNameAsText
)
617 pImpl
->maText
= removeCRLF(pSh
->GetSelectionText(/*bCompleteWords*/false, /*bOnlyASample*/true));
618 pImpl
->mbGetSelection
= true;
619 pImpl
->mbSelection
= !(pImpl
->maText
.isEmpty());
622 if (!pImpl
->mbSelection
|| pImpl
->mbUseFontNameAsText
)
624 //If we're showing multiple sample texts, then they're all
625 //sample texts. If only showing Latin, continue to use
626 //the fontname as the preview
627 if ((pImpl
->m_bCJKEnabled
) || (pImpl
->m_bCTLEnabled
))
628 pImpl
->maText
= makeRepresentativeTextForFont(LATIN
, rFont
);
630 pImpl
->maText
= rFont
.GetFamilyName();
632 if (pImpl
->m_bCJKEnabled
)
634 if (!pImpl
->maText
.isEmpty())
635 pImpl
->maText
+= " ";
636 pImpl
->maText
+= makeRepresentativeTextForFont(ASIAN
, rCJKFont
);
639 if (pImpl
->m_bCTLEnabled
)
641 if (!pImpl
->maText
.isEmpty())
642 pImpl
->maText
+= " ";
643 pImpl
->maText
+= makeRepresentativeTextForFont(COMPLEX
, rCTLFont
);
647 if (pImpl
->maText
.isEmpty())
648 { // fdo#58427: still no text? let's try that one...
649 pImpl
->maText
= makeRepresentativeTextForFont(LATIN
, rFont
);
652 pImpl
->maText
= removeCRLF(pImpl
->maText
);
654 if (pImpl
->maText
.getLength() > (TEXT_WIDTH
- 1))
656 const sal_Int32 nSpaceIdx
= pImpl
->maText
.indexOf(" ", TEXT_WIDTH
);
658 pImpl
->maText
= pImpl
->maText
.copy(0, nSpaceIdx
);
660 pImpl
->maText
= pImpl
->maText
.copy(0, (TEXT_WIDTH
- 1));
664 // calculate text width scaling
665 pImpl
->ScaleFontWidth(rRenderContext
);
667 pImpl
->CheckScript();
668 Size aTxtSize
= pImpl
->CalcTextSize(rRenderContext
, pPrinter
, rFont
);
670 const Size
aLogSize(rRenderContext
.GetOutputSize());
672 tools::Long nX
= aLogSize
.Width() / 2 - aTxtSize
.Width() / 2;
673 tools::Long nY
= aLogSize
.Height() / 2 - aTxtSize
.Height() / 2;
675 if (nY
+ pImpl
->mnAscent
> aLogSize
.Height())
676 nY
= aLogSize
.Height() - pImpl
->mnAscent
;
678 if (pImpl
->mxBackColor
)
680 tools::Rectangle
aRect(Point(0, 0), aLogSize
);
681 Color aLineCol
= rRenderContext
.GetLineColor();
682 Color aFillCol
= rRenderContext
.GetFillColor();
683 rRenderContext
.SetLineColor();
684 rRenderContext
.SetFillColor(*pImpl
->mxBackColor
);
685 rRenderContext
.DrawRect(aRect
);
686 rRenderContext
.SetLineColor(aLineCol
);
687 rRenderContext
.SetFillColor(aFillCol
);
691 tools::Rectangle
aRect(Point(nX
, nY
), aTxtSize
);
692 Color aLineCol
= rRenderContext
.GetLineColor();
693 Color aFillCol
= rRenderContext
.GetFillColor();
694 rRenderContext
.SetLineColor();
695 rRenderContext
.SetFillColor(*pImpl
->mxColor
);
696 rRenderContext
.DrawRect(aRect
);
697 rRenderContext
.SetLineColor(aLineCol
);
698 rRenderContext
.SetFillColor(aFillCol
);
701 if (pImpl
->mxTextLineColor
)
703 rRenderContext
.SetTextLineColor(*pImpl
->mxTextLineColor
);
706 if (pImpl
->mxOverlineColor
)
708 rRenderContext
.SetOverlineColor(*pImpl
->mxOverlineColor
);
711 tools::Long nStdAscent
= pImpl
->mnAscent
;
716 SvxFont
aSmallFont(rFont
);
717 Size aOldSize
= pImpl
->maCJKFont
.GetFontSize();
718 setFontSize(aSmallFont
);
719 setFontSize(pImpl
->maCJKFont
);
721 tools::Long nStartBracketWidth
= 0;
722 tools::Long nEndBracketWidth
= 0;
723 tools::Long nTextWidth
= 0;
724 if (pImpl
->mcStartBracket
)
726 OUString
sBracket(pImpl
->mcStartBracket
);
727 nStartBracketWidth
= rFont
.GetTextSize(*pPrinter
, sBracket
).Width();
729 if (pImpl
->mcEndBracket
)
731 OUString
sBracket(pImpl
->mcEndBracket
);
732 nEndBracketWidth
= rFont
.GetTextSize(*pPrinter
, sBracket
).Width();
734 nTextWidth
= pImpl
->CalcTextSize(rRenderContext
, pPrinter
, aSmallFont
).Width();
735 tools::Long nResultWidth
= nStartBracketWidth
;
736 nResultWidth
+= nEndBracketWidth
;
737 nResultWidth
+= nTextWidth
;
739 tools::Long _nX
= (aLogSize
.Width() - nResultWidth
) / 2;
740 rRenderContext
.DrawLine(Point(0, nY
), Point(_nX
, nY
));
741 rRenderContext
.DrawLine(Point(_nX
+ nResultWidth
, nY
), Point(aLogSize
.Width(), nY
));
743 tools::Long nSmallAscent
= pImpl
->mnAscent
;
744 tools::Long nOffset
= (nStdAscent
- nSmallAscent
) / 2;
746 if (pImpl
->mcStartBracket
)
748 OUString
sBracket(pImpl
->mcStartBracket
);
749 rFont
.DrawPrev(&rRenderContext
, pPrinter
, Point(_nX
, nY
- nOffset
- 4), sBracket
);
750 _nX
+= nStartBracketWidth
;
753 Point
aTmpPoint1(_nX
, nY
- nSmallAscent
- 2);
754 Point
aTmpPoint2(_nX
, nY
);
755 pImpl
->DrawPrev(rRenderContext
, pPrinter
, aTmpPoint1
, aSmallFont
);
756 pImpl
->DrawPrev(rRenderContext
, pPrinter
, aTmpPoint2
, aSmallFont
);
759 if (pImpl
->mcEndBracket
)
761 Point
aTmpPoint( _nX
+ 1, nY
- nOffset
- 4);
762 OUString
sBracket(pImpl
->mcEndBracket
);
763 rFont
.DrawPrev(&rRenderContext
, pPrinter
, aTmpPoint
, sBracket
);
765 pImpl
->maCJKFont
.SetFontSize(aOldSize
);
770 Color aLineCol
= rRenderContext
.GetLineColor();
772 rRenderContext
.SetLineColor(rFont
.GetColor());
773 rRenderContext
.DrawLine(Point(0, nY
), Point(nX
, nY
));
774 rRenderContext
.DrawLine(Point(nX
+ aTxtSize
.Width(), nY
), Point(aLogSize
.Width(), nY
));
775 rRenderContext
.SetLineColor(aLineCol
);
777 Point
aTmpPoint(nX
, nY
);
778 pImpl
->DrawPrev(rRenderContext
, pPrinter
, aTmpPoint
, rFont
);
781 rRenderContext
.Pop();
784 bool SvxFontPrevWindow::IsTwoLines() const
786 return pImpl
->mbTwoLines
;
789 void SvxFontPrevWindow::SetTwoLines(bool bSet
)
791 pImpl
->mbTwoLines
= bSet
;
794 void SvxFontPrevWindow::SetBrackets(sal_Unicode cStart
, sal_Unicode cEnd
)
796 pImpl
->mcStartBracket
= cStart
;
797 pImpl
->mcEndBracket
= cEnd
;
800 void SvxFontPrevWindow::SetFontWidthScale( sal_uInt16 n
)
802 if (pImpl
->SetFontWidthScale(n
))
806 void SvxFontPrevWindow::AutoCorrectFontColor()
808 Color
aColor(COL_AUTO
);
809 if ( pImpl
->mxBackColor
) aColor
= *pImpl
->mxBackColor
;
810 const bool bIsDark(aColor
.IsDark());
812 aColor
= pImpl
->maFont
.GetColor();
813 if (aColor
== COL_AUTO
)
814 pImpl
->maFont
.SetColor( bIsDark
? COL_WHITE
: COL_BLACK
);
815 aColor
= pImpl
->maCJKFont
.GetColor();
816 if (aColor
== COL_AUTO
)
817 pImpl
->maCJKFont
.SetColor( bIsDark
? COL_WHITE
: COL_BLACK
);
818 aColor
= pImpl
->maCTLFont
.GetColor();
819 if (aColor
== COL_AUTO
)
820 pImpl
->maCTLFont
.SetColor( bIsDark
? COL_WHITE
: COL_BLACK
);
823 void SvxFontPrevWindow::SetFontSize( const SfxItemSet
& rSet
, sal_uInt16 nSlot
, SvxFont
& rFont
)
827 if (GetWhich(rSet
, nSlot
, nWhich
))
829 nH
= OutputDevice::LogicToLogic(static_cast<const SvxFontHeightItem
&>(rSet
.Get(nWhich
)).GetHeight(),
830 rSet
.GetPool()->GetMetric(nWhich
),
834 nH
= 240;// as default 12pt
836 rFont
.SetFontSize(Size(0, nH
));
839 void SvxFontPrevWindow::SetFontLang(const SfxItemSet
& rSet
, sal_uInt16 nSlot
, SvxFont
& rFont
)
843 if( GetWhich( rSet
, nSlot
, nWhich
) )
844 nLang
= static_cast<const SvxLanguageItem
&>(rSet
.Get(nWhich
)).GetLanguage();
846 nLang
= LANGUAGE_NONE
;
847 rFont
.SetLanguage(nLang
);
850 void SvxFontPrevWindow::SetFromItemSet(const SfxItemSet
&rSet
, bool bPreviewBackgroundToCharacter
)
853 SvxFont
& rFont
= GetFont();
854 SvxFont
& rCJKFont
= GetCJKFont();
855 SvxFont
& rCTLFont
= GetCTLFont();
858 if( GetWhich( rSet
, SID_CHAR_DLG_PREVIEW_STRING
, nWhich
) )
860 const SfxStringItem
& rItem
= static_cast<const SfxStringItem
&>( rSet
.Get( nWhich
) );
861 const OUString
& aString
= rItem
.GetValue();
862 if( !aString
.isEmpty() )
863 SetPreviewText( aString
);
865 SetFontNameAsPreviewText();
869 FontLineStyle eUnderline
;
870 if( GetWhich( rSet
, SID_ATTR_CHAR_UNDERLINE
, nWhich
) )
872 const SvxUnderlineItem
& rItem
= static_cast<const SvxUnderlineItem
&>( rSet
.Get( nWhich
) );
873 eUnderline
= rItem
.GetValue();
876 eUnderline
= LINESTYLE_NONE
;
878 rFont
.SetUnderline( eUnderline
);
879 rCJKFont
.SetUnderline( eUnderline
);
880 rCTLFont
.SetUnderline( eUnderline
);
883 FontLineStyle eOverline
;
884 if( GetWhich( rSet
, SID_ATTR_CHAR_OVERLINE
, nWhich
) )
886 const SvxOverlineItem
& rItem
= static_cast<const SvxOverlineItem
&>( rSet
.Get( nWhich
) );
887 eOverline
= rItem
.GetValue();
890 eOverline
= LINESTYLE_NONE
;
892 rFont
.SetOverline( eOverline
);
893 rCJKFont
.SetOverline( eOverline
);
894 rCTLFont
.SetOverline( eOverline
);
897 FontStrikeout eStrikeout
;
898 if( GetWhich( rSet
, SID_ATTR_CHAR_STRIKEOUT
, nWhich
) )
900 const SvxCrossedOutItem
& rItem
= static_cast<const SvxCrossedOutItem
&>( rSet
.Get( nWhich
) );
901 eStrikeout
= rItem
.GetValue();
904 eStrikeout
= STRIKEOUT_NONE
;
906 rFont
.SetStrikeout( eStrikeout
);
907 rCJKFont
.SetStrikeout( eStrikeout
);
908 rCTLFont
.SetStrikeout( eStrikeout
);
911 if( GetWhich( rSet
, SID_ATTR_CHAR_WORDLINEMODE
, nWhich
) )
913 const SvxWordLineModeItem
& rItem
= static_cast<const SvxWordLineModeItem
&>( rSet
.Get( nWhich
) );
914 rFont
.SetWordLineMode( rItem
.GetValue() );
915 rCJKFont
.SetWordLineMode( rItem
.GetValue() );
916 rCTLFont
.SetWordLineMode( rItem
.GetValue() );
920 if( GetWhich( rSet
, SID_ATTR_CHAR_EMPHASISMARK
, nWhich
) )
922 const SvxEmphasisMarkItem
& rItem
= static_cast<const SvxEmphasisMarkItem
&>( rSet
.Get( nWhich
) );
923 FontEmphasisMark eMark
= rItem
.GetEmphasisMark();
924 rFont
.SetEmphasisMark( eMark
);
925 rCJKFont
.SetEmphasisMark( eMark
);
926 rCTLFont
.SetEmphasisMark( eMark
);
930 if( GetWhich( rSet
, SID_ATTR_CHAR_RELIEF
, nWhich
) )
932 const SvxCharReliefItem
& rItem
= static_cast<const SvxCharReliefItem
&>( rSet
.Get( nWhich
) );
933 FontRelief eFontRelief
= rItem
.GetValue();
934 rFont
.SetRelief( eFontRelief
);
935 rCJKFont
.SetRelief( eFontRelief
);
936 rCTLFont
.SetRelief( eFontRelief
);
940 if( GetWhich( rSet
, SID_ATTR_CHAR_CASEMAP
, nWhich
) )
942 const SvxCaseMapItem
& rItem
= static_cast<const SvxCaseMapItem
&>( rSet
.Get( nWhich
) );
943 SvxCaseMap eCaseMap
= rItem
.GetValue();
944 rFont
.SetCaseMap( eCaseMap
);
945 rCJKFont
.SetCaseMap( eCaseMap
);
946 // #i78474# small caps do not exist in CTL fonts
947 rCTLFont
.SetCaseMap( eCaseMap
== SvxCaseMap::SmallCaps
? SvxCaseMap::NotMapped
: eCaseMap
);
951 if( GetWhich( rSet
, SID_ATTR_CHAR_CONTOUR
, nWhich
) )
953 const SvxContourItem
& rItem
= static_cast<const SvxContourItem
&>( rSet
.Get( nWhich
) );
954 bool bOutline
= rItem
.GetValue();
955 rFont
.SetOutline( bOutline
);
956 rCJKFont
.SetOutline( bOutline
);
957 rCTLFont
.SetOutline( bOutline
);
961 if( GetWhich( rSet
, SID_ATTR_CHAR_SHADOWED
, nWhich
) )
963 const SvxShadowedItem
& rItem
= static_cast<const SvxShadowedItem
&>( rSet
.Get( nWhich
) );
964 bool bShadow
= rItem
.GetValue();
965 rFont
.SetShadow( bShadow
);
966 rCJKFont
.SetShadow( bShadow
);
967 rCTLFont
.SetShadow( bShadow
);
972 if( GetWhich( rSet
, bPreviewBackgroundToCharacter
? SID_ATTR_BRUSH
: SID_ATTR_BRUSH_CHAR
, nWhich
) )
974 const SvxBrushItem
& rBrush
= static_cast<const SvxBrushItem
&>( rSet
.Get( nWhich
) );
975 const Color
& rColor
= rBrush
.GetColor();
976 bTransparent
= rColor
.IsTransparent();
977 rFont
.SetFillColor( rColor
);
978 rCJKFont
.SetFillColor( rColor
);
979 rCTLFont
.SetFillColor( rColor
);
984 rFont
.SetTransparent( bTransparent
);
985 rCJKFont
.SetTransparent( bTransparent
);
986 rCTLFont
.SetTransparent( bTransparent
);
988 if( !bPreviewBackgroundToCharacter
)
990 bool bBackColorFound
= false;
991 if( GetWhich( rSet
, SID_ATTR_BRUSH
, nWhich
) )
993 const SvxBrushItem
& rBrush
= static_cast<const SvxBrushItem
&>( rSet
.Get( nWhich
) );
994 if (GPOS_NONE
== rBrush
.GetGraphicPos())
996 const Color
& rBrushColor
= rBrush
.GetColor();
997 if (rBrushColor
!= COL_TRANSPARENT
)
999 pImpl
->mxBackColor
= rBrush
.GetColor();
1000 bBackColorFound
= true;
1004 if (!bBackColorFound
)
1005 pImpl
->mxBackColor
= svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
;
1009 SetPrevFont( rSet
, SID_ATTR_CHAR_FONT
, rFont
);
1010 SetPrevFont( rSet
, SID_ATTR_CHAR_CJK_FONT
, rCJKFont
);
1011 SetPrevFont( rSet
, SID_ATTR_CHAR_CTL_FONT
, rCTLFont
);
1014 SetPrevFontStyle( rSet
, SID_ATTR_CHAR_POSTURE
, SID_ATTR_CHAR_WEIGHT
, rFont
);
1015 SetPrevFontStyle( rSet
, SID_ATTR_CHAR_CJK_POSTURE
, SID_ATTR_CHAR_CJK_WEIGHT
, rCJKFont
);
1016 SetPrevFontStyle( rSet
, SID_ATTR_CHAR_CTL_POSTURE
, SID_ATTR_CHAR_CTL_WEIGHT
, rCTLFont
);
1019 SetFontSize( rSet
, SID_ATTR_CHAR_FONTHEIGHT
, rFont
);
1020 SetFontSize( rSet
, SID_ATTR_CHAR_CJK_FONTHEIGHT
, rCJKFont
);
1021 SetFontSize( rSet
, SID_ATTR_CHAR_CTL_FONTHEIGHT
, rCTLFont
);
1024 SetFontLang( rSet
, SID_ATTR_CHAR_LANGUAGE
, rFont
);
1025 SetFontLang( rSet
, SID_ATTR_CHAR_CJK_LANGUAGE
, rCJKFont
);
1026 SetFontLang( rSet
, SID_ATTR_CHAR_CTL_LANGUAGE
, rCTLFont
);
1029 if( GetWhich( rSet
, SID_ATTR_CHAR_COLOR
, nWhich
) )
1031 const SvxColorItem
& rItem
= static_cast<const SvxColorItem
&>( rSet
.Get( nWhich
) );
1032 Color
aCol( rItem
.GetValue() );
1033 rFont
.SetColor( aCol
);
1035 rCJKFont
.SetColor( aCol
);
1036 rCTLFont
.SetColor( aCol
);
1038 AutoCorrectFontColor(); // handle color COL_AUTO
1042 if( GetWhich( rSet
, SID_ATTR_CHAR_KERNING
, nWhich
) )
1044 const SvxKerningItem
& rItem
= static_cast<const SvxKerningItem
&>( rSet
.Get( nWhich
) );
1045 short nKern
= static_cast<short>(OutputDevice::LogicToLogic(rItem
.GetValue(), rSet
.GetPool()->GetMetric(nWhich
), MapUnit::MapTwip
));
1046 rFont
.SetFixKerning( nKern
);
1047 rCJKFont
.SetFixKerning( nKern
);
1048 rCTLFont
.SetFixKerning( nKern
);
1052 const sal_uInt8 nProp
= 100;
1055 if( GetWhich( rSet
, SID_ATTR_CHAR_ESCAPEMENT
, nWhich
) )
1057 const SvxEscapementItem
& rItem
= static_cast<const SvxEscapementItem
&>( rSet
.Get( nWhich
) );
1058 nEsc
= rItem
.GetEsc();
1059 nEscProp
= rItem
.GetProportionalHeight();
1061 if( nEsc
== DFLT_ESC_AUTO_SUPER
)
1062 nEsc
= DFLT_ESC_SUPER
;
1063 else if( nEsc
== DFLT_ESC_AUTO_SUB
)
1064 nEsc
= DFLT_ESC_SUB
;
1071 SetPrevFontEscapement( rFont
, nProp
, nEscProp
, nEsc
);
1072 SetPrevFontEscapement( rCJKFont
, nProp
, nEscProp
, nEsc
);
1073 SetPrevFontEscapement( rCTLFont
, nProp
, nEscProp
, nEsc
);
1076 if( GetWhich( rSet
, SID_ATTR_CHAR_SCALEWIDTH
, nWhich
) )
1078 const SvxCharScaleWidthItem
&rItem
= static_cast<const SvxCharScaleWidthItem
&>( rSet
.Get( nWhich
) );
1079 SetFontWidthScale( rItem
.GetValue() );
1085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */