LibreOffice Module sdext (master)  1
PresenterTheme.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "PresenterTheme.hxx"
24 #include <com/sun/star/drawing/XPresenterHelper.hpp>
25 #include <com/sun/star/rendering/PanoseWeight.hpp>
26 #include <osl/diagnose.h>
27 #include <map>
28 #include <numeric>
29 
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::std;
33 
34 namespace sdext::presenter {
35 
36 namespace {
37 
38 class BorderSize
39 {
40 public:
41  const static sal_Int32 mnInvalidValue = -10000;
42 
43  BorderSize() : mnLeft(mnInvalidValue),
44  mnTop(mnInvalidValue),
45  mnRight(mnInvalidValue),
46  mnBottom(mnInvalidValue) {}
47 
48  sal_Int32 mnLeft;
49  sal_Int32 mnTop;
50  sal_Int32 mnRight;
51  sal_Int32 mnBottom;
52 
53  vector<sal_Int32> ToVector()
54  {
55  return
56  {
57  mnLeft == mnInvalidValue ? 0 : mnLeft,
58  mnTop == mnInvalidValue ? 0 : mnTop,
59  mnRight == mnInvalidValue ? 0 : mnRight,
60  mnBottom == mnInvalidValue ? 0 : mnBottom
61  };
62  };
63 
64  void Merge (const BorderSize& rBorderSize)
65  {
66  if (mnLeft == mnInvalidValue)
67  mnLeft = rBorderSize.mnLeft;
68  if (mnTop == mnInvalidValue)
69  mnTop = rBorderSize.mnTop;
70  if (mnRight == mnInvalidValue)
71  mnRight = rBorderSize.mnRight;
72  if (mnBottom == mnInvalidValue)
73  mnBottom = rBorderSize.mnBottom;
74  }
75 };
76 
81 class ReadContext
82 {
83 public:
85  Reference<rendering::XCanvas> mxCanvas;
86  Reference<drawing::XPresenterHelper> mxPresenterHelper;
87 
88  ReadContext (
89  const Reference<XComponentContext>& rxContext,
90  const Reference<rendering::XCanvas>& rxCanvas);
91 
98  const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
99  const PresenterTheme::SharedFontDescriptor& rpDefault);
101  const Reference<beans::XPropertySet>& rxFontProperties,
102  const PresenterTheme::SharedFontDescriptor& rpDefault);
103 
104  std::shared_ptr<PresenterTheme::Theme> ReadTheme (
105  PresenterConfigurationAccess& rConfiguration,
106  const OUString& rsThemeName);
107 
108  static BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
109 
110 private:
111  static Any GetByName (
112  const Reference<container::XNameAccess>& rxNode,
113  const OUString& rsName);
114 };
115 
118 class PaneStyle
119 {
120 public:
121  PaneStyle();
122 
123  SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
124 
125  OUString msStyleName;
126  std::shared_ptr<PaneStyle> mpParentStyle;
128  BorderSize maInnerBorderSize;
129  BorderSize maOuterBorderSize;
130  std::shared_ptr<PresenterBitmapContainer> mpBitmaps;
131 
133 };
134 
135 typedef std::shared_ptr<PaneStyle> SharedPaneStyle;
136 
137 class PaneStyleContainer
138 {
139 private:
140  ::std::vector<SharedPaneStyle> mStyles;
141 
142 public:
143  void Read (
144  const ReadContext& rReadContext,
145  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
146 
147  SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
148 
149 private:
150  void ProcessPaneStyle (
151  ReadContext const & rReadContext,
152  const ::std::vector<css::uno::Any>& rValues);
153 };
154 
157 class ViewStyle
158 {
159 public:
160  ViewStyle();
161 
162  SharedBitmapDescriptor GetBitmap (std::u16string_view sBitmapName) const;
163 
165 
166  OUString msStyleName;
167  std::shared_ptr<ViewStyle> mpParentStyle;
170 };
171 
172 typedef std::shared_ptr<ViewStyle> SharedViewStyle;
173 
174 class ViewStyleContainer
175 {
176 private:
177  ::std::vector<SharedViewStyle> mStyles;
178 
179 public:
180  void Read (
181  const ReadContext& rReadContext,
182  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
183 
184  SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
185 
186 private:
187  void ProcessViewStyle(
188  ReadContext const & rReadContext,
189  const Reference<beans::XPropertySet>& rxProperties);
190 };
191 
192 class StyleAssociationContainer
193 {
194 public:
195  void Read (
196  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
197 
198  OUString GetStyleName (const OUString& rsResourceName) const;
199 
200 private:
201  typedef map<OUString, OUString> StyleAssociations;
202  StyleAssociations maStyleAssociations;
203 
204  void ProcessStyleAssociation(
205  const ::std::vector<css::uno::Any>& rValues);
206 };
207 
208 } // end of anonymous namespace
209 
211 {
212 public:
213  Theme (
214  const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
215  const OUString& rsNodeName);
216 
217  void Read (
218  PresenterConfigurationAccess& rConfiguration,
219  ReadContext& rReadContext);
220 
222  std::shared_ptr<Theme> mpParentTheme;
224  PaneStyleContainer maPaneStyles;
225  ViewStyleContainer maViewStyles;
226  StyleAssociationContainer maStyleAssociations;
227  Reference<container::XHierarchicalNameAccess> mxThemeRoot;
228  std::shared_ptr<PresenterBitmapContainer> mpIconContainer;
229  typedef map<OUString,SharedFontDescriptor> FontContainer;
230  FontContainer maFontContainer;
231 
232  SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
233  SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
234 
235 private:
236  void ProcessFont(
237  const OUString& rsKey,
238  const Reference<beans::XPropertySet>& rxProperties);
239 };
240 
241 //===== PresenterTheme ========================================================
242 
244  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
245  const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
246  : mxContext(rxContext),
247  mxCanvas(rxCanvas)
248 {
249  mpTheme = ReadTheme();
250 }
251 
253 {
254 }
255 
256 std::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme()
257 {
258  ReadContext aReadContext(mxContext, mxCanvas);
259 
260  PresenterConfigurationAccess aConfiguration (
261  mxContext,
262  "/org.openoffice.Office.PresenterScreen/",
264 
265  return aReadContext.ReadTheme(aConfiguration, OUString());
266 }
267 
269 {
270  return mxCanvas.is();
271 }
272 
273 void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
274 {
275  if ( ! mxCanvas.is() && rxCanvas.is())
276  {
277  mxCanvas = rxCanvas;
278  ReadTheme();
279  }
280 }
281 
282 OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const
283 {
284  OUString sStyleName;
285  std::shared_ptr<Theme> pTheme (mpTheme);
286  while (sStyleName.isEmpty() && pTheme != nullptr)
287  {
288  sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
289  pTheme = pTheme->mpParentTheme;
290  }
291  return sStyleName;
292 }
293 
294 ::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
295  const OUString& rsStyleName,
296  const bool bOuter) const
297 {
298  OSL_ASSERT(mpTheme != nullptr);
299 
300  SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
301  if (pPaneStyle)
302  if (bOuter)
303  return pPaneStyle->maOuterBorderSize.ToVector();
304  else
305  return pPaneStyle->maInnerBorderSize.ToVector();
306  else
307  {
308  return ::std::vector<sal_Int32>(4,0);
309  }
310 }
311 
313  const Reference<container::XHierarchicalNameAccess>& rxNode,
314  const PresenterTheme::SharedFontDescriptor& rpDefault)
315 {
316  return ReadContext::ReadFont(rxNode, rpDefault);
317 }
318 
320  const Any& rColorSequence,
321  sal_uInt32& rColor)
322 {
323  Sequence<sal_Int8> aByteSequence;
324  if (rColorSequence >>= aByteSequence)
325  {
326  rColor = std::accumulate(aByteSequence.begin(), aByteSequence.end(), sal_uInt32(0),
327  [](const sal_uInt32 nRes, const sal_uInt8 nByte) { return (nRes << 8) | nByte; });
328  return true;
329  }
330  else
331  return false;
332 }
333 
334 std::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
335  const OUString& rsStyleName) const
336 {
337  if (mpTheme == nullptr)
338  return std::shared_ptr<PresenterConfigurationAccess>();
339 
340  // Open configuration for writing.
341  auto pConfiguration = std::make_shared<PresenterConfigurationAccess>(
342  mxContext,
343  "/org.openoffice.Office.PresenterScreen/",
345 
346  // Get configuration node for the view style container of the current
347  // theme.
348  if (pConfiguration->GoToChild( OUString(
349  "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
350  {
351  pConfiguration->GoToChild(
352  [&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
353  {
355  rsStyleName, "StyleName", xProps);
356  });
357  }
358  return pConfiguration;
359 }
360 
362  const OUString& rsStyleName,
363  const OUString& rsBitmapName) const
364 {
365  if (mpTheme != nullptr)
366  {
367  if (rsStyleName.isEmpty())
368  {
369  if (rsBitmapName == "Background")
370  {
371  std::shared_ptr<Theme> pTheme (mpTheme);
372  while (pTheme != nullptr && !pTheme->mpBackground)
373  pTheme = pTheme->mpParentTheme;
374  if (pTheme != nullptr)
375  return pTheme->mpBackground;
376  else
377  return SharedBitmapDescriptor();
378  }
379  }
380  else
381  {
382  SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
383  if (pPaneStyle)
384  {
385  SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
386  if (pBitmap)
387  return pBitmap;
388  }
389 
390  SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
391  if (pViewStyle)
392  {
393  SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
394  if (pBitmap)
395  return pBitmap;
396  }
397  }
398  }
399 
400  return SharedBitmapDescriptor();
401 }
402 
404  const OUString& rsBitmapName) const
405 {
406  if (mpTheme != nullptr)
407  {
408  if (rsBitmapName == "Background")
409  {
410  std::shared_ptr<Theme> pTheme (mpTheme);
411  while (pTheme != nullptr && !pTheme->mpBackground)
412  pTheme = pTheme->mpParentTheme;
413  if (pTheme != nullptr)
414  return pTheme->mpBackground;
415  else
416  return SharedBitmapDescriptor();
417  }
418  else
419  {
420  if (mpTheme->mpIconContainer != nullptr)
421  return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
422  }
423  }
424 
425  return SharedBitmapDescriptor();
426 }
427 
428 std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const
429 {
430  if (mpTheme != nullptr)
431  return mpTheme->mpIconContainer;
432  else
433  return std::shared_ptr<PresenterBitmapContainer>();
434 }
435 
437  const OUString& rsStyleName) const
438 {
439  if (mpTheme != nullptr)
440  {
441  SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
442  if (pPaneStyle)
443  return pPaneStyle->GetFont();
444 
445  SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
446  if (pViewStyle)
447  return pViewStyle->GetFont();
448 
449  std::shared_ptr<Theme> pTheme (mpTheme);
450  while (pTheme != nullptr)
451  {
452  Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
453  if (iFont != pTheme->maFontContainer.end())
454  return iFont->second;
455 
456  pTheme = pTheme->mpParentTheme;
457  }
458  }
459 
460  return SharedFontDescriptor();
461 }
462 
463 //===== FontDescriptor ========================================================
464 
466  const std::shared_ptr<FontDescriptor>& rpDescriptor)
467  : mnSize(12),
468  mnColor(0x00000000),
469  msAnchor(OUString("Left")),
470  mnXOffset(0),
471  mnYOffset(0)
472 {
473  if (rpDescriptor != nullptr)
474  {
475  msFamilyName = rpDescriptor->msFamilyName;
476  msStyleName = rpDescriptor->msStyleName;
477  mnSize = rpDescriptor->mnSize;
478  mnColor = rpDescriptor->mnColor;
479  msAnchor = rpDescriptor->msAnchor;
480  mnXOffset = rpDescriptor->mnXOffset;
481  mnYOffset = rpDescriptor->mnYOffset;
482  }
483 }
484 
486  const Reference<rendering::XCanvas>& rxCanvas)
487 {
488  if (mxFont.is())
489  return true;
490 
491  if ( ! rxCanvas.is())
492  return false;
493 
494  const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
495  mxFont = CreateFont(rxCanvas, nCellSize);
496 
497  return mxFont.is();
498 }
499 
500 Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
501  const Reference<rendering::XCanvas>& rxCanvas,
502  const double nCellSize) const
503 {
504  rendering::FontRequest aFontRequest;
505  aFontRequest.FontDescription.FamilyName = msFamilyName;
506  if (msFamilyName.isEmpty())
507  aFontRequest.FontDescription.FamilyName = "Tahoma";
508  aFontRequest.FontDescription.StyleName = msStyleName;
509  aFontRequest.CellSize = nCellSize;
510 
511  // Make an attempt at translating the style name(s)into a corresponding
512  // font description.
513  if (msStyleName == "Bold")
514  aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
515 
516  return rxCanvas->createFont(
517  aFontRequest,
519  geometry::Matrix2D(1,0,0,1));
520 }
521 
523  const Reference<rendering::XCanvas>& rxCanvas,
524  const double nDesignSize) const
525 {
526  // Use the given design size as initial value in calculating the cell
527  // size.
528  double nCellSize (nDesignSize);
529 
530  if ( ! rxCanvas.is())
531  {
532  // We need the canvas to do the conversion. Return the design size,
533  // it is the our best guess in this circumstance.
534  return nDesignSize;
535  }
536 
537  Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
538  if ( ! xFont.is())
539  return nDesignSize;
540 
541  geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
542 
543  const double nAscent (-aBox.Y1);
544  //tdf#112408
545  if (nAscent == 0)
546  return nDesignSize;
547  const double nDescent (aBox.Y2);
548  const double nScale = (nAscent+nDescent) / nAscent;
549  return nDesignSize * nScale;
550 }
551 
552 //===== Theme =================================================================
553 
555  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
556  const OUString& rsNodeName)
557  : msConfigurationNodeName(rsNodeName),
558  maPaneStyles(),
559  maViewStyles(),
561  mxThemeRoot(rxThemeRoot)
562 {
563 }
564 
566  PresenterConfigurationAccess& rConfiguration,
567  ReadContext& rReadContext)
568 {
569  // Parent theme name.
570  OUString sParentThemeName;
571  if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
572  >>= sParentThemeName)
573  && !sParentThemeName.isEmpty())
574  {
575  mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
576  }
577 
578  // Background.
580  mxThemeRoot,
581  "Background",
582  rReadContext.mxPresenterHelper,
583  rReadContext.mxCanvas,
585 
586  // Style associations.
587  maStyleAssociations.Read(mxThemeRoot);
588 
589  // Pane styles.
590  maPaneStyles.Read(rReadContext, mxThemeRoot);
591 
592  // View styles.
593  maViewStyles.Read(rReadContext, mxThemeRoot);
594 
595  // Read bitmaps.
596  mpIconContainer = std::make_shared<PresenterBitmapContainer>(
598  PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY),
599  mpParentTheme != nullptr ? mpParentTheme->mpIconContainer
600  : std::shared_ptr<PresenterBitmapContainer>(),
601  rReadContext.mxComponentContext, rReadContext.mxCanvas);
602 
603  // Read fonts.
606  UNO_QUERY);
608  xFontNode,
609  [this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps)
610  {
611  return this->ProcessFont(rKey, xProps);
612  });
613 }
614 
615 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
616 {
617  SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
618  if (pPaneStyle)
619  return pPaneStyle;
620  else if (mpParentTheme != nullptr)
621  return mpParentTheme->GetPaneStyle(rsStyleName);
622  else
623  return SharedPaneStyle();
624 }
625 
626 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
627 {
628  SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
629  if (pViewStyle)
630  return pViewStyle;
631  else if (mpParentTheme != nullptr)
632  return mpParentTheme->GetViewStyle(rsStyleName);
633  else
634  return SharedViewStyle();
635 }
636 
638  const OUString& rsKey,
639  const Reference<beans::XPropertySet>& rxProperties)
640 {
641  maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
642 }
643 
644 namespace {
645 
646 //===== ReadContext ===========================================================
647 
648 ReadContext::ReadContext (
649  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
650  const Reference<rendering::XCanvas>& rxCanvas)
651  : mxComponentContext(rxContext),
652  mxCanvas(rxCanvas)
653 {
654  Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
655  if (xFactory.is())
656  {
657  mxPresenterHelper.set(
658  xFactory->createInstanceWithContext(
659  "com.sun.star.comp.Draw.PresenterHelper",
660  rxContext),
661  UNO_QUERY_THROW);
662  }
663 }
664 
665 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
666  const Reference<container::XHierarchicalNameAccess>& rxNode,
667  const PresenterTheme::SharedFontDescriptor& rpDefault)
668 {
669  if ( ! rxNode.is())
671 
672  try
673  {
674  Reference<container::XHierarchicalNameAccess> xFont (
676  rxNode,
677  /*rsFontPath*/""),
678  UNO_QUERY_THROW);
679 
680  Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
681  return ReadFont(xProperties, rpDefault);
682  }
683  catch (Exception&)
684  {
685  OSL_ASSERT(false);
686  }
687 
689 }
690 
691 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
692  const Reference<beans::XPropertySet>& rxProperties,
693  const PresenterTheme::SharedFontDescriptor& rpDefault)
694 {
695  auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault);
696 
697  PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
698  PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
699  PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
701  PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
702  pDescriptor->mnColor);
703  PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
704  PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
705  PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
706 
707  return pDescriptor;
708 }
709 
710 Any ReadContext::GetByName (
711  const Reference<container::XNameAccess>& rxNode,
712  const OUString& rsName)
713 {
714  OSL_ASSERT(rxNode.is());
715  if (rxNode->hasByName(rsName))
716  return rxNode->getByName(rsName);
717  else
718  return Any();
719 }
720 
721 std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
722  PresenterConfigurationAccess& rConfiguration,
723  const OUString& rsThemeName)
724 {
725  std::shared_ptr<PresenterTheme::Theme> pTheme;
726 
727  OUString sCurrentThemeName (rsThemeName);
728  if (sCurrentThemeName.isEmpty())
729  {
730  // No theme name given. Look up the CurrentTheme property.
731  rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
732  if (sCurrentThemeName.isEmpty())
733  {
734  // Still no name. Use "DefaultTheme".
735  sCurrentThemeName = "DefaultTheme";
736  }
737  }
738 
740  rConfiguration.GetConfigurationNode("Presenter/Themes"),
741  UNO_QUERY);
742  if (xThemes.is())
743  {
744  // Iterate over all themes and search the one with the given name.
745  const Sequence<OUString> aKeys (xThemes->getElementNames());
746  for (const OUString& rsKey : aKeys)
747  {
748  Reference<container::XHierarchicalNameAccess> xTheme (
749  xThemes->getByName(rsKey), UNO_QUERY);
750  if (xTheme.is())
751  {
752  OUString sThemeName;
754  >>= sThemeName;
755  if (sThemeName == sCurrentThemeName)
756  {
757  pTheme = std::make_shared<PresenterTheme::Theme>(xTheme,rsKey);
758  break;
759  }
760  }
761  }
762  }
763 
764  if (pTheme != nullptr)
765  {
766  pTheme->Read(rConfiguration, *this);
767  }
768 
769  return pTheme;
770 }
771 
772 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
773 {
774  BorderSize aBorderSize;
775 
776  if (rxNode.is())
777  {
778  GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
779  GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
780  GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
781  GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
782  }
783 
784  return aBorderSize;
785 }
786 
787 //===== PaneStyleContainer ====================================================
788 
789 void PaneStyleContainer::Read (
790  const ReadContext& rReadContext,
791  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
792 {
793  Reference<container::XNameAccess> xPaneStyleList (
795  rxThemeRoot,
796  "PaneStyles"),
797  UNO_QUERY);
798  if (!xPaneStyleList.is())
799  return;
800 
801  ::std::vector<OUString> aProperties;
802  aProperties.reserve(6);
803  aProperties.emplace_back("StyleName");
804  aProperties.emplace_back("ParentStyle");
805  aProperties.emplace_back("TitleFont");
806  aProperties.emplace_back("InnerBorderSize");
807  aProperties.emplace_back("OuterBorderSize");
808  aProperties.emplace_back("BorderBitmapList");
810  xPaneStyleList,
811  aProperties,
812  [this, &rReadContext] (std::vector<uno::Any> const& rValues)
813  {
814  return this->ProcessPaneStyle(rReadContext, rValues);
815  });
816 }
817 
818 void PaneStyleContainer::ProcessPaneStyle(
819  ReadContext const & rReadContext,
820  const ::std::vector<Any>& rValues)
821 {
822  if (rValues.size() != 6)
823  return;
824 
825  auto pStyle = std::make_shared<PaneStyle>();
826 
827  rValues[0] >>= pStyle->msStyleName;
828 
829  OUString sParentStyleName;
830  if (rValues[1] >>= sParentStyleName)
831  {
832  // Find parent style.
833  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
834  [&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
835  if (iStyle != mStyles.end())
836  pStyle->mpParentStyle = *iStyle;
837  }
838 
839  Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
840  pStyle->mpFont = ReadContext::ReadFont(
842 
843  Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
844  pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode);
845  Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
846  pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode);
847 
848  if (pStyle->mpParentStyle != nullptr)
849  {
850  pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
851  pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
852  }
853 
854  if (rReadContext.mxCanvas.is())
855  {
856  Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
857  pStyle->mpBitmaps = std::make_shared<PresenterBitmapContainer>(
858  xBitmapsNode,
859  pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps
860  : std::shared_ptr<PresenterBitmapContainer>(),
861  rReadContext.mxComponentContext, rReadContext.mxCanvas,
862  rReadContext.mxPresenterHelper);
863  }
864 
865  mStyles.push_back(pStyle);
866 }
867 
868 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
869 {
870  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
871  [&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
872  if (iStyle != mStyles.end())
873  return *iStyle;
874  return SharedPaneStyle();
875 }
876 
877 //===== PaneStyle =============================================================
878 
879 PaneStyle::PaneStyle()
880 {
881 }
882 
883 SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
884 {
885  if (mpBitmaps != nullptr)
886  {
887  SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
888  if (pBitmap)
889  return pBitmap;
890  }
891 
892  if (mpParentStyle != nullptr)
893  return mpParentStyle->GetBitmap(rsBitmapName);
894  else
895  return SharedBitmapDescriptor();
896 }
897 
898 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
899 {
900  if (mpFont)
901  return mpFont;
902  else if (mpParentStyle != nullptr)
903  return mpParentStyle->GetFont();
904  else
906 }
907 
908 //===== ViewStyleContainer ====================================================
909 
910 void ViewStyleContainer::Read (
911  const ReadContext& rReadContext,
912  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
913 {
914  Reference<container::XNameAccess> xViewStyleList (
916  rxThemeRoot,
917  "ViewStyles"),
918  UNO_QUERY);
919  if (xViewStyleList.is())
920  {
922  xViewStyleList,
923  [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
924  {
925  return this->ProcessViewStyle(rReadContext, xProps);
926  });
927  }
928 }
929 
930 void ViewStyleContainer::ProcessViewStyle(
931  ReadContext const & rReadContext,
932  const Reference<beans::XPropertySet>& rxProperties)
933 {
934  auto pStyle = std::make_shared<ViewStyle>();
935 
936  PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
937  >>= pStyle->msStyleName;
938 
939  OUString sParentStyleName;
940  if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
941  >>= sParentStyleName)
942  {
943  // Find parent style.
944  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
945  [&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
946  if (iStyle != mStyles.end())
947  {
948  pStyle->mpParentStyle = *iStyle;
949  pStyle->mpFont = (*iStyle)->mpFont;
950  pStyle->mpBackground = (*iStyle)->mpBackground;
951  }
952  }
953 
954  Reference<container::XHierarchicalNameAccess> xFontNode (
955  PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
957  ReadContext::ReadFont(xFontNode, PresenterTheme::SharedFontDescriptor()));
958  if (pFont)
959  pStyle->mpFont = pFont;
960 
961  Reference<container::XHierarchicalNameAccess> xBackgroundNode (
962  PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
963  UNO_QUERY);
965  xBackgroundNode,
966  OUString(),
967  rReadContext.mxPresenterHelper,
968  rReadContext.mxCanvas,
970  if (pBackground && pBackground->GetNormalBitmap().is())
971  pStyle->mpBackground = pBackground;
972 
973  mStyles.push_back(pStyle);
974 }
975 
976 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
977 {
978  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
979  [&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
980  if (iStyle != mStyles.end())
981  return *iStyle;
982  return SharedViewStyle();
983 }
984 
985 //===== ViewStyle =============================================================
986 
987 ViewStyle::ViewStyle()
988 {
989 }
990 
991 SharedBitmapDescriptor ViewStyle::GetBitmap (std::u16string_view rsBitmapName) const
992 {
993  if (rsBitmapName == u"Background")
994  return mpBackground;
995  else
996  return SharedBitmapDescriptor();
997 }
998 
999 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
1000 {
1001  if (mpFont)
1002  return mpFont;
1003  else if (mpParentStyle != nullptr)
1004  return mpParentStyle->GetFont();
1005  else
1007 }
1008 
1009 //===== StyleAssociationContainer =============================================
1010 
1011 void StyleAssociationContainer::Read (
1012  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1013 {
1014  Reference<container::XNameAccess> xStyleAssociationList (
1016  rxThemeRoot,
1017  "StyleAssociations"),
1018  UNO_QUERY);
1019  if (!xStyleAssociationList.is())
1020  return;
1021 
1022  ::std::vector<OUString> aProperties { "ResourceURL", "StyleName" };
1024  xStyleAssociationList,
1025  aProperties,
1026  [this] (std::vector<uno::Any> const& rValues)
1027  {
1028  return this->ProcessStyleAssociation(rValues);
1029  });
1030 }
1031 
1032 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1033 {
1034  StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1035  if (iAssociation != maStyleAssociations.end())
1036  return iAssociation->second;
1037  else
1038  return OUString();
1039 }
1040 
1041 void StyleAssociationContainer::ProcessStyleAssociation(
1042  const ::std::vector<Any>& rValues)
1043 {
1044  if (rValues.size() != 2)
1045  return;
1046 
1047  OUString sResourceURL;
1048  OUString sStyleName;
1049  if ((rValues[0] >>= sResourceURL)
1050  && (rValues[1] >>= sStyleName))
1051  {
1052  maStyleAssociations[sResourceURL] = sStyleName;
1053  }
1054 }
1055 
1056 } // end of anonymous namespace
1057 
1058 } // end of namespace ::sdext::presenter
1059 
1060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void ForAll(const css::uno::Reference< css::container::XNameAccess > &rxContainer, const ::std::vector< OUString > &rArguments, const ItemProcessor &rProcessor)
Execute a functor for all elements of the given container.
::std::vector< sal_Int32 > GetBorderSize(const OUString &rsStyleName, const bool bOuter) const
Reference< rendering::XCanvas > mxCanvas
BorderSize maOuterBorderSize
std::shared_ptr< FontDescriptor > SharedFontDescriptor
static css::uno::Any GetProperty(const css::uno::Reference< css::beans::XPropertySet > &rxProperties, const OUString &rsKey)
This method wraps a call to getPropertyValue() and returns an empty Any instead of throwing an except...
map< OUString, SharedFontDescriptor > FontContainer
SharedBitmapDescriptor mpBackground
std::shared_ptr< PresenterBitmapContainer > mpIconContainer
sal_Int32 mnLeft
PresenterTheme(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
Theme(const Reference< container::XHierarchicalNameAccess > &rThemeRoot, const OUString &rsNodeName)
uno::Reference< uno::XComponentContext > mxContext
::std::vector< SharedPaneStyle > mStyles
FontDescriptor(const std::shared_ptr< FontDescriptor > &rpDescriptor)
std::shared_ptr< PresenterConfigurationAccess > GetNodeForViewStyle(const OUString &rsStyleName) const
std::shared_ptr< Theme > mpTheme
uno::Reference< rendering::XCanvasFont > mxFont
Reference< XComponentContext > mxComponentContext
bool PrepareFont(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
std::shared_ptr< PresenterBitmapContainer::BitmapDescriptor > SharedBitmapDescriptor
sal_Int32 mnBottom
SharedBitmapDescriptor GetBitmap(const OUString &rsStyleName, const OUString &rsBitmapName) const
Reference< drawing::XPresenterHelper > mxPresenterHelper
PropertiesInfo aProperties
This class gives access to the configuration.
std::shared_ptr< PresenterBitmapContainer > mpBitmaps
double GetCellSizeForDesignSize(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const double nDesignSize) const
SharedPaneStyle GetPaneStyle(const OUString &rsStyleName) const
OUString msStyleName
sal_Int32 mnRight
SharedViewStyle GetViewStyle(const OUString &rsStyleName) const
void Read(PresenterConfigurationAccess &rConfiguration, ReadContext &rReadContext)
static const sal_Int32 mnInvalidValue
static bool ConvertToColor(const css::uno::Any &rColorSequence, sal_uInt32 &rColor)
static SharedFontDescriptor ReadFont(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const SharedFontDescriptor &rDefaultFount)
BorderSize maInnerBorderSize
void CreateFont(SvxFont &rFont, const SfxItemSet &rSet, bool bSearchInParent, SvtScriptType nScriptType)
StyleAssociationContainer maStyleAssociations
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
css::uno::Reference< css::rendering::XCanvasFont > CreateFont(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const double nCellSize) const
css::uno::Reference< css::rendering::XCanvas > mxCanvas
std::shared_ptr< Theme > ReadTheme()
void ProvideCanvas(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
PresenterTheme::SharedFontDescriptor mpFont
static bool IsStringPropertyEqual(std::u16string_view rsValue, const OUString &rsPropertyName, const css::uno::Reference< css::beans::XPropertySet > &rxNode)
SharedFontDescriptor GetFont(const OUString &rsStyleName) const
OUString GetStyleName(const OUString &rsResourceURL) const
static std::shared_ptr< BitmapDescriptor > LoadBitmap(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const OUString &rsPathToBitmapNode, const css::uno::Reference< css::drawing::XPresenterHelper > &rxPresenterHelper, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const std::shared_ptr< BitmapDescriptor > &rpDefaultBitmap)
unsigned char sal_uInt8
SvStream & ReadFont(SvStream &rIStm, vcl::Font &rFont)
std::shared_ptr< PaneStyle > mpParentStyle
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
sal_Int32 mnTop
void ProcessFont(const OUString &rsKey, const Reference< beans::XPropertySet > &rxProperties)
StyleAssociations maStyleAssociations
css::uno::Reference< css::uno::XComponentContext > mxContext
Reference< container::XHierarchicalNameAccess > mxThemeRoot
static css::geometry::RealRectangle2D GetTextBoundingBox(const css::uno::Reference< css::rendering::XCanvasFont > &rxFont, const OUString &rsText, const sal_Int8=css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT)
Reference< XSingleServiceFactory > xFactory
std::shared_ptr< PresenterBitmapContainer > GetBitmapContainer() const
Color mnColor
sal_uInt32 mnSize