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