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 #ifndef SDEXT_PRESENTER_TEXT_VIEW_HXX
29 #define SDEXT_PRESENTER_TEXT_VIEW_HXX
30 
31 #include "PresenterTheme.hxx"
32 #include <com/sun/star/accessibility/XAccessibleText.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/geometry/RealPoint2D.hpp>
35 #include <com/sun/star/geometry/RealSize2D.hpp>
36 #include <com/sun/star/i18n/XBreakIterator.hpp>
37 #include <com/sun/star/i18n/XScriptTypeDetector.hpp>
38 #include <com/sun/star/rendering/XCanvas.hpp>
39 #include <com/sun/star/style/ParagraphAdjust.hpp>
40 #include <com/sun/star/text/XText.hpp>
41 #include <com/sun/star/uno/XComponentContext.hpp>
42 #include <cppuhelper/compbase1.hxx>
43 #include <cppuhelper/basemutex.hxx>
44 
45 namespace css = ::com::sun::star;
46 namespace cssu = ::com::sun::star::uno;
47 namespace cssa = ::com::sun::star::accessibility;
48 
49 namespace sdext { namespace presenter {
50 
51 class PresenterTextCaret
52 {
53 public:
54     PresenterTextCaret (
55         const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)>&
56             rCharacterBoundsAccess,
57         const ::boost::function<void(const css::awt::Rectangle&)>&
58             rInvalidator);
59     ~PresenterTextCaret (void);
60 
61     void ShowCaret (void);
62     void HideCaret (void);
63 
64     sal_Int32 GetParagraphIndex (void) const;
65     sal_Int32 GetCharacterIndex (void) const;
66     void SetPosition (
67         const sal_Int32 nParagraphIndex,
68         const sal_Int32 nCharacterIndex);
69 
70     bool IsVisible (void) const;
71 
72     /** Set a (possibly empty) functor that broadcasts changes of the caret
73         position.  This is used when a PresenterTextView object is set at
74         the accessibility object so that accessibility events can be sent
75         when the caret changes position.
76     */
77     void SetCaretMotionBroadcaster (
78         const ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster);
79 
80     css::awt::Rectangle GetBounds (void) const;
81 
82 private:
83     sal_Int32 mnParagraphIndex;
84     sal_Int32 mnCharacterIndex;
85     sal_Int32 mnCaretBlinkTaskId;
86     bool mbIsCaretVisible;
87     const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)> maCharacterBoundsAccess;
88     const ::boost::function<void(const css::awt::Rectangle&)> maInvalidator;
89     ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)> maBroadcaster;
90     css::awt::Rectangle maCaretBounds;
91 
92     void InvertCaret (void);
93 };
94 typedef ::boost::shared_ptr<PresenterTextCaret> SharedPresenterTextCaret;
95 
96 
97 
98 
99 //===== PresenterTextParagraph ================================================
100 
101 class PresenterTextParagraph
102 {
103 public:
104     PresenterTextParagraph (
105         const sal_Int32 nParagraphIndex,
106         const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
107         const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
108         const cssu::Reference<css::text::XTextRange>& rxTextRange,
109         const SharedPresenterTextCaret& rpCaret);
110     PresenterTextParagraph (
111         const sal_Int32 nParagraphIndex,
112         const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
113         const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
114         const ::rtl::OUString& rsText,
115         const SharedPresenterTextCaret& rpCaret);
116 
117     void Paint (
118         const cssu::Reference<css::rendering::XCanvas>& rxCanvas,
119         const css::geometry::RealSize2D& rSize,
120         const PresenterTheme::SharedFontDescriptor& rpFont,
121         const css::rendering::ViewState& rViewState,
122         css::rendering::RenderState& rRenderState,
123         const double nTopOffset,
124         const double nClipTop,
125         const double nClipBottom);
126 
127     sal_Int32 GetParagraphIndex (void) const;
128     double GetTotalTextHeight (void);
129 
130     sal_Int32 GetCharacterOffset (void) const;
131     void SetCharacterOffset (const sal_Int32 nCharacterOffset);
132     sal_Int32 GetCharacterCount (void) const;
133     sal_Unicode GetCharacter (const sal_Int32 nGlobalCharacterIndex) const;
134     ::rtl::OUString GetText (void) const;
135     cssa::TextSegment GetTextSegment (
136         const sal_Int32 nOffset,
137         const sal_Int32 nGlobalCharacterIndex,
138         const sal_Int16 nTextType) const;
139     cssa::TextSegment GetWordTextSegment (
140         const sal_Int32 nOffset,
141         const sal_Int32 nIndex) const;
142     cssa::TextSegment CreateTextSegment (
143         sal_Int32 nStartIndex,
144         sal_Int32 nEndIndex) const;
145     css::awt::Rectangle GetCharacterBounds (
146         sal_Int32 nGlobalCharacterIndex,
147         const bool bCaretBox);
148     sal_Int32 GetIndexAtPoint (const css::awt::Point& rPoint) const;
149     void SetupCellArray (
150         const PresenterTheme::SharedFontDescriptor& rpFont);
151     void Format (
152         const double nY,
153         const double nWidth,
154         const PresenterTheme::SharedFontDescriptor& rpFont);
155     sal_Int32 GetWordBoundary(
156         const sal_Int32 nLocalCharacterIndex,
157         const sal_Int32 nDistance);
158     sal_Int32 GetCaretPosition (void) const;
159     void SetCaretPosition (const sal_Int32 nPosition) const;
160     void SetOrigin (const double nXOrigin, const double nYOrigin);
161     css::awt::Point GetRelativeLocation (void) const;
162     css::awt::Size GetSize (void);
163 
164 private:
165     ::rtl::OUString msParagraphText;
166     const sal_Int32 mnParagraphIndex;
167     SharedPresenterTextCaret mpCaret;
168 
169     /** A portion of a string that encodes one unicode cell.  It describes
170         number of characters in the unicode string that make up the cell and its
171         width in pixel (with respect to some configuration that is stored
172         externally or implicitly).
173     */
174     class Cell
175     {
176     public:
177         Cell (const sal_Int32 nCharacterIndex, const sal_Int32 nCharacterCount, const double nCellWidth);
178         sal_Int32 mnCharacterIndex;
179         sal_Int32 mnCharacterCount;
180         double mnCellWidth;
181     };
182 
183     class Line
184     {
185     public:
186         Line (const sal_Int32 nLineStartCharacterIndex, const sal_Int32 nLineEndCharacterIndex);
187         sal_Int32 mnLineStartCharacterIndex;
188         sal_Int32 mnLineEndCharacterIndex;
189         sal_Int32 mnLineStartCellIndex;
190         sal_Int32 mnLineEndCellIndex;
191         cssu::Reference<css::rendering::XTextLayout> mxLayoutedLine;
192         double mnBaseLine;
193         double mnWidth;
194         cssu::Sequence<css::geometry::RealRectangle2D> maCellBoxes;
195 
196         sal_Int32 GetLength (void) const;
197         void ProvideLayoutedLine (
198             const ::rtl::OUString& rsParagraphText,
199             const PresenterTheme::SharedFontDescriptor& rpFont,
200             const sal_Int8 nTextDirection);
201         void ProvideCellBoxes (void);
202         bool IsEmpty (void) const;
203     };
204 
205 
206     cssu::Reference<css::i18n::XBreakIterator> mxBreakIterator;
207     cssu::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
208     ::std::vector<Line> maLines;
209     ::std::vector<sal_Int32> maWordBoundaries;
210     // Offset of the top of the paragraph with respect to the origin of the
211     // whole text (specified by mnXOrigin and mnYOrigin).
212     double mnVerticalOffset;
213     double mnXOrigin;
214     double mnYOrigin;
215     double mnWidth;
216     double mnAscent;
217     double mnDescent;
218     double mnLineHeight;
219     css::style::ParagraphAdjust meAdjust;
220     sal_Int8 mnWritingMode;
221     /// The index of the first character in this paragraph with respect to
222     /// the whole text.
223     sal_Int32 mnCharacterOffset;
224     ::std::vector<Cell> maCells;
225 
226     void AddWord (
227         const double nWidth,
228         css::i18n::Boundary& rCurrentLine,
229         const sal_Int32 nWordBoundary,
230         const PresenterTheme::SharedFontDescriptor& rpFont);
231     void AddLine (
232         css::i18n::Boundary& rCurrentLine);
233     sal_Int8 GetTextDirection (void) const;
234     bool IsTextReferencePointLeft (void) const;
235 };
236 typedef ::boost::shared_ptr<PresenterTextParagraph> SharedPresenterTextParagraph;
237 
238 
239 
240 
241 /** A simple text view that paints text onto a given canvas.
242 */
243 class PresenterTextView
244 {
245 public:
246 
247     PresenterTextView (
248         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
249         const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
250         const ::boost::function<void(const ::css::awt::Rectangle&)>& rInvalidator);
251     /** Create a new instance that does no output but only provides
252         geometric information to an accessibility object.
253     */
254     PresenterTextView (
255         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
256         const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
257 
258     void SetText (const css::uno::Reference<css::text::XText>& rxText);
259     void SetText (const ::rtl::OUString& rsText);
260     void SetTextChangeBroadcaster (const ::boost::function<void(void)>& rBroadcaster);
261 
262     void SetLocation (const css::geometry::RealPoint2D& rLocation);
263     void SetSize (const css::geometry::RealSize2D& rSize);
264     double GetTotalTextHeight (void);
265 
266     void SetFont (const PresenterTheme::SharedFontDescriptor& rpFont);
267 
268     void SetOffset (
269         const double nLeft,
270         const double nTop);
271 
272     /** Move the caret forward or backward by character or by word.
273         @param nDistance
274             Should be either -1 or +1 to move caret backwards or forwards,
275             respectively.
276         @param nTextType
277             Valid values are the
278             com::sun::star::accessibility::AccessibleTextType constants.
279     */
280     void MoveCaret (
281         const sal_Int32 nDistance,
282         const sal_Int16 nTextType);
283 
284     void Paint (const css::awt::Rectangle& rUpdateBox);
285 
286     SharedPresenterTextCaret GetCaret (void) const;
287 
288     sal_Int32 GetParagraphCount (void) const;
289     SharedPresenterTextParagraph GetParagraph (const sal_Int32 nParagraphIndex) const;
290 
291 private:
292     css::uno::Reference<css::rendering::XCanvas> mxCanvas;
293     bool mbDoOuput;
294     css::uno::Reference<css::i18n::XBreakIterator> mxBreakIterator;
295     css::uno::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
296     css::geometry::RealPoint2D maLocation;
297     css::geometry::RealSize2D maSize;
298     PresenterTheme::SharedFontDescriptor mpFont;
299     ::std::vector<SharedPresenterTextParagraph> maParagraphs;
300     SharedPresenterTextCaret mpCaret;
301     double mnLeftOffset;
302     double mnTopOffset;
303     const ::boost::function<void(const ::css::awt::Rectangle&)> maInvalidator;
304     bool mbIsFormatPending;
305     sal_Int32 mnCharacterCount;
306     ::boost::function<void(void)> maTextChangeBroadcaster;
307 
308     void RequestFormat (void);
309     void Format (void);
310     SharedPresenterTextParagraph GetParagraphForCharacterIndex (const sal_Int32 nCharacterIndex) const;
311     sal_Int32 GetCharacterOffset (const sal_Int32 nParagraphIndex) const;
312     css::awt::Rectangle GetCaretBounds (
313         const sal_Int32 nParagraphIndex,
314         const sal_Int32 nCharacterIndex) const;
315 };
316 
317 } } // end of namespace ::sdext::presenter
318 
319 #endif
320