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