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