1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
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>
52 const int PreviewRenderer::snSubstitutionTextSize
= 11;
53 const int PreviewRenderer::snFrameWidth
= 1;
55 PreviewRenderer::PreviewRenderer (
56 OutputDevice
* pTemplate
,
58 : mpPreviewDevice (new VirtualDevice()),
60 mpDocShellOfView(NULL
),
62 maFrameColor (svtools::ColorConfig().GetColorValue(svtools::DOCBOUNDARIES
).nColor
),
65 if (pTemplate
!= NULL
)
67 mpPreviewDevice
->SetDigitLanguage (pTemplate
->GetDigitLanguage());
68 mpPreviewDevice
->SetBackground(pTemplate
->GetBackground());
71 mpPreviewDevice
->SetBackground(Wallpaper(COL_WHITE
));
77 PreviewRenderer::~PreviewRenderer (void)
79 if (mpDocShellOfView
!= NULL
)
80 EndListening (*mpDocShellOfView
);
86 Image
PreviewRenderer::RenderPage (
88 const sal_Int32 nWidth
,
89 const String
& rSubstitutionText
,
90 const bool bObeyHighContrastMode
)
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
);
109 Image
PreviewRenderer::RenderPage (
112 const String
& rSubstitutionText
,
113 const bool bObeyHighContrastMode
)
121 if (Initialize (pPage
, aPixelSize
, bObeyHighContrastMode
))
124 PaintSubstitutionText (rSubstitutionText
);
127 Size
aSize (mpPreviewDevice
->GetOutputSizePixel());
128 aPreview
= mpPreviewDevice
->GetBitmap (
129 mpPreviewDevice
->PixelToLogic(Point(0,0)),
130 mpPreviewDevice
->PixelToLogic(aSize
));
135 catch (const com::sun::star::uno::Exception
&)
137 OSL_TRACE("PreviewRenderer::RenderPage: caught exception");
147 Image
PreviewRenderer::RenderSubstitution (
148 const Size
& rPreviewPixelSize
,
149 const String
& rSubstitutionText
)
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
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 (
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
);
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");
208 bool PreviewRenderer::Initialize (
210 const Size
& rPixelSize
,
211 const bool bObeyHighContrastMode
)
213 bool bSuccess
= false;
219 SdrModel
* pModel
= pPage
->GetModel();
223 SetupOutputSize(*pPage
, rPixelSize
);
225 SdDrawDocument
* pDocument
226 = static_cast<SdDrawDocument
*>(pPage
->GetModel());
227 DrawDocShell
* pDocShell
= pDocument
->GetDocSh();
230 ProvideView (pDocShell
);
231 if (mpView
.get() == NULL
)
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()));
250 mpView
->ShowSdrPage(pNonConstPage
);
253 // Make sure that a page view exists.
254 SdrPageView
* pPageView
= mpView
->GetSdrPageView();
255 if (pPageView
== NULL
)
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
));
277 void PreviewRenderer::Cleanup (void)
279 mpView
->HideSdrPage();
285 void PreviewRenderer::PaintPage (const SdPage
* pPage
)
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.
333 mpPreviewDevice
->PixelToLogic(
334 mpPreviewDevice
->GetOutputSizePixel()));
338 | TEXT_DRAW_MULTILINE
339 | TEXT_DRAW_WORDBREAK
;
340 mpPreviewDevice
->DrawText (aTextBox
, rSubstitutionText
, nTextStyle
);
343 mpPreviewDevice
->SetFont (rOriginalFont
);
350 void PreviewRenderer::PaintFrame (void)
354 // Paint a frame arround the preview.
355 Rectangle
aPaintRectangle (
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 (
371 const Size
& rFramePixelSize
)
373 // First set the map mode to some arbitrary scale that is numerically
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.
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
,
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
);
444 Size
aSize (rBitmapEx
.GetSizePixel());
445 if (aSize
.Width() <= 0)
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 (
470 aScaledBitmap
.GetBitmap());
472 // Get the resulting bitmap.
473 aPreview
= mpPreviewDevice
->GetBitmap (Point(0,0), aFrameSize
);
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.)
497 mpDocShellOfView
= NULL
;
504 } // end of namespace ::sd