merge the formfield patch from ooo-build
[ooovba.git] / sd / source / ui / tools / PreviewRenderer.cxx
blobcee7400f94df7719b35856a14984271d12a347ac
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PreviewRenderer.cxx,v $
10 * $Revision: 1.16.34.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "PreviewRenderer.hxx"
36 #include "DrawDocShell.hxx"
37 #include "drawdoc.hxx"
38 #include "drawview.hxx"
39 #include "sdpage.hxx"
40 #include "ViewShell.hxx"
41 #include <vcl/virdev.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/svdoutl.hxx>
44 #include <svx/eeitem.hxx>
45 #include <svx/editstat.hxx>
46 #include <tools/link.hxx>
47 #include <vcl/svapp.hxx>
50 namespace sd {
52 const int PreviewRenderer::snSubstitutionTextSize = 11;
53 const int PreviewRenderer::snFrameWidth = 1;
55 PreviewRenderer::PreviewRenderer (
56 OutputDevice* pTemplate,
57 const bool bHasFrame)
58 : mpPreviewDevice (new VirtualDevice()),
59 mpView(NULL),
60 mpDocShellOfView(NULL),
61 mnWidthOfView(0),
62 maFrameColor (svtools::ColorConfig().GetColorValue(svtools::DOCBOUNDARIES).nColor),
63 mbHasFrame(bHasFrame)
65 if (pTemplate != NULL)
67 mpPreviewDevice->SetDigitLanguage (pTemplate->GetDigitLanguage());
68 mpPreviewDevice->SetBackground(pTemplate->GetBackground());
70 else
71 mpPreviewDevice->SetBackground(Wallpaper(COL_WHITE));
77 PreviewRenderer::~PreviewRenderer (void)
79 if (mpDocShellOfView != NULL)
80 EndListening (*mpDocShellOfView);
86 Image PreviewRenderer::RenderPage (
87 const SdPage* pPage,
88 const sal_Int32 nWidth,
89 const String& rSubstitutionText,
90 const bool bObeyHighContrastMode)
92 if (pPage != NULL)
94 const Size aPageModelSize (pPage->GetSize());
95 const double nAspectRatio (
96 double(aPageModelSize.Width()) / double(aPageModelSize.Height()));
97 const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0);
98 const sal_Int32 nHeight (sal::static_int_cast<sal_Int32>(
99 (nWidth - 2*nFrameWidth) / nAspectRatio + 2*nFrameWidth + 0.5));
100 return RenderPage (pPage, Size(nWidth,nHeight), rSubstitutionText, bObeyHighContrastMode);
102 else
103 return Image();
109 Image PreviewRenderer::RenderPage (
110 const SdPage* pPage,
111 Size aPixelSize,
112 const String& rSubstitutionText,
113 const bool bObeyHighContrastMode)
115 Image aPreview;
117 if (pPage != NULL)
121 if (Initialize (pPage, aPixelSize, bObeyHighContrastMode))
123 PaintPage (pPage);
124 PaintSubstitutionText (rSubstitutionText);
125 PaintFrame();
127 Size aSize (mpPreviewDevice->GetOutputSizePixel());
128 aPreview = mpPreviewDevice->GetBitmap (
129 mpPreviewDevice->PixelToLogic(Point(0,0)),
130 mpPreviewDevice->PixelToLogic(aSize));
132 Cleanup();
135 catch (const com::sun::star::uno::Exception&)
137 OSL_TRACE("PreviewRenderer::RenderPage: caught exception");
141 return aPreview;
147 Image PreviewRenderer::RenderSubstitution (
148 const Size& rPreviewPixelSize,
149 const String& rSubstitutionText)
151 Image aPreview;
155 // Set size.
156 mpPreviewDevice->SetOutputSizePixel(rPreviewPixelSize);
158 // Adjust contrast mode.
159 bool bUseContrast = Application::GetSettings().GetStyleSettings().
160 GetHighContrastMode();
161 mpPreviewDevice->SetDrawMode (bUseContrast
162 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
163 : ViewShell::OUTPUT_DRAWMODE_COLOR);
165 // Set a map mode makes a typical substitution text completely
166 // visible.
167 MapMode aMapMode (mpPreviewDevice->GetMapMode());
168 aMapMode.SetMapUnit(MAP_100TH_MM);
169 double nFinalScale (25.0 * rPreviewPixelSize.Width() / 28000.0);
170 aMapMode.SetScaleX(nFinalScale);
171 aMapMode.SetScaleY(nFinalScale);
172 const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0);
173 aMapMode.SetOrigin(mpPreviewDevice->PixelToLogic(
174 Point(nFrameWidth,nFrameWidth),aMapMode));
175 mpPreviewDevice->SetMapMode (aMapMode);
177 // Clear the background.
178 Rectangle aPaintRectangle (
179 Point(0,0),
180 mpPreviewDevice->GetOutputSizePixel());
181 mpPreviewDevice->EnableMapMode(FALSE);
182 mpPreviewDevice->SetLineColor();
183 svtools::ColorConfig aColorConfig;
184 mpPreviewDevice->SetFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
185 mpPreviewDevice->DrawRect (aPaintRectangle);
186 mpPreviewDevice->EnableMapMode(TRUE);
188 // Paint substitution text and a frame around it.
189 PaintSubstitutionText (rSubstitutionText);
190 PaintFrame();
192 Size aSize (mpPreviewDevice->GetOutputSizePixel());
193 aPreview = mpPreviewDevice->GetBitmap (
194 mpPreviewDevice->PixelToLogic(Point(0,0)),
195 mpPreviewDevice->PixelToLogic(aSize));
197 catch (const com::sun::star::uno::Exception&)
199 OSL_TRACE("PreviewRenderer::RenderPage: caught exception");
202 return aPreview;
208 bool PreviewRenderer::Initialize (
209 const SdPage* pPage,
210 const Size& rPixelSize,
211 const bool bObeyHighContrastMode)
213 bool bSuccess = false;
216 if (pPage == NULL)
217 break;
219 SdrModel* pModel = pPage->GetModel();
220 if (pModel == NULL)
221 break;
223 SetupOutputSize(*pPage, rPixelSize);
225 SdDrawDocument* pDocument
226 = static_cast<SdDrawDocument*>(pPage->GetModel());
227 DrawDocShell* pDocShell = pDocument->GetDocSh();
229 // Create view
230 ProvideView (pDocShell);
231 if (mpView.get() == NULL)
232 break;
234 // Adjust contrast mode.
235 bool bUseContrast (bObeyHighContrastMode
236 && Application::GetSettings().GetStyleSettings().GetHighContrastMode());
237 mpPreviewDevice->SetDrawMode (bUseContrast
238 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
239 : ViewShell::OUTPUT_DRAWMODE_COLOR);
240 mpPreviewDevice->SetSettings(Application::GetSettings());
242 // Tell the view to show the given page.
243 SdPage* pNonConstPage = const_cast<SdPage*>(pPage);
244 if (pPage->IsMasterPage())
246 mpView->ShowSdrPage(mpView->GetModel()->GetMasterPage(pPage->GetPageNum()));
248 else
250 mpView->ShowSdrPage(pNonConstPage);
253 // Make sure that a page view exists.
254 SdrPageView* pPageView = mpView->GetSdrPageView();
255 if (pPageView == NULL)
256 break;
257 // Set background color of page view and outliner.
258 svtools::ColorConfig aColorConfig;
259 const Color aPageBackgroundColor(pPage->GetPageBackgroundColor(pPageView));
260 pPageView->SetApplicationBackgroundColor(aPageBackgroundColor);
261 SdrOutliner& rOutliner (pDocument->GetDrawOutliner(NULL));
262 rOutliner.SetBackgroundColor(aPageBackgroundColor);
263 rOutliner.SetDefaultLanguage(pDocument->GetLanguage(EE_CHAR_LANGUAGE));
264 mpView->SetApplicationBackgroundColor(
265 Color(aColorConfig.GetColorValue(svtools::APPBACKGROUND).nColor));
267 bSuccess = true;
269 while (false);
271 return bSuccess;
277 void PreviewRenderer::Cleanup (void)
279 mpView->HideSdrPage();
285 void PreviewRenderer::PaintPage (const SdPage* pPage)
287 // Paint the page.
288 Rectangle aPaintRectangle (Point(0,0), pPage->GetSize());
289 Region aRegion (aPaintRectangle);
291 // Turn off online spelling and redlining.
292 SdrOutliner* pOutliner = NULL;
293 ULONG nOriginalControlWord = 0;
294 if (mpDocShellOfView!=NULL && mpDocShellOfView->GetDoc()!=NULL)
296 pOutliner = &mpDocShellOfView->GetDoc()->GetDrawOutliner();
297 nOriginalControlWord = pOutliner->GetControlWord();
298 pOutliner->SetControlWord(
299 (nOriginalControlWord & ~EE_CNTRL_ONLINESPELLING));
304 mpView->CompleteRedraw (mpPreviewDevice.get(), aRegion);
306 catch (const ::com::sun::star::uno::Exception&)
308 OSL_TRACE("PreviewRenderer::PaintPage: caught exception");
311 // Restore the previous online spelling and redlining states.
312 if (pOutliner != NULL)
313 pOutliner->SetControlWord(nOriginalControlWord);
319 void PreviewRenderer::PaintSubstitutionText (const String& rSubstitutionText)
321 if (rSubstitutionText.Len() > 0)
323 // Set the font size.
324 const Font& rOriginalFont (mpPreviewDevice->GetFont());
325 Font aFont (mpPreviewDevice->GetSettings().GetStyleSettings().GetAppFont());
326 sal_Int32 nHeight (mpPreviewDevice->PixelToLogic(Size(0,snSubstitutionTextSize)).Height());
327 aFont.SetHeight(nHeight);
328 mpPreviewDevice->SetFont (aFont);
330 // Paint the substitution text.
331 Rectangle aTextBox (
332 Point(0,0),
333 mpPreviewDevice->PixelToLogic(
334 mpPreviewDevice->GetOutputSizePixel()));
335 USHORT nTextStyle =
336 TEXT_DRAW_CENTER
337 | TEXT_DRAW_VCENTER
338 | TEXT_DRAW_MULTILINE
339 | TEXT_DRAW_WORDBREAK;
340 mpPreviewDevice->DrawText (aTextBox, rSubstitutionText, nTextStyle);
342 // Restore the font.
343 mpPreviewDevice->SetFont (rOriginalFont);
350 void PreviewRenderer::PaintFrame (void)
352 if (mbHasFrame)
354 // Paint a frame arround the preview.
355 Rectangle aPaintRectangle (
356 Point(0,0),
357 mpPreviewDevice->GetOutputSizePixel());
358 mpPreviewDevice->EnableMapMode(FALSE);
359 mpPreviewDevice->SetLineColor(maFrameColor);
360 mpPreviewDevice->SetFillColor();
361 mpPreviewDevice->DrawRect(aPaintRectangle);
362 mpPreviewDevice->EnableMapMode(TRUE);
369 void PreviewRenderer::SetupOutputSize (
370 const SdPage& rPage,
371 const Size& rFramePixelSize)
373 // First set the map mode to some arbitrary scale that is numerically
374 // stable.
375 MapMode aMapMode (mpPreviewDevice->GetMapMode());
376 aMapMode.SetMapUnit(MAP_100TH_MM);
377 double nInitialScale = 1;
378 aMapMode.SetScaleX (Fraction(nInitialScale));
379 aMapMode.SetScaleY (Fraction(nInitialScale));
380 aMapMode.SetOrigin (Point(0,0));
382 // Adapt it to the desired width.
383 const Size aPageModelSize (rPage.GetSize());
384 const Size aOutputSize = mpPreviewDevice->LogicToPixel(rPage.GetSize(), aMapMode);
385 const sal_Int32 nFrameWidth (mbHasFrame ? snFrameWidth : 0);
386 const double nFinalScale (nInitialScale * (rFramePixelSize.Width()-2*nFrameWidth)
387 / aOutputSize.Width());
388 aMapMode.SetScaleX (nFinalScale);
389 aMapMode.SetScaleY (nFinalScale);
390 aMapMode.SetOrigin (mpPreviewDevice->PixelToLogic(
391 Point(nFrameWidth,nFrameWidth),aMapMode));
393 mpPreviewDevice->SetMapMode (aMapMode);
394 mpPreviewDevice->SetOutputSizePixel(rFramePixelSize);
400 void PreviewRenderer::ProvideView (DrawDocShell* pDocShell)
402 if (pDocShell != mpDocShellOfView)
404 // Destroy the view that is connected to the current doc shell.
405 mpView.reset (NULL);
407 // Switch our attention, i.e. listening for DYING events, to
408 // the new doc shell.
409 if (mpDocShellOfView != NULL)
410 EndListening (*mpDocShellOfView);
411 mpDocShellOfView = pDocShell;
412 if (mpDocShellOfView != NULL)
413 StartListening (*mpDocShellOfView);
415 if (mpView.get() == NULL)
417 mpView.reset (new DrawView (pDocShell, mpPreviewDevice.get(), NULL));
419 mpView->SetPreviewRenderer( sal_True );
420 mpView->SetBordVisible(FALSE);
421 mpView->SetPageBorderVisible(FALSE);
422 mpView->SetPageVisible(TRUE);
428 Image PreviewRenderer::ScaleBitmap (
429 const BitmapEx& rBitmapEx,
430 int nWidth)
432 Image aPreview;
436 // Adjust contrast mode.
437 bool bUseContrast = Application::GetSettings().GetStyleSettings().
438 GetHighContrastMode();
439 mpPreviewDevice->SetDrawMode (bUseContrast
440 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
441 : ViewShell::OUTPUT_DRAWMODE_COLOR);
443 // Set output size.
444 Size aSize (rBitmapEx.GetSizePixel());
445 if (aSize.Width() <= 0)
446 break;
447 Size aFrameSize (
448 nWidth,
449 (long)((nWidth*1.0 * aSize.Height()) / aSize.Width() + 0.5));
450 Size aPreviewSize (aFrameSize.Width()-2,aFrameSize.Height()-2);
451 MapMode aMapMode (mpPreviewDevice->GetMapMode());
452 aMapMode.SetMapUnit(MAP_PIXEL);
453 aMapMode.SetOrigin (Point());
454 aMapMode.SetScaleX (1.0);
455 aMapMode.SetScaleY (1.0);
456 mpPreviewDevice->SetMapMode (aMapMode);
457 mpPreviewDevice->SetOutputSize (aFrameSize);
459 // Paint a frame arround the preview.
460 mpPreviewDevice->SetLineColor (maFrameColor);
461 mpPreviewDevice->SetFillColor ();
462 mpPreviewDevice->DrawRect (Rectangle(Point(0,0), aFrameSize));
464 // Paint the bitmap scaled to the desired width.
465 BitmapEx aScaledBitmap (rBitmapEx.GetBitmap());
466 aScaledBitmap.Scale (aPreviewSize, BMP_SCALE_INTERPOLATE);
467 mpPreviewDevice->DrawBitmap (
468 Point(1,1),
469 aPreviewSize,
470 aScaledBitmap.GetBitmap());
472 // Get the resulting bitmap.
473 aPreview = mpPreviewDevice->GetBitmap (Point(0,0), aFrameSize);
475 while (false);
477 return aPreview;
483 void PreviewRenderer::Notify(SfxBroadcaster&, const SfxHint& rHint)
485 if (rHint.IsA(TYPE(SfxSimpleHint))
486 && mpDocShellOfView != NULL)
488 const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, &rHint);
489 if (pSimpleHint != NULL
490 && pSimpleHint->GetId() == SFX_HINT_DYING)
492 // The doc shell is dying. Our view uses its item pool and
493 // has to be destroyed as well. The next call to
494 // ProvideView will create a new one (for another
495 // doc shell, of course.)
496 mpView.reset (NULL);
497 mpDocShellOfView = NULL;
504 } // end of namespace ::sd