summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-04-07 12:21:47 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-04-21 10:19:41 +0200
commit2e0a32b51681fb356699b4a722f461f55a46b890 (patch)
treeac96e726d777aba5b6f57513f5b00b3d766e34d3 /svtools
parent6c559b122add7db32b06faa15854df58b30460f6 (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.hxx6
-rw-r--r--svtools/source/control/ctrlbox.cxx503
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)