diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-04-07 12:21:47 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-04-21 10:19:41 +0200 |
commit | 2e0a32b51681fb356699b4a722f461f55a46b890 (patch) | |
tree | ac96e726d777aba5b6f57513f5b00b3d766e34d3 /svtools | |
parent | 6c559b122add7db32b06faa15854df58b30460f6 (diff) |
weld FontNameBox
with custom row rendering
Change-Id: Ia909b5b9ad56b6ea4611e9ea0a1e2cb0064a8cd4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91841
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svtools')
-rw-r--r-- | svtools/inc/pch/precompiled_svt.hxx | 6 | ||||
-rw-r--r-- | svtools/source/control/ctrlbox.cxx | 503 |
2 files changed, 307 insertions, 202 deletions
diff --git a/svtools/inc/pch/precompiled_svt.hxx b/svtools/inc/pch/precompiled_svt.hxx index 2797de08da3a..40cfe76421db 100644 --- a/svtools/inc/pch/precompiled_svt.hxx +++ b/svtools/inc/pch/precompiled_svt.hxx @@ -13,7 +13,7 @@ manual changes will be rewritten by the next run of update_pch.sh (which presumably also fixes all possible problems, so it's usually better to use it). - Generated on 2020-02-19 12:45:36 using: + Generated on 2020-04-07 17:26:37 using: ./bin/update_pch svtools svt --cutoff=4 --exclude:system --include:module --exclude:local If after updating build fails, use the following command to locate conflicting headers: @@ -37,6 +37,7 @@ #include <math.h> #include <memory> #include <new> +#include <optional> #include <ostream> #include <set> #include <stddef.h> @@ -102,7 +103,6 @@ #include <vcl/builder.hxx> #include <vcl/button.hxx> #include <vcl/checksum.hxx> -#include <vcl/combobox.hxx> #include <vcl/commandevent.hxx> #include <vcl/ctrl.hxx> #include <vcl/dllapi.h> @@ -162,6 +162,7 @@ #include <basegfx/tuple/b2dtuple.hxx> #include <basegfx/tuple/b2ituple.hxx> #include <basegfx/tuple/b3dtuple.hxx> +#include <basegfx/utils/common.hxx> #include <basegfx/vector/b2dsize.hxx> #include <basegfx/vector/b2dvector.hxx> #include <basegfx/vector/b2enums.hxx> @@ -314,7 +315,6 @@ #include <i18nutil/transliteration.hxx> #include <o3tl/cow_wrapper.hxx> #include <o3tl/deleter.hxx> -#include <optional> #include <o3tl/safeint.hxx> #include <o3tl/strong_int.hxx> #include <o3tl/typed_flags_set.hxx> diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx index 51895051551f..d1b9943dfd2c 100644 --- a/svtools/source/control/ctrlbox.cxx +++ b/svtools/source/control/ctrlbox.cxx @@ -61,7 +61,6 @@ #define IMGOUTERTEXTSPACE 5 #define EXTRAFONTSIZE 5 #define GAPTOEXTRAPREVIEW 10 -#define MAXPREVIEWWIDTH 120 #define MINGAPWIDTH 2 #define FONTNAMEBOXMRUENTRIESFILE "/user/config/fontnameboxmruentries" @@ -329,31 +328,43 @@ void DrawLine( OutputDevice& rDev, const basegfx::B2DPoint& rP1, const basegfx:: } -FontNameBox::FontNameBox( vcl::Window* pParent, WinBits nWinStyle ) : - ComboBox( pParent, nWinStyle ) +static Size gUserItemSz; +static int gFontNameBoxes; +static size_t gPreviewsPerDevice; +static std::vector<VclPtr<VirtualDevice>> gFontPreviewVirDevs; +static std::vector<OUString> gRenderedFontNames; + +FontNameBox::FontNameBox(std::unique_ptr<weld::ComboBox> p) + : m_xComboBox(std::move(p)) + , mnPreviewProgress(0) + , mbWYSIWYG(false) + , maUpdateIdle("FontNameBox Preview Update") { - mbWYSIWYG = false; + ++gFontNameBoxes; InitFontMRUEntriesFile(); -} -FontNameBox::~FontNameBox() -{ - disposeOnce(); + maUpdateIdle.SetPriority(TaskPriority::LOWEST); + maUpdateIdle.SetInvokeHandler(LINK(this, FontNameBox, UpdateHdl)); } -void FontNameBox::dispose() +FontNameBox::~FontNameBox() { if (mpFontList) { SaveMRUEntries (maFontMRUEntriesFile); ImplDestroyFontList(); } - ComboBox::dispose(); + --gFontNameBoxes; + if (!gFontNameBoxes) + { + gFontPreviewVirDevs.clear(); + gRenderedFontNames.clear(); + } } -void FontNameBox::SaveMRUEntries( const OUString& aFontMRUEntriesFile ) const +void FontNameBox::SaveMRUEntries(const OUString& aFontMRUEntriesFile) const { - OString aEntries(OUStringToOString(GetMRUEntries(), + OString aEntries(OUStringToOString(m_xComboBox->get_mru_entries(), RTL_TEXTENCODING_UTF8)); if (aEntries.isEmpty() || aFontMRUEntriesFile.isEmpty()) @@ -392,7 +403,7 @@ void FontNameBox::LoadMRUEntries( const OUString& aFontMRUEntriesFile ) aStream.ReadLine( aLine ); OUString aEntries = OStringToOUString(aLine, RTL_TEXTENCODING_UTF8); - SetMRUEntries( aEntries ); + m_xComboBox->set_mru_entries(aEntries); } void FontNameBox::InitFontMRUEntriesFile() @@ -415,61 +426,71 @@ void FontNameBox::ImplDestroyFontList() void FontNameBox::Fill( const FontList* pList ) { // store old text and clear box - OUString aOldText = GetText(); - OUString rEntries = GetMRUEntries(); + OUString aOldText = m_xComboBox->get_active_text(); + OUString rEntries = m_xComboBox->get_mru_entries(); bool bLoadFromFile = rEntries.isEmpty(); - Clear(); + m_xComboBox->freeze(); + m_xComboBox->clear(); ImplDestroyFontList(); mpFontList.reset(new ImplFontList); // insert fonts - sal_uInt16 nFontCount = pList->GetFontNameCount(); - for ( sal_uInt16 i = 0; i < nFontCount; i++ ) + size_t nFontCount = pList->GetFontNameCount(); + for (size_t i = 0; i < nFontCount; ++i) { - const FontMetric& rFontMetric = pList->GetFontName( i ); - sal_Int32 nIndex = InsertEntry( rFontMetric.GetFamilyName() ); - if ( nIndex < static_cast<sal_Int32>(mpFontList->size()) ) { - ImplFontList::iterator it = mpFontList->begin(); - ::std::advance( it, nIndex ); - mpFontList->insert( it, rFontMetric ); - } else { - mpFontList->push_back( rFontMetric ); - } + const FontMetric& rFontMetric = pList->GetFontName(i); + m_xComboBox->append(OUString::number(i), rFontMetric.GetFamilyName()); + mpFontList->push_back(rFontMetric); } - if ( bLoadFromFile ) - LoadMRUEntries (maFontMRUEntriesFile); + if (bLoadFromFile) + LoadMRUEntries(maFontMRUEntriesFile); else - SetMRUEntries( rEntries ); + m_xComboBox->set_mru_entries(rEntries); - ImplCalcUserItemSize(); + m_xComboBox->thaw(); + + if (mbWYSIWYG) + { + mnPreviewProgress = 0; + maUpdateIdle.Start(); + } // restore text if (!aOldText.isEmpty()) - SetText( aOldText ); + set_active_or_entry_text(aOldText); } -void FontNameBox::EnableWYSIWYG( bool bEnable ) +void FontNameBox::EnableWYSIWYG() { - if ( bEnable != mbWYSIWYG ) + if (mbWYSIWYG) + return; + mbWYSIWYG = true; + + static bool bGlobalsInited; + if (!bGlobalsInited) { - mbWYSIWYG = bEnable; - EnableUserDraw( mbWYSIWYG ); - ImplCalcUserItemSize(); + gUserItemSz = Size(m_xComboBox->get_approximate_digit_width() * 52, m_xComboBox->get_text_height()); + gUserItemSz.setHeight(gUserItemSz.Height() * 16); + gUserItemSz.setHeight(gUserItemSz.Height() / 10); + + size_t nMaxDeviceHeight = SAL_MAX_INT16 / 2; // see limitXCreatePixmap + gPreviewsPerDevice = nMaxDeviceHeight / gUserItemSz.Height(); + + bGlobalsInited = true; } + + m_xComboBox->connect_custom_get_size(LINK(this, FontNameBox, CustomGetSizeHdl)); + m_xComboBox->connect_custom_render(LINK(this, FontNameBox, CustomRenderHdl)); + m_xComboBox->set_custom_renderer(); + + mbWYSIWYG = true; } -void FontNameBox::ImplCalcUserItemSize() +IMPL_STATIC_LINK_NOARG(FontNameBox, CustomGetSizeHdl, weld::ComboBox::get_size_args, Size) { - Size aUserItemSz; - if ( mbWYSIWYG && mpFontList ) - { - aUserItemSz = Size(MAXPREVIEWWIDTH, GetTextHeight() ); - aUserItemSz.setHeight( aUserItemSz.Height() * 16 ); - aUserItemSz.setHeight( aUserItemSz.Height() / 10 ); - } - SetUserItemSize( aUserItemSz ); + return gUserItemSz; } namespace @@ -500,192 +521,275 @@ namespace } } -void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt ) +IMPL_LINK_NOARG(FontNameBox, UpdateHdl, Timer*, void) { - assert( mpFontList ); + CachePreview(mnPreviewProgress++, nullptr); + if (mnPreviewProgress < mpFontList->size()) + maUpdateIdle.Start(); +} - FontMetric& rFontMetric = (*mpFontList)[ rUDEvt.GetItemId() ]; - Point aTopLeft = rUDEvt.GetRect().TopLeft(); - long nX = aTopLeft.X(); - long nH = rUDEvt.GetRect().GetHeight(); +static void DrawPreview(const FontMetric& rFontMetric, const Point& rTopLeft, OutputDevice& rDevice, bool bSelected) +{ + rDevice.Push(PushFlags::TEXTCOLOR); - if ( mbWYSIWYG ) - { - nX += IMGOUTERTEXTSPACE; + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + if (bSelected) + rDevice.SetTextColor(rStyleSettings.GetHighlightTextColor()); + else + rDevice.SetTextColor(rStyleSettings.GetDialogTextColor()); - const bool bSymbolFont = isSymbolFont(rFontMetric); - vcl::RenderContext* pRenderContext = rUDEvt.GetRenderContext(); + long nX = rTopLeft.X(); + long nH = gUserItemSz.Height(); - Color aTextColor = pRenderContext->GetTextColor(); - vcl::Font aOldFont(pRenderContext->GetFont()); - Size aSize( aOldFont.GetFontSize() ); - aSize.AdjustHeight(EXTRAFONTSIZE ); - vcl::Font aFont( rFontMetric ); - aFont.SetFontSize( aSize ); - pRenderContext->SetFont(aFont); - pRenderContext->SetTextColor(aTextColor); + nX += IMGOUTERTEXTSPACE; - bool bUsingCorrectFont = true; - tools::Rectangle aTextRect; + const bool bSymbolFont = isSymbolFont(rFontMetric); - // Preview the font name - const OUString& sFontName = rFontMetric.GetFamilyName(); + vcl::Font aOldFont(rDevice.GetFont()); + Size aSize( aOldFont.GetFontSize() ); + aSize.AdjustHeight(EXTRAFONTSIZE ); + vcl::Font aFont( rFontMetric ); + aFont.SetFontSize( aSize ); + rDevice.SetFont(aFont); - //If it shouldn't or can't draw its own name because it doesn't have the glyphs - if (!canRenderNameOfSelectedFont(*pRenderContext)) - bUsingCorrectFont = false; - else - { - //Make sure it fits in the available height, shrinking the font if necessary - bUsingCorrectFont = shrinkFontToFit(sFontName, nH, aFont, *pRenderContext, aTextRect) != 0; - } + bool bUsingCorrectFont = true; + tools::Rectangle aTextRect; - if (!bUsingCorrectFont) - { - pRenderContext->SetFont(aOldFont); - pRenderContext->GetTextBoundRect(aTextRect, sFontName); - } + // Preview the font name + const OUString& sFontName = rFontMetric.GetFamilyName(); - long nTextHeight = aTextRect.GetHeight(); - long nDesiredGap = (nH-nTextHeight)/2; - long nVertAdjust = nDesiredGap - aTextRect.Top(); - Point aPos( nX, aTopLeft.Y() + nVertAdjust ); - pRenderContext->DrawText(aPos, sFontName); - long nTextX = aPos.X() + aTextRect.GetWidth() + GAPTOEXTRAPREVIEW; + //If it shouldn't or can't draw its own name because it doesn't have the glyphs + if (!canRenderNameOfSelectedFont(rDevice)) + bUsingCorrectFont = false; + else + { + //Make sure it fits in the available height, shrinking the font if necessary + bUsingCorrectFont = shrinkFontToFit(sFontName, nH, aFont, rDevice, aTextRect) != 0; + } - if (!bUsingCorrectFont) - pRenderContext->SetFont(aFont); + if (!bUsingCorrectFont) + { + rDevice.SetFont(aOldFont); + rDevice.GetTextBoundRect(aTextRect, sFontName); + } - OUString sSampleText; + long nTextHeight = aTextRect.GetHeight(); + long nDesiredGap = (nH-nTextHeight)/2; + long nVertAdjust = nDesiredGap - aTextRect.Top(); + Point aPos( nX, rTopLeft.Y() + nVertAdjust ); + rDevice.DrawText(aPos, sFontName); + long nTextX = aPos.X() + aTextRect.GetWidth() + GAPTOEXTRAPREVIEW; - if (!bSymbolFont) - { - const bool bNameBeginsWithLatinText = rFontMetric.GetFamilyName()[0] <= 'z'; + if (!bUsingCorrectFont) + rDevice.SetFont(aFont); - if (bNameBeginsWithLatinText || !bUsingCorrectFont) - sSampleText = makeShortRepresentativeTextForSelectedFont(*pRenderContext); - } + OUString sSampleText; + + if (!bSymbolFont) + { + const bool bNameBeginsWithLatinText = rFontMetric.GetFamilyName()[0] <= 'z'; - //If we're not a symbol font, but could neither render our own name and - //we can't determine what script it would like to render, then try a - //few well known scripts - if (sSampleText.isEmpty() && !bUsingCorrectFont) + if (bNameBeginsWithLatinText || !bUsingCorrectFont) + sSampleText = makeShortRepresentativeTextForSelectedFont(rDevice); + } + + //If we're not a symbol font, but could neither render our own name and + //we can't determine what script it would like to render, then try a + //few well known scripts + if (sSampleText.isEmpty() && !bUsingCorrectFont) + { + static const UScriptCode aScripts[] = { - static const UScriptCode aScripts[] = - { - USCRIPT_ARABIC, - USCRIPT_HEBREW, - - USCRIPT_BENGALI, - USCRIPT_GURMUKHI, - USCRIPT_GUJARATI, - USCRIPT_ORIYA, - USCRIPT_TAMIL, - USCRIPT_TELUGU, - USCRIPT_KANNADA, - USCRIPT_MALAYALAM, - USCRIPT_SINHALA, - USCRIPT_DEVANAGARI, - - USCRIPT_THAI, - USCRIPT_LAO, - USCRIPT_GEORGIAN, - USCRIPT_TIBETAN, - USCRIPT_SYRIAC, - USCRIPT_MYANMAR, - USCRIPT_ETHIOPIC, - USCRIPT_KHMER, - USCRIPT_MONGOLIAN, - - USCRIPT_KOREAN, - USCRIPT_JAPANESE, - USCRIPT_HAN, - USCRIPT_SIMPLIFIED_HAN, - USCRIPT_TRADITIONAL_HAN, - - USCRIPT_GREEK - }; - - for (const UScriptCode& rScript : aScripts) + USCRIPT_ARABIC, + USCRIPT_HEBREW, + + USCRIPT_BENGALI, + USCRIPT_GURMUKHI, + USCRIPT_GUJARATI, + USCRIPT_ORIYA, + USCRIPT_TAMIL, + USCRIPT_TELUGU, + USCRIPT_KANNADA, + USCRIPT_MALAYALAM, + USCRIPT_SINHALA, + USCRIPT_DEVANAGARI, + + USCRIPT_THAI, + USCRIPT_LAO, + USCRIPT_GEORGIAN, + USCRIPT_TIBETAN, + USCRIPT_SYRIAC, + USCRIPT_MYANMAR, + USCRIPT_ETHIOPIC, + USCRIPT_KHMER, + USCRIPT_MONGOLIAN, + + USCRIPT_KOREAN, + USCRIPT_JAPANESE, + USCRIPT_HAN, + USCRIPT_SIMPLIFIED_HAN, + USCRIPT_TRADITIONAL_HAN, + + USCRIPT_GREEK + }; + + for (const UScriptCode& rScript : aScripts) + { + OUString sText = makeShortRepresentativeTextForScript(rScript); + if (!sText.isEmpty()) { - OUString sText = makeShortRepresentativeTextForScript(rScript); - if (!sText.isEmpty()) + bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(aFont, sText)); + if (bHasSampleTextGlyphs) { - bool bHasSampleTextGlyphs = (-1 == pRenderContext->HasGlyphs(aFont, sText)); - if (bHasSampleTextGlyphs) - { - sSampleText = sText; - break; - } + sSampleText = sText; + break; } } + } - static const UScriptCode aMinimalScripts[] = - { - USCRIPT_HEBREW, //e.g. biblical hebrew - USCRIPT_GREEK - }; + static const UScriptCode aMinimalScripts[] = + { + USCRIPT_HEBREW, //e.g. biblical hebrew + USCRIPT_GREEK + }; - for (const UScriptCode& rMinimalScript : aMinimalScripts) + for (const UScriptCode& rMinimalScript : aMinimalScripts) + { + OUString sText = makeShortMinimalTextForScript(rMinimalScript); + if (!sText.isEmpty()) { - OUString sText = makeShortMinimalTextForScript(rMinimalScript); - if (!sText.isEmpty()) + bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(aFont, sText)); + if (bHasSampleTextGlyphs) { - bool bHasSampleTextGlyphs = (-1 == pRenderContext->HasGlyphs(aFont, sText)); - if (bHasSampleTextGlyphs) - { - sSampleText = sText; - break; - } + sSampleText = sText; + break; } } } + } - //If we're a symbol font, or for some reason the font still couldn't - //render something representative of what it would like to render then - //make up some semi-random text that it *can* display - if (bSymbolFont || (!bUsingCorrectFont && sSampleText.isEmpty())) - sSampleText = makeShortRepresentativeSymbolTextForSelectedFont(*pRenderContext); + //If we're a symbol font, or for some reason the font still couldn't + //render something representative of what it would like to render then + //make up some semi-random text that it *can* display + if (bSymbolFont || (!bUsingCorrectFont && sSampleText.isEmpty())) + sSampleText = makeShortRepresentativeSymbolTextForSelectedFont(rDevice); - if (!sSampleText.isEmpty()) - { - const Size &rItemSize = rUDEvt.GetWindow()->GetOutputSize(); + if (!sSampleText.isEmpty()) + { + const Size &rItemSize = gUserItemSz; - //leave a little border at the edge - long nSpace = rItemSize.Width() - nTextX - IMGOUTERTEXTSPACE; - if (nSpace >= 0) + //leave a little border at the edge + long nSpace = rItemSize.Width() - nTextX - IMGOUTERTEXTSPACE; + if (nSpace >= 0) + { + //Make sure it fits in the available height, and get how wide that would be + long nWidth = shrinkFontToFit(sSampleText, nH, aFont, rDevice, aTextRect); + //Chop letters off until it fits in the available width + while (nWidth > nSpace || nWidth > gUserItemSz.Width()) { - //Make sure it fits in the available height, and get how wide that would be - long nWidth = shrinkFontToFit(sSampleText, nH, aFont, *pRenderContext, aTextRect); - //Chop letters off until it fits in the available width - while (nWidth > nSpace || nWidth > MAXPREVIEWWIDTH) - { - sSampleText = sSampleText.copy(0, sSampleText.getLength()-1); - nWidth = pRenderContext->GetTextBoundRect(aTextRect, sSampleText) ? - aTextRect.GetWidth() : 0; - } + sSampleText = sSampleText.copy(0, sSampleText.getLength()-1); + nWidth = rDevice.GetTextBoundRect(aTextRect, sSampleText) ? + aTextRect.GetWidth() : 0; + } - //center the text on the line - if (!sSampleText.isEmpty() && nWidth) - { - nTextHeight = aTextRect.GetHeight(); - nDesiredGap = (nH-nTextHeight)/2; - nVertAdjust = nDesiredGap - aTextRect.Top(); - aPos = Point(nTextX + nSpace - nWidth, aTopLeft.Y() + nVertAdjust); - pRenderContext->DrawText(aPos, sSampleText); - } + //center the text on the line + if (!sSampleText.isEmpty() && nWidth) + { + nTextHeight = aTextRect.GetHeight(); + nDesiredGap = (nH-nTextHeight)/2; + nVertAdjust = nDesiredGap - aTextRect.Top(); + aPos = Point(nTextX + nSpace - nWidth, rTopLeft.Y() + nVertAdjust); + rDevice.DrawText(aPos, sSampleText); } } + } + + rDevice.SetFont(aOldFont); + rDevice.Pop(); +} + +OutputDevice& FontNameBox::CachePreview(size_t nIndex, Point* pTopLeft) +{ + SolarMutexGuard aGuard; + const FontMetric& rFontMetric = (*mpFontList)[nIndex]; + const OUString& rFontName = rFontMetric.GetFamilyName(); + + size_t nPreviewIndex; + auto xFind = std::find(gRenderedFontNames.begin(), gRenderedFontNames.end(), rFontName); + bool bPreviewAvailable = xFind != gRenderedFontNames.end(); + if (!bPreviewAvailable) + { + nPreviewIndex = gRenderedFontNames.size(); + gRenderedFontNames.push_back(rFontName); + } + else + nPreviewIndex = std::distance(gRenderedFontNames.begin(), xFind); + + size_t nPage = nPreviewIndex / gPreviewsPerDevice; + size_t nIndexInPage = nPreviewIndex - (nPage * gPreviewsPerDevice); + + Point aTopLeft(0, gUserItemSz.Height() * nIndexInPage); + + if (!bPreviewAvailable) + { + if (nPage >= gFontPreviewVirDevs.size()) + { + gFontPreviewVirDevs.emplace_back(m_xComboBox->create_render_virtual_device()); + VirtualDevice& rDevice = *gFontPreviewVirDevs.back(); + rDevice.SetOutputSizePixel(Size(gUserItemSz.Width(), gUserItemSz.Height() * gPreviewsPerDevice)); + if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice())) + pDefaultDevice->SetPointFont(rDevice, m_xComboBox->get_font()); + assert(gFontPreviewVirDevs.size() == nPage + 1); + } + + DrawPreview(rFontMetric, aTopLeft, *gFontPreviewVirDevs.back(), false); + } + + if (pTopLeft) + *pTopLeft = aTopLeft; + + return *gFontPreviewVirDevs[nPage]; +} + +IMPL_LINK(FontNameBox, CustomRenderHdl, weld::ComboBox::render_args, aPayload, void) +{ + vcl::RenderContext& rRenderContext = std::get<0>(aPayload); + const ::tools::Rectangle& rRect = std::get<1>(aPayload); + bool bSelected = std::get<2>(aPayload); + const OUString& rId = std::get<3>(aPayload); + + sal_uInt32 nIndex = rId.toUInt32(); + + Point aDestPoint(rRect.TopLeft()); + auto nMargin = (rRect.GetHeight() - gUserItemSz.Height()) / 2; + aDestPoint.AdjustY(nMargin); - pRenderContext->SetFont(aOldFont); - DrawEntry( rUDEvt, false, false); // draw separator + if (bSelected) + { + const FontMetric& rFontMetric = (*mpFontList)[nIndex]; + DrawPreview(rFontMetric, aDestPoint, rRenderContext, true); } else { - DrawEntry( rUDEvt, true, true ); + // use cache of unselected entries + Point aTopLeft; + OutputDevice& rDevice = CachePreview(nIndex, &aTopLeft); + + rRenderContext.DrawOutDev(aDestPoint, gUserItemSz, + aTopLeft, gUserItemSz, + rDevice); } } +void FontNameBox::set_active_or_entry_text(const OUString& rText) +{ + const int nFound = m_xComboBox->find_text(rText); + if (nFound != -1) + m_xComboBox->set_active(nFound); + else + m_xComboBox->set_entry_text(rText); +} + FontStyleBox::FontStyleBox(std::unique_ptr<weld::ComboBox> p) : m_xComboBox(std::move(p)) { @@ -866,9 +970,13 @@ FontSizeBox::FontSizeBox(std::unique_ptr<weld::ComboBox> p) m_xComboBox->connect_changed(LINK(this, FontSizeBox, ModifyHdl)); } -void FontSizeBox::set_entry_text(const OUString& rText) +void FontSizeBox::set_active_or_entry_text(const OUString& rText) { - m_xComboBox->set_entry_text(rText); + const int nFound = m_xComboBox->find_text(rText); + if (nFound != -1) + m_xComboBox->set_active(nFound); + else + m_xComboBox->set_entry_text(rText); } IMPL_LINK(FontSizeBox, ReformatHdl, weld::Widget&, rWidget, void) @@ -1020,7 +1128,7 @@ void FontSizeBox::Fill( const FontMetric* pFontMetric, const FontList* pList ) ++pTempAry; } - m_xComboBox->set_entry_text(aStr); + set_active_or_entry_text(aStr); m_xComboBox->select_entry_region(nSelectionStart, nSelectionEnd); m_xComboBox->thaw(); } @@ -1105,7 +1213,7 @@ void FontSizeBox::SetRelative( bool bNewRelative ) Fill( &aFontMetric, pFontList ); } - m_xComboBox->set_entry_text(aStr); + set_active_or_entry_text(aStr); m_xComboBox->select_entry_region(nSelectionStart, nSelectionEnd); } @@ -1157,10 +1265,7 @@ void FontSizeBox::SetValue(int nNewValue, FieldUnit eInUnit) } } OUString aResult = format_number(nTempValue); - const int nFound = m_xComboBox->find_text(aResult); - if (nFound != -1) - m_xComboBox->set_active(nFound); - m_xComboBox->set_entry_text(aResult); + set_active_or_entry_text(aResult); } void FontSizeBox::set_value(int nNewValue) |