summaryrefslogtreecommitdiffstats
path: root/sd/source/ui/presenter/PresenterTextView.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/source/ui/presenter/PresenterTextView.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/source/ui/presenter/PresenterTextView.cxx')
-rw-r--r--sd/source/ui/presenter/PresenterTextView.cxx466
1 files changed, 466 insertions, 0 deletions
diff --git a/sd/source/ui/presenter/PresenterTextView.cxx b/sd/source/ui/presenter/PresenterTextView.cxx
new file mode 100644
index 000000000..affa21b03
--- /dev/null
+++ b/sd/source/ui/presenter/PresenterTextView.cxx
@@ -0,0 +1,466 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "PresenterTextView.hxx"
+
+#include <i18nlangtag/mslangid.hxx>
+#include <cppcanvas/vclfactory.hxx>
+#include <svl/itempool.hxx>
+#include <unotools/lingucfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+constexpr OUStringLiteral gsTextPropertyName(u"Text");
+constexpr OUStringLiteral gsBitmapPropertyName(u"Bitmap");
+constexpr OUStringLiteral gsSizePropertyName(u"Size");
+constexpr OUStringLiteral gsBackgroundColorPropertyName(u"BackgroundColor");
+constexpr OUStringLiteral gsTextColorPropertyName(u"TextColor");
+constexpr OUStringLiteral gsFontDescriptorPropertyName(u"FontDescriptor");
+constexpr OUStringLiteral gsTopPropertyName(u"Top");
+constexpr OUStringLiteral gsTopRelativePropertyName(u"RelativeTop");
+constexpr OUStringLiteral gsTotalHeightPropertyName(u"TotalHeight");
+
+namespace sd::presenter {
+
+// PresenterTextView::Implementation
+class PresenterTextView::Implementation
+{
+public:
+ Implementation();
+ ~Implementation();
+
+ void SetCanvas (const cppcanvas::CanvasSharedPtr& rCanvas);
+ void SetSize (const Size aSize);
+ void SetBackgroundColor (const Color aColor);
+ void SetTextColor (const Color aColor);
+ void SetFontDescriptor (const awt::FontDescriptor& rFontDescriptor);
+ sal_Int32 GetTop() const { return mnTop;}
+ void SetTop (const sal_Int32 nTop);
+ void SetText (const OUString& Text);
+ sal_Int32 ParseDistance (const OUString& rsDistance) const;
+ Reference<rendering::XBitmap> const & GetBitmap();
+ sal_Int32 GetTotalHeight();
+
+private:
+ Reference<rendering::XBitmap> mxBitmap;
+ cppcanvas::CanvasSharedPtr mpCanvas;
+ VclPtr<VirtualDevice> mpOutputDevice;
+ std::unique_ptr<EditEngine> mpEditEngine;
+ rtl::Reference<SfxItemPool> mpEditEngineItemPool;
+ Size maSize;
+ OUString msText;
+ sal_Int32 mnTop;
+ sal_Int32 mnTotalHeight;
+
+ void CheckTop();
+};
+
+// PresenterTextView
+PresenterTextView::PresenterTextView ()
+ : mpImplementation(new Implementation())
+{
+}
+
+PresenterTextView::~PresenterTextView()
+{
+}
+
+void SAL_CALL PresenterTextView::disposing()
+{
+ mpImplementation.reset();
+}
+
+// XInitialization
+void SAL_CALL PresenterTextView::initialize (const Sequence<Any>& rArguments)
+{
+ ThrowIfDisposed();
+
+ if (rArguments.getLength() != 1)
+ {
+ throw RuntimeException("PresenterTextView: invalid number of arguments",
+ static_cast<XWeak*>(this));
+ }
+
+ Reference<rendering::XCanvas> xCanvas (rArguments[0], UNO_QUERY_THROW);
+ mpImplementation->SetCanvas(
+ cppcanvas::VCLFactory::createCanvas(xCanvas));
+}
+
+Any PresenterTextView::GetPropertyValue (const OUString& rsPropertyName)
+{
+ ThrowIfDisposed();
+
+ if (rsPropertyName == gsBitmapPropertyName)
+ {
+ return Any(mpImplementation->GetBitmap());
+ }
+ else if (rsPropertyName == gsTopPropertyName)
+ {
+ return Any(mpImplementation->GetTop());
+ }
+ else if (rsPropertyName == gsTotalHeightPropertyName)
+ {
+ return Any(mpImplementation->GetTotalHeight());
+ }
+
+ return Any();
+}
+
+Any PresenterTextView::SetPropertyValue (
+ const OUString& rsPropertyName,
+ const css::uno::Any& rValue)
+{
+ ThrowIfDisposed();
+
+ Any aOldValue;
+ if (rsPropertyName == gsTextPropertyName)
+ {
+ OUString sText;
+ if (rValue >>= sText)
+ mpImplementation->SetText(sText);
+ }
+ else if (rsPropertyName == gsSizePropertyName)
+ {
+ awt::Size aSize;
+ if (rValue >>= aSize)
+ mpImplementation->SetSize(Size(aSize.Width,aSize.Height));
+ }
+ else if (rsPropertyName == gsBackgroundColorPropertyName)
+ {
+ ::Color aColor;
+ if (rValue >>= aColor)
+ mpImplementation->SetBackgroundColor(aColor);
+ }
+ else if (rsPropertyName == gsTextColorPropertyName)
+ {
+ ::Color aColor;
+ if (rValue >>= aColor)
+ mpImplementation->SetTextColor(aColor);
+ }
+ else if (rsPropertyName == gsFontDescriptorPropertyName)
+ {
+ awt::FontDescriptor aFontDescriptor;
+ if (rValue >>= aFontDescriptor)
+ mpImplementation->SetFontDescriptor(aFontDescriptor);
+ }
+ else if (rsPropertyName == gsTopPropertyName)
+ {
+ sal_Int32 nTop = 0;
+ if (rValue >>= nTop)
+ mpImplementation->SetTop(nTop);
+ }
+ else if (rsPropertyName == gsTopRelativePropertyName)
+ {
+ OUString sDistance;
+ if (rValue >>= sDistance)
+ mpImplementation->SetTop(
+ mpImplementation->GetTop()
+ + mpImplementation->ParseDistance(sDistance));
+ }
+ return aOldValue;
+}
+
+void PresenterTextView::ThrowIfDisposed()
+{
+ if (PresenterTextViewInterfaceBase::rBHelper.bDisposed
+ || PresenterTextViewInterfaceBase::rBHelper.bInDispose || mpImplementation == nullptr)
+ {
+ throw lang::DisposedException ("PresenterTextView object has already been disposed",
+ static_cast<uno::XWeak*>(this));
+ }
+}
+
+// PresenterTextView::Implementation
+PresenterTextView::Implementation::Implementation()
+ : mpOutputDevice(VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::DEFAULT)),
+ mpEditEngineItemPool(EditEngine::CreatePool()),
+ maSize(100,100),
+ mnTop(0),
+ mnTotalHeight(-1)
+{
+ mpOutputDevice->SetMapMode(MapMode(MapUnit::MapPixel));
+
+ // set fonts to be used
+ SvtLinguOptions aOpt;
+ SvtLinguConfig().GetOptions( aOpt );
+
+ struct FontDta {
+ LanguageType nFallbackLang;
+ LanguageType nLang;
+ DefaultFontType nFontType;
+ sal_uInt16 nFontInfoId;
+ } aTable[3] =
+ {
+ // info to get western font to be used
+ { LANGUAGE_ENGLISH_US, LANGUAGE_NONE,
+ DefaultFontType::SERIF, EE_CHAR_FONTINFO },
+ // info to get CJK font to be used
+ { LANGUAGE_JAPANESE, LANGUAGE_NONE,
+ DefaultFontType::CJK_TEXT, EE_CHAR_FONTINFO_CJK },
+ // info to get CTL font to be used
+ { LANGUAGE_ARABIC_SAUDI_ARABIA, LANGUAGE_NONE,
+ DefaultFontType::CTL_TEXT, EE_CHAR_FONTINFO_CTL }
+ };
+ aTable[0].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN);
+ aTable[1].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN);
+ aTable[2].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
+
+ for (const FontDta & rFntDta : aTable)
+ {
+ LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
+ rFntDta.nFallbackLang : rFntDta.nLang;
+ vcl::Font aFont = OutputDevice::GetDefaultFont(
+ rFntDta.nFontType, nLang, GetDefaultFontFlags::OnlyOne);
+ mpEditEngineItemPool->SetPoolDefaultItem(
+ SvxFontItem(
+ aFont.GetFamilyType(),
+ aFont.GetFamilyName(),
+ aFont.GetStyleName(),
+ aFont.GetPitch(),
+ aFont.GetCharSet(),
+ rFntDta.nFontInfoId));
+ }
+
+ mpEditEngine.reset( new EditEngine (mpEditEngineItemPool.get()) );
+
+ mpEditEngine->EnableUndo (true);
+ mpEditEngine->SetDefTab (sal_uInt16(
+ Application::GetDefaultDevice()->GetTextWidth("XXXX")));
+
+ mpEditEngine->SetControlWord(
+ EEControlBits(mpEditEngine->GetControlWord() | EEControlBits::AUTOINDENTING) &
+ EEControlBits(~EEControlBits::UNDOATTRIBS) &
+ EEControlBits(~EEControlBits::PASTESPECIAL) );
+
+ mpEditEngine->SetWordDelimiters (" .=+-*/(){}[];\"");
+ mpEditEngine->SetRefMapMode(MapMode(MapUnit::MapPixel));
+ mpEditEngine->SetPaperSize (Size(800, 0));
+ mpEditEngine->EraseVirtualDevice();
+ mpEditEngine->ClearModifyFlag();
+}
+
+PresenterTextView::Implementation::~Implementation()
+{
+ mpEditEngine.reset();
+ mpEditEngineItemPool.clear();
+ mpOutputDevice.disposeAndClear();
+}
+
+void PresenterTextView::Implementation::SetCanvas (const cppcanvas::CanvasSharedPtr& rpCanvas)
+{
+ mpCanvas = rpCanvas;
+ mxBitmap = nullptr;
+}
+
+void PresenterTextView::Implementation::SetSize (const Size aSize)
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+
+ maSize = aSize;
+ mpEditEngine->SetPaperSize(maSize);
+ mnTotalHeight = -1;
+ mxBitmap = nullptr;
+}
+
+void PresenterTextView::Implementation::SetBackgroundColor (const Color aColor)
+{
+ mxBitmap = nullptr;
+
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+ DBG_ASSERT(mpEditEngineItemPool!=nullptr, "EditEngineItemPool missing");
+ mpEditEngine->SetBackgroundColor(aColor);
+ mpEditEngine->EnableAutoColor(false);
+ mpEditEngine->ForceAutoColor(false);
+}
+
+void PresenterTextView::Implementation::SetTextColor (const Color aColor)
+{
+ mxBitmap = nullptr;
+
+ DBG_ASSERT(mpEditEngineItemPool!=nullptr, "EditEngineItemPool missing");
+ mpEditEngineItemPool->SetPoolDefaultItem(SvxColorItem(aColor, EE_CHAR_COLOR));
+}
+
+void PresenterTextView::Implementation::SetFontDescriptor (
+ const awt::FontDescriptor& rFontDescriptor)
+{
+ mxBitmap = nullptr;
+
+ DBG_ASSERT(mpEditEngineItemPool!=nullptr, "EditEngineItemPool missing");
+
+ const sal_Int32 nFontHeight = rFontDescriptor.Height;
+
+ SvxFontHeightItem aFontHeight(
+ Application::GetDefaultDevice()->LogicToPixel(
+ Size(0, nFontHeight), MapMode (MapUnit::MapPoint)).Height(),
+ 100,
+ EE_CHAR_FONTHEIGHT);
+ mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
+ aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CJK);
+ mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
+ aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CTL);
+ mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
+
+ SvxFontItem aSvxFontItem (EE_CHAR_FONTINFO);
+ aSvxFontItem.SetFamilyName( rFontDescriptor.Name );
+ mpEditEngineItemPool->SetPoolDefaultItem(aSvxFontItem);
+
+ mnTotalHeight = -1;
+ mxBitmap = nullptr;
+
+ CheckTop();
+ mnTotalHeight = -1;
+}
+
+void PresenterTextView::Implementation::SetTop (const sal_Int32 nTop)
+{
+ if (nTop == mnTop)
+ return;
+
+ mnTop = nTop;
+ mxBitmap = nullptr;
+ CheckTop();
+}
+
+void PresenterTextView::Implementation::SetText (const OUString& rText)
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+ msText = rText;
+ mpEditEngine->SetPaperSize(maSize);
+ mnTotalHeight = -1;
+ mxBitmap = nullptr;
+}
+
+sal_Int32 PresenterTextView::Implementation::ParseDistance (const OUString& rsDistance) const
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+ sal_Int32 nDistance (0);
+ if (rsDistance.endsWith("px"))
+ {
+ nDistance = o3tl::toInt32(rsDistance.subView(0,rsDistance.getLength()-2));
+ }
+ else if (rsDistance.endsWith("l"))
+ {
+ const sal_Int32 nLines (o3tl::toInt32(rsDistance.subView(0,rsDistance.getLength()-1)));
+ // Take the height of the first line as the height of every line.
+ const sal_uInt32 nFirstLineHeight (mpEditEngine->GetLineHeight(0));
+ nDistance = nFirstLineHeight * nLines;
+ }
+
+ return nDistance;
+}
+
+Reference<rendering::XBitmap> const & PresenterTextView::Implementation::GetBitmap()
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+
+ if ( ! mxBitmap.is())
+ {
+ mpOutputDevice.disposeAndClear();
+ mpOutputDevice = VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(),
+ DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+ mpOutputDevice->SetMapMode(MapMode(MapUnit::MapPixel));
+ mpOutputDevice->SetOutputSizePixel(maSize);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor();
+ mpOutputDevice->SetBackground(Wallpaper());
+ mpOutputDevice->Erase();
+
+ MapMode aMapMode (mpOutputDevice->GetMapMode());
+ aMapMode.SetOrigin(Point(0,0));
+ mpOutputDevice->SetMapMode(aMapMode);
+ const ::tools::Rectangle aWindowBox (Point(0,0), maSize);
+ mpOutputDevice->DrawRect(aWindowBox);
+
+ mpEditEngine->Clear();
+ mpEditEngine->SetText(msText);
+ mpEditEngine->SetPaperSize(maSize);
+
+ mpEditEngine->Draw(*mpOutputDevice, aWindowBox, Point(0,mnTop));
+
+ const BitmapEx aBitmap (mpOutputDevice->GetBitmapEx(Point(0,0), maSize));
+ mxBitmap = cppcanvas::VCLFactory::createBitmap(
+ mpCanvas,
+ aBitmap
+ )->getUNOBitmap();
+ }
+ return mxBitmap;
+}
+
+sal_Int32 PresenterTextView::Implementation::GetTotalHeight()
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+
+ if (mnTotalHeight < 0)
+ {
+ if ( ! mxBitmap.is())
+ GetBitmap();
+ mnTotalHeight = mpEditEngine->GetTextHeight();
+ }
+ return mnTotalHeight;
+}
+
+void PresenterTextView::Implementation::CheckTop()
+{
+ DBG_ASSERT(mpEditEngine!=nullptr, "EditEngine missing");
+
+ if (mpEditEngine!=nullptr && mnTotalHeight < 0)
+ mnTotalHeight = mpEditEngine->GetTextHeight();
+ if (mpEditEngine!=nullptr && mnTop >= mnTotalHeight)
+ mnTop = mnTotalHeight - mpEditEngine->GetLineHeight(0);
+
+ if (mnTotalHeight < maSize.Height())
+ mnTop = 0;
+
+ if (mnTotalHeight - mnTop < maSize.Height())
+ mnTop = mnTotalHeight - maSize.Height();
+
+ if (mnTop < 0)
+ mnTop = 0;
+}
+
+} // end of namespace ::sd::presenter
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_Draw_PresenterTextView_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new sd::presenter::PresenterTextView);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */