Change text auto-fit alg. to also increase the scaling
When in edit mode, the text can be deleted, so the text box size can become smaller, but the auto-fit algorithm didn't take into account. In this case we already have the font and spacing scaling already set to a specific value and we need to find a scaling value where the margin is the smallest. This change also adds a test for the issue. Change-Id: I6c52f06dfbf5a1e582f7b31aceabf4736498ee90 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151412 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
parent
6868a857fc
commit
6c042848b6
7 changed files with 272 additions and 3 deletions
|
@ -2275,11 +2275,27 @@ void EditEngine::getGlobalSpacingScale(double& rX, double& rY) const
|
|||
pImpEditEngine->getSpacingScale(rX, rY);
|
||||
}
|
||||
|
||||
basegfx::B2DTuple EditEngine::getGlobalSpacingScale() const
|
||||
{
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
pImpEditEngine->getSpacingScale(x, y);
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
void EditEngine::getGlobalFontScale(double& rX, double& rY) const
|
||||
{
|
||||
pImpEditEngine->getFontScale(rX, rY);
|
||||
}
|
||||
|
||||
basegfx::B2DTuple EditEngine::getGlobalFontScale() const
|
||||
{
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
pImpEditEngine->getFontScale(x, y);
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
void EditEngine::setRoundFontSizeToPt(bool bRound) const
|
||||
{
|
||||
pImpEditEngine->setRoundToNearestPt(bRound);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
||||
*/
|
||||
// MyEDITENG, due to exported EditEng
|
||||
|
||||
#ifndef INCLUDED_EDITENG_EDITENG_HXX
|
||||
#define INCLUDED_EDITENG_EDITENG_HXX
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
|||
#include <tools/degree.hxx>
|
||||
#include <tools/long.hxx>
|
||||
#include <tools/fontenum.hxx>
|
||||
#include <basegfx/tuple/b2dtuple.hxx>
|
||||
|
||||
#include <editeng/eedata.hxx>
|
||||
#include <o3tl/typed_flags_set.hxx>
|
||||
|
@ -418,7 +419,9 @@ public:
|
|||
void setGlobalScale(double fFontScaleX, double fFontScaleY, double fSpacingScaleX, double fSpacingScaleY);
|
||||
|
||||
void getGlobalSpacingScale(double& rX, double& rY) const;
|
||||
basegfx::B2DTuple getGlobalSpacingScale() const;
|
||||
void getGlobalFontScale(double& rX, double& rY) const;
|
||||
basegfx::B2DTuple getGlobalFontScale() const;
|
||||
|
||||
void setRoundFontSizeToPt(bool bRound) const;
|
||||
|
||||
|
|
79
sd/CppunitTest_sd_textfitting_tests.mk
Normal file
79
sd/CppunitTest_sd_textfitting_tests.mk
Normal file
|
@ -0,0 +1,79 @@
|
|||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#*************************************************************************
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
#*************************************************************************
|
||||
|
||||
$(eval $(call gb_CppunitTest_CppunitTest,sd_textfitting_tests))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_externals,sd_textfitting_tests,\
|
||||
boost_headers \
|
||||
libxml2 \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_common_precompiled_header,sd_textfitting_tests))
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_exception_objects,sd_textfitting_tests, \
|
||||
sd/qa/unit/TextFittingTest \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_libraries,sd_textfitting_tests, \
|
||||
basegfx \
|
||||
comphelper \
|
||||
cppu \
|
||||
cppuhelper \
|
||||
drawinglayer \
|
||||
editeng \
|
||||
for \
|
||||
forui \
|
||||
i18nlangtag \
|
||||
msfilter \
|
||||
oox \
|
||||
sal \
|
||||
salhelper \
|
||||
sax \
|
||||
sd \
|
||||
sfx \
|
||||
sot \
|
||||
subsequenttest \
|
||||
svl \
|
||||
svt \
|
||||
svx \
|
||||
svxcore \
|
||||
test \
|
||||
tl \
|
||||
tk \
|
||||
ucbhelper \
|
||||
unotest \
|
||||
utl \
|
||||
vcl \
|
||||
xo \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_set_include,sd_textfitting_tests,\
|
||||
-I$(SRCDIR)/sd/source/ui/inc \
|
||||
-I$(SRCDIR)/sd/inc \
|
||||
$$(INCLUDE) \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_sdk_api,sd_textfitting_tests))
|
||||
$(eval $(call gb_CppunitTest_use_ure,sd_textfitting_tests))
|
||||
$(eval $(call gb_CppunitTest_use_vcl,sd_textfitting_tests))
|
||||
$(eval $(call gb_CppunitTest_use_rdb,sd_textfitting_tests,services))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_custom_headers,sd_textfitting_tests,\
|
||||
officecfg/registry \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_configuration,sd_textfitting_tests))
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_arguments,sd_textfitting_tests, \
|
||||
-env:arg-env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
|
@ -49,6 +49,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sd,\
|
|||
CppunitTest_sd_filter_eppt \
|
||||
CppunitTest_sd_shape_import_export_tests \
|
||||
CppunitTest_sd_a11y \
|
||||
CppunitTest_sd_textfitting_tests \
|
||||
))
|
||||
endif
|
||||
|
||||
|
|
154
sd/qa/unit/TextFittingTest.cxx
Normal file
154
sd/qa/unit/TextFittingTest.cxx
Normal file
|
@ -0,0 +1,154 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <officecfg/Office/Common.hxx>
|
||||
|
||||
#include "sdmodeltestbase.hxx"
|
||||
|
||||
#include <com/sun/star/uno/Reference.hxx>
|
||||
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
|
||||
|
||||
#include <com/sun/star/awt/Gradient.hpp>
|
||||
#include <com/sun/star/drawing/FillStyle.hpp>
|
||||
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
|
||||
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
|
||||
#include <com/sun/star/drawing/XDrawPages.hpp>
|
||||
#include <com/sun/star/drawing/XDrawPage.hpp>
|
||||
#include <com/sun/star/drawing/XShapes.hpp>
|
||||
#include <com/sun/star/graphic/XGraphic.hpp>
|
||||
#include <com/sun/star/container/XIndexAccess.hpp>
|
||||
#include <com/sun/star/table/XTable.hpp>
|
||||
#include <com/sun/star/table/XMergeableCellRange.hpp>
|
||||
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
|
||||
|
||||
#include <DrawDocShell.hxx>
|
||||
#include <editeng/editeng.hxx>
|
||||
#include <drawdoc.hxx>
|
||||
#include <vcl/scheduler.hxx>
|
||||
#include <svx/sdr/table/tablecontroller.hxx>
|
||||
#include <sfx2/request.hxx>
|
||||
#include <svx/svdpagv.hxx>
|
||||
#include <svx/svxids.hrc>
|
||||
#include <editeng/eeitem.hxx>
|
||||
#include <editeng/adjustitem.hxx>
|
||||
#include <editeng/outlobj.hxx>
|
||||
#include <editeng/editobj.hxx>
|
||||
#include <undo/undomanager.hxx>
|
||||
#include <GraphicViewShell.hxx>
|
||||
#include <sdpage.hxx>
|
||||
#include <comphelper/base64.hxx>
|
||||
#include <LayerTabBar.hxx>
|
||||
#include <vcl/event.hxx>
|
||||
#include <vcl/keycodes.hxx>
|
||||
#include <svx/svdoashp.hxx>
|
||||
#include <tools/gen.hxx>
|
||||
#include <svx/view3d.hxx>
|
||||
#include <svx/scene3d.hxx>
|
||||
#include <svx/sdmetitm.hxx>
|
||||
#include <unomodel.hxx>
|
||||
|
||||
using namespace css;
|
||||
|
||||
class TextFittingTest : public SdModelTestBase
|
||||
{
|
||||
public:
|
||||
TextFittingTest()
|
||||
: SdModelTestBase("/sd/qa/unit/data/")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(TextFittingTest, testTest)
|
||||
{
|
||||
createSdImpressDoc("TextFitting.odp");
|
||||
|
||||
SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
|
||||
CPPUNIT_ASSERT(pXImpressDocument);
|
||||
sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
|
||||
SdPage* pPage = pViewShell->GetActualPage();
|
||||
auto pTextObject = DynCastSdrTextObj(pPage->GetObj(0));
|
||||
CPPUNIT_ASSERT(pTextObject);
|
||||
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pTextObject->GetFontScale(), 1E-2);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pTextObject->GetSpacingScale(), 1E-2);
|
||||
|
||||
{
|
||||
OutlinerParaObject* pOutlinerParagraphObject = pTextObject->GetOutlinerParaObject();
|
||||
const EditTextObject& aEdit = pOutlinerParagraphObject->GetTextObject();
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"D1"), aEdit.GetText(0));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"D2"), aEdit.GetText(1));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(u"D3"), aEdit.GetText(2));
|
||||
}
|
||||
|
||||
sd::ViewShell* pViewShell1 = pXImpressDocument->GetDocShell()->GetViewShell();
|
||||
SdrView* pView1 = pViewShell1->GetView();
|
||||
Scheduler::ProcessEventsToIdle();
|
||||
pView1->SdrBeginTextEdit(pTextObject);
|
||||
CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
|
||||
|
||||
auto* pOLV = pView1->GetTextEditOutlinerView();
|
||||
CPPUNIT_ASSERT(pOLV);
|
||||
auto& rEditView = pOLV->GetEditView();
|
||||
auto* pEditEngine = rEditView.GetEditEngine();
|
||||
CPPUNIT_ASSERT(pEditEngine);
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pEditEngine->GetParagraphCount());
|
||||
|
||||
// Add paragraph 4
|
||||
rEditView.SetSelection(ESelection(3, 0, 3, 0));
|
||||
rEditView.InsertText(u"\nD4");
|
||||
Scheduler::ProcessEventsToIdle();
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pEditEngine->GetParagraphCount());
|
||||
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(87.49, pEditEngine->getGlobalFontScale().getY(), 1E-2);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(90.0, pEditEngine->getGlobalSpacingScale().getY(), 1E-2);
|
||||
|
||||
// Add paragraph 5
|
||||
rEditView.SetSelection(ESelection(4, 0, 4, 0));
|
||||
rEditView.InsertText(u"\nD5");
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pEditEngine->GetParagraphCount());
|
||||
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(54.68, pEditEngine->getGlobalFontScale().getY(), 1E-2);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pEditEngine->getGlobalSpacingScale().getY(), 1E-2);
|
||||
|
||||
// Add paragraph 6
|
||||
rEditView.SetSelection(ESelection(5, 0, 5, 0));
|
||||
rEditView.InsertText(u"\nD6");
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pEditEngine->GetParagraphCount());
|
||||
|
||||
// Delete paragraph 6
|
||||
rEditView.SetSelection(ESelection(4, EE_TEXTPOS_MAX_COUNT, 5, EE_TEXTPOS_MAX_COUNT));
|
||||
rEditView.DeleteSelected();
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pEditEngine->GetParagraphCount());
|
||||
|
||||
// Delete paragraph 5
|
||||
rEditView.SetSelection(ESelection(3, EE_TEXTPOS_MAX_COUNT, 4, EE_TEXTPOS_MAX_COUNT));
|
||||
rEditView.DeleteSelected();
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pEditEngine->GetParagraphCount());
|
||||
|
||||
// Delete paragraph 4
|
||||
rEditView.SetSelection(ESelection(2, EE_TEXTPOS_MAX_COUNT, 3, EE_TEXTPOS_MAX_COUNT));
|
||||
rEditView.DeleteSelected();
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pEditEngine->GetParagraphCount());
|
||||
|
||||
// not ideal - scaling should be 100%, but close enough
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(99.05, pEditEngine->getGlobalFontScale().getY(), 1E-2);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pEditEngine->getGlobalSpacingScale().getY(), 1E-2);
|
||||
|
||||
// are we still in text edit mode?
|
||||
CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
|
||||
pView1->SdrEndTextEdit();
|
||||
CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
|
||||
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pTextObject->GetFontScale(), 1E-2);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(100.0, pTextObject->GetSpacingScale(), 1E-2);
|
||||
}
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
BIN
sd/qa/unit/data/TextFitting.odp
Normal file
BIN
sd/qa/unit/data/TextFitting.odp
Normal file
Binary file not shown.
|
@ -1303,7 +1303,11 @@ void SdrTextObj::autoFitTextForCompatibility(SdrOutliner& rOutliner, const Size&
|
|||
else
|
||||
fCurrentFitFactor = double(rTextBoxSize.Height()) / aCurrentTextBoxSize.Height();
|
||||
|
||||
if (fCurrentFitFactor >= 1.0)
|
||||
double fInitialFontScaleY = 0.0;
|
||||
double fInitialSpacing = 0.0;
|
||||
rOutliner.getGlobalScale(o3tl::temporary(double()), fInitialFontScaleY, o3tl::temporary(double()), fInitialSpacing);
|
||||
|
||||
if (fCurrentFitFactor >= 1.0 && fInitialFontScaleY >= 100.0 && fInitialSpacing >= 100.0)
|
||||
return;
|
||||
|
||||
sal_Int32 nFontHeight = GetObjectItemSet().Get(EE_CHAR_FONTHEIGHT).GetHeight();
|
||||
|
@ -1313,9 +1317,21 @@ void SdrTextObj::autoFitTextForCompatibility(SdrOutliner& rOutliner, const Size&
|
|||
double fMaxY = fMaxScale;
|
||||
|
||||
double fBestFontScale = 0.0;
|
||||
double fBestSpacing = fMaxScale;
|
||||
double fBestSpacing = 100.0;
|
||||
double fBestFitFactor = fCurrentFitFactor;
|
||||
|
||||
if (fCurrentFitFactor >= 1.0)
|
||||
{
|
||||
fMinY = fInitialFontScaleY;
|
||||
fBestFontScale = fInitialFontScaleY;
|
||||
fBestSpacing = fInitialSpacing;
|
||||
fBestFitFactor = fCurrentFitFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMaxY = std::min(fInitialFontScaleY, fMaxScale);
|
||||
}
|
||||
|
||||
double fInTheMidle = 0.5;
|
||||
|
||||
int iteration = 0;
|
||||
|
|
Loading…
Reference in a new issue