xref: /trunk/main/sd/source/ui/presenter/PresenterTextView.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include "PresenterTextView.hxx"
27 
28 #include <i18npool/mslangid.hxx>
29 #include <cppcanvas/vclfactory.hxx>
30 #include <svl/itempool.hxx>
31 #include <svl/itemset.hxx>
32 #include <unotools/linguprops.hxx>
33 #include <unotools/lingucfg.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/editeng.hxx>
36 #include <editeng/editstat.hxx>
37 #include <editeng/eeitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <svx/xflclit.hxx>
41 #include <vcl/bitmapex.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/virdev.hxx>
44 #include <com/sun/star/awt/FontDescriptor.hpp>
45 #include <com/sun/star/awt/Size.hpp>
46 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
47 #include <com/sun/star/util/Color.hpp>
48 #include <com/sun/star/i18n/ScriptType.hpp>
49 
50 
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using ::rtl::OUString;
55 
56 namespace sd { namespace presenter {
57 
58 //===== Service ===============================================================
59 
PresenterTextViewService_createInstance(const Reference<XComponentContext> & rxContext)60 Reference<XInterface> SAL_CALL PresenterTextViewService_createInstance (
61     const Reference<XComponentContext>& rxContext)
62 {
63     return Reference<XInterface>(static_cast<XWeak*>(new PresenterTextView(rxContext)));
64 }
65 
66 
67 
68 
PresenterTextViewService_getImplementationName(void)69 ::rtl::OUString PresenterTextViewService_getImplementationName (void)
70 {
71     return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterTextView");
72 }
73 
74 
75 
76 
PresenterTextViewService_getSupportedServiceNames(void)77 Sequence<rtl::OUString> SAL_CALL PresenterTextViewService_getSupportedServiceNames (void)
78 {
79     static const ::rtl::OUString sServiceName(
80         ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterTextView"));
81     return Sequence<rtl::OUString>(&sServiceName, 1);
82 }
83 
84 
85 
86 //===== PresenterTextView::Implementation =====================================
87 
88 class PresenterTextView::Implementation
89 {
90 public:
91     const OUString msTextPropertyName;
92     const OUString msBitmapPropertyName;
93     const OUString msSizePropertyName;
94     const OUString msBackgroundColorPropertyName;
95     const OUString msTextColorPropertyName;
96     const OUString msFontDescriptorPropertyName;
97     const OUString msTopPropertyName;
98     const OUString msTopRelativePropertyName;
99     const OUString msTotalHeightPropertyName;
100 
101     Implementation (void);
102     ~Implementation (void);
103 
104     void SetCanvas (const cppcanvas::CanvasSharedPtr& rCanvas);
105     void SetSize (const Size aSize);
106     void SetBackgroundColor (const Color aColor);
107     void SetTextColor (const Color aColor);
108     void SetFontDescriptor (const awt::FontDescriptor& rFontDescriptor);
109     sal_Int32 GetTop (void) const;
110     void SetTop (const sal_Int32 nTop);
111     void SetText (const OUString& Text);
112     sal_Int32 ParseDistance (const OUString& rsDistance) const;
113     Reference<rendering::XBitmap> GetBitmap (void);
114     sal_Int32 GetTotalHeight (void);
115 
116 private:
117     Reference<rendering::XBitmap> mxBitmap;
118     cppcanvas::CanvasSharedPtr mpCanvas;
119     VirtualDevice* mpOutputDevice;
120     EditEngine* mpEditEngine;
121     SfxItemPool* mpEditEngineItemPool;
122     Size maSize;
123     Color maBackgroundColor;
124     Color maTextColor;
125     String msText;
126     sal_Int32 mnTop;
127     sal_Int32 mnTotalHeight;
128 
129     EditEngine * GetEditEngine (void);
130     EditEngine* CreateEditEngine (void);
131     void CheckTop (void);
132 };
133 
134 
135 
136 
137 //===== PresenterTextView =====================================================
138 
PresenterTextView(const Reference<XComponentContext> & rxContext)139 PresenterTextView::PresenterTextView (const Reference<XComponentContext>& rxContext)
140     : PresenterTextViewInterfaceBase(),
141       mpImplementation(new Implementation())
142 {
143     (void)rxContext;
144 }
145 
146 
147 
148 
~PresenterTextView(void)149 PresenterTextView::~PresenterTextView (void)
150 {
151 }
152 
153 
154 
155 
disposing(void)156 void SAL_CALL PresenterTextView::disposing (void)
157 {
158     mpImplementation.reset();
159 }
160 
161 
162 
163 
164 //----- XInitialization -------------------------------------------------------
165 
initialize(const Sequence<Any> & rArguments)166 void SAL_CALL PresenterTextView::initialize (const Sequence<Any>& rArguments)
167 {
168     ThrowIfDisposed();
169 
170     if (rArguments.getLength() == 1)
171     {
172         try
173         {
174             Reference<rendering::XBitmapCanvas> xCanvas (rArguments[0], UNO_QUERY_THROW);
175             if (xCanvas.is())
176             {
177                 mpImplementation->SetCanvas(
178                     cppcanvas::VCLFactory::getInstance().createCanvas(xCanvas));
179             }
180         }
181         catch (RuntimeException&)
182         {
183             throw;
184         }
185     }
186     else
187     {
188         throw RuntimeException(
189             OUString::createFromAscii("PresenterTextView: invalid number of arguments"),
190                 static_cast<XWeak*>(this));
191     }
192 }
193 
194 
195 
196 
197 //-----------------------------------------------------------------------------
198 
GetPropertyValue(const OUString & rsPropertyName)199 Any PresenterTextView::GetPropertyValue (const OUString& rsPropertyName)
200 {
201     ThrowIfDisposed();
202 
203     if (rsPropertyName == mpImplementation->msBitmapPropertyName)
204     {
205         return Any(mpImplementation->GetBitmap());
206     }
207     else if (rsPropertyName == mpImplementation->msTopPropertyName)
208     {
209         return Any(mpImplementation->GetTop());
210     }
211     else if (rsPropertyName == mpImplementation->msTotalHeightPropertyName)
212     {
213         return Any(mpImplementation->GetTotalHeight());
214     }
215 
216     return Any();
217 }
218 
219 
220 
221 
SetPropertyValue(const::rtl::OUString & rsPropertyName,const css::uno::Any & rValue)222 Any PresenterTextView::SetPropertyValue (
223     const ::rtl::OUString& rsPropertyName,
224     const css::uno::Any& rValue)
225 {
226     ThrowIfDisposed();
227 
228     Any aOldValue;
229     if (rsPropertyName == mpImplementation->msTextPropertyName)
230     {
231         OUString sText;
232         if (rValue >>= sText)
233             mpImplementation->SetText(sText);
234     }
235     else if (rsPropertyName == mpImplementation->msSizePropertyName)
236     {
237         awt::Size aSize;
238         if (rValue >>= aSize)
239             mpImplementation->SetSize(Size(aSize.Width,aSize.Height));
240     }
241     else if (rsPropertyName == mpImplementation->msBackgroundColorPropertyName)
242     {
243         util::Color aColor = util::Color();
244         if (rValue >>= aColor)
245             mpImplementation->SetBackgroundColor(Color(aColor));
246     }
247     else if (rsPropertyName == mpImplementation->msTextColorPropertyName)
248     {
249         util::Color aColor = util::Color();
250         if (rValue >>= aColor)
251             mpImplementation->SetTextColor(Color(aColor));
252     }
253     else if (rsPropertyName == mpImplementation->msFontDescriptorPropertyName)
254     {
255         awt::FontDescriptor aFontDescriptor;
256         if (rValue >>= aFontDescriptor)
257             mpImplementation->SetFontDescriptor(aFontDescriptor);
258     }
259     else if (rsPropertyName == mpImplementation->msTopPropertyName)
260     {
261         sal_Int32 nTop = 0;
262         if (rValue >>= nTop)
263             mpImplementation->SetTop(nTop);
264     }
265     else if (rsPropertyName == mpImplementation->msTopRelativePropertyName)
266     {
267         OUString sDistance;
268         if (rValue >>= sDistance)
269             mpImplementation->SetTop(
270                 mpImplementation->GetTop()
271                     + mpImplementation->ParseDistance(sDistance));
272     }
273     return aOldValue;
274 }
275 
276 
277 
278 
ThrowIfDisposed(void)279 void PresenterTextView::ThrowIfDisposed (void)
280 {
281     if (PresenterTextViewInterfaceBase::rBHelper.bDisposed
282         || PresenterTextViewInterfaceBase::rBHelper.bInDispose
283         || mpImplementation.get()==NULL)
284     {
285         throw lang::DisposedException (
286             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
287                 "PresenterTextView object has already been disposed")),
288             static_cast<uno::XWeak*>(this));
289     }
290 }
291 
292 
293 
294 
295 //===== PresenterTextView::Implementation =====================================
296 
Implementation(void)297 PresenterTextView::Implementation::Implementation (void)
298     : msTextPropertyName(OUString::createFromAscii("Text")),
299       msBitmapPropertyName(OUString::createFromAscii("Bitmap")),
300       msSizePropertyName(OUString::createFromAscii("Size")),
301       msBackgroundColorPropertyName(OUString::createFromAscii("BackgroundColor")),
302       msTextColorPropertyName(OUString::createFromAscii("TextColor")),
303       msFontDescriptorPropertyName(OUString::createFromAscii("FontDescriptor")),
304       msTopPropertyName(OUString::createFromAscii("Top")),
305       msTopRelativePropertyName(OUString::createFromAscii("RelativeTop")),
306       msTotalHeightPropertyName(OUString::createFromAscii("TotalHeight")),
307       mxBitmap(),
308       mpCanvas(),
309       mpOutputDevice(new VirtualDevice(*Application::GetDefaultDevice(), 0, 0)),
310       mpEditEngine(NULL),
311       mpEditEngineItemPool(EditEngine::CreatePool()),
312       maSize(100,100),
313       maBackgroundColor(0xffffffff),
314       maTextColor(0x00000000),
315       msText(),
316       mnTop(0),
317       mnTotalHeight(-1)
318 {
319     mpOutputDevice->SetMapMode(MAP_PIXEL);
320 
321     GetEditEngine();
322 }
323 
324 
325 
326 
~Implementation(void)327 PresenterTextView::Implementation::~Implementation (void)
328 {
329     delete mpEditEngine;
330     SfxItemPool::Free(mpEditEngineItemPool);
331     delete mpOutputDevice;
332 }
333 
334 
335 
336 
GetEditEngine(void)337 EditEngine * PresenterTextView::Implementation::GetEditEngine (void)
338 {
339     if (mpEditEngine == NULL)
340         mpEditEngine = CreateEditEngine ();
341     return mpEditEngine;
342 }
343 
344 
345 
346 
CreateEditEngine(void)347 EditEngine* PresenterTextView::Implementation::CreateEditEngine (void)
348 {
349     EditEngine* pEditEngine = mpEditEngine;
350     if (pEditEngine == NULL)
351     {
352         //
353         // set fonts to be used
354         //
355         SvtLinguOptions aOpt;
356         SvtLinguConfig().GetOptions( aOpt );
357         //
358         struct FontDta {
359             sal_Int16       nFallbackLang;
360             sal_Int16       nLang;
361             sal_uInt16      nFontType;
362             sal_uInt16      nFontInfoId;
363             } aTable[3] =
364         {
365             // info to get western font to be used
366             {   LANGUAGE_ENGLISH_US,    LANGUAGE_NONE,
367                 DEFAULTFONT_SERIF,      EE_CHAR_FONTINFO },
368             // info to get CJK font to be used
369             {   LANGUAGE_JAPANESE,      LANGUAGE_NONE,
370                 DEFAULTFONT_CJK_TEXT,   EE_CHAR_FONTINFO_CJK },
371             // info to get CTL font to be used
372             {   LANGUAGE_ARABIC_SAUDI_ARABIA,  LANGUAGE_NONE,
373                 DEFAULTFONT_CTL_TEXT,   EE_CHAR_FONTINFO_CTL }
374         };
375         aTable[0].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN);
376         aTable[1].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CJK, ::com::sun::star::i18n::ScriptType::ASIAN);
377         aTable[2].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CTL, ::com::sun::star::i18n::ScriptType::COMPLEX);
378         //
379         for (int i = 0;  i < 3;  ++i)
380         {
381             const FontDta &rFntDta = aTable[i];
382             LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
383                 rFntDta.nFallbackLang : rFntDta.nLang;
384             Font aFont = Application::GetDefaultDevice()->GetDefaultFont(
385                 rFntDta.nFontType, nLang, DEFAULTFONT_FLAGS_ONLYONE);
386             mpEditEngineItemPool->SetPoolDefaultItem(
387                 SvxFontItem(
388                     aFont.GetFamily(),
389                     aFont.GetName(),
390                     aFont.GetStyleName(),
391                     aFont.GetPitch(),
392                     aFont.GetCharSet(),
393                     rFntDta.nFontInfoId));
394         }
395 
396 
397         pEditEngine = new EditEngine (mpEditEngineItemPool);
398 
399         pEditEngine->EnableUndo (sal_True);
400         pEditEngine->SetDefTab (sal_uInt16(
401             Application::GetDefaultDevice()->GetTextWidth(
402                 UniString::CreateFromAscii("XXXX"))));
403 
404         pEditEngine->SetControlWord(
405                 (pEditEngine->GetControlWord()
406                     | EE_CNTRL_AUTOINDENTING) &
407                 (~EE_CNTRL_UNDOATTRIBS) &
408                 (~EE_CNTRL_PASTESPECIAL));
409 
410         pEditEngine->SetWordDelimiters (
411             UniString::CreateFromAscii(" .=+-*/(){}[];\""));
412         pEditEngine->SetRefMapMode (MAP_PIXEL);
413         pEditEngine->SetPaperSize (Size(800, 0));
414         pEditEngine->EraseVirtualDevice();
415         pEditEngine->ClearModifyFlag();
416     }
417 
418     return pEditEngine;
419 }
420 
421 
422 
423 
SetCanvas(const cppcanvas::CanvasSharedPtr & rpCanvas)424 void PresenterTextView::Implementation::SetCanvas (const cppcanvas::CanvasSharedPtr& rpCanvas)
425 {
426     mpCanvas = rpCanvas;
427     mxBitmap = NULL;
428 }
429 
430 
431 
432 
SetSize(const Size aSize)433 void PresenterTextView::Implementation::SetSize (const Size aSize)
434 {
435     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
436 
437     maSize = aSize;
438     mpEditEngine->SetPaperSize(maSize);
439     mnTotalHeight = -1;
440     mxBitmap = NULL;
441 }
442 
443 
444 
445 
SetBackgroundColor(const Color aColor)446 void PresenterTextView::Implementation::SetBackgroundColor (const Color aColor)
447 {
448     maBackgroundColor = aColor;
449     mxBitmap = NULL;
450 
451     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
452     DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
453     mpEditEngine->SetBackgroundColor(aColor);
454     mpEditEngine->EnableAutoColor(sal_False);
455     mpEditEngine->ForceAutoColor(sal_False);
456 }
457 
458 
459 
460 
SetTextColor(const Color aColor)461 void PresenterTextView::Implementation::SetTextColor (const Color aColor)
462 {
463     maTextColor = aColor;
464     mxBitmap = NULL;
465 
466     DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
467     mpEditEngineItemPool->SetPoolDefaultItem(SvxColorItem(aColor, EE_CHAR_COLOR));
468 }
469 
470 
471 
472 
SetFontDescriptor(const awt::FontDescriptor & rFontDescriptor)473 void PresenterTextView::Implementation::SetFontDescriptor (
474     const awt::FontDescriptor& rFontDescriptor)
475 {
476     mxBitmap = NULL;
477 
478     DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
479 
480     const sal_Int32 nFontHeight = rFontDescriptor.Height;
481 
482     SvxFontHeightItem aFontHeight(
483         Application::GetDefaultDevice()->LogicToPixel(
484             Size(0, nFontHeight), MapMode (MAP_POINT)).Height(),
485         100,
486         EE_CHAR_FONTHEIGHT);
487     mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
488     aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CJK);
489     mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
490     aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CTL);
491     mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
492 
493     SvxFontItem aSvxFontItem (EE_CHAR_FONTINFO);
494     aSvxFontItem.SetFamilyName( rFontDescriptor.Name );
495     mpEditEngineItemPool->SetPoolDefaultItem(aSvxFontItem);
496 
497     mnTotalHeight = -1;
498     mxBitmap = NULL;
499 
500     CheckTop();
501     mnTotalHeight = -1;
502 }
503 
504 
505 
506 
GetTop(void) const507 sal_Int32 PresenterTextView::Implementation::GetTop (void) const
508 {
509     return mnTop;
510 }
511 
512 
513 
514 
SetTop(const sal_Int32 nTop)515 void PresenterTextView::Implementation::SetTop (const sal_Int32 nTop)
516 {
517     if (nTop == mnTop)
518         return;
519 
520     mnTop = nTop;
521     mxBitmap = NULL;
522     CheckTop();
523 }
524 
525 
526 
527 
SetText(const OUString & rText)528 void PresenterTextView::Implementation::SetText (const OUString& rText)
529 {
530     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
531     msText = rText;
532     mpEditEngine->SetPaperSize(maSize);
533     mnTotalHeight = -1;
534     mxBitmap = NULL;
535 }
536 
537 
538 
539 
ParseDistance(const OUString & rsDistance) const540 sal_Int32 PresenterTextView::Implementation::ParseDistance (const OUString& rsDistance) const
541 {
542     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
543     sal_Int32 nDistance (0);
544     if (rsDistance.endsWithAsciiL("px", 2))
545     {
546         nDistance = rsDistance.copy(0,rsDistance.getLength()-2).toInt32();
547     }
548     else if (rsDistance.endsWithAsciiL("l", 1))
549     {
550         const sal_Int32 nLines (rsDistance.copy(0,rsDistance.getLength()-1).toInt32());
551         // Take the height of the first line as the height of every line.
552         const sal_uInt32 nFirstLineHeight (mpEditEngine->GetLineHeight(0,0));
553         nDistance = nFirstLineHeight * nLines;
554     }
555 
556     return nDistance;
557 }
558 
559 
560 
561 
GetBitmap(void)562 Reference<rendering::XBitmap> PresenterTextView::Implementation::GetBitmap (void)
563 {
564     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
565 
566     if ( ! mxBitmap.is())
567     {
568         if (mpOutputDevice != NULL)
569             delete mpOutputDevice;
570         mpOutputDevice = new VirtualDevice(*Application::GetDefaultDevice(), 0, 0);
571         mpOutputDevice->SetMapMode(MAP_PIXEL);
572         mpOutputDevice->SetOutputSizePixel(maSize, sal_True);
573         mpOutputDevice->SetLineColor();
574         mpOutputDevice->SetFillColor();
575         mpOutputDevice->SetBackground(Wallpaper());
576         mpOutputDevice->Erase();
577 
578         MapMode aMapMode (mpOutputDevice->GetMapMode());
579         aMapMode.SetOrigin(Point(0,0));
580         mpOutputDevice->SetMapMode(aMapMode);
581         const Rectangle aWindowBox (Point(0,0), maSize);
582         mpOutputDevice->DrawRect(aWindowBox);
583 
584         mpEditEngine->Clear();
585         mpEditEngine->SetText(msText);
586         mpEditEngine->SetPaperSize(maSize);
587 
588         mpEditEngine->Draw(mpOutputDevice, aWindowBox, Point(0,mnTop));
589 
590         const BitmapEx aBitmap (mpOutputDevice->GetBitmapEx(Point(0,0), maSize));
591         mxBitmap = cppcanvas::VCLFactory::getInstance().createBitmap(
592             mpCanvas,
593             aBitmap
594             )->getUNOBitmap();
595     }
596     return mxBitmap;
597 }
598 
599 
600 
601 
GetTotalHeight(void)602 sal_Int32 PresenterTextView::Implementation::GetTotalHeight (void)
603 {
604     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
605 
606     if (mnTotalHeight < 0)
607     {
608         if ( ! mxBitmap.is())
609             GetBitmap();
610         mnTotalHeight = mpEditEngine->GetTextHeight();
611     }
612     return mnTotalHeight;
613 }
614 
615 
616 
617 
CheckTop(void)618 void PresenterTextView::Implementation::CheckTop (void)
619 {
620     DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
621 
622     if (mnTotalHeight < 0)
623         mnTotalHeight = mpEditEngine->GetTextHeight();
624     if (mpEditEngine!=NULL && mnTop >= mnTotalHeight)
625         mnTop = mnTotalHeight - mpEditEngine->GetLineHeight(0,0);
626 
627     if (mnTotalHeight < maSize.Height())
628         mnTop = 0;
629 
630     if (mnTotalHeight - mnTop < maSize.Height())
631         mnTop = mnTotalHeight - maSize.Height();
632 
633     if (mnTop < 0)
634         mnTop = 0;
635 }
636 
637 
638 } } // end of namespace ::sd::presenter
639