svx/source/tbxctrls/tbcontrl.cxx |  386 ++++++++++++++++++++++++++++++++-------
 1 file changed, 320 insertions(+), 66 deletions(-)

New commits:
commit 044fc5c8b225732d57970d3bf0720c13a5a9e0a4
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Sun Aug 21 06:08:01 2022 +0200
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Aug 22 15:44:06 2022 +0200

    tdf#87535: Preview styles using CTL/CJK fonts in the styles menu
    
    Code is similar to code in svx/source/styles/CommonStylePreviewRenderer.cxx,
     etc. Instead of using only the “western” font, it splits the text based
    on script type and uses the appropriate font for each script type.
    
    Change-Id: I1db87748119beac18e5b7e61617419c149400c27
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138601
    Tested-by: Jenkins
    Tested-by: Caolán McNamara <caol...@redhat.com>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 70063a04980b..610bb630e55e 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -26,6 +26,7 @@
 #include <svl/numformat.hxx>
 #include <svl/poolitem.hxx>
 #include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
 #include <vcl/commandinfoprovider.hxx>
 #include <vcl/event.hxx>
 #include <vcl/toolbox.hxx>
@@ -103,6 +104,11 @@
 #include <comphelper/lok.hxx>
 #include <tools/json_writer.hxx>
 
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/i18n/BreakIterator.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+
 #define MAX_MRU_FONTNAME_ENTRIES    5
 
 #define COMBO_WIDTH_IN_CHARS        18
@@ -117,6 +123,19 @@ using namespace ::com::sun::star::lang;
 
 namespace
 {
+struct ScriptInfo
+{
+    tools::Long textWidth;
+    sal_uInt16 scriptType;
+    sal_Int32 changePos;
+    ScriptInfo(sal_uInt16 scrptType, sal_Int32 position)
+        : textWidth(0)
+        , scriptType(scrptType)
+        , changePos(position)
+    {
+    }
+};
+
 class SvxStyleBox_Base
 {
 public:
@@ -186,6 +205,12 @@ public:
     virtual bool DoKeyInput(const KeyEvent& rKEvt);
 
 private:
+    std::optional<SvxFont> m_oFont;
+    std::optional<SvxFont> m_oCJKFont;
+    std::optional<SvxFont> m_oCTLFont;
+
+    css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
+
     DECL_LINK(SelectHdl, weld::ComboBox&, void);
     DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
     DECL_LINK(ActivateHdl, weld::ComboBox&, bool);
@@ -199,6 +224,9 @@ private:
 
     void Select(bool bNonTravelSelect);
 
+    std::vector<ScriptInfo> CheckScript(const OUString &rStyleName);
+    tools::Rectangle CalcBoundRect(vcl::RenderContext& rRenderContext, const 
OUString &rStyleName, std::vector<ScriptInfo>& rScriptChanges, double fRatio = 
1);
+
 protected:
     SvxStyleToolBoxControl& m_rCtrl;
 
@@ -220,9 +248,8 @@ protected:
 
     void            ReleaseFocus();
     static Color    TestColorsVisible(const Color &FontCol, const Color 
&BackCol);
-    static void     UserDrawEntry(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect, const OUString &rStyleName);
+    void            UserDrawEntry(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect, const tools::Rectangle& rTextRect, const OUString 
&rStyleName, const std::vector<ScriptInfo>& rScriptChanges);
     void            SetupEntry(vcl::RenderContext& rRenderContext, sal_Int32 
nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, bool 
bIsNotSelected);
-    static bool     AdjustFontForItemHeight(OutputDevice& rDevice, 
tools::Rectangle const & rTextRect, tools::Long nHeight);
     DECL_LINK(MenuSelectHdl, const OString&, void);
     DECL_STATIC_LINK(SvxStyleBox_Base, ShowMoreHdl, void*, void);
 };
@@ -1088,23 +1115,6 @@ void SvxStyleBox_Impl::DataChanged( const 
DataChangedEvent& rDCEvt )
     InterimItemWindow::DataChanged( rDCEvt );
 }
 
-bool SvxStyleBox_Base::AdjustFontForItemHeight(OutputDevice& rDevice, 
tools::Rectangle const & rTextRect, tools::Long nHeight)
-{
-    if (rTextRect.Bottom() > nHeight)
-    {
-        // the text does not fit, adjust the font size
-        double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
-        vcl::Font aFont(rDevice.GetFont());
-        Size aPixelSize(aFont.GetFontSize());
-        aPixelSize.setWidth( aPixelSize.Width() * ratio );
-        aPixelSize.setHeight( aPixelSize.Height() * ratio );
-        aFont.SetFontSize(aPixelSize);
-        rDevice.SetFont(aFont);
-        return true;
-    }
-    return false;
-}
-
 void SvxStyleBox_Impl::SetOptimalSize()
 {
     // set width in chars low so the size request will not be overridden
@@ -1116,23 +1126,232 @@ void SvxStyleBox_Impl::SetOptimalSize()
     SetSizePixel(get_preferred_size());
 }
 
-void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect, const OUString &rStyleName)
+std::vector<ScriptInfo> SvxStyleBox_Base::CheckScript(const OUString 
&rStyleName)
+{
+    assert(!rStyleName.isEmpty()); // must have a preview text here!
+
+    std::vector<ScriptInfo> aScriptChanges;
+
+    if (!mxBreak.is())
+    {
+        auto xContext = comphelper::getProcessComponentContext();
+        mxBreak = css::i18n::BreakIterator::create(xContext);
+    }
+
+    sal_Int16 nScript = mxBreak->getScriptType(rStyleName, 0);
+    sal_Int32 nChg = 0;
+    if (css::i18n::ScriptType::WEAK == nScript)
+    {
+        nChg = mxBreak->endOfScript(rStyleName, nChg, nScript);
+        if (nChg < rStyleName.getLength())
+            nScript = mxBreak->getScriptType(rStyleName, nChg);
+        else
+            nScript = css::i18n::ScriptType::LATIN;
+    }
+
+    while (true)
+    {
+        nChg = mxBreak->endOfScript(rStyleName, nChg, nScript);
+        aScriptChanges.emplace_back(nScript, nChg);
+        if (nChg >= rStyleName.getLength() || nChg < 0)
+            break;
+        nScript = mxBreak->getScriptType(rStyleName, nChg);
+    }
+
+    return aScriptChanges;
+}
+
+tools::Rectangle SvxStyleBox_Base::CalcBoundRect(vcl::RenderContext& 
rRenderContext, const OUString &rStyleName, std::vector<ScriptInfo>& 
rScriptChanges, double fRatio)
+{
+    tools::Rectangle aTextRect;
+
+    sal_uInt16 nScript;
+    sal_uInt16 nIdx = 0;
+    sal_Int32 nStart = 0;
+    sal_Int32 nEnd;
+    size_t nCnt = rScriptChanges.size();
+
+    if (nCnt)
+    {
+        nEnd = rScriptChanges[nIdx].changePos;
+        nScript = rScriptChanges[nIdx].scriptType;
+    }
+    else
+    {
+        nEnd = rStyleName.getLength();
+        nScript = css::i18n::ScriptType::LATIN;
+    }
+
+    do
+    {
+        auto oFont = (nScript == css::i18n::ScriptType::ASIAN) ?
+                         m_oCJKFont :
+                         ((nScript == css::i18n::ScriptType::COMPLEX) ?
+                             m_oCTLFont :
+                             m_oFont);
+
+        rRenderContext.Push(vcl::PushFlags::FONT);
+
+        if (oFont)
+            rRenderContext.SetFont(*oFont);
+
+        if (fRatio != 1)
+        {
+            vcl::Font aFont(rRenderContext.GetFont());
+            Size aPixelSize(aFont.GetFontSize());
+            aPixelSize.setWidth(aPixelSize.Width() * fRatio);
+            aPixelSize.setHeight(aPixelSize.Height() * fRatio);
+            aFont.SetFontSize(aPixelSize);
+            rRenderContext.SetFont(aFont);
+        }
+
+        tools::Rectangle aRect;
+        rRenderContext.GetTextBoundRect(aRect, rStyleName, nStart, nStart, 
nEnd - nStart);
+        aTextRect = aTextRect.Union(aRect);
+
+        tools::Long nWidth = rRenderContext.GetTextWidth(rStyleName, nStart, 
nEnd - nStart);
+
+        rRenderContext.Pop();
+
+        if (nIdx >= rScriptChanges.size())
+            break;
+
+        rScriptChanges[nIdx++].textWidth = nWidth;
+
+        if (nEnd < rStyleName.getLength() && nIdx < nCnt)
+        {
+            nStart = nEnd;
+            nEnd = rScriptChanges[nIdx].changePos;
+            nScript = rScriptChanges[nIdx].scriptType;
+        }
+        else
+            break;
+    }
+    while(true);
+
+    return aTextRect;
+}
+
+void SvxStyleBox_Base::UserDrawEntry(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect, const tools::Rectangle& rTextRect, const OUString 
&rStyleName, const std::vector<ScriptInfo>& rScriptChanges)
 {
     // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
     // nBorder, and we are adding 1 in order to look better when
     // italics is present
     const int nLeftDistance = 8;
 
-    tools::Rectangle aTextRect;
-    rRenderContext.GetTextBoundRect(aTextRect, rStyleName);
-
     Point aPos(rRect.TopLeft());
     aPos.AdjustX(nLeftDistance );
 
-    if (!AdjustFontForItemHeight(rRenderContext, aTextRect, rRect.GetHeight()))
-        aPos.AdjustY((rRect.GetHeight() - aTextRect.Bottom() ) / 2);
+    double fRatio = 1;
+    if (rTextRect.Bottom() > rRect.GetHeight())
+        fRatio = static_cast<double>(rRect.GetHeight()) / rTextRect.Bottom();
+    else
+        aPos.AdjustY((rRect.GetHeight() - rTextRect.Bottom()) / 2);
 
-    rRenderContext.DrawText(aPos, rStyleName);
+    sal_uInt16 nScript;
+    sal_uInt16 nIdx = 0;
+    sal_Int32 nStart = 0;
+    sal_Int32 nEnd;
+    size_t nCnt = rScriptChanges.size();
+    if (nCnt)
+    {
+        nEnd = rScriptChanges[nIdx].changePos;
+        nScript = rScriptChanges[nIdx].scriptType;
+    }
+    else
+    {
+        nEnd = rStyleName.getLength();
+        nScript = css::i18n::ScriptType::LATIN;
+    }
+
+    do
+    {
+        auto oFont = (nScript == css::i18n::ScriptType::ASIAN)
+                         ? m_oCJKFont
+                         : ((nScript == css::i18n::ScriptType::COMPLEX)
+                             ? m_oCTLFont
+                             : m_oFont);
+
+        rRenderContext.Push(vcl::PushFlags::FONT);
+
+        if (oFont)
+            rRenderContext.SetFont(*oFont);
+
+        if (fRatio != 1)
+        {
+            vcl::Font aFont(rRenderContext.GetFont());
+            Size aPixelSize(aFont.GetFontSize());
+            aPixelSize.setWidth(aPixelSize.Width() * fRatio);
+            aPixelSize.setHeight(aPixelSize.Height() * fRatio);
+            aFont.SetFontSize(aPixelSize);
+            rRenderContext.SetFont(aFont);
+        }
+
+        rRenderContext.DrawText(aPos, rStyleName, nStart, nEnd - nStart);
+
+        rRenderContext.Pop();
+
+        aPos.AdjustX(rScriptChanges[nIdx++].textWidth * fRatio);
+        if (nEnd < rStyleName.getLength() && nIdx < nCnt)
+        {
+            nStart = nEnd;
+            nEnd = rScriptChanges[nIdx].changePos;
+            nScript = rScriptChanges[nIdx].scriptType;
+        }
+        else
+            break;
+    }
+    while(true);
+}
+
+static bool GetWhich(const SfxItemSet& rSet, sal_uInt16 nSlot, sal_uInt16& 
rWhich)
+{
+    rWhich = rSet.GetPool()->GetWhich(nSlot);
+    return rSet.GetItemState(rWhich) >= SfxItemState::DEFAULT;
+}
+
+static bool SetFont(const SfxItemSet& rSet, sal_uInt16 nSlot, SvxFont& rFont)
+{
+    sal_uInt16 nWhich;
+    if (GetWhich(rSet, nSlot, nWhich))
+    {
+        const auto& rFontItem = static_cast<const 
SvxFontItem&>(rSet.Get(nWhich));
+        rFont.SetFamilyName(rFontItem.GetFamilyName());
+        rFont.SetStyleName(rFontItem.GetStyleName());
+        return true;
+    }
+    return false;
+}
+
+static bool SetFontSize(vcl::RenderContext& rRenderContext, const SfxItemSet& 
rSet, sal_uInt16 nSlot, SvxFont& rFont)
+{
+    sal_uInt16 nWhich;
+    if (GetWhich(rSet, nSlot, nWhich))
+    {
+        const auto& rFontHeightItem = static_cast<const 
SvxFontHeightItem&>(rSet.Get(nWhich));
+        SfxObjectShell *pShell = SfxObjectShell::Current();
+        Size aFontSize(0, rFontHeightItem.GetHeight());
+        Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, 
MapMode(pShell->GetMapUnit())));
+        rFont.SetFontSize(aPixelSize);
+        return true;
+    }
+    return false;
+}
+
+static void SetFontStyle(const SfxItemSet& rSet, sal_uInt16 nPosture, 
sal_uInt16 nWeight, SvxFont& rFont)
+{
+    sal_uInt16 nWhich;
+    if (GetWhich(rSet, nPosture, nWhich))
+    {
+        const auto& rItem = static_cast<const 
SvxPostureItem&>(rSet.Get(nWhich));
+        rFont.SetItalic(rItem.GetPosture());
+    }
+
+    if (GetWhich(rSet, nWeight, nWhich))
+    {
+        const auto& rItem = static_cast<const 
SvxWeightItem&>(rSet.Get(nWhich));
+        rFont.SetWeight(rItem.GetWeight());
+    }
 }
 
 void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& rRenderContext, 
sal_Int32 nItem, const tools::Rectangle& rRect, std::u16string_view rStyleName, 
bool bIsNotSelected)
@@ -1175,68 +1394,89 @@ void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& 
rRenderContext, sal_Int32
     std::optional<SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
     if (!pItemSet) return;
 
-    const SvxFontItem * const pFontItem =
-        pItemSet->GetItem<SvxFontItem>(SID_ATTR_CHAR_FONT);
-    const SvxFontHeightItem * const pFontHeightItem =
-        pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
-
-    if ( !(pFontItem && pFontHeightItem) )
-        return;
-
-    Size aFontSize( 0, pFontHeightItem->GetHeight() );
-    Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, 
MapMode(pShell->GetMapUnit())));
-
-    // setup the font properties
     SvxFont aFont;
-    aFont.SetFamilyName(pFontItem->GetFamilyName());
-    aFont.SetStyleName(pFontItem->GetStyleName());
-    aFont.SetFontSize(aPixelSize);
+    SvxFont aCJKFont;
+    SvxFont aCTLFont;
 
-    const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_WEIGHT );
-    if ( pItem )
-        aFont.SetWeight( static_cast< const SvxWeightItem* >( pItem 
)->GetWeight() );
-
-    pItem = pItemSet->GetItem( SID_ATTR_CHAR_POSTURE );
-    if ( pItem )
-        aFont.SetItalic( static_cast< const SvxPostureItem* >( pItem 
)->GetPosture() );
+    SetFontStyle(*pItemSet, SID_ATTR_CHAR_POSTURE, SID_ATTR_CHAR_WEIGHT, 
aFont);
+    SetFontStyle(*pItemSet, SID_ATTR_CHAR_CJK_POSTURE, 
SID_ATTR_CHAR_CJK_WEIGHT, aCJKFont);
+    SetFontStyle(*pItemSet, SID_ATTR_CHAR_CTL_POSTURE, 
SID_ATTR_CHAR_CTL_WEIGHT, aCTLFont);
 
-    pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
+    const SfxPoolItem *pItem = pItemSet->GetItem( SID_ATTR_CHAR_CONTOUR );
     if ( pItem )
-        aFont.SetOutline( static_cast< const SvxContourItem* >( pItem 
)->GetValue() );
+    {
+        auto aVal = static_cast< const SvxContourItem* >( pItem )->GetValue();
+        aFont.SetOutline(aVal);
+        aCJKFont.SetOutline(aVal);
+        aCTLFont.SetOutline(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_SHADOWED );
     if ( pItem )
-        aFont.SetShadow( static_cast< const SvxShadowedItem* >( pItem 
)->GetValue() );
+    {
+        auto aVal = static_cast< const SvxShadowedItem* >( pItem )->GetValue();
+        aFont.SetShadow(aVal);
+        aCJKFont.SetShadow(aVal);
+        aCTLFont.SetShadow(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_RELIEF );
     if ( pItem )
-        aFont.SetRelief( static_cast< const SvxCharReliefItem* >( pItem 
)->GetValue() );
+    {
+        auto aVal = static_cast< const SvxCharReliefItem* >( pItem 
)->GetValue();
+        aFont.SetRelief(aVal);
+        aCJKFont.SetRelief(aVal);
+        aCTLFont.SetRelief(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_UNDERLINE );
     if ( pItem )
-        aFont.SetUnderline( static_cast< const SvxUnderlineItem* >( pItem 
)->GetLineStyle() );
+    {
+        auto aVal = static_cast<const 
SvxUnderlineItem*>(pItem)->GetLineStyle();
+        aFont.SetUnderline(aVal);
+        aCJKFont.SetUnderline(aVal);
+        aCTLFont.SetUnderline(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_OVERLINE );
     if ( pItem )
-        aFont.SetOverline( static_cast< const SvxOverlineItem* >( pItem 
)->GetValue() );
+    {
+        auto aVal = static_cast< const SvxOverlineItem* >( pItem )->GetValue();
+        aFont.SetOverline(aVal);
+        aCJKFont.SetOverline(aVal);
+        aCTLFont.SetOverline(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_STRIKEOUT );
     if ( pItem )
-        aFont.SetStrikeout( static_cast< const SvxCrossedOutItem* >( pItem 
)->GetStrikeout() );
+    {
+        auto aVal = static_cast< const SvxCrossedOutItem* >( pItem 
)->GetStrikeout();
+        aFont.SetStrikeout(aVal);
+        aCJKFont.SetStrikeout(aVal);
+        aCTLFont.SetStrikeout(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_CASEMAP );
     if ( pItem )
-        aFont.SetCaseMap(static_cast<const 
SvxCaseMapItem*>(pItem)->GetCaseMap());
+    {
+        auto aVal = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap();
+        aFont.SetCaseMap(aVal);
+        aCJKFont.SetCaseMap(aVal);
+        aCTLFont.SetCaseMap(aVal);
+    }
 
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_EMPHASISMARK );
     if ( pItem )
-        aFont.SetEmphasisMark( static_cast< const SvxEmphasisMarkItem* >( 
pItem )->GetEmphasisMark() );
+    {
+        auto aVal = static_cast< const SvxEmphasisMarkItem* >( pItem 
)->GetEmphasisMark();
+        aFont.SetEmphasisMark(aVal);
+        aCJKFont.SetEmphasisMark(aVal);
+        aCTLFont.SetEmphasisMark(aVal);
+    }
 
     // setup the device & draw
     Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
 
-    rRenderContext.SetFont(aFont);
-
     pItem = pItemSet->GetItem( SID_ATTR_CHAR_COLOR );
     // text color, when nothing is selected
     if ( (nullptr != pItem) && bIsNotSelected)
@@ -1277,6 +1517,18 @@ void SvxStyleBox_Base::SetupEntry(vcl::RenderContext& 
rRenderContext, sal_Int32
     // set text color
     if ( aFontCol != COL_AUTO )
         rRenderContext.SetTextColor(aFontCol);
+
+    if (SetFont(*pItemSet, SID_ATTR_CHAR_FONT, aFont) &&
+        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_FONTHEIGHT, 
aFont))
+        m_oFont = aFont;
+
+    if (SetFont(*pItemSet, SID_ATTR_CHAR_CJK_FONT, aCJKFont) &&
+        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CJK_FONTHEIGHT, 
aCJKFont))
+        m_oCJKFont = aCJKFont;
+
+    if (SetFont(*pItemSet, SID_ATTR_CHAR_CTL_FONT, aCTLFont) &&
+        SetFontSize(rRenderContext, *pItemSet, SID_ATTR_CHAR_CTL_FONTHEIGHT, 
aCTLFont))
+        m_oCTLFont = aCTLFont;
 }
 
 IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, weld::ComboBox::render_args, 
aPayload, void)
@@ -1293,8 +1545,9 @@ IMPL_LINK(SvxStyleBox_Base, CustomRenderHdl, 
weld::ComboBox::render_args, aPaylo
     rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT | 
vcl::PushFlags::TEXTCOLOR);
 
     SetupEntry(rRenderContext, nIndex, rRect, aStyleName, !bSelected);
-
-    UserDrawEntry(rRenderContext, rRect, aStyleName);
+    auto aScriptChanges = CheckScript(aStyleName);
+    auto aTextRect = CalcBoundRect(rRenderContext, aStyleName, aScriptChanges);
+    UserDrawEntry(rRenderContext, rRect, aTextRect, aStyleName, 
aScriptChanges);
 
     rRenderContext.Pop();
 }
@@ -1324,12 +1577,13 @@ void 
SvxStyleBox_Base::CalcOptimalExtraUserWidth(vcl::RenderContext& rRenderCont
 
         rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT | 
vcl::PushFlags::TEXTCOLOR);
         SetupEntry(rRenderContext, i, tools::Rectangle(0, 0, RECT_MAX, 
ITEM_HEIGHT), sStyleName, true);
-        tools::Rectangle aTextRectForActualFont;
-        rRenderContext.GetTextBoundRect(aTextRectForActualFont, sStyleName);
-        if (AdjustFontForItemHeight(rRenderContext, aTextRectForActualFont, 
ITEM_HEIGHT))
+        auto aScriptChanges = CheckScript(sStyleName);
+        tools::Rectangle aTextRectForActualFont = 
CalcBoundRect(rRenderContext, sStyleName, aScriptChanges);
+        if (aTextRectForActualFont.Bottom() > ITEM_HEIGHT)
         {
-            //Font didn't fit, so it was changed, refetch with final font size
-            rRenderContext.GetTextBoundRect(aTextRectForActualFont, 
sStyleName);
+            //Font didn't fit, re-calculate with adjustment ratio.
+            double fRatio = static_cast<double>(ITEM_HEIGHT) / 
aTextRectForActualFont.Bottom();
+            aTextRectForActualFont = CalcBoundRect(rRenderContext, sStyleName, 
aScriptChanges, fRatio);
         }
         rRenderContext.Pop();
 

Reply via email to