Line data Source code
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 "PresenterTextView.hxx"
21 : #include "facreg.hxx"
22 :
23 : #include <i18nlangtag/mslangid.hxx>
24 : #include <cppcanvas/vclfactory.hxx>
25 : #include <svl/itempool.hxx>
26 : #include <svl/itemset.hxx>
27 : #include <unotools/linguprops.hxx>
28 : #include <unotools/lingucfg.hxx>
29 : #include <editeng/colritem.hxx>
30 : #include <editeng/editeng.hxx>
31 : #include <editeng/editstat.hxx>
32 : #include <editeng/eeitem.hxx>
33 : #include <editeng/fhgtitem.hxx>
34 : #include <editeng/fontitem.hxx>
35 : #include <svx/xflclit.hxx>
36 : #include <vcl/bitmapex.hxx>
37 : #include <vcl/svapp.hxx>
38 : #include <vcl/virdev.hxx>
39 : #include <com/sun/star/awt/FontDescriptor.hpp>
40 : #include <com/sun/star/awt/Size.hpp>
41 : #include <com/sun/star/rendering/XSpriteCanvas.hpp>
42 : #include <com/sun/star/rendering/XBitmapCanvas.hpp>
43 : #include <com/sun/star/uno/XComponentContext.hpp>
44 : #include <com/sun/star/util/Color.hpp>
45 : #include <com/sun/star/i18n/ScriptType.hpp>
46 :
47 : using namespace ::com::sun::star;
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::lang;
50 :
51 : namespace sd { namespace presenter {
52 :
53 : // PresenterTextView::Implementation
54 : class PresenterTextView::Implementation
55 : {
56 : public:
57 : const OUString msTextPropertyName;
58 : const OUString msBitmapPropertyName;
59 : const OUString msSizePropertyName;
60 : const OUString msBackgroundColorPropertyName;
61 : const OUString msTextColorPropertyName;
62 : const OUString msFontDescriptorPropertyName;
63 : const OUString msTopPropertyName;
64 : const OUString msTopRelativePropertyName;
65 : const OUString msTotalHeightPropertyName;
66 :
67 : Implementation();
68 : ~Implementation();
69 :
70 : void SetCanvas (const cppcanvas::CanvasSharedPtr& rCanvas);
71 : void SetSize (const Size aSize);
72 : void SetBackgroundColor (const Color aColor);
73 : void SetTextColor (const Color aColor);
74 : void SetFontDescriptor (const awt::FontDescriptor& rFontDescriptor);
75 0 : sal_Int32 GetTop() const { return mnTop;}
76 : void SetTop (const sal_Int32 nTop);
77 : void SetText (const OUString& Text);
78 : sal_Int32 ParseDistance (const OUString& rsDistance) const;
79 : Reference<rendering::XBitmap> GetBitmap();
80 : sal_Int32 GetTotalHeight();
81 :
82 : private:
83 : Reference<rendering::XBitmap> mxBitmap;
84 : cppcanvas::CanvasSharedPtr mpCanvas;
85 : VclPtr<VirtualDevice> mpOutputDevice;
86 : EditEngine* mpEditEngine;
87 : SfxItemPool* mpEditEngineItemPool;
88 : Size maSize;
89 : Color maBackgroundColor;
90 : Color maTextColor;
91 : OUString msText;
92 : sal_Int32 mnTop;
93 : sal_Int32 mnTotalHeight;
94 :
95 : EditEngine * GetEditEngine();
96 : EditEngine* CreateEditEngine();
97 : void CheckTop();
98 : };
99 :
100 : // PresenterTextView
101 0 : PresenterTextView::PresenterTextView (const Reference<XComponentContext>& rxContext)
102 : : PresenterTextViewInterfaceBase(),
103 0 : mpImplementation(new Implementation())
104 : {
105 : (void)rxContext;
106 0 : }
107 :
108 0 : PresenterTextView::~PresenterTextView()
109 : {
110 0 : }
111 :
112 0 : void SAL_CALL PresenterTextView::disposing()
113 : {
114 0 : mpImplementation.reset();
115 0 : }
116 :
117 : // XInitialization
118 0 : void SAL_CALL PresenterTextView::initialize (const Sequence<Any>& rArguments)
119 : throw (Exception, RuntimeException, std::exception)
120 : {
121 0 : ThrowIfDisposed();
122 :
123 0 : if (rArguments.getLength() == 1)
124 : {
125 : try
126 : {
127 0 : Reference<rendering::XCanvas> xCanvas (rArguments[0], UNO_QUERY_THROW);
128 0 : if (xCanvas.is())
129 : {
130 : mpImplementation->SetCanvas(
131 0 : cppcanvas::VCLFactory::createCanvas(xCanvas));
132 0 : }
133 : }
134 0 : catch (RuntimeException&)
135 : {
136 0 : throw;
137 : }
138 : }
139 : else
140 : {
141 : throw RuntimeException("PresenterTextView: invalid number of arguments",
142 0 : static_cast<XWeak*>(this));
143 : }
144 0 : }
145 :
146 0 : Any PresenterTextView::GetPropertyValue (const OUString& rsPropertyName)
147 : {
148 0 : ThrowIfDisposed();
149 :
150 0 : if (rsPropertyName == mpImplementation->msBitmapPropertyName)
151 : {
152 0 : return Any(mpImplementation->GetBitmap());
153 : }
154 0 : else if (rsPropertyName == mpImplementation->msTopPropertyName)
155 : {
156 0 : return Any(mpImplementation->GetTop());
157 : }
158 0 : else if (rsPropertyName == mpImplementation->msTotalHeightPropertyName)
159 : {
160 0 : return Any(mpImplementation->GetTotalHeight());
161 : }
162 :
163 0 : return Any();
164 : }
165 :
166 0 : Any PresenterTextView::SetPropertyValue (
167 : const OUString& rsPropertyName,
168 : const css::uno::Any& rValue)
169 : {
170 0 : ThrowIfDisposed();
171 :
172 0 : Any aOldValue;
173 0 : if (rsPropertyName == mpImplementation->msTextPropertyName)
174 : {
175 0 : OUString sText;
176 0 : if (rValue >>= sText)
177 0 : mpImplementation->SetText(sText);
178 : }
179 0 : else if (rsPropertyName == mpImplementation->msSizePropertyName)
180 : {
181 0 : awt::Size aSize;
182 0 : if (rValue >>= aSize)
183 0 : mpImplementation->SetSize(Size(aSize.Width,aSize.Height));
184 : }
185 0 : else if (rsPropertyName == mpImplementation->msBackgroundColorPropertyName)
186 : {
187 0 : util::Color aColor = util::Color();
188 0 : if (rValue >>= aColor)
189 0 : mpImplementation->SetBackgroundColor(Color(aColor));
190 : }
191 0 : else if (rsPropertyName == mpImplementation->msTextColorPropertyName)
192 : {
193 0 : util::Color aColor = util::Color();
194 0 : if (rValue >>= aColor)
195 0 : mpImplementation->SetTextColor(Color(aColor));
196 : }
197 0 : else if (rsPropertyName == mpImplementation->msFontDescriptorPropertyName)
198 : {
199 0 : awt::FontDescriptor aFontDescriptor;
200 0 : if (rValue >>= aFontDescriptor)
201 0 : mpImplementation->SetFontDescriptor(aFontDescriptor);
202 : }
203 0 : else if (rsPropertyName == mpImplementation->msTopPropertyName)
204 : {
205 0 : sal_Int32 nTop = 0;
206 0 : if (rValue >>= nTop)
207 0 : mpImplementation->SetTop(nTop);
208 : }
209 0 : else if (rsPropertyName == mpImplementation->msTopRelativePropertyName)
210 : {
211 0 : OUString sDistance;
212 0 : if (rValue >>= sDistance)
213 : mpImplementation->SetTop(
214 0 : mpImplementation->GetTop()
215 0 : + mpImplementation->ParseDistance(sDistance));
216 : }
217 0 : return aOldValue;
218 : }
219 :
220 0 : void PresenterTextView::ThrowIfDisposed()
221 : throw (::com::sun::star::lang::DisposedException)
222 : {
223 0 : if (PresenterTextViewInterfaceBase::rBHelper.bDisposed
224 0 : || PresenterTextViewInterfaceBase::rBHelper.bInDispose
225 0 : || mpImplementation.get()==NULL)
226 : {
227 : throw lang::DisposedException ("PresenterTextView object has already been disposed",
228 0 : static_cast<uno::XWeak*>(this));
229 : }
230 0 : }
231 :
232 : // PresenterTextView::Implementation
233 0 : PresenterTextView::Implementation::Implementation()
234 : : msTextPropertyName("Text"),
235 : msBitmapPropertyName("Bitmap"),
236 : msSizePropertyName("Size"),
237 : msBackgroundColorPropertyName("BackgroundColor"),
238 : msTextColorPropertyName("TextColor"),
239 : msFontDescriptorPropertyName("FontDescriptor"),
240 : msTopPropertyName("Top"),
241 : msTopRelativePropertyName("RelativeTop"),
242 : msTotalHeightPropertyName("TotalHeight"),
243 : mxBitmap(),
244 : mpCanvas(),
245 0 : mpOutputDevice(VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), 0, 0)),
246 : mpEditEngine(NULL),
247 0 : mpEditEngineItemPool(EditEngine::CreatePool()),
248 : maSize(100,100),
249 : maBackgroundColor(0xffffffff),
250 : maTextColor(0x00000000),
251 : msText(),
252 : mnTop(0),
253 0 : mnTotalHeight(-1)
254 : {
255 0 : mpOutputDevice->SetMapMode(MAP_PIXEL);
256 :
257 0 : GetEditEngine();
258 0 : }
259 :
260 0 : PresenterTextView::Implementation::~Implementation()
261 : {
262 0 : delete mpEditEngine;
263 0 : SfxItemPool::Free(mpEditEngineItemPool);
264 0 : mpOutputDevice.disposeAndClear();
265 0 : }
266 :
267 0 : EditEngine * PresenterTextView::Implementation::GetEditEngine()
268 : {
269 0 : if (mpEditEngine == NULL)
270 0 : mpEditEngine = CreateEditEngine ();
271 0 : return mpEditEngine;
272 : }
273 :
274 0 : EditEngine* PresenterTextView::Implementation::CreateEditEngine()
275 : {
276 0 : EditEngine* pEditEngine = mpEditEngine;
277 0 : if (pEditEngine == NULL)
278 : {
279 :
280 : // set fonts to be used
281 :
282 0 : SvtLinguOptions aOpt;
283 0 : SvtLinguConfig().GetOptions( aOpt );
284 :
285 : struct FontDta {
286 : sal_Int16 nFallbackLang;
287 : sal_Int16 nLang;
288 : DefaultFontType nFontType;
289 : sal_uInt16 nFontInfoId;
290 : } aTable[3] =
291 : {
292 : // info to get western font to be used
293 : { LANGUAGE_ENGLISH_US, LANGUAGE_NONE,
294 : DefaultFontType::SERIF, EE_CHAR_FONTINFO },
295 : // info to get CJK font to be used
296 : { LANGUAGE_JAPANESE, LANGUAGE_NONE,
297 : DefaultFontType::CJK_TEXT, EE_CHAR_FONTINFO_CJK },
298 : // info to get CTL font to be used
299 : { LANGUAGE_ARABIC_SAUDI_ARABIA, LANGUAGE_NONE,
300 : DefaultFontType::CTL_TEXT, EE_CHAR_FONTINFO_CTL }
301 0 : };
302 0 : aTable[0].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN);
303 0 : aTable[1].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CJK, ::com::sun::star::i18n::ScriptType::ASIAN);
304 0 : aTable[2].nLang = MsLangId::resolveSystemLanguageByScriptType(aOpt.nDefaultLanguage_CTL, ::com::sun::star::i18n::ScriptType::COMPLEX);
305 :
306 0 : for (int i = 0; i < 3; ++i)
307 : {
308 0 : const FontDta &rFntDta = aTable[i];
309 0 : LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
310 0 : rFntDta.nFallbackLang : rFntDta.nLang;
311 : vcl::Font aFont = OutputDevice::GetDefaultFont(
312 0 : rFntDta.nFontType, nLang, GetDefaultFontFlags::OnlyOne);
313 : mpEditEngineItemPool->SetPoolDefaultItem(
314 : SvxFontItem(
315 : aFont.GetFamily(),
316 0 : aFont.GetName(),
317 0 : aFont.GetStyleName(),
318 : aFont.GetPitch(),
319 0 : aFont.GetCharSet(),
320 0 : rFntDta.nFontInfoId));
321 0 : }
322 :
323 0 : pEditEngine = new EditEngine (mpEditEngineItemPool);
324 :
325 0 : pEditEngine->EnableUndo (true);
326 : pEditEngine->SetDefTab (sal_uInt16(
327 0 : Application::GetDefaultDevice()->GetTextWidth(OUString("XXXX"))));
328 :
329 : pEditEngine->SetControlWord(
330 0 : EEControlBits(pEditEngine->GetControlWord() | EEControlBits::AUTOINDENTING) &
331 0 : EEControlBits(~EEControlBits::UNDOATTRIBS) &
332 0 : EEControlBits(~EEControlBits::PASTESPECIAL) );
333 :
334 0 : pEditEngine->SetWordDelimiters (" .=+-*/(){}[];\"");
335 0 : pEditEngine->SetRefMapMode (MAP_PIXEL);
336 0 : pEditEngine->SetPaperSize (Size(800, 0));
337 0 : pEditEngine->EraseVirtualDevice();
338 0 : pEditEngine->ClearModifyFlag();
339 : }
340 :
341 0 : return pEditEngine;
342 : }
343 :
344 0 : void PresenterTextView::Implementation::SetCanvas (const cppcanvas::CanvasSharedPtr& rpCanvas)
345 : {
346 0 : mpCanvas = rpCanvas;
347 0 : mxBitmap = NULL;
348 0 : }
349 :
350 0 : void PresenterTextView::Implementation::SetSize (const Size aSize)
351 : {
352 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
353 :
354 0 : maSize = aSize;
355 0 : mpEditEngine->SetPaperSize(maSize);
356 0 : mnTotalHeight = -1;
357 0 : mxBitmap = NULL;
358 0 : }
359 :
360 0 : void PresenterTextView::Implementation::SetBackgroundColor (const Color aColor)
361 : {
362 0 : maBackgroundColor = aColor;
363 0 : mxBitmap = NULL;
364 :
365 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
366 : DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
367 0 : mpEditEngine->SetBackgroundColor(aColor);
368 0 : mpEditEngine->EnableAutoColor(false);
369 0 : mpEditEngine->ForceAutoColor(false);
370 0 : }
371 :
372 0 : void PresenterTextView::Implementation::SetTextColor (const Color aColor)
373 : {
374 0 : maTextColor = aColor;
375 0 : mxBitmap = NULL;
376 :
377 : DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
378 0 : mpEditEngineItemPool->SetPoolDefaultItem(SvxColorItem(aColor, EE_CHAR_COLOR));
379 0 : }
380 :
381 0 : void PresenterTextView::Implementation::SetFontDescriptor (
382 : const awt::FontDescriptor& rFontDescriptor)
383 : {
384 0 : mxBitmap = NULL;
385 :
386 : DBG_ASSERT(mpEditEngineItemPool!=NULL, "EditEngineItemPool missing");
387 :
388 0 : const sal_Int32 nFontHeight = rFontDescriptor.Height;
389 :
390 : SvxFontHeightItem aFontHeight(
391 : Application::GetDefaultDevice()->LogicToPixel(
392 0 : Size(0, nFontHeight), MapMode (MAP_POINT)).Height(),
393 : 100,
394 0 : EE_CHAR_FONTHEIGHT);
395 0 : mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
396 0 : aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CJK);
397 0 : mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
398 0 : aFontHeight.SetWhich (EE_CHAR_FONTHEIGHT_CTL);
399 0 : mpEditEngineItemPool->SetPoolDefaultItem( aFontHeight);
400 :
401 0 : SvxFontItem aSvxFontItem (EE_CHAR_FONTINFO);
402 0 : aSvxFontItem.SetFamilyName( rFontDescriptor.Name );
403 0 : mpEditEngineItemPool->SetPoolDefaultItem(aSvxFontItem);
404 :
405 0 : mnTotalHeight = -1;
406 0 : mxBitmap = NULL;
407 :
408 0 : CheckTop();
409 0 : mnTotalHeight = -1;
410 0 : }
411 :
412 0 : void PresenterTextView::Implementation::SetTop (const sal_Int32 nTop)
413 : {
414 0 : if (nTop == mnTop)
415 0 : return;
416 :
417 0 : mnTop = nTop;
418 0 : mxBitmap = NULL;
419 0 : CheckTop();
420 : }
421 :
422 0 : void PresenterTextView::Implementation::SetText (const OUString& rText)
423 : {
424 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
425 0 : msText = rText;
426 0 : mpEditEngine->SetPaperSize(maSize);
427 0 : mnTotalHeight = -1;
428 0 : mxBitmap = NULL;
429 0 : }
430 :
431 0 : sal_Int32 PresenterTextView::Implementation::ParseDistance (const OUString& rsDistance) const
432 : {
433 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
434 0 : sal_Int32 nDistance (0);
435 0 : if (rsDistance.endsWith("px"))
436 : {
437 0 : nDistance = rsDistance.copy(0,rsDistance.getLength()-2).toInt32();
438 : }
439 0 : else if (rsDistance.endsWith("l"))
440 : {
441 0 : const sal_Int32 nLines (rsDistance.copy(0,rsDistance.getLength()-1).toInt32());
442 : // Take the height of the first line as the height of every line.
443 0 : const sal_uInt32 nFirstLineHeight (mpEditEngine->GetLineHeight(0,0));
444 0 : nDistance = nFirstLineHeight * nLines;
445 : }
446 :
447 0 : return nDistance;
448 : }
449 :
450 0 : Reference<rendering::XBitmap> PresenterTextView::Implementation::GetBitmap()
451 : {
452 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
453 :
454 0 : if ( ! mxBitmap.is())
455 : {
456 0 : mpOutputDevice.disposeAndClear();
457 0 : mpOutputDevice = VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), 0, 0);
458 0 : mpOutputDevice->SetMapMode(MAP_PIXEL);
459 0 : mpOutputDevice->SetOutputSizePixel(maSize, true);
460 0 : mpOutputDevice->SetLineColor();
461 0 : mpOutputDevice->SetFillColor();
462 0 : mpOutputDevice->SetBackground(Wallpaper());
463 0 : mpOutputDevice->Erase();
464 :
465 0 : MapMode aMapMode (mpOutputDevice->GetMapMode());
466 0 : aMapMode.SetOrigin(Point(0,0));
467 0 : mpOutputDevice->SetMapMode(aMapMode);
468 0 : const Rectangle aWindowBox (Point(0,0), maSize);
469 0 : mpOutputDevice->DrawRect(aWindowBox);
470 :
471 0 : mpEditEngine->Clear();
472 0 : mpEditEngine->SetText(msText);
473 0 : mpEditEngine->SetPaperSize(maSize);
474 :
475 0 : mpEditEngine->Draw(mpOutputDevice, aWindowBox, Point(0,mnTop));
476 :
477 0 : const BitmapEx aBitmap (mpOutputDevice->GetBitmapEx(Point(0,0), maSize));
478 0 : mxBitmap = cppcanvas::VCLFactory::createBitmap(
479 : mpCanvas,
480 : aBitmap
481 0 : )->getUNOBitmap();
482 : }
483 0 : return mxBitmap;
484 : }
485 :
486 0 : sal_Int32 PresenterTextView::Implementation::GetTotalHeight()
487 : {
488 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
489 :
490 0 : if (mnTotalHeight < 0)
491 : {
492 0 : if ( ! mxBitmap.is())
493 0 : GetBitmap();
494 0 : mnTotalHeight = mpEditEngine->GetTextHeight();
495 : }
496 0 : return mnTotalHeight;
497 : }
498 :
499 0 : void PresenterTextView::Implementation::CheckTop()
500 : {
501 : DBG_ASSERT(mpEditEngine!=NULL, "EditEngine missing");
502 :
503 0 : if (mpEditEngine!=NULL && mnTotalHeight < 0)
504 0 : mnTotalHeight = mpEditEngine->GetTextHeight();
505 0 : if (mpEditEngine!=NULL && mnTop >= mnTotalHeight)
506 0 : mnTop = mnTotalHeight - mpEditEngine->GetLineHeight(0,0);
507 :
508 0 : if (mnTotalHeight < maSize.Height())
509 0 : mnTop = 0;
510 :
511 0 : if (mnTotalHeight - mnTop < maSize.Height())
512 0 : mnTop = mnTotalHeight - maSize.Height();
513 :
514 0 : if (mnTop < 0)
515 0 : mnTop = 0;
516 0 : }
517 :
518 : } } // end of namespace ::sd::presenter
519 :
520 :
521 : extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
522 0 : com_sun_star_comp_Draw_PresenterTextView_get_implementation(::com::sun::star::uno::XComponentContext* context,
523 : ::com::sun::star::uno::Sequence<css::uno::Any> const &)
524 : {
525 0 : return cppu::acquire(new sd::presenter::PresenterTextView(context));
526 : }
527 :
528 :
529 :
530 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|