32
|
1 |
/*
|
|
2 |
* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description:
|
|
15 |
* CTextLayout implementation using the TAGMA text formatting system.
|
|
16 |
*
|
|
17 |
*/
|
|
18 |
|
|
19 |
|
|
20 |
#include <txtlaydc.h>
|
|
21 |
#include "FRMTLAY.H"
|
|
22 |
#include "FRMCONST.H"
|
|
23 |
#include "FORMUTIL.H"
|
|
24 |
|
|
25 |
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
|
|
26 |
#include "FRMCONST_INTERNAL.H"
|
|
27 |
#include "FRMCONST_PARTNER.H"
|
|
28 |
#include "TAGMA_INTERNAL.H"
|
|
29 |
#include "FRMTLAY_INTERNAL.H"
|
|
30 |
#endif
|
|
31 |
|
|
32 |
const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines
|
|
33 |
// before using background formatting
|
|
34 |
// during page down/up, the number of lines that should remain visible after
|
|
35 |
// the scroll, counting from the first line that is not completely visible.
|
|
36 |
// i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll.
|
|
37 |
// setting it to 1 means make sure that no lines are ever both partially off the
|
|
38 |
// top/bottom before the scroll and partially visible off the bottom/top after
|
|
39 |
// the scroll.
|
|
40 |
// setting it to any number higher means keep that number -1 lines completely
|
|
41 |
// visible before and after the scroll.
|
|
42 |
const TInt KNumberOfLinesToKeepVisibleDuringScroll = 2;
|
|
43 |
/** maximum scroll proportions in thousandths. This overrides
|
|
44 |
the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
|
|
45 |
const TInt KMaxProportionOfScreenToScroll = 1000;
|
|
46 |
/** minimum scroll proportions in thousandths. This overrides
|
|
47 |
the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
|
|
48 |
const TInt KMinProportionOfScreenToScroll = 600;
|
|
49 |
|
|
50 |
|
|
51 |
/**
|
|
52 |
Constructs an iterator over the text referenced by aSource.
|
|
53 |
@param aSource The source of the text to be iterated over.
|
|
54 |
*/
|
|
55 |
CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const MTmSource& aSource)
|
|
56 |
: iSource(&aSource), iCurrentViewIndex(-1)
|
|
57 |
{
|
|
58 |
}
|
|
59 |
|
|
60 |
/**
|
|
61 |
Constructs an iterator over the text formatted by aLayout.
|
|
62 |
@param aLayout The formatter of the text to be iterated over.
|
|
63 |
*/
|
|
64 |
CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const CTextLayout& aLayout)
|
|
65 |
: iSource(aLayout.iSource), iCurrentViewIndex(-1)
|
|
66 |
{
|
|
67 |
}
|
|
68 |
|
|
69 |
/**
|
|
70 |
Gets the specified character without uniting surrogate pairs.
|
|
71 |
@param aIndex The document position to retrieve.
|
|
72 |
@pre 0 <= aIndex && aIndex < {document length}
|
|
73 |
*/
|
|
74 |
TText CTextLayout::TUtf32SourceCache::GetUtf16(TInt aIndex)
|
|
75 |
{
|
|
76 |
TTmCharFormat dummy;
|
|
77 |
if (aIndex < iCurrentViewIndex)
|
|
78 |
{
|
|
79 |
iCurrentViewIndex = 0;
|
|
80 |
iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
|
|
81 |
}
|
|
82 |
TInt currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
|
|
83 |
while (currentViewEnd <= aIndex)
|
|
84 |
{
|
|
85 |
TInt difference = aIndex - iCurrentViewIndex;
|
|
86 |
TInt newIndex = aIndex - (difference >> 1);
|
|
87 |
iCurrentViewIndex = newIndex < currentViewEnd?
|
|
88 |
currentViewEnd : newIndex;
|
|
89 |
iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
|
|
90 |
currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
|
|
91 |
}
|
|
92 |
return iCurrentView[aIndex - iCurrentViewIndex];
|
|
93 |
}
|
|
94 |
|
|
95 |
/**
|
|
96 |
Gets the specified character, uniting surrogate pairs if appropriate.
|
|
97 |
@param aIndex
|
|
98 |
The document position to retrive.
|
|
99 |
@return
|
|
100 |
The character at position aIndex. If aIndex is at the first code of a
|
|
101 |
surrogate pair, the full character is returned. If it is the second of a
|
|
102 |
valid surrogate pair or an unpaired surrogate, the surrogate is returned.
|
|
103 |
*/
|
|
104 |
TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex)
|
|
105 |
{
|
|
106 |
TText code = GetUtf16(aIndex);
|
|
107 |
if (TChar::IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1)
|
|
108 |
{
|
|
109 |
TText code2 = GetUtf16(aIndex + 1);
|
|
110 |
if (TChar::IsLowSurrogate(code2))
|
|
111 |
return TChar::JoinSurrogate(code, code2);
|
|
112 |
}
|
|
113 |
return code;
|
|
114 |
}
|
|
115 |
|
|
116 |
/** Allocates and constructs a CTextLayout object. By default, the formatting
|
|
117 |
is set to the entire document (EFFormatAllText).
|
|
118 |
|
|
119 |
The text needs to be reformatted after a call to this function.
|
|
120 |
|
|
121 |
@param aDoc Pointer to the MLayDoc implementation that is the source of the
|
|
122 |
text and formatting information. Must not be NULL or a panic occurs.
|
|
123 |
@param aWrapWidth The wrapping width in pixels.
|
|
124 |
@return Pointer to the new CTextLayout object. */
|
|
125 |
EXPORT_C CTextLayout *CTextLayout::NewL(MLayDoc *aLayDoc,TInt aWrapWidth)
|
|
126 |
{
|
|
127 |
CTextLayout* t = new(ELeave) CTextLayout;
|
|
128 |
CleanupStack::PushL(t);
|
|
129 |
t->ConstructL(aLayDoc,aWrapWidth);
|
|
130 |
CleanupStack::Pop();
|
|
131 |
return t;
|
|
132 |
}
|
|
133 |
|
|
134 |
EXPORT_C CTextLayout::CTextLayout():
|
|
135 |
iText(NULL),
|
|
136 |
iExcessHeightRequired(0),
|
|
137 |
iWnd(NULL),
|
|
138 |
iBeginRedrawCount(0),
|
|
139 |
iRedrawRect(),
|
|
140 |
iTextViewCursorPos(NULL),
|
|
141 |
iIsWndInExternalRedraw(EFalse),
|
|
142 |
iUnformattedStart(KMaxTInt),
|
|
143 |
iHighlightExtensions(NULL),
|
|
144 |
iSource(NULL)
|
|
145 |
{
|
|
146 |
}
|
|
147 |
|
|
148 |
/** Constructs an object with a text source of aLayDoc and a wrap width of
|
|
149 |
aWrapWidth, with wrapping turned on.
|
|
150 |
*/
|
|
151 |
EXPORT_C void CTextLayout::ConstructL(MLayDoc *aLayDoc,TInt aWrapWidth)
|
|
152 |
{
|
|
153 |
iHighlightExtensions = new(ELeave) TTmHighlightExtensions;
|
|
154 |
CleanupStack::PushL(iHighlightExtensions);
|
|
155 |
iHighlightExtensions->SetAll(0);
|
|
156 |
|
|
157 |
iText = new(ELeave) CTmTextLayout;
|
|
158 |
CleanupStack::PushL(iHighlightExtensions);
|
|
159 |
|
|
160 |
iSource = new(ELeave) TLayDocTextSource;
|
|
161 |
iSource->iLayDoc = aLayDoc;
|
|
162 |
SetWrapWidth(aWrapWidth);
|
|
163 |
SetAmountToFormat(EFFormatAllText);
|
|
164 |
|
|
165 |
CleanupStack::Pop(2);
|
|
166 |
}
|
|
167 |
|
|
168 |
EXPORT_C CTextLayout::~CTextLayout()
|
|
169 |
{
|
|
170 |
delete iHighlightExtensions;
|
|
171 |
iHighlightExtensions = NULL;
|
|
172 |
delete iText;
|
|
173 |
iText = NULL;
|
|
174 |
delete iSource;
|
|
175 |
iSource = NULL;
|
|
176 |
}
|
|
177 |
|
|
178 |
void CTextLayout::SetWindow(RWindow* aWnd)
|
|
179 |
{
|
|
180 |
iWnd = aWnd;
|
|
181 |
}
|
|
182 |
|
|
183 |
void CTextLayout::SetReadyToRedraw()
|
|
184 |
{
|
|
185 |
iReadyToRedraw = ETrue;
|
|
186 |
}
|
|
187 |
|
|
188 |
void CTextLayout::BeginRedraw(const TRect& aRect)
|
|
189 |
{
|
|
190 |
if(!iReadyToRedraw)
|
|
191 |
return;
|
|
192 |
|
|
193 |
if (0 == iBeginRedrawCount++)
|
|
194 |
{
|
|
195 |
iRedrawRect = aRect;
|
|
196 |
if (NULL != iWnd)
|
|
197 |
{
|
|
198 |
if (iWnd->GetDrawRect() == TRect::EUninitialized)
|
|
199 |
{
|
|
200 |
iWnd->Invalidate(aRect);
|
|
201 |
iWnd->BeginRedraw(aRect);
|
|
202 |
}
|
|
203 |
else
|
|
204 |
iIsWndInExternalRedraw = ETrue;
|
|
205 |
}
|
|
206 |
}
|
|
207 |
}
|
|
208 |
|
|
209 |
void CTextLayout::EndRedraw()
|
|
210 |
{
|
|
211 |
if(!iReadyToRedraw)
|
|
212 |
return;
|
|
213 |
|
|
214 |
__ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw));
|
|
215 |
|
|
216 |
if (0 == --iBeginRedrawCount)
|
|
217 |
{
|
|
218 |
if (NULL != iWnd)
|
|
219 |
{
|
|
220 |
if (!iIsWndInExternalRedraw)
|
|
221 |
{
|
|
222 |
iWnd->EndRedraw();
|
|
223 |
iRedrawRect = TRect();
|
|
224 |
}
|
|
225 |
else
|
|
226 |
iIsWndInExternalRedraw = EFalse;
|
|
227 |
}
|
|
228 |
}
|
|
229 |
}
|
|
230 |
|
|
231 |
void CTextLayout::SetExternalDraw(const TRect& aRect)
|
|
232 |
{
|
|
233 |
__ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw));
|
|
234 |
iBeginRedrawCount++;
|
|
235 |
iRedrawRect = aRect;
|
|
236 |
}
|
|
237 |
|
|
238 |
void CTextLayout::ResetExternalDraw()
|
|
239 |
{
|
|
240 |
__ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw));
|
|
241 |
|
|
242 |
iBeginRedrawCount--;
|
|
243 |
iRedrawRect = TRect();
|
|
244 |
}
|
|
245 |
|
|
246 |
TBool CTextLayout::BeginRedrawCalled() const
|
|
247 |
{
|
|
248 |
return iBeginRedrawCount > 0;
|
|
249 |
}
|
|
250 |
|
|
251 |
|
|
252 |
/** Discards all formatting information. This function is used by the CTextView
|
|
253 |
and the printing classes, but should be called by higher-level classes that
|
|
254 |
need to clean up after any CTextLayout function has caused an out-of-memory
|
|
255 |
exception. */
|
|
256 |
EXPORT_C void CTextLayout::DiscardFormat()
|
|
257 |
{
|
|
258 |
iText->Clear();
|
|
259 |
iBandTop = 0;
|
|
260 |
}
|
|
261 |
|
|
262 |
TInt CTextLayout::SetBandTop()
|
|
263 |
{
|
|
264 |
TInt originalBandTop = iBandTop;
|
|
265 |
if (iScrollFlags & EFScrollOnlyToTopsOfLines)
|
|
266 |
{
|
|
267 |
TTmLineInfo line;
|
|
268 |
if (iText->YPosToLine(iBandTop, line))
|
|
269 |
iBandTop = line.iOuterRect.iTl.iY;
|
|
270 |
}
|
|
271 |
return originalBandTop - iBandTop;
|
|
272 |
}
|
|
273 |
|
|
274 |
/** Sets the layout object's source text to aDoc.
|
|
275 |
|
|
276 |
The text needs to be reformatted after a call to this function.
|
|
277 |
|
|
278 |
@param aDoc Pointer to the MLayDoc implementation that is the source of the
|
|
279 |
text and formatting information. Must not be NULL or a panic occurs. */
|
|
280 |
EXPORT_C void CTextLayout::SetLayDoc(MLayDoc *aLayDoc)
|
|
281 |
{
|
|
282 |
iSource->iLayDoc = aLayDoc;
|
|
283 |
}
|
|
284 |
|
|
285 |
/** Sets the wrap width. If the current format mode is screen mode
|
|
286 |
(CLayoutData::EFScreenMode) aWrapWidth is in pixels, otherwise it is in twips.
|
|
287 |
|
|
288 |
The text needs to be reformatted after a call to this function.
|
|
289 |
|
|
290 |
Note:
|
|
291 |
|
|
292 |
A valid wrap width (>0) must be supplied or the expected amount of formatting will
|
|
293 |
not take place. This could lead to panics when trying to retrieve formatting
|
|
294 |
information that does not exist.
|
|
295 |
|
|
296 |
@param aWrapWidth The wrap width in pixels or twips. */
|
|
297 |
EXPORT_C void CTextLayout::SetWrapWidth(TInt aWrapWidth)
|
|
298 |
{
|
|
299 |
if (iSource->iFormatMode == CLayoutData::EFScreenMode)
|
|
300 |
iSource->iWidth = aWrapWidth;
|
|
301 |
else
|
|
302 |
iSource->iWidth = iSource->iFormatDevice->HorizontalTwipsToPixels(aWrapWidth);
|
|
303 |
}
|
|
304 |
|
|
305 |
/** Sets the height of the band in pixels or twips. This is the height of the
|
|
306 |
visible text, or the view window, and it is also the page height for the
|
|
307 |
purposes of scrolling up and down by page. If the current mode is screen mode
|
|
308 |
(CLayoutData::EFScreenMode) or what-you-see-is-what-you-get mode
|
|
309 |
(CLayoutData::EFWysiwygMode), aHeight is in pixels, otherwise it is in twips.
|
|
310 |
|
|
311 |
The text needs to be reformatted after a call to this function.
|
|
312 |
|
|
313 |
Note:
|
|
314 |
|
|
315 |
A valid band height (>0) must be supplied or the expected amount of formatting will
|
|
316 |
not take place. This could lead to panics when trying to retrieve formatting
|
|
317 |
information that does not exist.
|
|
318 |
|
|
319 |
@param aHeight The band height in pixels or twips. */
|
|
320 |
EXPORT_C void CTextLayout::SetBandHeight(TInt aHeight)
|
|
321 |
{
|
|
322 |
iVisibleHeight = aHeight;
|
|
323 |
if (iBandHeight != CLayoutData::EFHeightForFormattingAllText || aHeight < 1)
|
|
324 |
iBandHeight = aHeight;
|
|
325 |
}
|
|
326 |
|
|
327 |
/** Gets the height of the band in pixels or twips.
|
|
328 |
@return The height of the band in pixels or twips. */
|
|
329 |
EXPORT_C TInt CTextLayout::BandHeight() const
|
|
330 |
{
|
|
331 |
return VisibleHeightInPixels();
|
|
332 |
}
|
|
333 |
|
|
334 |
/** Sets the device map used for drawing and formatting. This device map is
|
|
335 |
also used for formatting and drawing paragraph labels unless a separate label
|
|
336 |
device map has been set (see SetLabelsDeviceMap()).
|
|
337 |
|
|
338 |
The text needs to be reformatted after a call to this function.
|
|
339 |
|
|
340 |
Note:
|
|
341 |
|
|
342 |
Although the name of the function suggests that only the image device is set,
|
|
343 |
the formatting device is also set.
|
|
344 |
|
|
345 |
@param aGd The device map used for drawing and formatting. */
|
|
346 |
EXPORT_C void CTextLayout::SetImageDeviceMap(MGraphicsDeviceMap *aDeviceMap)
|
|
347 |
{
|
|
348 |
iSource->iImageDevice = aDeviceMap;
|
|
349 |
iSource->iFormatDevice = aDeviceMap;
|
|
350 |
}
|
|
351 |
|
|
352 |
/** Sets the device map used for formatting and drawing paragraph labels. If
|
|
353 |
not set, the device map used for labels will be the same as that used for the
|
|
354 |
text.
|
|
355 |
|
|
356 |
The text needs to be reformatted after a call to this function.
|
|
357 |
|
|
358 |
@param aDeviceMap The device map used for formatting and drawing paragraph
|
|
359 |
labels. */
|
|
360 |
EXPORT_C void CTextLayout::SetLabelsDeviceMap(MGraphicsDeviceMap *aDeviceMap)
|
|
361 |
{
|
|
362 |
iSource->iLabelsDevice = aDeviceMap;
|
|
363 |
}
|
|
364 |
|
|
365 |
/** Sets whether to format all the text (if aAmountOfFormat is
|
|
366 |
EFFormatAllText), or just the visible band (if aAmountOfFormat is
|
|
367 |
EFFormatBand). If band formatting is selected, enough text is formatted to fill
|
|
368 |
the visible height.
|
|
369 |
|
|
370 |
The text needs to be reformatted after a call to this function.
|
|
371 |
|
|
372 |
@param aAmountOfFormat CTextLayout::EFFormatBand (the default) to format the
|
|
373 |
visible text only. CTextLayout::EFFormatAllText to format all the text in the
|
|
374 |
document. */
|
|
375 |
EXPORT_C void CTextLayout::SetAmountToFormat(TAmountFormatted aAmountOfFormat)
|
|
376 |
{
|
|
377 |
if (aAmountOfFormat == EFFormatBand)
|
|
378 |
iBandHeight = iVisibleHeight;
|
|
379 |
else
|
|
380 |
iBandHeight = CLayoutData::EFHeightForFormattingAllText;
|
|
381 |
}
|
|
382 |
|
|
383 |
/** Tests whether band formatting is on, as set by
|
|
384 |
CTextLayout::SetAmountToFormat().
|
|
385 |
@return ETrue if band formatting is on, EFalse if not. */
|
|
386 |
EXPORT_C TBool CTextLayout::IsFormattingBand() const
|
|
387 |
{
|
|
388 |
return iBandHeight != CLayoutData::EFHeightForFormattingAllText;
|
|
389 |
}
|
|
390 |
|
|
391 |
/** Sets the format mode and wrap width and (for certain format modes only)
|
|
392 |
sets the formatting device.
|
|
393 |
|
|
394 |
The text needs to be reformatted after a call to this function.
|
|
395 |
|
|
396 |
Notes:
|
|
397 |
|
|
398 |
If aFormatMode is CLayoutData::EFWysiwygMode or
|
|
399 |
CLayoutData::EFPrintPreviewMode, the format device is set to aFormatDevice,
|
|
400 |
which must not be NULL.
|
|
401 |
|
|
402 |
If aFormatMode is CLayoutData::EFScreenMode or CLayoutData::EFPrintMode,
|
|
403 |
aFormatDevice is ignored and should be NULL; the format device is set to the
|
|
404 |
image device.
|
|
405 |
|
|
406 |
The wrap width is set in either twips or pixels using the same rule as for
|
|
407 |
SetWrapWidth().
|
|
408 |
|
|
409 |
@param aFormatMode The format mode.
|
|
410 |
@param aWrapWidth The wrap width in pixels or twips.
|
|
411 |
@param aFormatDevice The formatting device or NULL, depending on the format
|
|
412 |
mode. */
|
|
413 |
EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth,
|
|
414 |
MGraphicsDeviceMap* aFormatDevice)
|
|
415 |
{
|
|
416 |
if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode)
|
|
417 |
{
|
|
418 |
__ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet));
|
|
419 |
iSource->iFormatDevice = aFormatDevice;
|
|
420 |
}
|
|
421 |
else
|
|
422 |
iSource->iFormatDevice = iSource->iImageDevice;
|
|
423 |
iSource->iFormatMode = aFormatMode;
|
|
424 |
SetWrapWidth(aWrapWidth);
|
|
425 |
}
|
|
426 |
|
|
427 |
/** Turns wrapping on (if aNoWrapping is EFParagraphsWrappedByDefault) or off
|
|
428 |
(if aNoWrapping is EFAllParagraphsNotWrapped). Overrides the paragraph format
|
|
429 |
when wrapping is turned off -paragraphs are not broken into lines even if the
|
|
430 |
iWrap member of CParaFormat is ETrue. If wrapping is turned on,
|
|
431 |
CParaFormat::iWrap is honoured.
|
|
432 |
|
|
433 |
The text needs to be reformatted after a call to this function.
|
|
434 |
|
|
435 |
@param aNoWrapping EFAllParagraphsNotWrapped (the default) to turn wrapping
|
|
436 |
off, EFParagraphsWrappedByDefault to turn wrapping on. */
|
|
437 |
EXPORT_C void CTextLayout::ForceNoWrapping(TBool aNoWrapping)
|
|
438 |
{
|
|
439 |
if (aNoWrapping)
|
|
440 |
iSource->iFlags &= ~TLayDocTextSource::EWrap;
|
|
441 |
else
|
|
442 |
iSource->iFlags |= TLayDocTextSource::EWrap;
|
|
443 |
}
|
|
444 |
|
|
445 |
/** Tests whether wrapping is on or off.
|
|
446 |
@return ETrue if wrapping is on, EFalse if off. */
|
|
447 |
EXPORT_C TBool CTextLayout::IsWrapping() const
|
|
448 |
{
|
|
449 |
return (iSource->iFlags & TLayDocTextSource::EWrap) != 0;
|
|
450 |
}
|
|
451 |
|
|
452 |
/** Sets the truncation mode. If truncation is on, lines that exceed the wrap
|
|
453 |
width, either because they have no legal line break, or because wrapping is
|
|
454 |
off, are truncated, and an ellipsis is inserted.
|
|
455 |
|
|
456 |
@param aOn If ETrue, lines which extend beyond the wrap width are truncated
|
|
457 |
with an ellipsis character. If EFalse, no ellipsis is used. */
|
|
458 |
EXPORT_C void CTextLayout::SetTruncating(TBool aOn)
|
|
459 |
{
|
|
460 |
if (aOn)
|
|
461 |
iSource->iFlags |= TLayDocTextSource::ETruncateWithEllipsis;
|
|
462 |
else
|
|
463 |
iSource->iFlags &= ~TLayDocTextSource::ETruncateWithEllipsis;
|
|
464 |
}
|
|
465 |
|
|
466 |
/** Tests whether truncation is on (as set by SetTruncating()).
|
|
467 |
@return ETrue if truncation is on, EFalse if not. */
|
|
468 |
EXPORT_C TBool CTextLayout::Truncating() const
|
|
469 |
{
|
|
470 |
return (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis) != 0;
|
|
471 |
}
|
|
472 |
|
|
473 |
/** Sets the ellipsis character to be used if truncation is on. Specify the
|
|
474 |
value 0xFFFFÂ (the illegal Unicode character) if no ellipsis character should
|
|
475 |
be used. By default, the ellipsis character is 0x2026, the ordinary horizontal
|
|
476 |
ellipsis.
|
|
477 |
|
|
478 |
@param aEllipsis The Unicode value of the truncating ellipsis character. */
|
|
479 |
EXPORT_C void CTextLayout::SetTruncatingEllipsis(TChar aEllipsis)
|
|
480 |
{
|
|
481 |
iSource->iEllipsis = aEllipsis;
|
|
482 |
}
|
|
483 |
|
|
484 |
/** Returns the ellipsis character used when truncation is on. The value 0xFFFF
|
|
485 |
(the illegal Unicode character) means that no ellipsis character is appended to
|
|
486 |
truncated text.
|
|
487 |
|
|
488 |
@return The Unicode value of the truncating ellipsis character. */
|
|
489 |
EXPORT_C TChar CTextLayout::TruncatingEllipsis() const
|
|
490 |
{
|
|
491 |
return iSource->iEllipsis;
|
|
492 |
}
|
|
493 |
|
|
494 |
/** Sets the width in pixels of the margin in which labels are drawn.
|
|
495 |
|
|
496 |
The text needs to be reformatted after a call to this function.
|
|
497 |
|
|
498 |
@param aWidth The width in pixels of the labels margin. */
|
|
499 |
EXPORT_C void CTextLayout::SetLabelsMarginWidth(TInt aWidth)
|
|
500 |
{
|
|
501 |
iSource->iLabelsWidth = aWidth;
|
|
502 |
}
|
|
503 |
|
|
504 |
/** Specifies which non-printing characters (e.g. space, paragraph break, etc.)
|
|
505 |
are to be drawn using symbols.
|
|
506 |
|
|
507 |
The text needs to be reformatted after a call to this function.(because
|
|
508 |
non-printing characters may differ in width from their visible
|
|
509 |
representations).
|
|
510 |
|
|
511 |
@param aVisibility Indicates which non-printing characters are drawn using
|
|
512 |
symbols. */
|
|
513 |
EXPORT_C void CTextLayout::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility)
|
|
514 |
{
|
|
515 |
iSource->iNonPrintingCharVisibility = aVisibility;
|
|
516 |
}
|
|
517 |
|
|
518 |
/** Returns which non-printing characters are drawn using symbols.
|
|
519 |
@return Indicates which non-printing characters are drawn using symbols. */
|
|
520 |
EXPORT_C TNonPrintingCharVisibility CTextLayout::NonPrintingCharsVisibility() const
|
|
521 |
{
|
|
522 |
return iSource->iNonPrintingCharVisibility;
|
|
523 |
}
|
|
524 |
|
|
525 |
/** Tests whether background formatting is currently taking place. Background
|
|
526 |
formatting is managed by CTextView, using an active object, when the
|
|
527 |
CTextLayout object is owned by a CTextView object.
|
|
528 |
|
|
529 |
Not generally useful.
|
|
530 |
|
|
531 |
@return ETrue if background formatting is currently taking place. EFalse if not.
|
|
532 |
*/
|
|
533 |
EXPORT_C TBool CTextLayout::IsBackgroundFormatting() const
|
|
534 |
{
|
|
535 |
return iUnformattedStart < KMaxTInt;
|
|
536 |
}
|
|
537 |
|
|
538 |
/** CTextView calls this function when background formatting has ended. It
|
|
539 |
allows the CTextLayout object to discard information used only during
|
|
540 |
background formatting.
|
|
541 |
|
|
542 |
Not generally useful. */
|
|
543 |
EXPORT_C void CTextLayout::NotifyTerminateBackgroundFormatting()
|
|
544 |
{
|
|
545 |
iUnformattedStart = KMaxTInt;
|
|
546 |
}
|
|
547 |
|
|
548 |
|
|
549 |
/** Specifies whether partially displayed lines (at the top and bottom of
|
|
550 |
the view) are to be prevented from being drawn, and whether the top of
|
|
551 |
the display is to be aligned to the nearest line.
|
|
552 |
|
|
553 |
This function takes effect only when the text is next formatted or
|
|
554 |
scrolled.Note:This function was designed for non-editable text in the
|
|
555 |
Agenda application, and there is an important restriction:
|
|
556 |
CTextView functions that reformat the text after editing must not be used
|
|
557 |
while partial lines are excluded; these functions are
|
|
558 |
CTextView::HandleCharEditL(),
|
|
559 |
CTextView::HandleInsertDeleteL() and
|
|
560 |
CTextView::HandleRangeFormatChangeL().
|
|
561 |
|
|
562 |
@param aExcludePartialLines ETrue (the default) to exclude partially
|
|
563 |
displayed lines from the view. EFalse to include them.
|
|
564 |
@deprecated 7.0 */
|
|
565 |
//It did not work, and it was not what the customer wanted. A more comprehensive
|
|
566 |
//solution is being considered.
|
|
567 |
EXPORT_C void CTextLayout::SetExcludePartialLines(TBool) {}
|
|
568 |
|
|
569 |
/** Tests whether partial lines at the top and bottom of the view are
|
|
570 |
currently excluded.
|
|
571 |
|
|
572 |
@return ETrue if partial lines are excluded, EFalse if they are displayed.
|
|
573 |
@deprecated 7.0 */
|
|
574 |
EXPORT_C TBool CTextLayout::ExcludingPartialLines() const
|
|
575 |
{
|
|
576 |
return EFalse;
|
|
577 |
}
|
|
578 |
|
|
579 |
/** Sets the percentage by which font heights are increased in order to provide
|
|
580 |
automatic extra spacing (leading) between lines. This amount is set to
|
|
581 |
CLayoutData::EFFontHeightIncreaseFactor, which is 7, when a CTextLayout object
|
|
582 |
is created.
|
|
583 |
|
|
584 |
The text needs to be reformatted after a call to this function.
|
|
585 |
|
|
586 |
@param aPercentage Factor by which to increase font heights. */
|
|
587 |
EXPORT_C void CTextLayout::SetFontHeightIncreaseFactor(TInt aPercentage)
|
|
588 |
{
|
|
589 |
iSource->iFontHeightIncreaseFactor = aPercentage;
|
|
590 |
}
|
|
591 |
|
|
592 |
/** Returns the font height increase factor as a percentage (i.e. a return
|
|
593 |
value of 7 means that font heights are increased by 7% to provide automatic
|
|
594 |
extra spacing between lines).
|
|
595 |
|
|
596 |
@return Factor by which font heights are increased. */
|
|
597 |
EXPORT_C TInt CTextLayout::FontHeightIncreaseFactor() const
|
|
598 |
{
|
|
599 |
return iSource->iFontHeightIncreaseFactor;
|
|
600 |
}
|
|
601 |
|
|
602 |
/** Sets the minimum line descent in pixels. This amount is set to
|
|
603 |
CLayoutData::EFMinimumLineDescent, which is 3, when a CTextLayout object is
|
|
604 |
created.
|
|
605 |
|
|
606 |
The text needs to be reformatted after a call to this function.
|
|
607 |
|
|
608 |
@param aPixels The minimum line descent in pixels. */
|
|
609 |
EXPORT_C void CTextLayout::SetMinimumLineDescent(TInt aPixels)
|
|
610 |
{
|
|
611 |
iSource->iMinimumLineDescent = aPixels;
|
|
612 |
}
|
|
613 |
|
|
614 |
/** Returns the minimum line descent in pixels.
|
|
615 |
@return The minimum line descent in pixels. */
|
|
616 |
EXPORT_C TInt CTextLayout::MinimumLineDescent() const
|
|
617 |
{
|
|
618 |
return iSource->iMinimumLineDescent;
|
|
619 |
}
|
|
620 |
|
|
621 |
/** Returns the document length in characters, including all the text, not just
|
|
622 |
the formatted portion, but not including the final paragraph delimiter (the
|
|
623 |
"end-of-text character") if any. Thus the length of an empty document is zero.
|
|
624 |
|
|
625 |
@return The number of characters in the document */
|
|
626 |
EXPORT_C TInt CTextLayout::DocumentLength() const
|
|
627 |
{
|
|
628 |
return iSource->DocumentLength();
|
|
629 |
}
|
|
630 |
|
|
631 |
/** Sets aDocPos to the paragraph start and returns the amount by which aDocPos
|
|
632 |
has changed, as a non-negative number.
|
|
633 |
|
|
634 |
@param aDocPos A document position. On return, contains the document position
|
|
635 |
of the first character in the paragraph.
|
|
636 |
@return The number of characters skipped in moving to the new document
|
|
637 |
position. */
|
|
638 |
EXPORT_C TInt CTextLayout::ToParagraphStart(TInt& aDocPos) const
|
|
639 |
{
|
|
640 |
TInt old_pos = aDocPos;
|
|
641 |
aDocPos = iSource->ParagraphStart(aDocPos);
|
|
642 |
return old_pos - aDocPos;
|
|
643 |
}
|
|
644 |
|
|
645 |
/** Returns the height in pixels of any formatted text above the visible
|
|
646 |
region.
|
|
647 |
@return The height in pixels of any formatted text above the visible region. */
|
|
648 |
EXPORT_C TInt CTextLayout::PixelsAboveBand() const
|
|
649 |
{
|
|
650 |
return iBandTop;
|
|
651 |
}
|
|
652 |
|
|
653 |
/** Returns the y coordinate of the bottom of the last formatted line, relative
|
|
654 |
to the top of the visible region.
|
|
655 |
|
|
656 |
@return The y coordinate of the bottom of the last formatted line. */
|
|
657 |
EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const
|
|
658 |
{
|
|
659 |
return Max(0, iText->LayoutHeight() - iBandTop );
|
|
660 |
}
|
|
661 |
|
|
662 |
/** Returns the height in pixels of the formatted text.
|
|
663 |
|
|
664 |
@return The height in pixels of all the formatted text. */
|
|
665 |
EXPORT_C TInt CTextLayout::FormattedHeightInPixels() const
|
|
666 |
{
|
|
667 |
return iText->LayoutHeight();
|
|
668 |
}
|
|
669 |
|
|
670 |
/** Returns the number of fully or partially visible characters in the visible
|
|
671 |
band.
|
|
672 |
|
|
673 |
@param aDocPos On return, contains the document position of the first fully or
|
|
674 |
partially visible character in the band.
|
|
675 |
@return The total number of characters in the band. */
|
|
676 |
EXPORT_C TInt CTextLayout::PosRangeInBand(TInt& aDocPos) const
|
|
677 |
{
|
|
678 |
TTmLineInfo info;
|
|
679 |
if (!iText->YPosToLine(iBandTop,info))
|
|
680 |
{
|
|
681 |
aDocPos = 0;
|
|
682 |
return 0;
|
|
683 |
}
|
|
684 |
aDocPos = info.iStart;
|
|
685 |
int end = iSource->DocumentLength();
|
|
686 |
//INC085809 - less 1 pixel. Rect edge is actually outside bounds
|
|
687 |
if (iText->YPosToLine(iBandTop + VisibleHeightInPixels() - 1,info))
|
|
688 |
end = info.iEnd;
|
|
689 |
return end - aDocPos;
|
|
690 |
}
|
|
691 |
|
|
692 |
/** Tests whether the document position aDocPos is fully or partially visible.
|
|
693 |
If it is, puts the y coordinate of the left-hand end of the baseline of the
|
|
694 |
line containing aDocPos into aXyPos.
|
|
695 |
|
|
696 |
@param aDocPos The document position of interest.
|
|
697 |
@param aXyPos On return, contains the y coordinate of the left-hand end of the
|
|
698 |
baseline of the line containing aDocPos.
|
|
699 |
@return ETrue if the position is visible. EFalse if the position is not visible.
|
|
700 |
*/
|
|
701 |
EXPORT_C TBool CTextLayout::PosInBand(TInt aDocPos,TPoint& aXyPos) const
|
|
702 |
{
|
|
703 |
TTmLineInfo info;
|
|
704 |
TTmDocPos pos(aDocPos, ETrue);
|
|
705 |
TBool result = PosInBand(pos,&info);
|
|
706 |
aXyPos.iX = 0;
|
|
707 |
aXyPos.iY = info.iBaseline;
|
|
708 |
return result;
|
|
709 |
}
|
|
710 |
|
|
711 |
/** Tests whether the document position aDocPos is fully or partially visible.
|
|
712 |
If it is, puts the y coordinate of the left-hand end of the baseline of the
|
|
713 |
line containing aDocPos into aXyPos.
|
|
714 |
|
|
715 |
@param aDocPos The document position of interest.
|
|
716 |
@param aXyPos On return, contains the y coordinate of the left-hand end of the
|
|
717 |
baseline of the line containing aDocPos.
|
|
718 |
@return ETrue if the position is visible. EFalse if the position is not visible.
|
|
719 |
*/
|
|
720 |
EXPORT_C TBool CTextLayout::PosInBand(TTmDocPos aDocPos,TPoint& aXyPos) const
|
|
721 |
{
|
|
722 |
TTmLineInfo info;
|
|
723 |
TBool result = PosInBand(aDocPos,&info);
|
|
724 |
aXyPos.iX = 0;
|
|
725 |
aXyPos.iY = info.iBaseline;
|
|
726 |
return result;
|
|
727 |
}
|
|
728 |
|
|
729 |
/** Tests whether the document position aDocPos is fully or partially visible.
|
|
730 |
If it is, puts the baseline of the line containing aDocPos into aLineInfo.
|
|
731 |
|
|
732 |
@param aDocPos The document position of interest.
|
|
733 |
@param aLineInfo On return, contains the baseline of the line containing
|
|
734 |
aDocPos.
|
|
735 |
|
|
736 |
@return ETrue if the document position aDocPos is fully or partially visible. If
|
|
737 |
so, and if aLineInfo is non-NULL, puts information about the line in aLineInfo.
|
|
738 |
Otherwise, EFalse */
|
|
739 |
EXPORT_C TBool CTextLayout::PosInBand(const TTmDocPos& aDocPos,TTmLineInfo* aLineInfo) const
|
|
740 |
{
|
|
741 |
TTmLineInfo dummy;
|
|
742 |
TTmLineInfo* info_ptr = aLineInfo ? aLineInfo : &dummy;
|
|
743 |
TTagmaForwarder forwarder(*this);
|
|
744 |
if (!forwarder.DocPosToLine(aDocPos,*info_ptr))
|
|
745 |
return FALSE;
|
|
746 |
return info_ptr->iOuterRect.iBr.iY > 0 && info_ptr->iOuterRect.iTl.iY < VisibleHeightInPixels();
|
|
747 |
}
|
|
748 |
|
|
749 |
/** Tests whether the character aDocPos is formatted.
|
|
750 |
|
|
751 |
Note:
|
|
752 |
|
|
753 |
If a section of text contains characters p to q, it contains document positions
|
|
754 |
p to q + 1; but this function returns ETrue for positions p to q only, so it
|
|
755 |
refers to characters, not positions. However, it will return ETrue for q if q is
|
|
756 |
the end of the document.
|
|
757 |
|
|
758 |
@param aDocPos The document position of interest.
|
|
759 |
@return ETrue if the character at the document position specified is formatted.
|
|
760 |
EFalse if not. */
|
|
761 |
EXPORT_C TBool CTextLayout::PosIsFormatted(TInt aDocPos) const
|
|
762 |
{
|
|
763 |
if (aDocPos < iText->StartChar())
|
|
764 |
return FALSE;
|
|
765 |
if (aDocPos >= iText->StartChar() + FormattedLength())
|
|
766 |
return FALSE;
|
|
767 |
return TRUE;
|
|
768 |
}
|
|
769 |
|
|
770 |
/** Gets the document position of the first character in the specified line,
|
|
771 |
counting the first line as line one (not zero) in the band. If the line is
|
|
772 |
after the band, returns the last character position of the band. If there is no
|
|
773 |
formatted text, returns CTextLayout::EFNoCurrentFormat.
|
|
774 |
|
|
775 |
@param aLineNo Line number in formatted text, counting the first line as line
|
|
776 |
one.
|
|
777 |
@return The document position of the first character on the line. */
|
|
778 |
EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const
|
|
779 |
{
|
|
780 |
__ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber));
|
|
781 |
if (iText->StartChar() == iText->EndChar())
|
|
782 |
return EFNoCurrentFormat;
|
|
783 |
aLineNo--;
|
|
784 |
TTmLineInfo info;
|
|
785 |
if (!iText->LineNumberToLine(aLineNo,info))
|
|
786 |
return Min(iText->EndChar(),iSource->DocumentLength());
|
|
787 |
return info.iStart;
|
|
788 |
}
|
|
789 |
|
|
790 |
/** Returns the number of formatted characters. This will be one more than
|
|
791 |
expected if the formatted text runs to the end of the document, because it will
|
|
792 |
include the end-of-text character.
|
|
793 |
|
|
794 |
@return The number of formatted characters in the document. */
|
|
795 |
EXPORT_C TInt CTextLayout::FormattedLength() const
|
|
796 |
{
|
|
797 |
return iText->EndChar() - iText->StartChar();
|
|
798 |
}
|
|
799 |
|
|
800 |
/** Returns the document position of the first formatted character.
|
|
801 |
|
|
802 |
@return The document position of the first formatted character. */
|
|
803 |
EXPORT_C TInt CTextLayout::FirstFormattedPos() const
|
|
804 |
{
|
|
805 |
return iText->StartChar();
|
|
806 |
}
|
|
807 |
|
|
808 |
/** Gets the number of formatted lines.
|
|
809 |
|
|
810 |
@return The number of formatted lines in the document. */
|
|
811 |
EXPORT_C TInt CTextLayout::NumFormattedLines() const
|
|
812 |
{
|
|
813 |
return iText->Lines();
|
|
814 |
}
|
|
815 |
|
|
816 |
/** Returns the line number, counting from 0, of the first fully visible line.
|
|
817 |
|
|
818 |
@return The line number of the first fully visible line. */
|
|
819 |
EXPORT_C TInt CTextLayout::FirstLineInBand() const
|
|
820 |
{
|
|
821 |
TTmLineInfo info;
|
|
822 |
if (!iText->YPosToLine(iBandTop,info))
|
|
823 |
return 0;
|
|
824 |
int line = info.iLineNumber;
|
|
825 |
if (info.iOuterRect.iTl.iY < iBandTop)
|
|
826 |
line++;
|
|
827 |
return line;
|
|
828 |
}
|
|
829 |
|
|
830 |
/** Gets the rectangle enclosing the formatted line that contains or is closest
|
|
831 |
to y coordinate aYPos. If aYPos is above the first formatted line, the
|
|
832 |
rectangle returned is that of the first formatted line. If aYPos is below the
|
|
833 |
last formatted line the rectangle returned is that of the last formatted line.
|
|
834 |
If there is no formatted text, returns CTextLayout::EFNoCurrentFormat.
|
|
835 |
|
|
836 |
@param aYPos The y coordinate of the line of interest.
|
|
837 |
@param aLine On return, contains the rectangle which encloses the line at
|
|
838 |
aYPos.
|
|
839 |
|
|
840 |
@return The line width in pixels. */
|
|
841 |
EXPORT_C TInt CTextLayout::GetLineRect(TInt aYPos,TRect& aRect) const
|
|
842 |
{
|
|
843 |
int y = iBandTop + aYPos;
|
|
844 |
|
|
845 |
// Snap to formatted area.
|
|
846 |
if (y >= iText->LayoutHeight())
|
|
847 |
y = iText->LayoutHeight() - 1;
|
|
848 |
if (y < 0)
|
|
849 |
y = 0;
|
|
850 |
|
|
851 |
TTmLineInfo info;
|
|
852 |
TBool found = iText->YPosToLine(y,info);
|
|
853 |
if (!found)
|
|
854 |
{
|
|
855 |
aRect.SetSize(TSize(0,0));
|
|
856 |
return EFNoCurrentFormat;
|
|
857 |
}
|
|
858 |
|
|
859 |
aRect = info.iOuterRect;
|
|
860 |
aRect.iTl.iX = info.iInnerRect.iTl.iX;
|
|
861 |
aRect.iBr.iX = info.iInnerRect.iBr.iX;
|
|
862 |
aRect.Move(0,-iBandTop);
|
|
863 |
return aRect.Width();
|
|
864 |
}
|
|
865 |
|
|
866 |
/** Returns the height of the paragraph containing aDocPos. If the paragraph is
|
|
867 |
not formatted, returns zero. If the paragraph is partially formatted, returns
|
|
868 |
the height of the formatted part.
|
|
869 |
|
|
870 |
@param aDocPos A document position within the paragraph of interest.
|
|
871 |
@return The height in pixels of the paragraph. Zero if the paragraph is not
|
|
872 |
formatted. */
|
|
873 |
EXPORT_C TInt CTextLayout::ParagraphHeight(TInt aDocPos) const
|
|
874 |
{
|
|
875 |
TRect r;
|
|
876 |
GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
|
|
877 |
return r.Height();
|
|
878 |
}
|
|
879 |
|
|
880 |
/** Returns the rectangle enclosing the paragraph containing aDocPos. If the
|
|
881 |
paragraph is not formatted, returns an empty rectangle. If the paragraph is
|
|
882 |
partially formatted, returns the rectangle enclosing the formatted part.
|
|
883 |
|
|
884 |
@param aDocPos A document position within the paragraph.
|
|
885 |
@return The rectangle which encloses the paragraph containing aDocPos. */
|
|
886 |
EXPORT_C TRect CTextLayout::ParagraphRectL(TInt aDocPos) const
|
|
887 |
{
|
|
888 |
TRect r;
|
|
889 |
GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
|
|
890 |
return r;
|
|
891 |
}
|
|
892 |
|
|
893 |
/** Returns the left and right extremes, in layout coordinates, of the
|
|
894 |
formatted text.
|
|
895 |
|
|
896 |
@param aLeftX On return, contains the x coordinate of the leftmost point of the
|
|
897 |
formatted text.
|
|
898 |
@param aRightX On return, contains the x coordinate of the rightmost point of
|
|
899 |
the formatted text.
|
|
900 |
@param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines.
|
|
901 |
If EFalse, scans all the formatted text.
|
|
902 |
@param aIgnoreWrapCharacters If ETrue, does not include wrap characters in the
|
|
903 |
measurement (paragraph delimiters, forced line breaks, etc.). If EFalse,
|
|
904 |
includes them.
|
|
905 |
@return EFalse if there is no formatted text, otherwise ETrue. */
|
|
906 |
EXPORT_C TBool CTextLayout::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,
|
|
907 |
TBool aOnlyVisibleLines,
|
|
908 |
TBool /*aIgnoreWrapCharacters*/) const
|
|
909 |
{
|
|
910 |
return CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines);
|
|
911 |
//+ implement aIgnoreWrapCharacters? not until clearly specified
|
|
912 |
}
|
|
913 |
|
|
914 |
TBool CTextLayout::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX,
|
|
915 |
TBool aOnlyVisibleLines) const
|
|
916 |
{
|
|
917 |
int top = 0;
|
|
918 |
int bottom = KMaxTInt;
|
|
919 |
if (aOnlyVisibleLines)
|
|
920 |
{
|
|
921 |
top = iBandTop;
|
|
922 |
bottom = iBandTop + VisibleHeightInPixels();
|
|
923 |
}
|
|
924 |
iText->HorizontalExtremes(aLeftX, aRightX, top, bottom);
|
|
925 |
if (0 < aLeftX)
|
|
926 |
aLeftX = 0;
|
|
927 |
if (aRightX < iSource->iWidth)
|
|
928 |
aRightX = iSource->iWidth;
|
|
929 |
return iText->StartChar() < iText->EndChar();
|
|
930 |
}
|
|
931 |
|
|
932 |
TInt CTextLayout::WrapWidth() const
|
|
933 |
{
|
|
934 |
return iSource->iWidth;
|
|
935 |
}
|
|
936 |
|
|
937 |
TBool CTextLayout::GetCursor(const TTmDocPos& aDocPos,TTmCursorPlacement aPlacement,
|
|
938 |
TRect& aLineRect,TPoint& aOrigin,TInt& aWidth,TInt& aAscent,TInt& aDescent) const
|
|
939 |
{
|
|
940 |
TTmLineInfo info;
|
|
941 |
TBool result = iText->GetCursor(aDocPos,aPlacement,info,aOrigin,aWidth,aAscent,aDescent);
|
|
942 |
if (result)
|
|
943 |
{
|
|
944 |
aOrigin.iY -= iBandTop;
|
|
945 |
aLineRect = info.iOuterRect;
|
|
946 |
aLineRect.iTl.iX = info.iInnerRect.iTl.iX;
|
|
947 |
aLineRect.iBr.iX = info.iInnerRect.iBr.iX;
|
|
948 |
aLineRect.Move(0,-iBandTop);
|
|
949 |
}
|
|
950 |
return result;
|
|
951 |
}
|
|
952 |
|
|
953 |
/** Gets the height (ascent + descent) and ascent of the font of the character
|
|
954 |
at aDocPos, as created using the graphics device map used for drawing (the
|
|
955 |
"image device") and returns them in aHeight and aAscent, after increasing
|
|
956 |
aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
|
|
957 |
|
|
958 |
@param aDocPos A document position.
|
|
959 |
@param aHeight On return contains the height in pixels of the character at
|
|
960 |
aDocPos.
|
|
961 |
@param aAscent On return, contains the ascent in pixels of the character at
|
|
962 |
aDocPos. */
|
|
963 |
EXPORT_C void CTextLayout::GetCharacterHeightAndAscentL(TInt aDocPos,TInt& aHeight,TInt& aAscent) const
|
|
964 |
{
|
|
965 |
TPtrC text;
|
|
966 |
TTmCharFormat format;
|
|
967 |
iSource->GetText(aDocPos,text,format);
|
|
968 |
TFontSpec fs;
|
|
969 |
format.iFontSpec.GetTFontSpec(fs);
|
|
970 |
GetFontHeightAndAscentL(fs,aHeight,aAscent);
|
|
971 |
}
|
|
972 |
|
|
973 |
/** Gets the height (ascent + descent) and ascent of the font specified by
|
|
974 |
aFontSpec, as created using the graphics device map used for drawing (the
|
|
975 |
"image device") and puts them into aHeight and aAscent, after increasing
|
|
976 |
aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
|
|
977 |
|
|
978 |
@param aFontSpec Font specification.
|
|
979 |
@param aHeight On return, contains the height in pixels of the font.
|
|
980 |
@param aAscent On return, contains the ascent in pixels of the font. */
|
|
981 |
EXPORT_C void CTextLayout::GetFontHeightAndAscentL(const TFontSpec& aFontSpec,TInt& aHeight,TInt& aAscent) const
|
|
982 |
{
|
|
983 |
CFont* font;
|
|
984 |
MGraphicsDeviceMap& device = iSource->InterpretDevice();
|
|
985 |
User::LeaveIfError(device.GetNearestFontInTwips(font,aFontSpec));
|
|
986 |
aHeight = font->HeightInPixels();
|
|
987 |
int increase = (iSource->iFontHeightIncreaseFactor * aHeight) / 100;
|
|
988 |
aHeight += increase;
|
|
989 |
aAscent = font->AscentInPixels() + increase;
|
|
990 |
device.ReleaseFont(font);
|
|
991 |
}
|
|
992 |
|
|
993 |
/** Returns the index of the nearest character in the document to the window
|
|
994 |
coordinates specified. Sets aPos to the actual position of the intersection
|
|
995 |
of the line's baseline with the character's edge. If aPos is before the start
|
|
996 |
of the formatted area, returns the first formatted character; if it is after
|
|
997 |
the end of the formatted area, returns the position after the last formatted
|
|
998 |
character, or the end of the document, whichever is less.
|
|
999 |
|
|
1000 |
This function is deprecated in v7.0s. Use the more powerful FindXYPos() instead.
|
|
1001 |
|
|
1002 |
@param aPos Contains coordinates to convert to a document position. On return,
|
|
1003 |
contains the exact coordinates of the intersection of the line's baseline with
|
|
1004 |
the character edge at the document position.
|
|
1005 |
@param aFlags Three possible values: 0 is the default, and performs the task at
|
|
1006 |
full accuracy (the function returns the document position of the character edge
|
|
1007 |
nearest to the coordinates). CLayoutData::EFWholeLinesOnly examines lines only
|
|
1008 |
and returns the position at the right end of the line if aPos.iX > 0, otherwise
|
|
1009 |
the position at the left end.
|
|
1010 |
@return The document position of the nearest character to the coordinates, or
|
|
1011 |
of the start or end of the line, depending on the value of aFlags. */
|
|
1012 |
EXPORT_C TInt CTextLayout::XyPosToDocPosL(TPoint &aXyPos,TUint) const
|
|
1013 |
{
|
|
1014 |
if (aXyPos.iY < -iBandTop)
|
|
1015 |
return iText->StartChar();
|
|
1016 |
else if (aXyPos.iY >= iText->LayoutHeight() - iBandTop)
|
|
1017 |
return Min(iText->EndChar(),iSource->DocumentLength());
|
|
1018 |
TTmPosInfo2 pos_info;
|
|
1019 |
TTmLineInfo lineInfo;
|
|
1020 |
FindXyPos(aXyPos,pos_info, &lineInfo);
|
|
1021 |
aXyPos = pos_info.iEdge;
|
|
1022 |
TInt r = pos_info.iDocPos.iPos;
|
|
1023 |
if (!pos_info.iDocPos.iLeadingEdge && lineInfo.iStart != r)
|
|
1024 |
{
|
|
1025 |
r -= 1;
|
|
1026 |
|
|
1027 |
// surrogate support
|
|
1028 |
if ( r > 0 )
|
|
1029 |
{
|
|
1030 |
TPtrC text;
|
|
1031 |
TTmCharFormat format;
|
|
1032 |
|
|
1033 |
iSource->GetText( r - 1, text, format );
|
|
1034 |
if ( text.Length() > 1 )
|
|
1035 |
{
|
|
1036 |
TUint highSurrogate = text[0];
|
|
1037 |
TUint lowSurrogate = text[1];
|
|
1038 |
if ( TChar::IsHighSurrogate( highSurrogate ) &&
|
|
1039 |
TChar::IsLowSurrogate( lowSurrogate ) )
|
|
1040 |
--r;
|
|
1041 |
}
|
|
1042 |
}
|
|
1043 |
}
|
|
1044 |
|
|
1045 |
return r;
|
|
1046 |
}
|
|
1047 |
|
|
1048 |
/** Finds the document position nearest to aXyPos. If aXyPos is in the
|
|
1049 |
formatted text returns ETrue, otherwise returns EFalse. If ETrue is returned,
|
|
1050 |
places information about the document position in aPosInfo and information
|
|
1051 |
about the line containing the document position in aLineInfo if it is non-NULL.
|
|
1052 |
|
|
1053 |
@param aXyPos Contains coordinates to convert to a document position.
|
|
1054 |
@param aPosInfo Buffer to store information about the document position if the
|
|
1055 |
specified coordinates are located in the formatted text.
|
|
1056 |
@param aLineInfo Buffer to store information about the line if the specified
|
|
1057 |
coordinates are located in the formatted text.
|
|
1058 |
@return ETrue if aXyPos is a formatted position, otherwise EFalse. */
|
|
1059 |
EXPORT_C TBool CTextLayout::FindXyPos(const TPoint& aXyPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
|
|
1060 |
{
|
|
1061 |
TTagmaForwarder forwarder(*this);
|
|
1062 |
TTmLineInfo line_info;
|
|
1063 |
TBool result = forwarder.FindXyPos(aXyPos,aPosInfo,line_info);
|
|
1064 |
if (aLineInfo && result)
|
|
1065 |
*aLineInfo = line_info;
|
|
1066 |
return result;
|
|
1067 |
}
|
|
1068 |
|
|
1069 |
/** Returns the x-y coordinates of the document position aDocPos in aPos. The
|
|
1070 |
return value is ETrue if the position is formatted, or EFalse if it is not, in
|
|
1071 |
which case aPos is undefined.
|
|
1072 |
|
|
1073 |
Deprecated - use the more powerful FindDocPos() instead
|
|
1074 |
|
|
1075 |
@param aDocPos The document position.
|
|
1076 |
@param aPos On return, contains the x-y coordinates of aDocPos.
|
|
1077 |
@param aFlags Two possible values: 0 is the default, and performs the task at
|
|
1078 |
full accuracy, and CLayoutData::EFWholeLinesOnly, which examines lines only and
|
|
1079 |
sets aXyPos.iY only, and cannot leave.
|
|
1080 |
@return ETrue if the document position is formatted, EFalse if not. */
|
|
1081 |
EXPORT_C TBool CTextLayout::DocPosToXyPosL(TInt aDocPos,TPoint& aXyPos,TUint /*aFlags*/) const
|
|
1082 |
{
|
|
1083 |
TTmDocPos doc_pos(aDocPos, ETrue);
|
|
1084 |
TTmPosInfo2 pos_info;
|
|
1085 |
TBool result = FindDocPos(doc_pos,pos_info);
|
|
1086 |
aXyPos = pos_info.iEdge;
|
|
1087 |
return result;
|
|
1088 |
}
|
|
1089 |
|
|
1090 |
/** Finds the x-y position of the document position aDocPos.
|
|
1091 |
|
|
1092 |
If ETrue is returned, places information about the document position in aPosInfo
|
|
1093 |
and information about the line containing the document position in aLineInfo if
|
|
1094 |
it is non-NULL.
|
|
1095 |
|
|
1096 |
@param aDocPos Contains the document position to check.
|
|
1097 |
@param aPosInfo On return, stores information about the document position if
|
|
1098 |
the position is formatted.
|
|
1099 |
@param aLineInfo Buffer to store the line information if the document position
|
|
1100 |
is formatted.
|
|
1101 |
@return ETrue if aDocPos is in the formatted text, otherwise EFalse. */
|
|
1102 |
EXPORT_C TBool CTextLayout::FindDocPos(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
|
|
1103 |
{
|
|
1104 |
TTagmaForwarder forwarder(*this);
|
|
1105 |
TTmLineInfo line_info;
|
|
1106 |
TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info);
|
|
1107 |
if (aLineInfo && result)
|
|
1108 |
*aLineInfo = line_info;
|
|
1109 |
return result;
|
|
1110 |
}
|
|
1111 |
|
|
1112 |
/** Finds the next cursor position to aDocPos in the visually ordered line.
|
|
1113 |
|
|
1114 |
@param aDocPos Contains the document position to check.
|
|
1115 |
@param aPosInfo On return, stores information about the document position of
|
|
1116 |
the next cursor position, if ETrue is returned.
|
|
1117 |
@param aToLeft ETrue if the position to the left is to be found, or EFalse if
|
|
1118 |
the position to the right is to be found.
|
|
1119 |
@return EFalse if there is no formatting, or the position is at the end of the
|
|
1120 |
line already. ETrue otherwise. */
|
|
1121 |
EXPORT_C TBool CTextLayout::GetNextVisualCursorPos(
|
|
1122 |
const TTmDocPosSpec& aDocPos, TTmPosInfo2& aPosInfo, TBool aToLeft) const
|
|
1123 |
{
|
|
1124 |
TTagmaForwarder forwarder(*this);
|
|
1125 |
return forwarder.GetNextVisualCursorPos(aDocPos, aPosInfo, aToLeft);
|
|
1126 |
}
|
|
1127 |
|
|
1128 |
/** Gets a rectangle enclosing two formatted document positions on the same
|
|
1129 |
line. If the second position is less than the first, or on a different line, it
|
|
1130 |
is taken to indicate the end of the line. This function panics if either
|
|
1131 |
position is unformatted.
|
|
1132 |
|
|
1133 |
Note:
|
|
1134 |
|
|
1135 |
CTextLayout must have been set with a valid wrap width and band height before
|
|
1136 |
calling this function, otherwise no formatting will take place and the function
|
|
1137 |
will panic. Wrap width and band height values must be > 0 to be valid.
|
|
1138 |
|
|
1139 |
@param aDocPos1 The first document position on the line.
|
|
1140 |
@param aDocPos2 The second document position on the line.
|
|
1141 |
@return The minimal rectangle, which bounds both positions.
|
|
1142 |
@see SetBandHeight
|
|
1143 |
@see SetWrapWidth */
|
|
1144 |
EXPORT_C TRect CTextLayout::GetLineRectL(TInt aDocPos1,TInt aDocPos2) const
|
|
1145 |
{
|
|
1146 |
TRect rect;
|
|
1147 |
TPoint point;
|
|
1148 |
TInt xCoords[4];
|
|
1149 |
|
|
1150 |
if (iText->LayoutHeight() == 0)
|
|
1151 |
return TRect(0,0,0,0);
|
|
1152 |
|
|
1153 |
__ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted));
|
|
1154 |
__ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted));
|
|
1155 |
|
|
1156 |
TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading);
|
|
1157 |
TTmPosInfo2 pos_info;
|
|
1158 |
|
|
1159 |
// Finding the leading edge of aDocPos1
|
|
1160 |
FindDocPos(docSpec,pos_info);
|
|
1161 |
point = pos_info.iEdge;
|
|
1162 |
xCoords[0] = point.iX;
|
|
1163 |
|
|
1164 |
// Getthe Line rectangle
|
|
1165 |
GetLineRect(point.iY,rect);
|
|
1166 |
|
|
1167 |
__ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine));
|
|
1168 |
|
|
1169 |
// Finding the leading edge of aDocPos2
|
|
1170 |
docSpec.iPos = aDocPos2;
|
|
1171 |
TBool isformatted = FindDocPos(docSpec, pos_info);
|
|
1172 |
point = pos_info.iEdge;
|
|
1173 |
|
|
1174 |
// Checks if the aDocPos2 is contained in the same line of the aDocPos1
|
|
1175 |
// Can't use TRect::Contains() here, because TRect::Contains() considers a point located on the right
|
|
1176 |
// hand side or bottom as outside the rectangle, which will has problem when work with RTL text that
|
|
1177 |
// is at the right hand end of a line.
|
|
1178 |
TBool isContained = (point.iX>=rect.iTl.iX && point.iX<=rect.iBr.iX
|
|
1179 |
&& point.iY>=rect.iTl.iY && point.iY<=rect.iBr.iY);
|
|
1180 |
|
|
1181 |
RTmParFormat parFormat;
|
|
1182 |
iSource->GetParagraphFormatL(aDocPos1, parFormat);
|
|
1183 |
|
|
1184 |
// The special cases (as indicated in the description):
|
|
1185 |
// When the aDocPos2 is less than the aDocPos1, or not formatted, or on a different line from which the
|
|
1186 |
// aDocPos1 is in, then the function will return the rectangle starting from docPos1's leading edge and
|
|
1187 |
// ending at the end of the line (which is determined by paragraph directionality).
|
|
1188 |
if (aDocPos2 < aDocPos1 || !isformatted || !isContained)
|
|
1189 |
{
|
|
1190 |
if (parFormat.RightToLeft())
|
|
1191 |
rect.iBr.iX = xCoords[0];
|
|
1192 |
else
|
|
1193 |
rect.iTl.iX = xCoords[0];
|
|
1194 |
|
|
1195 |
parFormat.Close();
|
|
1196 |
return rect;
|
|
1197 |
}
|
|
1198 |
|
|
1199 |
xCoords[1] = point.iX;
|
|
1200 |
|
|
1201 |
// Finding the Trailing edge of (aDocPos1 + 1)
|
|
1202 |
docSpec.iType = TTmDocPosSpec::ETrailing;
|
|
1203 |
docSpec.iPos = aDocPos1 + 1;
|
|
1204 |
FindDocPos(docSpec, pos_info);
|
|
1205 |
xCoords[2] = pos_info.iEdge.iX;
|
|
1206 |
|
|
1207 |
// Finding the Trailing edge of (aDocPos2 + 1)
|
|
1208 |
docSpec.iPos = aDocPos2 + 1;
|
|
1209 |
FindDocPos(docSpec, pos_info);
|
|
1210 |
xCoords[3] = pos_info.iEdge.iX;
|
|
1211 |
|
|
1212 |
rect.iBr.iX = xCoords[0];
|
|
1213 |
rect.iTl.iX = xCoords[0];
|
|
1214 |
|
|
1215 |
// The returned rectangle is generated by (when is not a special case)
|
|
1216 |
// 1) Find the Line rectangle
|
|
1217 |
// 2) Find the:
|
|
1218 |
// - leading edge of docPos1
|
|
1219 |
// - leading edge of docPos2
|
|
1220 |
// - trailing edge of docPos1+1
|
|
1221 |
// - trailing edge of docPos2+1
|
|
1222 |
// 3) Cut the line rectangle at the smallest edge and the largest edge among
|
|
1223 |
// the four edges found in step 2.
|
|
1224 |
for (TInt i = 1; i<4; i++ )
|
|
1225 |
{
|
|
1226 |
if (rect.iBr.iX < xCoords[i])
|
|
1227 |
rect.iBr.iX = xCoords[i];
|
|
1228 |
if (rect.iTl.iX > xCoords[i])
|
|
1229 |
rect.iTl.iX = xCoords[i];
|
|
1230 |
}
|
|
1231 |
|
|
1232 |
parFormat.Close();
|
|
1233 |
return rect;
|
|
1234 |
}
|
|
1235 |
|
|
1236 |
/** Gets the bounding rectangle of the picture, if any, located at the document
|
|
1237 |
position or coordinates specified, and returns it in aPictureRect.
|
|
1238 |
|
|
1239 |
If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate
|
|
1240 |
whether the picture can be scaled or cropped.
|
|
1241 |
Returns ETrue if the operation was successful. Returns EFalse otherwise;
|
|
1242 |
that is, if there is no picture at the position, or if the position is unformatted.
|
|
1243 |
|
|
1244 |
@param aDocPos The document position of interest.
|
|
1245 |
@param aXyPos The layout coordinates of interest.
|
|
1246 |
@param aPictureRect On return, contains the rectangle which encloses the
|
|
1247 |
picture located at the position specified.
|
|
1248 |
@param aCanScaleOrCrop If non-NULL and the function returns ETrue, on return,
|
|
1249 |
indicates whether the picture can be scaled or cropped. By default, NULL.
|
|
1250 |
@return ETrue if the operation was successful, (i.e. there is a
|
|
1251 |
picture character at the position, it has been loaded into
|
|
1252 |
memory, and the position is formatted). EFalse if any of these
|
|
1253 |
conditions are not met. */
|
|
1254 |
EXPORT_C TBool CTextLayout::PictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop) const
|
|
1255 |
{
|
|
1256 |
if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar() - 1)
|
|
1257 |
return FALSE;
|
|
1258 |
|
|
1259 |
aPictureRect.SetRect(0,0,0,0);
|
|
1260 |
TSize size;
|
|
1261 |
if (iSource->GetPictureSizeInTwipsL(aDocPos,size) != KErrNone)
|
|
1262 |
return FALSE;
|
|
1263 |
|
|
1264 |
TRect rect;
|
|
1265 |
TTmDocPos pos(aDocPos, ETrue);
|
|
1266 |
TTmPosInfo2 pos_info;
|
|
1267 |
TTmLineInfo info;
|
|
1268 |
TInt subscript;
|
|
1269 |
if (!iText->FindDocPos(pos,pos_info,info,subscript))
|
|
1270 |
return FALSE;
|
|
1271 |
|
|
1272 |
MGraphicsDeviceMap& device = iSource->InterpretDevice();
|
|
1273 |
size.iWidth = device.HorizontalTwipsToPixels(size.iWidth);
|
|
1274 |
size.iHeight = device.VerticalTwipsToPixels(size.iHeight);
|
|
1275 |
rect.iBr.iY = pos_info.iEdge.iY - iBandTop + subscript;
|
|
1276 |
rect.iTl.iY = rect.iBr.iY - size.iHeight;
|
|
1277 |
if (pos_info.iRightToLeft)
|
|
1278 |
{
|
|
1279 |
rect.iBr.iX = pos_info.iEdge.iX;
|
|
1280 |
rect.iTl.iX = rect.iBr.iX - size.iWidth;
|
|
1281 |
}
|
|
1282 |
else
|
|
1283 |
{
|
|
1284 |
rect.iTl.iX = pos_info.iEdge.iX;
|
|
1285 |
rect.iBr.iX = rect.iTl.iX + size.iWidth;
|
|
1286 |
}
|
|
1287 |
/* rect.iTl = pos_info.iEdge;
|
|
1288 |
rect.Move(0,-iBandTop);
|
|
1289 |
rect.iTl.iY -= size.iHeight;
|
|
1290 |
rect.iBr = rect.iTl + size;*/
|
|
1291 |
CPicture* picture = iSource->PictureL(aDocPos);
|
|
1292 |
if (!picture)
|
|
1293 |
return FALSE;
|
|
1294 |
|
|
1295 |
if (aCanScaleOrCrop)
|
|
1296 |
*aCanScaleOrCrop = picture->Capability().iScalingType != TPictureCapability::ENotScaleable ||
|
|
1297 |
picture->Capability().iIsCroppable;
|
|
1298 |
aPictureRect = rect;
|
|
1299 |
return TRUE;
|
|
1300 |
}
|
|
1301 |
|
|
1302 |
/** Finds if there is a picture at the position under the point aXyPos.
|
|
1303 |
If there is, returns the document position of it, sets the rectangle
|
|
1304 |
occupied in aPictureRect, and whether the picture allows scaling
|
|
1305 |
in aCanScaleOrCrop, if non-null. Note that aXyPos may be outside
|
|
1306 |
the picture found.
|
|
1307 |
@return The document position of the picture found, or KErrNotFound if there
|
|
1308 |
is none. */
|
|
1309 |
TInt CTextLayout::PictureRectangleAndPosL(const TPoint& aXyPos, TRect& aPictureRect,
|
|
1310 |
TBool* aCanScaleOrCrop) const
|
|
1311 |
{
|
|
1312 |
TTmPosInfo2 posInfo;
|
|
1313 |
if (!FindXyPos(aXyPos, posInfo))
|
|
1314 |
return KErrNotFound;
|
|
1315 |
TInt doc_pos = posInfo.iDocPos.iPos - (posInfo.iDocPos.iLeadingEdge? 0 : 1);
|
|
1316 |
if (PictureRectangleL(doc_pos, aPictureRect, aCanScaleOrCrop))
|
|
1317 |
return doc_pos;
|
|
1318 |
return KErrNotFound;
|
|
1319 |
}
|
|
1320 |
|
|
1321 |
/** Gets the bounding rectangle of the picture (if any) at aXyPos and puts it
|
|
1322 |
in aPictureRect. If aCanScaleOrCrop is non-null sets *aCanScaleOrCrop to
|
|
1323 |
indicate whether the picture can be scaled or cropped. Note that aXyPos
|
|
1324 |
may be outside aPictureRect on a successful return, if the picture does
|
|
1325 |
not occupy the whole of the section of the line it is in.
|
|
1326 |
@return ETrue if the position is formatted and there is a picture there. */
|
|
1327 |
EXPORT_C TBool CTextLayout::PictureRectangleL(const TPoint& aXyPos,
|
|
1328 |
TRect& aPictureRect, TBool* aCanScaleOrCrop) const
|
|
1329 |
{
|
|
1330 |
return 0 <= PictureRectangleAndPosL(aXyPos, aPictureRect, aCanScaleOrCrop)?
|
|
1331 |
ETrue : EFalse;
|
|
1332 |
}
|
|
1333 |
|
|
1334 |
/** Gets the first document position in a line that starts at or below the top
|
|
1335 |
of the visible area. If there is no such line, returns the position after the
|
|
1336 |
last formatted character.
|
|
1337 |
|
|
1338 |
@return The document position of the first character in a line within the
|
|
1339 |
visible area. */
|
|
1340 |
EXPORT_C TInt CTextLayout::FirstDocPosFullyInBand() const
|
|
1341 |
{
|
|
1342 |
TTmLineInfo info;
|
|
1343 |
if (!iText->YPosToLine(iBandTop,info))
|
|
1344 |
return iText->EndChar();
|
|
1345 |
if (info.iOuterRect.iTl.iY < iBandTop)
|
|
1346 |
return info.iEnd;
|
|
1347 |
else
|
|
1348 |
return info.iStart;
|
|
1349 |
}
|
|
1350 |
|
|
1351 |
|
|
1352 |
|
|
1353 |
|
|
1354 |
/** This interface is deprecated, and is made available in version 7.0s solely
|
|
1355 |
to provide binary compatibility with Symbian OS v6.1. Developers are strongly
|
|
1356 |
advised not to make use of this API in new applications. In particular, use the
|
|
1357 |
other overload of this function if you need to distinguish between leading and
|
|
1358 |
trailing edge positions.
|
|
1359 |
|
|
1360 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1361 |
|
|
1362 |
@param aDocPos A valid document position.
|
|
1363 |
@param aYPos The y coordinate at which to display the character at aDocPos. On
|
|
1364 |
return, contains the actual vertical position of the specified part of the
|
|
1365 |
line.
|
|
1366 |
@param aYPosQualifier Controls which part of the line is set to appear at
|
|
1367 |
aYPos.
|
|
1368 |
@param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
|
|
1369 |
to include aDocPos, otherwise text is formatted only as necessary when bringing
|
|
1370 |
new lines into the visible area.
|
|
1371 |
@return The number of pixels the text was scrolled, may be positive or
|
|
1372 |
negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
|
|
1373 |
entire visible area, at least, was scrolled, and so there is no point in
|
|
1374 |
blitting text; a full redraw is needed. */
|
|
1375 |
EXPORT_C TInt CTextLayout::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,TDiscard aDiscardFormat)
|
|
1376 |
{
|
|
1377 |
TTmDocPos pos(aDocPos, ETrue);
|
|
1378 |
return SetViewL(pos,aYPos,aYPosQualifier,aDiscardFormat);
|
|
1379 |
}
|
|
1380 |
|
|
1381 |
/** Changes the top of the visible area so that the line containing aDocPos is
|
|
1382 |
vertically positioned at aYPos. Which part of the line is set to appear at
|
|
1383 |
aYPos (top, baseline, or bottom) is controlled by the TViewYPosQualifier
|
|
1384 |
argument, which also specifies whether the visible area is to be filled and
|
|
1385 |
whether the line should be made fully visible if possible.
|
|
1386 |
|
|
1387 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1388 |
|
|
1389 |
@param aDocPos A valid document position.
|
|
1390 |
@param aYPos The y coordinate at which to display the character at aDocPos. On
|
|
1391 |
return, contains the actual vertical position of the specified part of the
|
|
1392 |
line.
|
|
1393 |
@param aYPosQualifier Controls which part of the line is set to appear at
|
|
1394 |
aYPos.
|
|
1395 |
@param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
|
|
1396 |
to include aDocPos, otherwise text is formatted only as necessary when bringing
|
|
1397 |
new lines into the visible area.
|
|
1398 |
@return The number of pixels the text was scrolled, may be positive or
|
|
1399 |
negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
|
|
1400 |
entire visible area, at least, was scrolled, and so there is no point in
|
|
1401 |
blitting text; a full redraw is needed. */
|
|
1402 |
EXPORT_C TInt CTextLayout::SetViewL(const TTmDocPos& aDocPos, TInt& aYPos,
|
|
1403 |
TViewYPosQualifier aYPosQualifier, TDiscard aDiscardFormat)
|
|
1404 |
{
|
|
1405 |
if (aDocPos.iPos < 0 || aDocPos.iPos > iSource->DocumentLength())
|
|
1406 |
Panic(EInvalidDocPos);
|
|
1407 |
|
|
1408 |
/*
|
|
1409 |
If the format is to be discarded, or no text has yet been formatted, or if the document position
|
|
1410 |
to be viewed is not formatted, format the band.
|
|
1411 |
*/
|
|
1412 |
TTmLineInfo info;
|
|
1413 |
TBool all_formatted = FALSE;
|
|
1414 |
TBool pos_is_formatted = iText->DocPosToLine(aDocPos,info);
|
|
1415 |
if (!pos_is_formatted ||
|
|
1416 |
aDiscardFormat == EFViewDiscardAllFormat ||
|
|
1417 |
(iText->StartChar() == iText->EndChar() && iSource->DocumentLength() > 0))
|
|
1418 |
{
|
|
1419 |
FormatBandL(aDocPos.iPos,aDocPos.iPos);
|
|
1420 |
all_formatted = TRUE;
|
|
1421 |
pos_is_formatted = iText->DocPosToLine(aDocPos,info);
|
|
1422 |
}
|
|
1423 |
|
|
1424 |
// Find out where the top of the line is.
|
|
1425 |
if (!pos_is_formatted)
|
|
1426 |
return 0;
|
|
1427 |
int line_top_y = info.iOuterRect.iTl.iY - iBandTop;
|
|
1428 |
|
|
1429 |
// Determine the desired position of the top of the line.
|
|
1430 |
int offset = 0;
|
|
1431 |
if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBaseLine)
|
|
1432 |
offset = info.iBaseline - info.iOuterRect.iTl.iY;
|
|
1433 |
else if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
|
|
1434 |
offset = info.iOuterRect.iBr.iY - info.iOuterRect.iTl.iY;
|
|
1435 |
int desired_line_top_y = aYPos - offset;
|
|
1436 |
|
|
1437 |
// Adjust aYPos so that the line is fully visible if desired.
|
|
1438 |
if (aYPosQualifier.iFullyVisible == TViewYPosQualifier::EFViewForceLineFullyVisible)
|
|
1439 |
{
|
|
1440 |
TInt screenHeight = VisibleHeightInPixels();
|
|
1441 |
TInt lineHeight = info.iOuterRect.Height();
|
|
1442 |
TInt lineAscent = info.iBaseline - info.iOuterRect.iTl.iY;
|
|
1443 |
// If the top of the line is off the top of the screen, and the
|
|
1444 |
// baseline and the top can both fit, make the top of the line flush
|
|
1445 |
// with the top of the screen.
|
|
1446 |
if (lineAscent <= screenHeight
|
|
1447 |
&& desired_line_top_y < 0)
|
|
1448 |
desired_line_top_y = 0;
|
|
1449 |
// If the whole line can fit and the bottom if off the bottom of the
|
|
1450 |
// screen, make the bottom flush with the bottom of the screen.
|
|
1451 |
if (lineHeight <= screenHeight
|
|
1452 |
&& screenHeight < desired_line_top_y + lineHeight)
|
|
1453 |
desired_line_top_y = screenHeight - lineHeight;
|
|
1454 |
// If the ascent will not fit, or the baseline is off the bottom of
|
|
1455 |
// the screen, move the baseline flush with the bottom of the screen
|
|
1456 |
if (screenHeight < lineAscent
|
|
1457 |
|| screenHeight < desired_line_top_y + lineAscent)
|
|
1458 |
desired_line_top_y = screenHeight - lineAscent;
|
|
1459 |
}
|
|
1460 |
|
|
1461 |
// Scroll the document position to the desired vertical coordinate and update aYPos.
|
|
1462 |
TInt dy = desired_line_top_y - line_top_y;
|
|
1463 |
if (dy)
|
|
1464 |
{
|
|
1465 |
dy = ScrollL(dy,aYPosQualifier.iFillScreen ? EFDisallowScrollingBlankSpace : EFAllowScrollingBlankSpace);
|
|
1466 |
line_top_y += dy;
|
|
1467 |
aYPos = line_top_y + offset;
|
|
1468 |
|
|
1469 |
// Ensure that aYPos is in the line.
|
|
1470 |
if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
|
|
1471 |
aYPos--;
|
|
1472 |
}
|
|
1473 |
return all_formatted ? EFScrollRedrawWholeScreen : dy;
|
|
1474 |
}
|
|
1475 |
|
|
1476 |
/** Formats enough text to fill the visible band.
|
|
1477 |
|
|
1478 |
Note: Do not use if a CTextView object owns this CTextLayout object. */
|
|
1479 |
EXPORT_C void CTextLayout::FormatBandL()
|
|
1480 |
{
|
|
1481 |
FormatBandL(0,0);
|
|
1482 |
}
|
|
1483 |
|
|
1484 |
/**
|
|
1485 |
Format enough text to fill the visible band and include both aStartDocPos and
|
|
1486 |
aEndDocPos. Start at the start of the document if formatting everything, or at
|
|
1487 |
the start of the paragraph containing aStartDocPos if formatting the visible
|
|
1488 |
band only.
|
|
1489 |
*/
|
|
1490 |
void CTextLayout::FormatBandL(TInt aStartDocPos,TInt aEndDocPos)
|
|
1491 |
{
|
|
1492 |
TTmFormatParam param;
|
|
1493 |
InitFormatParam(param);
|
|
1494 |
if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
|
|
1495 |
param.iStartChar = iSource->ParagraphStart(aStartDocPos);
|
|
1496 |
if (param.iWrapWidth < 1 || param.iMaxHeight < 1)
|
|
1497 |
{
|
|
1498 |
// Do just a little formatting if the values are illegal.
|
|
1499 |
// This is to prevent the AddParL running with no
|
|
1500 |
// height limit, taking up huge amounts of time, and
|
|
1501 |
// having to return with 0 lines formatted, which
|
|
1502 |
// confuses CEikEdwin.
|
|
1503 |
param.iMaxHeight = 1;
|
|
1504 |
param.iWrapWidth = 1;
|
|
1505 |
iText->SetTextL(*iSource,param);
|
|
1506 |
return;
|
|
1507 |
}
|
|
1508 |
iText->SetTextL(*iSource,param);
|
|
1509 |
param.iMaxHeight = KMaxTInt;
|
|
1510 |
|
|
1511 |
if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()))
|
|
1512 |
{
|
|
1513 |
param.iEndChar = aEndDocPos;
|
|
1514 |
iText->ExtendFormattingDownwardsL(param);
|
|
1515 |
}
|
|
1516 |
else
|
|
1517 |
{
|
|
1518 |
while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())
|
|
1519 |
{
|
|
1520 |
int h,p;
|
|
1521 |
AddFormattingAtEndL(param, h, p);
|
|
1522 |
}
|
|
1523 |
}
|
|
1524 |
|
|
1525 |
|
|
1526 |
if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
|
|
1527 |
{
|
|
1528 |
int visible_height = VisibleHeightInPixels();
|
|
1529 |
while (iText->LayoutHeight() < visible_height)
|
|
1530 |
{
|
|
1531 |
int h,p;
|
|
1532 |
if (!iText->AddParL(param,TRUE,h,p))
|
|
1533 |
break;
|
|
1534 |
}
|
|
1535 |
}
|
|
1536 |
iBandTop = 0;
|
|
1537 |
}
|
|
1538 |
|
|
1539 |
/** Makes sure the line that aYPos is in (if it exists) is covered by the
|
|
1540 |
formatting.
|
|
1541 |
@param aYPos Y pixel position in window-relative co-ordinates.
|
|
1542 |
@internalComponent
|
|
1543 |
*/
|
|
1544 |
EXPORT_C void CTextLayout::ExtendFormattingToCoverYL(TInt aYPos)
|
|
1545 |
{
|
|
1546 |
TTmFormatParam param;
|
|
1547 |
InitFormatParam(param);
|
|
1548 |
param.iStartChar = iText->StartChar() - 1;
|
|
1549 |
param.iEndChar = iText->EndChar();
|
|
1550 |
param.iMaxHeight = KMaxTInt;
|
|
1551 |
TInt heightIncrease;
|
|
1552 |
TInt p;
|
|
1553 |
while (iBandTop < -aYPos && iText->AddParL(param, ETrue, heightIncrease, p))
|
|
1554 |
{
|
|
1555 |
iBandTop += heightIncrease;
|
|
1556 |
param.iStartChar = iText->StartChar() - 1;
|
|
1557 |
}
|
|
1558 |
TInt heightRemaining = iBandTop + aYPos - iText->LayoutHeight() + 1;
|
|
1559 |
if(heightRemaining > 0)
|
|
1560 |
{
|
|
1561 |
param.iStartChar = iText->EndChar();
|
|
1562 |
param.iEndChar = KMaxTInt;
|
|
1563 |
param.iMaxHeight = heightRemaining;
|
|
1564 |
iText->ExtendFormattingDownwardsL(param);
|
|
1565 |
}
|
|
1566 |
}
|
|
1567 |
|
|
1568 |
/** Allows you to increase the formatted text range by specifying a point in the text you
|
|
1569 |
want to increase the range to. Makes sure the line that aDocPos is in (if it exists) is covered by the
|
|
1570 |
formatting.
|
|
1571 |
@param aDocPos Position in the text you wish to extend the formatting to. e.g. passing in 0 will
|
|
1572 |
increase the formatting range to the very first character entered in the document.
|
|
1573 |
@pre aDocPos is in the range 0...DocumentLength
|
|
1574 |
@post aDocPos has been formatted
|
|
1575 |
*/
|
|
1576 |
EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos)
|
|
1577 |
{
|
|
1578 |
__ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(),
|
|
1579 |
Panic(EInvalidDocPos));
|
|
1580 |
TTmFormatParam param;
|
|
1581 |
InitFormatParam(param);
|
|
1582 |
param.iStartChar = iText->StartChar();
|
|
1583 |
param.iEndChar = iText->EndChar();
|
|
1584 |
param.iMaxHeight = KMaxTInt;
|
|
1585 |
TInt heightIncrease;
|
|
1586 |
TInt p;
|
|
1587 |
TInt pos = aDocPos;
|
|
1588 |
if(pos > 0) // Avoid going into infinite loop.
|
|
1589 |
{
|
|
1590 |
pos -= 1;
|
|
1591 |
}
|
|
1592 |
while ((pos < param.iStartChar) && (iText->AddParL(param, ETrue, heightIncrease, p)))
|
|
1593 |
{
|
|
1594 |
iBandTop += heightIncrease;
|
|
1595 |
param.iStartChar = iText->StartChar();
|
|
1596 |
}
|
|
1597 |
param.iEndChar = aDocPos + 1;
|
|
1598 |
if(iText->EndChar() < param.iEndChar)
|
|
1599 |
{
|
|
1600 |
iText->ExtendFormattingDownwardsL(param);
|
|
1601 |
}
|
|
1602 |
__ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()),
|
|
1603 |
Panic(ECharacterNotFormatted));
|
|
1604 |
}
|
|
1605 |
|
|
1606 |
|
|
1607 |
/** Sets the formatted text to begin at the start of the paragraph including
|
|
1608 |
aStartPos and end at aEndPos. Moves the line containing aStartDocPos to the top
|
|
1609 |
of the visible area.
|
|
1610 |
|
|
1611 |
Notes:
|
|
1612 |
|
|
1613 |
This function is not generally useful; it exists for the convenience of the
|
|
1614 |
printing system.
|
|
1615 |
|
|
1616 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1617 |
|
|
1618 |
@param aStartDocPos A document position within the paragraph from which to
|
|
1619 |
begin formatting.
|
|
1620 |
@param aEndDocPos Document position at which to end formatting. */
|
|
1621 |
EXPORT_C void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos)
|
|
1622 |
{
|
|
1623 |
FormatCharRangeL(aStartDocPos,aEndDocPos,0);
|
|
1624 |
}
|
|
1625 |
|
|
1626 |
void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset)
|
|
1627 |
{
|
|
1628 |
__ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos));
|
|
1629 |
__ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos));
|
|
1630 |
__ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat));
|
|
1631 |
|
|
1632 |
TTmFormatParam param;
|
|
1633 |
InitFormatParam(param);
|
|
1634 |
param.iStartChar = iSource->ParagraphStart(aStartDocPos);
|
|
1635 |
param.iEndChar = aEndDocPos;
|
|
1636 |
param.iMaxHeight = KMaxTInt;
|
|
1637 |
iText->SetTextL(*iSource,param);
|
|
1638 |
TTmLineInfo info;
|
|
1639 |
TTmDocPos pos(aStartDocPos, ETrue);
|
|
1640 |
if (iText->DocPosToLine(pos,info))
|
|
1641 |
iBandTop = info.iOuterRect.iTl.iY - aPixelOffset;
|
|
1642 |
else
|
|
1643 |
iBandTop = 0; //+ raise an exception?
|
|
1644 |
}
|
|
1645 |
|
|
1646 |
/** A special function to support background formatting by the higher level
|
|
1647 |
CTextView class. It formats the next pending line. The return value is ETrue if
|
|
1648 |
there is more formatting to do. On entry, aBotPixel contains the y coordinate
|
|
1649 |
of the bottom of the formatted text; this is updated by the function.
|
|
1650 |
|
|
1651 |
Notes:
|
|
1652 |
|
|
1653 |
Not generally useful.
|
|
1654 |
|
|
1655 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1656 |
|
|
1657 |
@param aBotPixel On entry, contains the y coordinate of the bottom of the
|
|
1658 |
formatted text; this is updated by the function.
|
|
1659 |
@return ETrue if there is more formatting to do. EFalse if not. */
|
|
1660 |
EXPORT_C TBool CTextLayout::FormatNextLineL(TInt& aBottomPixel)
|
|
1661 |
{
|
|
1662 |
if (iUnformattedStart < KMaxTInt)
|
|
1663 |
{
|
|
1664 |
TTmFormatParamBase param;
|
|
1665 |
InitFormatParam(param);
|
|
1666 |
param.iMaxHeight = KMaxTInt;
|
|
1667 |
TTmReformatParam reformat_param;
|
|
1668 |
reformat_param.iStartChar = iUnformattedStart;
|
|
1669 |
reformat_param.iMaxExtraLines = KMaxExtraLines;
|
|
1670 |
reformat_param.iParInvalid = iParInvalid;
|
|
1671 |
TTmReformatResult result;
|
|
1672 |
iText->FormatL(param,reformat_param,result);
|
|
1673 |
|
|
1674 |
// If there is no formatting to do, indicate that formatting is complete to the end of the paragraph
|
|
1675 |
if (result.iUnformattedStart == KMaxTInt)
|
|
1676 |
{
|
|
1677 |
TTmLineInfo info;
|
|
1678 |
TTmDocPos pos(iUnformattedStart, ETrue);
|
|
1679 |
TBool isFormatted = iText->DocPosToLine(pos,info);
|
|
1680 |
__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
|
|
1681 |
isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info);
|
|
1682 |
__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
|
|
1683 |
aBottomPixel = info.iOuterRect.iBr.iY - iBandTop;
|
|
1684 |
}
|
|
1685 |
|
|
1686 |
// Indicate that formatting is complete up to the lower edge of the current line.
|
|
1687 |
else
|
|
1688 |
aBottomPixel = result.iRedrawRect.iBr.iY - iBandTop;
|
|
1689 |
iUnformattedStart = result.iUnformattedStart;
|
|
1690 |
}
|
|
1691 |
return iUnformattedStart < KMaxTInt;
|
|
1692 |
}
|
|
1693 |
|
|
1694 |
/** Controls the height of a single line, for use by the pagination system
|
|
1695 |
only. Using the format supplied in aParaFormat, determines the height of the
|
|
1696 |
line containing aDocPos and returns it in aHeight. Changes aDocPos to the end
|
|
1697 |
of the line and returns ETrue if that position is not the end of the paragraph.
|
|
1698 |
|
|
1699 |
Notes:
|
|
1700 |
|
|
1701 |
Not generally useful; it exists for use by the pagination system only.
|
|
1702 |
|
|
1703 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1704 |
|
|
1705 |
@param aParaFormat Contains paragraph formatting.
|
|
1706 |
@param aDocPos A document position. On return, contains the document position
|
|
1707 |
of the end of the line.
|
|
1708 |
@param aHeight On return, contains the height of the formatted line containing
|
|
1709 |
aDocPos.
|
|
1710 |
@param aPageBreak On return, ETrue if the last character on the line is a page
|
|
1711 |
break. EFalse if not.
|
|
1712 |
@return ETrue if the line is not the last line in the paragraph. EFalse if it is
|
|
1713 |
the last line. */
|
|
1714 |
EXPORT_C TBool CTextLayout::FormatLineL(CParaFormat* /*aParaFormat*/,TInt& aDocPos,
|
|
1715 |
TInt& aHeight,TBool& aPageBreak)
|
|
1716 |
{
|
|
1717 |
// If the line is not formatted, replace the formatted text with the single paragraph containing the line.
|
|
1718 |
if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar())
|
|
1719 |
{
|
|
1720 |
TTmFormatParam param;
|
|
1721 |
InitFormatParam(param);
|
|
1722 |
param.iStartChar = iSource->ParagraphStart(aDocPos);
|
|
1723 |
param.iEndChar = iSource->ParagraphEnd(aDocPos);
|
|
1724 |
param.iMaxHeight = KMaxTInt;
|
|
1725 |
iText->SetTextL(*iSource,param);
|
|
1726 |
}
|
|
1727 |
TTmLineInfo info;
|
|
1728 |
TTmDocPos pos(aDocPos, ETrue);
|
|
1729 |
if (!iText->DocPosToLine(pos,info))
|
|
1730 |
User::Leave(KErrGeneral);
|
|
1731 |
aHeight = info.iOuterRect.Height();
|
|
1732 |
aDocPos = info.iEnd;
|
|
1733 |
TPtrC text;
|
|
1734 |
TTmCharFormat format;
|
|
1735 |
iSource->GetText(info.iEnd - 1,text,format);
|
|
1736 |
aPageBreak = text[0] == CEditableText::EPageBreak;
|
|
1737 |
|
|
1738 |
return !(info.iFlags & TTmLineInfo::EParEnd);
|
|
1739 |
}
|
|
1740 |
|
|
1741 |
/** Scrolls the text up or down by aNumParas paragraphs, disallowing blank
|
|
1742 |
space at the bottom of the visible area if aScrollBlankSpace is
|
|
1743 |
CTextLayout::EFDisallowScrollingBlankSpace.
|
|
1744 |
|
|
1745 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1746 |
|
|
1747 |
@param aNumParas The number of paragraphs to scroll; may be a positive or
|
|
1748 |
negative value. On return, contains the number of paragraphs not scrolled; that
|
|
1749 |
is the difference between the requested number and the number of paragraphs
|
|
1750 |
actually scrolled.
|
|
1751 |
@param aScrollBlankSpace Only relevant when scrolling downwards.
|
|
1752 |
CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
|
|
1753 |
visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
|
|
1754 |
from scrolling into the visible area.
|
|
1755 |
@pre aPars must not scroll the display beyond the formatted range. If aPars
|
|
1756 |
scrolls beyond the formatted range, this method will leave with the error code
|
|
1757 |
CTextLayout::EPosNotFormatted
|
|
1758 |
@return The number of pixels actually scrolled. */
|
|
1759 |
EXPORT_C TInt CTextLayout::ScrollParagraphsL(TInt& aPars,TAllowDisallow aScrollBlankSpace)
|
|
1760 |
{
|
|
1761 |
TTmFormatParam param;
|
|
1762 |
InitFormatParam(param);
|
|
1763 |
param.iMaxHeight = KMaxTInt;
|
|
1764 |
TTmLineInfo info;
|
|
1765 |
int height_increase = 0;
|
|
1766 |
int paragraphs_increase = 0;
|
|
1767 |
int cur_par = 0;
|
|
1768 |
int desired_par = 0;
|
|
1769 |
int pixels_to_scroll = 0;
|
|
1770 |
|
|
1771 |
if (aPars > 0)
|
|
1772 |
{
|
|
1773 |
if (iText->YPosToLine(iBandTop,info))
|
|
1774 |
cur_par = info.iParNumber;
|
|
1775 |
else
|
|
1776 |
User::Leave(EPosNotFormatted);
|
|
1777 |
if (info.iParTop < iBandTop)
|
|
1778 |
aPars--;
|
|
1779 |
desired_par = cur_par - aPars;
|
|
1780 |
while (desired_par < 0 && iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
|
|
1781 |
{
|
|
1782 |
iBandTop += height_increase;
|
|
1783 |
desired_par += paragraphs_increase;
|
|
1784 |
}
|
|
1785 |
aPars = -desired_par;
|
|
1786 |
if (desired_par < 0)
|
|
1787 |
desired_par = 0;
|
|
1788 |
if (!iText->ParNumberToLine(desired_par,0,info))
|
|
1789 |
User::Leave(EPosNotFormatted);
|
|
1790 |
pixels_to_scroll = iBandTop - info.iOuterRect.iTl.iY;
|
|
1791 |
}
|
|
1792 |
else if (aPars < 0)
|
|
1793 |
{
|
|
1794 |
int band_bottom = iBandTop + VisibleHeightInPixels();
|
|
1795 |
|
|
1796 |
// Extend formatting until the visible height is filled.
|
|
1797 |
param.iEndChar = KMaxTInt;
|
|
1798 |
param.iMaxHeight = band_bottom - iText->LayoutHeight();
|
|
1799 |
if(param.iMaxHeight > 0)
|
|
1800 |
{
|
|
1801 |
iText->ExtendFormattingDownwardsL(param);
|
|
1802 |
}
|
|
1803 |
|
|
1804 |
if (iText->YPosToLine(band_bottom - 1,info))
|
|
1805 |
cur_par = info.iParNumber;
|
|
1806 |
else
|
|
1807 |
User::Leave(EPosNotFormatted);
|
|
1808 |
if (!((info.iFlags & TTmLineInfo::EParEnd) && info.iOuterRect.iBr.iY == band_bottom))
|
|
1809 |
aPars++;
|
|
1810 |
desired_par = cur_par - aPars;
|
|
1811 |
int last_par = iText->Paragraphs() - 1;
|
|
1812 |
while (desired_par > last_par && iText->AddParL(param, EFalse, height_increase,paragraphs_increase))
|
|
1813 |
last_par += paragraphs_increase;
|
|
1814 |
aPars = last_par - desired_par;
|
|
1815 |
if (desired_par > last_par)
|
|
1816 |
desired_par = last_par;
|
|
1817 |
if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
|
|
1818 |
iText->AddParL(param, EFalse, height_increase, paragraphs_increase);
|
|
1819 |
if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
|
|
1820 |
User::Leave(EPosNotFormatted);
|
|
1821 |
pixels_to_scroll = band_bottom - info.iOuterRect.iBr.iY;
|
|
1822 |
}
|
|
1823 |
|
|
1824 |
return ScrollL(pixels_to_scroll,aScrollBlankSpace);
|
|
1825 |
}
|
|
1826 |
|
|
1827 |
/** Scrolls the text up or down by aNumLines lines, disallowing blank space at
|
|
1828 |
the bottom of the visible area if aScrollBlankSpace is
|
|
1829 |
CTextLayout::EFDisallowScrollingBlankSpace.
|
|
1830 |
|
|
1831 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1832 |
|
|
1833 |
@param aNumLines The number of lines to scroll; may be a positive or negative
|
|
1834 |
value. On return, contains the number of lines not scrolled; that is, the
|
|
1835 |
requested number, minus the number actually scrolled.
|
|
1836 |
@param aScrollBlankSpace Only relevant when scrolling downwards.
|
|
1837 |
CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
|
|
1838 |
visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
|
|
1839 |
from scrolling into the visible area.
|
|
1840 |
@pre aLines must not scroll the display beyond the formatted range. If aLines
|
|
1841 |
scrolls beyond the formatted range, this method will leave with the error code
|
|
1842 |
CTextLayout::EPosNotFormatted
|
|
1843 |
@return The number of pixels actually scrolled. */
|
|
1844 |
EXPORT_C TInt CTextLayout::ScrollLinesL(TInt& aLines,TAllowDisallow aScrollBlankSpace)
|
|
1845 |
{
|
|
1846 |
TTmFormatParam param;
|
|
1847 |
InitFormatParam(param);
|
|
1848 |
param.iMaxHeight = KMaxTInt;
|
|
1849 |
TTmLineInfo info;
|
|
1850 |
int height_increase = 0;
|
|
1851 |
int paragraphs_increase = 0;
|
|
1852 |
int lines_scrolled = aLines;
|
|
1853 |
int visible_height = VisibleHeightInPixels();
|
|
1854 |
if (aLines > 0) // bring aLines lines into view at the top of the display
|
|
1855 |
{
|
|
1856 |
int desired_top_line_number = 0;
|
|
1857 |
for (;;)
|
|
1858 |
{
|
|
1859 |
// Find the line number of the first visible line.
|
|
1860 |
TBool partial_line = FALSE;
|
|
1861 |
int top_line_number = 0;
|
|
1862 |
if (iBandTop >= iText->LayoutHeight())
|
|
1863 |
top_line_number = iText->Lines();
|
|
1864 |
else
|
|
1865 |
{
|
|
1866 |
if (iText->YPosToLine(iBandTop,info))
|
|
1867 |
top_line_number = info.iLineNumber;
|
|
1868 |
else
|
|
1869 |
User::Leave(EPosNotFormatted);
|
|
1870 |
partial_line = iBandTop > info.iOuterRect.iTl.iY;
|
|
1871 |
}
|
|
1872 |
|
|
1873 |
// Find the line number of the desired first visible line.
|
|
1874 |
// Defect fix for INC015850. Changed IF so that if the currently
|
|
1875 |
// visible top line is as tall or taller (due to a large font or picture)
|
|
1876 |
// than the visible height of the view our desired top line remains
|
|
1877 |
// the next one above so that a scroll takes place.
|
|
1878 |
desired_top_line_number = top_line_number - aLines;
|
|
1879 |
if (partial_line && (info.iOuterRect.iBr.iY-info.iOuterRect.iTl.iY < visible_height))
|
|
1880 |
desired_top_line_number++;
|
|
1881 |
|
|
1882 |
// If the desired first visible line number is negative, more lines need to be formatted.
|
|
1883 |
if (desired_top_line_number >= 0)
|
|
1884 |
break;
|
|
1885 |
if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
|
|
1886 |
break;
|
|
1887 |
iBandTop += height_increase;
|
|
1888 |
}
|
|
1889 |
|
|
1890 |
if (desired_top_line_number < 0)
|
|
1891 |
{
|
|
1892 |
lines_scrolled += desired_top_line_number;
|
|
1893 |
desired_top_line_number = 0;
|
|
1894 |
}
|
|
1895 |
aLines -= lines_scrolled;
|
|
1896 |
if (lines_scrolled)
|
|
1897 |
{
|
|
1898 |
if (!iText->LineNumberToLine(desired_top_line_number,info))
|
|
1899 |
User::Leave(EPosNotFormatted);
|
|
1900 |
// if the line to be scrolled to is taller than the screen, we want
|
|
1901 |
// to make sure that the baseline is not scrolled off the screen.
|
|
1902 |
if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
|
|
1903 |
return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace);
|
|
1904 |
return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace);
|
|
1905 |
}
|
|
1906 |
else
|
|
1907 |
return 0;
|
|
1908 |
}
|
|
1909 |
else if (aLines < 0) // bring aLines lines into view at the bottom of the display
|
|
1910 |
{
|
|
1911 |
if (iScrollFlags & EFScrollOnlyToTopsOfLines)
|
|
1912 |
{
|
|
1913 |
// If we are restricting scroll to the tops of lines, then lines at
|
|
1914 |
// bottom are irrelevant, so all we do is lose the top line.
|
|
1915 |
if (!iText->YPosToLine(iBandTop, info))
|
|
1916 |
User::Leave(EPosNotFormatted);
|
|
1917 |
return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace);
|
|
1918 |
}
|
|
1919 |
|
|
1920 |
int desired_bottom_line_number = 0;
|
|
1921 |
int band_bottom = iBandTop + visible_height;
|
|
1922 |
int last_formatted_line = iText->Lines() - 1;
|
|
1923 |
|
|
1924 |
// Extend formatting until the visible height is filled.
|
|
1925 |
param.iEndChar = KMaxTInt;
|
|
1926 |
param.iMaxHeight = band_bottom - iText->LayoutHeight();
|
|
1927 |
if(param.iMaxHeight > 0)
|
|
1928 |
{
|
|
1929 |
iText->ExtendFormattingDownwardsL(param);
|
|
1930 |
}
|
|
1931 |
for (;;)
|
|
1932 |
{
|
|
1933 |
// Find the line number of the last visible line.
|
|
1934 |
TBool partial_line = FALSE;
|
|
1935 |
int bottom_line_number = 0;
|
|
1936 |
if (iText->YPosToLine(band_bottom - 1,info))
|
|
1937 |
bottom_line_number = info.iLineNumber;
|
|
1938 |
else
|
|
1939 |
User::Leave(EPosNotFormatted);
|
|
1940 |
partial_line = band_bottom < info.iOuterRect.iBr.iY;
|
|
1941 |
|
|
1942 |
// Find the line number of the desired last visible line.
|
|
1943 |
desired_bottom_line_number = bottom_line_number - aLines;
|
|
1944 |
if (partial_line)
|
|
1945 |
desired_bottom_line_number--;
|
|
1946 |
|
|
1947 |
// If the desired last visible line number is greater than the last line, more lines need to be formatted.
|
|
1948 |
if (desired_bottom_line_number <= last_formatted_line)
|
|
1949 |
break;
|
|
1950 |
if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
|
|
1951 |
break;
|
|
1952 |
last_formatted_line = iText->Lines() - 1;
|
|
1953 |
}
|
|
1954 |
|
|
1955 |
int shortfall = desired_bottom_line_number - last_formatted_line;
|
|
1956 |
if (shortfall > 0)
|
|
1957 |
{
|
|
1958 |
lines_scrolled += shortfall;
|
|
1959 |
desired_bottom_line_number = last_formatted_line;
|
|
1960 |
}
|
|
1961 |
aLines -= lines_scrolled;
|
|
1962 |
if (lines_scrolled)
|
|
1963 |
{
|
|
1964 |
if (!iText->LineNumberToLine(desired_bottom_line_number,info))
|
|
1965 |
User::Leave(EPosNotFormatted);
|
|
1966 |
return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace);
|
|
1967 |
}
|
|
1968 |
else
|
|
1969 |
return 0;
|
|
1970 |
}
|
|
1971 |
else
|
|
1972 |
return 0;
|
|
1973 |
}
|
|
1974 |
|
|
1975 |
/** Scrolls the text up or down by aPixels pixels, disallowing blank space at
|
|
1976 |
the bottom of the visible area if aScrollBlankSpace is
|
|
1977 |
CTextLayout::EFDisallowScrollingBlankSpace.
|
|
1978 |
|
|
1979 |
The return value (not aPixels, as you would expect from ScrollParagraphsL() and
|
|
1980 |
ScrollLinesL()) contains the number of pixels not successfully scrolled, that
|
|
1981 |
is, the original value of aPixels, minus the number of pixels actually
|
|
1982 |
scrolled. On return, aPixels is set to the number of pixels actually scrolled.
|
|
1983 |
|
|
1984 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
1985 |
|
|
1986 |
@param aPixels The number of pixels to scroll; may be a positive or negative
|
|
1987 |
value. On return, contains the number of pixels actually scrolled.
|
|
1988 |
@param aScrollBlankSpace Only relevant when scrolling downwards.
|
|
1989 |
CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
|
|
1990 |
visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
|
|
1991 |
from scrolling into the visible area.
|
|
1992 |
@return The difference between the requested number of pixels to scroll and the
|
|
1993 |
number of pixels actually scrolled. */
|
|
1994 |
EXPORT_C TInt CTextLayout::ChangeBandTopL(TInt& aPixels,TAllowDisallow aScrollBlankSpace)
|
|
1995 |
{
|
|
1996 |
int desired_pixels = aPixels;
|
|
1997 |
aPixels = ScrollL(aPixels,aScrollBlankSpace);
|
|
1998 |
return desired_pixels - aPixels;
|
|
1999 |
}
|
|
2000 |
|
|
2001 |
|
|
2002 |
|
|
2003 |
/** Scrolls the text up or down by aPixels pixels, allowing blank space at
|
|
2004 |
top and bottom of the visible area, which means the scrolling can go beyond the
|
|
2005 |
top or bottom border.
|
|
2006 |
|
|
2007 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2008 |
|
|
2009 |
@param aPixels The number of pixels to scroll; may be a positive or negative
|
|
2010 |
value. The actual scrolled pixel number is always identical to aPixels*/
|
|
2011 |
EXPORT_C void CTextLayout::ChangeBandTopNoLimitBorderL(TInt aPixels)
|
|
2012 |
{
|
|
2013 |
ScrollL(aPixels,EFAllowScrollingBlankSpace,ETrue,ETrue);
|
|
2014 |
}
|
|
2015 |
|
|
2016 |
|
|
2017 |
/**
|
|
2018 |
* Finds a position (in pixels, from the top of the window) where the cursor
|
|
2019 |
* can be such that its line will be fully visible. If this is not possible,
|
|
2020 |
* then return one with its baseline visible. If this is not possible, we don't
|
|
2021 |
* care what the answer is.
|
|
2022 |
*/
|
|
2023 |
TInt CTextLayout::SuggestCursorPos(TInt aCurrentCursorPos) const
|
|
2024 |
{
|
|
2025 |
int visible_height = VisibleHeightInPixels();
|
|
2026 |
TTmLineInfo info;
|
|
2027 |
if (iText->YPosToLine(iBandTop + aCurrentCursorPos, info))
|
|
2028 |
{
|
|
2029 |
TBool currentLineHasBaselineVisible =
|
|
2030 |
(TBool)(iBandTop <= info.iBaseline
|
|
2031 |
&& info.iBaseline < iBandTop + visible_height);
|
|
2032 |
TInt tryThisLine = -1;
|
|
2033 |
// find a good line to put the cursor on.
|
|
2034 |
if (info.iOuterRect.iTl.iY < iBandTop)
|
|
2035 |
{
|
|
2036 |
// try next line
|
|
2037 |
tryThisLine = info.iLineNumber + 1;
|
|
2038 |
}
|
|
2039 |
else if (iBandTop + visible_height < info.iOuterRect.iBr.iY)
|
|
2040 |
{
|
|
2041 |
tryThisLine = info.iLineNumber - 1;
|
|
2042 |
}
|
|
2043 |
if (0 <= tryThisLine && iText->LineNumberToLine(tryThisLine, info))
|
|
2044 |
{
|
|
2045 |
if (iBandTop <= info.iOuterRect.iTl.iY
|
|
2046 |
&& info.iOuterRect.iBr.iY < iBandTop + visible_height)
|
|
2047 |
// this line fully visible
|
|
2048 |
aCurrentCursorPos = info.iBaseline - iBandTop;
|
|
2049 |
else if (!currentLineHasBaselineVisible
|
|
2050 |
&& iBandTop <= info.iBaseline
|
|
2051 |
&& info.iBaseline < iBandTop + visible_height)
|
|
2052 |
// not fully visible, but its baseline is, and the original
|
|
2053 |
// line's baseline was not
|
|
2054 |
aCurrentCursorPos = info.iBaseline - iBandTop;
|
|
2055 |
}
|
|
2056 |
}
|
|
2057 |
return aCurrentCursorPos;
|
|
2058 |
}
|
|
2059 |
|
|
2060 |
/** Scrolls up by a page (that is the band height as set by SetBandHeight(), or
|
|
2061 |
half that amount if scrolling over lines taller than this), moving the text
|
|
2062 |
downwards. The current desired vertical cursor position is passed in
|
|
2063 |
aYCursorPos and updated to a new suggested position as near as possible to it,
|
|
2064 |
but within the visible text and on a baseline.
|
|
2065 |
|
|
2066 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2067 |
|
|
2068 |
@param aYCursorPos The current desired vertical cursor position. On return,
|
|
2069 |
updated to a new suggested position as near as possible to it.
|
|
2070 |
@param aPixelsScrolled On return, contains the number of pixels scrolled. */
|
|
2071 |
EXPORT_C void CTextLayout::PageUpL(TInt& aYCursorPos,TInt& aPixelsScrolled)
|
|
2072 |
{
|
|
2073 |
// Move the cursor into the visible area.
|
|
2074 |
int visible_height = VisibleHeightInPixels();
|
|
2075 |
if (aYCursorPos < 0)
|
|
2076 |
aYCursorPos = 0;
|
|
2077 |
else if (aYCursorPos > visible_height)
|
|
2078 |
aYCursorPos = visible_height - 1;
|
|
2079 |
|
|
2080 |
TTmLineInfo info;
|
|
2081 |
// position the top of the screen must be at least as low as
|
|
2082 |
TInt longestScrollTo = iBandTop + visible_height
|
|
2083 |
- visible_height * KMaxProportionOfScreenToScroll/1000;
|
|
2084 |
// position the top of the screen must be at least as high as
|
|
2085 |
TInt shortestScrollTo = iBandTop + visible_height
|
|
2086 |
- visible_height * KMinProportionOfScreenToScroll/1000;
|
|
2087 |
TInt desiredScrollTo = shortestScrollTo;
|
|
2088 |
// find the line at the top of the screen
|
|
2089 |
// (we cannot find the one that includes the first pixel off the screen
|
|
2090 |
// because it might not have been formatted yet)
|
|
2091 |
if (iText->YPosToLine(iBandTop, info))
|
|
2092 |
{
|
|
2093 |
// subtract one from the line number if this was on the screen
|
|
2094 |
TInt line = info.iLineNumber
|
|
2095 |
- (info.iOuterRect.iTl.iY < iBandTop? 0 : 1)
|
|
2096 |
+ KNumberOfLinesToKeepVisibleDuringScroll;
|
|
2097 |
if (iText->LineNumberToLine(Max(0, line), info))
|
|
2098 |
desiredScrollTo = info.iOuterRect.iTl.iY;
|
|
2099 |
}
|
|
2100 |
if (shortestScrollTo < desiredScrollTo)
|
|
2101 |
desiredScrollTo = shortestScrollTo;
|
|
2102 |
else if (desiredScrollTo < longestScrollTo)
|
|
2103 |
desiredScrollTo = longestScrollTo;
|
|
2104 |
aPixelsScrolled = ScrollL(iBandTop + visible_height - desiredScrollTo,
|
|
2105 |
EFDisallowScrollingBlankSpace);
|
|
2106 |
aYCursorPos = aPixelsScrolled == 0?
|
|
2107 |
0
|
|
2108 |
: SuggestCursorPos(aYCursorPos);
|
|
2109 |
}
|
|
2110 |
|
|
2111 |
/** Scrolls down by a page (that is the band height as set by SetBandHeight(),
|
|
2112 |
or half that amount if scrolling over lines taller than this), moving the text
|
|
2113 |
upwards. The current desired vertical cursor position is passed in aYCursorPos
|
|
2114 |
and updated to a new suggested position as near as possible to it, but within
|
|
2115 |
the visible text and on a baseline.
|
|
2116 |
|
|
2117 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2118 |
|
|
2119 |
@param aYCursorPos The current desired vertical cursor position. On return,
|
|
2120 |
updated to a new suggested position as near as possible to it.
|
|
2121 |
@param aPixelsScrolled On return, contains the number of pixels scrolled - a
|
|
2122 |
negative value. */
|
|
2123 |
EXPORT_C void CTextLayout::PageDownL(TInt& aYCursorPos,TInt& aPixelsScrolled)
|
|
2124 |
{
|
|
2125 |
// Move the cursor into the visible area.
|
|
2126 |
int visible_height = VisibleHeightInPixels();
|
|
2127 |
if (aYCursorPos < 0)
|
|
2128 |
aYCursorPos = 0;
|
|
2129 |
else if (aYCursorPos > visible_height)
|
|
2130 |
aYCursorPos = visible_height - 1;
|
|
2131 |
|
|
2132 |
TTmLineInfo info;
|
|
2133 |
// position the bottom of the screen must be at least as high as
|
|
2134 |
TInt longestScrollTo = iBandTop +
|
|
2135 |
visible_height * KMaxProportionOfScreenToScroll/1000;
|
|
2136 |
// position the bottom of the screen must be at least as low as
|
|
2137 |
TInt shortestScrollTo = iBandTop + visible_height * KMinProportionOfScreenToScroll/1000;
|
|
2138 |
TInt desiredScrollTo = shortestScrollTo;
|
|
2139 |
// find the line at the bottom of the screen
|
|
2140 |
// (we cannot find the one that includes the first pixel off the screen
|
|
2141 |
// because it might not have been formatted yet)
|
|
2142 |
if (iText->YPosToLine(iBandTop + visible_height - 1, info))
|
|
2143 |
{
|
|
2144 |
// add one to the line number if this was on the screen
|
|
2145 |
TInt line = info.iLineNumber
|
|
2146 |
+ (iBandTop + visible_height < info.iBaseline? 0 : 1)
|
|
2147 |
- KNumberOfLinesToKeepVisibleDuringScroll;
|
|
2148 |
if (iText->LineNumberToLine(Max(0, line), info))
|
|
2149 |
desiredScrollTo = info.iOuterRect.iBr.iY;
|
|
2150 |
}
|
|
2151 |
if (desiredScrollTo < shortestScrollTo)
|
|
2152 |
desiredScrollTo = shortestScrollTo;
|
|
2153 |
else if (longestScrollTo < desiredScrollTo)
|
|
2154 |
desiredScrollTo = longestScrollTo;
|
|
2155 |
aPixelsScrolled = ScrollL(iBandTop - desiredScrollTo,
|
|
2156 |
EFDisallowScrollingBlankSpace);
|
|
2157 |
aYCursorPos = aPixelsScrolled == 0?
|
|
2158 |
visible_height - 1
|
|
2159 |
: SuggestCursorPos(aYCursorPos);
|
|
2160 |
|
|
2161 |
__ASSERT_DEBUG(-visible_height <= aPixelsScrolled,
|
|
2162 |
Panic(EPageScrollError));
|
|
2163 |
__ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height,
|
|
2164 |
Panic(EPageScrollError));
|
|
2165 |
}
|
|
2166 |
|
|
2167 |
/** Reformats to reflect a single character edit.
|
|
2168 |
|
|
2169 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2170 |
|
|
2171 |
@param aType Indicates the type of edit which has taken place.
|
|
2172 |
CTextLayout::EFCharacterInsert (the default) for a character insertion,
|
|
2173 |
CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion,
|
|
2174 |
CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or
|
|
2175 |
paragraph delimiter deletion to the left or right of the document position.
|
|
2176 |
@param aCursorPos The document position at which the edit took place, before
|
|
2177 |
the edit. If this position is not formatted, a panic occurs; it is modified in
|
|
2178 |
accordance with the edit.
|
|
2179 |
@param aGood On return, the y coordinate of the top of the paragraph following
|
|
2180 |
the paragraph which has been edited, before the edit.
|
|
2181 |
@param aFormattedUpTo On return, the y coordinate of the bottom of the
|
|
2182 |
reformatted line or lines, after the edit.
|
|
2183 |
@param aFormattedFrom On return, the vertical layout coordinate of the top of
|
|
2184 |
the reformatted line or lines, after the edit.
|
|
2185 |
@param aScroll The number of pixels by which the text had to be scrolled
|
|
2186 |
(positive means text moved down).
|
|
2187 |
@param aFormatChanged ETrue if text is to be reformatted from the start of the
|
|
2188 |
paragraph the cursor was on before the edit, EFalse if from the start of the
|
|
2189 |
line the cursor was on before the edit.
|
|
2190 |
@return EFalse if no more lines need to be reformatted. ETrue if some more lines
|
|
2191 |
need to be reformatted. */
|
|
2192 |
EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom,
|
|
2193 |
TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar)
|
|
2194 |
{
|
|
2195 |
__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
|
|
2196 |
__ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType));
|
|
2197 |
__ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType));
|
|
2198 |
__ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted));
|
|
2199 |
|
|
2200 |
// Mark the entire paragraph invalid if background formatting is taking place.
|
|
2201 |
iParInvalid = iUnformattedStart != KMaxTInt;
|
|
2202 |
|
|
2203 |
// Cancel any pending background formatting, which has now been invalidated by the change.
|
|
2204 |
iUnformattedStart = KMaxTInt;
|
|
2205 |
|
|
2206 |
// Adjust the cursor position and determine the range of characters to reformat.
|
|
2207 |
TTmReformatParam reformat_param;
|
|
2208 |
reformat_param.iParInvalid = iParInvalid;
|
|
2209 |
switch (aType)
|
|
2210 |
{
|
|
2211 |
case EFCharacterInsert:
|
|
2212 |
case EFParagraphDelimiter:
|
|
2213 |
{
|
|
2214 |
reformat_param.iStartChar = aCursorPos++;
|
|
2215 |
reformat_param.iNewLength = 1;
|
|
2216 |
|
|
2217 |
// surrogate support
|
|
2218 |
TPtrC textForSurrogate;
|
|
2219 |
TTmCharFormat formatForSurrogate;
|
|
2220 |
|
|
2221 |
iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
|
|
2222 |
if ( textForSurrogate.Length() > 1 )
|
|
2223 |
{
|
|
2224 |
TUint highSurrogate = textForSurrogate[0];
|
|
2225 |
TUint lowSurrogate = textForSurrogate[1];
|
|
2226 |
if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
|
|
2227 |
{
|
|
2228 |
// if we are inserting a surrogate pair, do not break the pair
|
|
2229 |
aCursorPos++;
|
|
2230 |
reformat_param.iNewLength++;
|
|
2231 |
}
|
|
2232 |
}
|
|
2233 |
break;
|
|
2234 |
}
|
|
2235 |
case EFLeftDelete:
|
|
2236 |
{
|
|
2237 |
reformat_param.iStartChar = --aCursorPos;
|
|
2238 |
reformat_param.iOldLength = 1;
|
|
2239 |
|
|
2240 |
// surrogate support
|
|
2241 |
TPtrC textForSurrogate;
|
|
2242 |
TTmCharFormat formatForSurrogate;
|
|
2243 |
|
|
2244 |
if (aCursorPos >= 1)
|
|
2245 |
{
|
|
2246 |
iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
|
|
2247 |
if ( textForSurrogate.Length() > 1 )
|
|
2248 |
{
|
|
2249 |
TUint highSurrogate = textForSurrogate[0];
|
|
2250 |
TUint lowSurrogate = textForSurrogate[1];
|
|
2251 |
if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
|
|
2252 |
{
|
|
2253 |
// if we are deleting a surrogate pair, do not break the pair
|
|
2254 |
reformat_param.iStartChar = --aCursorPos;
|
|
2255 |
reformat_param.iOldLength++;
|
|
2256 |
}
|
|
2257 |
}
|
|
2258 |
}
|
|
2259 |
break;
|
|
2260 |
}
|
|
2261 |
case EFRightDelete:
|
|
2262 |
{
|
|
2263 |
reformat_param.iStartChar = aCursorPos;
|
|
2264 |
reformat_param.iOldLength = 1;
|
|
2265 |
|
|
2266 |
// surrogate support
|
|
2267 |
TPtrC textForSurrogate;
|
|
2268 |
TTmCharFormat formatForSurrogate;
|
|
2269 |
|
|
2270 |
iSource->GetText(aCursorPos, textForSurrogate, formatForSurrogate);
|
|
2271 |
if ( textForSurrogate.Length() > 1 )
|
|
2272 |
{
|
|
2273 |
TUint highSurrogate = textForSurrogate[0];
|
|
2274 |
TUint lowSurrogate = textForSurrogate[1];
|
|
2275 |
if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
|
|
2276 |
{
|
|
2277 |
reformat_param.iOldLength++;
|
|
2278 |
}
|
|
2279 |
}
|
|
2280 |
break;
|
|
2281 |
}
|
|
2282 |
default: break;
|
|
2283 |
}
|
|
2284 |
|
|
2285 |
// Set up the formatting parameters.
|
|
2286 |
TTmFormatParam param;
|
|
2287 |
InitFormatParam(param);
|
|
2288 |
param.iMaxHeight = KMaxTInt;
|
|
2289 |
|
|
2290 |
// Format the whole band if necessary.
|
|
2291 |
TTmDocPos cursorPos(aCursorPos, EFalse);
|
|
2292 |
if (reformat_param.iStartChar < iText->StartChar() || reformat_param.iStartChar + reformat_param.iOldLength >= iText->EndChar())
|
|
2293 |
{
|
|
2294 |
FormatBandL(reformat_param.iStartChar,reformat_param.iStartChar + reformat_param.iOldLength);
|
|
2295 |
aFormatTop = 0;
|
|
2296 |
aFormatBottom = iText->LayoutHeight() - iBandTop;
|
|
2297 |
aGood = aFormatBottom;
|
|
2298 |
aScroll = 0;
|
|
2299 |
ScrollDocPosIntoViewL(cursorPos);
|
|
2300 |
return FALSE;
|
|
2301 |
}
|
|
2302 |
|
|
2303 |
// Reformat the chosen range.
|
|
2304 |
reformat_param.iMaxExtraLines = KMaxExtraLines;
|
|
2305 |
TTmReformatResult result;
|
|
2306 |
iText->FormatL(param,reformat_param,result);
|
|
2307 |
result.iRedrawRect.Move(0,-iBandTop);
|
|
2308 |
iUnformattedStart = result.iUnformattedStart;
|
|
2309 |
|
|
2310 |
// Scroll if necessary and extend the redraw area to include material scrolled into view.
|
|
2311 |
aScroll = ScrollDocPosIntoViewL(cursorPos);
|
|
2312 |
if (aScroll > 0)
|
|
2313 |
result.iRedrawRect.iBr.iY += aScroll;
|
|
2314 |
else
|
|
2315 |
result.iRedrawRect.iTl.iY += aScroll;
|
|
2316 |
|
|
2317 |
// Return coordinates.
|
|
2318 |
aFormatTop = result.iRedrawRect.iTl.iY;
|
|
2319 |
aFormatBottom = result.iRedrawRect.iBr.iY;
|
|
2320 |
aGood = result.iUnchangedTop - iBandTop;
|
|
2321 |
|
|
2322 |
// Add new paragraphs if necessary.
|
|
2323 |
int visible_height = VisibleHeightInPixels();
|
|
2324 |
|
|
2325 |
param.iEndChar = KMaxTInt;
|
|
2326 |
param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
|
|
2327 |
if(param.iMaxHeight > 0)
|
|
2328 |
{
|
|
2329 |
iText->ExtendFormattingDownwardsL(param);
|
|
2330 |
}
|
|
2331 |
|
|
2332 |
//remove formatting from the end if necessary
|
|
2333 |
PruneFormatL(EFalse);
|
|
2334 |
// Return TRUE if more text needs to be formatted.
|
|
2335 |
return iUnformattedStart < KMaxTInt;
|
|
2336 |
}
|
|
2337 |
|
|
2338 |
/** Reformats to reflect changes to a block of text.
|
|
2339 |
|
|
2340 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2341 |
|
|
2342 |
@param aSelection The start and new length of the changed block. When
|
|
2343 |
inserting, specify the insertion position. When deleting, specify the position
|
|
2344 |
of the start of the deletion. When reformatting, specify the start and length
|
|
2345 |
of the reformatted block.
|
|
2346 |
@param aOldCharsChanged The old length of the changed block. When inserting,
|
|
2347 |
specify zero. When deleting, specify the number of deleted characters. When
|
|
2348 |
reformatting, specify the number of reformatted characters.
|
|
2349 |
@param aViewChanges On return, contains the top of the reformatted text
|
|
2350 |
(iFormattedFrom), the bottom of the reformatted text (iFormattedTo), the amount
|
|
2351 |
by which the text above the reformatted text has scrolled (iScrollAtTop) and
|
|
2352 |
the amount by which the text below the reformatted text has scrolled
|
|
2353 |
(iScrollAtBottom) (positive values mean the text moves down).
|
|
2354 |
@param aFormatChanged Indicates whether the paragraph format for the first or
|
|
2355 |
last affected paragraph has changed, meaning that the text to be reformatted
|
|
2356 |
must extend out to paragraph boundaries and cannot be restricted to only some
|
|
2357 |
lines. */
|
|
2358 |
EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength,
|
|
2359 |
TViewRectChanges& aChanges,TBool aFormatFromStartOfPar)
|
|
2360 |
{
|
|
2361 |
__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
|
|
2362 |
|
|
2363 |
// Do nothing if the selection is outside the formatted range.
|
|
2364 |
if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar())
|
|
2365 |
{
|
|
2366 |
aChanges.iFormattedFrom = 0;
|
|
2367 |
aChanges.iFormattedTo = 0;
|
|
2368 |
aChanges.iScrollAtTop = 0;
|
|
2369 |
aChanges.iScrollAtBottom = 0;
|
|
2370 |
return;
|
|
2371 |
}
|
|
2372 |
|
|
2373 |
// Format the whole band if necessary.
|
|
2374 |
TTmDocPos cursorPos(aSelection.iCursorPos,
|
|
2375 |
aSelection.iCursorPos < aSelection.iAnchorPos? ETrue : EFalse);
|
|
2376 |
if (aSelection.LowerPos() < iText->StartChar() || aSelection.LowerPos() + aOldLength >= iText->EndChar())
|
|
2377 |
{
|
|
2378 |
FormatBandL(aSelection.iCursorPos,aSelection.iCursorPos);
|
|
2379 |
aChanges.iFormattedFrom = 0;
|
|
2380 |
aChanges.iFormattedTo = VisibleHeightInPixels();
|
|
2381 |
aChanges.iScrollAtTop = 0;
|
|
2382 |
aChanges.iScrollAtBottom = 0;
|
|
2383 |
ScrollDocPosIntoViewL(cursorPos);
|
|
2384 |
return;
|
|
2385 |
}
|
|
2386 |
|
|
2387 |
// Reformat the chosen range.
|
|
2388 |
TTmFormatParam param;
|
|
2389 |
InitFormatParam(param);
|
|
2390 |
param.iMaxHeight = KMaxTInt;
|
|
2391 |
TTmReformatParam reformat_param;
|
|
2392 |
reformat_param.iStartChar = aSelection.LowerPos();
|
|
2393 |
reformat_param.iOldLength = aOldLength;
|
|
2394 |
reformat_param.iNewLength = aSelection.Length();
|
|
2395 |
reformat_param.iParFormatChanged = aFormatFromStartOfPar;
|
|
2396 |
TTmReformatResult result;
|
|
2397 |
iText->FormatL(param,reformat_param,result);
|
|
2398 |
result.iRedrawRect.Move(0,-iBandTop);
|
|
2399 |
|
|
2400 |
// Scroll if necessary.
|
|
2401 |
int dy;
|
|
2402 |
if(iTextViewCursorPos)
|
|
2403 |
{
|
|
2404 |
dy = ScrollDocPosIntoViewL(iTextViewCursorPos->TmDocPos());
|
|
2405 |
iTextViewCursorPos = NULL;
|
|
2406 |
}
|
|
2407 |
else
|
|
2408 |
{
|
|
2409 |
dy = ScrollDocPosIntoViewL(cursorPos);
|
|
2410 |
}
|
|
2411 |
result.iRedrawRect.Move(0,dy);
|
|
2412 |
|
|
2413 |
aChanges.iFormattedFrom = result.iRedrawRect.iTl.iY;
|
|
2414 |
aChanges.iFormattedTo = result.iRedrawRect.iBr.iY;
|
|
2415 |
aChanges.iScrollAtTop = dy;
|
|
2416 |
aChanges.iScrollAtBottom = dy + result.iHeightChange;
|
|
2417 |
|
|
2418 |
// Extend formatting to fill the band if necessary.
|
|
2419 |
int visible_height = VisibleHeightInPixels();
|
|
2420 |
|
|
2421 |
param.iEndChar = KMaxTInt;
|
|
2422 |
param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
|
|
2423 |
if(param.iMaxHeight > 0)
|
|
2424 |
{
|
|
2425 |
iText->ExtendFormattingDownwardsL(param);
|
|
2426 |
}
|
|
2427 |
|
|
2428 |
//remove formatting from the end if necessary
|
|
2429 |
PruneFormatL(EFalse);
|
|
2430 |
}
|
|
2431 |
|
|
2432 |
/** Reformats to reflect the addition of one or more complete paragraphs at the
|
|
2433 |
end of the text.
|
|
2434 |
|
|
2435 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2436 |
|
|
2437 |
@param aFirstPixel On return, the top y coordinate of the added material.
|
|
2438 |
@param aLastPixel On return, the bottom y coordinate of the added material.
|
|
2439 |
*/
|
|
2440 |
EXPORT_C void CTextLayout::HandleAdditionalCharactersAtEndL(TInt& aNewTextTop,TInt& aNewTextBottom)
|
|
2441 |
{
|
|
2442 |
aNewTextTop = aNewTextBottom = iText->LayoutHeight() - iBandTop;
|
|
2443 |
int format_required = BandHeightInPixels() - aNewTextBottom;
|
|
2444 |
if (format_required > 0)
|
|
2445 |
{
|
|
2446 |
TTmFormatParam param;
|
|
2447 |
InitFormatParam(param);
|
|
2448 |
param.iMaxHeight = format_required;
|
|
2449 |
TInt oldHeight = iText->LayoutHeight();
|
|
2450 |
iText->ExtendFormattingDownwardsL(param);
|
|
2451 |
aNewTextBottom += (iText->LayoutHeight() - oldHeight);
|
|
2452 |
}
|
|
2453 |
}
|
|
2454 |
|
|
2455 |
/** Reformats to reflect changes to the space above and below paragraphs
|
|
2456 |
(CParaFormat::iSpaceBeforeInTwips and iSpaceAfterInTwips).
|
|
2457 |
|
|
2458 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2459 |
@deprecated 6.1 Use FormatBandL()
|
|
2460 |
*/
|
|
2461 |
EXPORT_C void CTextLayout::ReformatVerticalSpaceL()
|
|
2462 |
{
|
|
2463 |
// Reformat the whole band; only space above and below paragraphs has changed, but who cares?
|
|
2464 |
FormatBandL();
|
|
2465 |
}
|
|
2466 |
|
|
2467 |
/** Temporarily changes the vertical alignment of the text with respect to the
|
|
2468 |
visible height.
|
|
2469 |
|
|
2470 |
Notes:
|
|
2471 |
|
|
2472 |
Not generally useful.
|
|
2473 |
|
|
2474 |
Do not use if a CTextView object owns this CTextLayout object.
|
|
2475 |
|
|
2476 |
@param aVerticalAlignment Specifies whether the formatted text should be placed
|
|
2477 |
at the top (CParaFormat::ETopAlign), vertical centre (CParaFormat::ECenterAlign
|
|
2478 |
or CParaFormat::EJustifiedAlign) or bottom (CParaFormat::EBottomAlign) of the
|
|
2479 |
band. CParaFormat::EUnspecifiedAlign or CParaFormat::ECustomAlign may also be
|
|
2480 |
specified. These values cause the baseline of the first formatted line to be
|
|
2481 |
positioned 82% of the way down the band (provided for the Agenda's
|
|
2482 |
application's year view). */
|
|
2483 |
EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment)
|
|
2484 |
{
|
|
2485 |
int excess = BandHeight() - FormattedHeightInPixels();
|
|
2486 |
int space_before = 0;
|
|
2487 |
__ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText));
|
|
2488 |
TTmLineInfo info;
|
|
2489 |
|
|
2490 |
switch (aVerticalAlignment)
|
|
2491 |
{
|
|
2492 |
case CParaFormat::EAbsoluteLeftAlign:
|
|
2493 |
case CParaFormat::ETopAlign:
|
|
2494 |
break;
|
|
2495 |
case CParaFormat::ECenterAlign:
|
|
2496 |
case CParaFormat::EJustifiedAlign:
|
|
2497 |
space_before = excess / 2;
|
|
2498 |
break;
|
|
2499 |
case CParaFormat::EAbsoluteRightAlign:
|
|
2500 |
case CParaFormat::EBottomAlign:
|
|
2501 |
space_before = excess;
|
|
2502 |
break;
|
|
2503 |
case CParaFormat::EUnspecifiedAlign:
|
|
2504 |
case CParaFormat::ECustomAlign:
|
|
2505 |
if (iText->LineNumberToLine(0,info))
|
|
2506 |
{
|
|
2507 |
space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100 - info.iBaseline;
|
|
2508 |
}
|
|
2509 |
else
|
|
2510 |
{
|
|
2511 |
space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100;
|
|
2512 |
}
|
|
2513 |
break;
|
|
2514 |
}
|
|
2515 |
|
|
2516 |
iBandTop = -space_before;
|
|
2517 |
}
|
|
2518 |
|
|
2519 |
static TInt SingleBorderWidthInPixels(const MGraphicsDeviceMap* aGd,const TParaBorder& aBorder,TBool aHoriz)
|
|
2520 |
{
|
|
2521 |
TInt width = aBorder.iThickness;
|
|
2522 |
if (width > 0)
|
|
2523 |
{
|
|
2524 |
if (aHoriz)
|
|
2525 |
width = aGd->VerticalTwipsToPixels(width);
|
|
2526 |
else
|
|
2527 |
width = aGd->HorizontalTwipsToPixels(width);
|
|
2528 |
}
|
|
2529 |
else
|
|
2530 |
width = 1;
|
|
2531 |
return width;
|
|
2532 |
}
|
|
2533 |
|
|
2534 |
/** Draws paragraph borders, optionally with a background colour for the border
|
|
2535 |
and a clip region. Provided for applications that display a menu of border
|
|
2536 |
styles, like a wordprocessor.
|
|
2537 |
|
|
2538 |
@param aGd Provides twip-to-pixel conversion.
|
|
2539 |
@param aGc Graphics context to which to draw the border. Its pen settings are
|
|
2540 |
overridden by the values specified by aBorder and its draw mode is set to
|
|
2541 |
CGraphicsContext::EDrawModePEN.
|
|
2542 |
@param aRect The outer bounds of the border.
|
|
2543 |
@param aBorder Specifies the four sides of the border.
|
|
2544 |
@param aBackground If not null, the background colour, (used between double
|
|
2545 |
border lines, or between dots or dashes).
|
|
2546 |
@param aClipRegion If non-null, specifies a clip region.
|
|
2547 |
@param aDrawRect If non-null, and if aClipRegion is non-null, specifies a
|
|
2548 |
rectangle to be subtracted from the clip region. */
|
|
2549 |
EXPORT_C void CTextLayout::DrawBorders(const MGraphicsDeviceMap* aGd,CGraphicsContext& aGc,const TRect& aBoundingRect,
|
|
2550 |
const TParaBorderArray& aBorder,const TRgb* aBackground,TRegion *aClipRegion,
|
|
2551 |
const TRect* aDrawRect)
|
|
2552 |
{
|
|
2553 |
TPoint pointTl,pointBr;
|
|
2554 |
TRect rect;
|
|
2555 |
TInt * ptrStartLength=NULL; //To stop a warning
|
|
2556 |
TInt * ptrEndLength=NULL; //To stop a warning
|
|
2557 |
TInt * ptrStartWidth=NULL; //To stop a warning
|
|
2558 |
TInt * ptrEndWidth=NULL; //To stop a warning
|
|
2559 |
TInt directionOut=0; //To stop a warning
|
|
2560 |
TInt indexJoint1=0,indexJoint2=0; //To stop a warning
|
|
2561 |
TBool drawAsLine=EFalse;
|
|
2562 |
TRect clipRect;
|
|
2563 |
CGraphicsContext::TPenStyle penStyle[4];
|
|
2564 |
TInt widthInPixels[4];
|
|
2565 |
TBool horiz;
|
|
2566 |
const MFormParam* form_param = MFormParam::Get();
|
|
2567 |
|
|
2568 |
{for (TInt border=0; border<=3; border++)
|
|
2569 |
{
|
|
2570 |
TParaBorder::TLineStyle lineStyle=aBorder.iBorder[border].iLineStyle;
|
|
2571 |
if (lineStyle == TParaBorder::ENullLineStyle)
|
|
2572 |
{
|
|
2573 |
penStyle[border]=CGraphicsContext::ENullPen;
|
|
2574 |
widthInPixels[border]=0;
|
|
2575 |
continue;
|
|
2576 |
}
|
|
2577 |
else
|
|
2578 |
{
|
|
2579 |
horiz=(border==CParaFormat::EParaBorderTop || border==CParaFormat::EParaBorderBottom);
|
|
2580 |
|
|
2581 |
widthInPixels[border]=SingleBorderWidthInPixels(aGd,aBorder.iBorder[border],horiz);
|
|
2582 |
}
|
|
2583 |
|
|
2584 |
if (lineStyle==TParaBorder::ESolid || lineStyle==TParaBorder::EDouble)
|
|
2585 |
{
|
|
2586 |
penStyle[border]=CGraphicsContext::ESolidPen;
|
|
2587 |
continue;
|
|
2588 |
}
|
|
2589 |
|
|
2590 |
if (lineStyle == TParaBorder::EDashed)
|
|
2591 |
penStyle[border]=CGraphicsContext::EDashedPen;
|
|
2592 |
else if (lineStyle == TParaBorder::EDotted)
|
|
2593 |
penStyle[border]=CGraphicsContext::EDottedPen;
|
|
2594 |
else if (lineStyle == TParaBorder::EDotDash)
|
|
2595 |
penStyle[border]=CGraphicsContext::EDotDashPen;
|
|
2596 |
else if (lineStyle == TParaBorder::EDotDotDash)
|
|
2597 |
penStyle[border]=CGraphicsContext::EDotDotDashPen;
|
|
2598 |
|
|
2599 |
}}
|
|
2600 |
|
|
2601 |
{for (TInt border=0; border<=3; border++)
|
|
2602 |
{
|
|
2603 |
// Go to next border, if have NULL linestyle.
|
|
2604 |
if (widthInPixels[border]==0)
|
|
2605 |
continue;
|
|
2606 |
|
|
2607 |
// Reset clipping region
|
|
2608 |
clipRect.SetSize(TSize(0,0));
|
|
2609 |
|
|
2610 |
// Draw as line if not solid lines.
|
|
2611 |
|
|
2612 |
if (penStyle[border]!=CGraphicsContext::ESolidPen)
|
|
2613 |
drawAsLine=ETrue;
|
|
2614 |
|
|
2615 |
pointTl=aBoundingRect.iTl;
|
|
2616 |
pointBr=aBoundingRect.iBr;
|
|
2617 |
|
|
2618 |
if (border==CParaFormat::EParaBorderLeft)
|
|
2619 |
{
|
|
2620 |
pointBr.iX=pointTl.iX;
|
|
2621 |
ptrStartLength=&pointTl.iY;
|
|
2622 |
ptrEndLength=&pointBr.iY;
|
|
2623 |
ptrStartWidth=&pointTl.iX;
|
|
2624 |
ptrEndWidth=&pointBr.iX;
|
|
2625 |
directionOut=-1;
|
|
2626 |
indexJoint1=CParaFormat::EParaBorderTop;
|
|
2627 |
indexJoint2=CParaFormat::EParaBorderBottom;
|
|
2628 |
}
|
|
2629 |
if (border == CParaFormat::EParaBorderRight)
|
|
2630 |
{
|
|
2631 |
pointTl.iX=pointBr.iX;
|
|
2632 |
ptrStartLength=&pointTl.iY;
|
|
2633 |
ptrEndLength=&pointBr.iY;
|
|
2634 |
ptrStartWidth=&pointTl.iX;
|
|
2635 |
ptrEndWidth=&pointBr.iX;
|
|
2636 |
directionOut=1;
|
|
2637 |
indexJoint1=CParaFormat::EParaBorderTop;
|
|
2638 |
indexJoint2=CParaFormat::EParaBorderBottom;
|
|
2639 |
}
|
|
2640 |
if (border == CParaFormat::EParaBorderTop)
|
|
2641 |
{
|
|
2642 |
pointBr.iY=pointTl.iY;
|
|
2643 |
ptrStartLength=&pointTl.iX;
|
|
2644 |
ptrEndLength=&pointBr.iX;
|
|
2645 |
ptrStartWidth=&pointTl.iY;
|
|
2646 |
ptrEndWidth=&pointBr.iY;
|
|
2647 |
directionOut=-1;
|
|
2648 |
indexJoint1=CParaFormat::EParaBorderLeft;
|
|
2649 |
indexJoint2=CParaFormat::EParaBorderRight;
|
|
2650 |
}
|
|
2651 |
if (border == CParaFormat::EParaBorderBottom)
|
|
2652 |
{
|
|
2653 |
pointTl.iY=pointBr.iY;
|
|
2654 |
ptrStartLength=&pointTl.iX;
|
|
2655 |
ptrEndLength=&pointBr.iX;
|
|
2656 |
ptrStartWidth=&pointTl.iY;
|
|
2657 |
ptrEndWidth=&pointBr.iY;
|
|
2658 |
directionOut=1;
|
|
2659 |
indexJoint1=CParaFormat::EParaBorderLeft;
|
|
2660 |
indexJoint2=CParaFormat::EParaBorderRight;
|
|
2661 |
}
|
|
2662 |
|
|
2663 |
if (!ptrStartWidth || !ptrEndWidth)
|
|
2664 |
{
|
|
2665 |
continue;
|
|
2666 |
}
|
|
2667 |
|
|
2668 |
if (drawAsLine)
|
|
2669 |
{
|
|
2670 |
if (directionOut<0)
|
|
2671 |
{
|
|
2672 |
(*ptrStartWidth)+=(widthInPixels[border]-1)/2;
|
|
2673 |
(*ptrEndWidth)+=(widthInPixels[border]-1)/2;
|
|
2674 |
}
|
|
2675 |
else
|
|
2676 |
{
|
|
2677 |
(*ptrStartWidth)-=(widthInPixels[border]+2)/2;
|
|
2678 |
(*ptrEndWidth)-=(widthInPixels[border]+2)/2;
|
|
2679 |
}
|
|
2680 |
(*ptrStartLength)+=(widthInPixels[border]-1)/2;
|
|
2681 |
(*ptrEndLength)-=(widthInPixels[border])/2;
|
|
2682 |
}
|
|
2683 |
else
|
|
2684 |
{
|
|
2685 |
if (directionOut<0)
|
|
2686 |
(*ptrEndWidth)+=widthInPixels[border];
|
|
2687 |
else
|
|
2688 |
(*ptrStartWidth)-=widthInPixels[border];
|
|
2689 |
}
|
|
2690 |
|
|
2691 |
// Colour of pen as is - NO logical combination with background etc.
|
|
2692 |
aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
|
|
2693 |
|
|
2694 |
if (drawAsLine)
|
|
2695 |
{
|
|
2696 |
// Must draw lines in background colour first, as have dotted/dashed lines.
|
|
2697 |
aGc.SetPenSize(TSize(widthInPixels[border],widthInPixels[border]));
|
|
2698 |
if (aBackground)
|
|
2699 |
{
|
|
2700 |
FormUtil::SetPenColor(form_param,&aGc,*aBackground);
|
|
2701 |
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
|
|
2702 |
aGc.DrawLine(pointTl,pointBr);
|
|
2703 |
}
|
|
2704 |
FormUtil::SetPenColor(form_param,&aGc,aBorder.iBorder[border].iColor);
|
|
2705 |
aGc.SetPenStyle(penStyle[border]);
|
|
2706 |
aGc.DrawLine(pointTl,pointBr);
|
|
2707 |
(*ptrStartWidth)-=(widthInPixels[border]-1)/2;
|
|
2708 |
(*ptrEndWidth)+=(widthInPixels[border]+2)/2;
|
|
2709 |
(*ptrStartLength)-=(widthInPixels[border]-1)/2;
|
|
2710 |
(*ptrEndLength)+=(widthInPixels[border])/2;
|
|
2711 |
clipRect.SetRect(pointTl,pointBr);
|
|
2712 |
}
|
|
2713 |
else
|
|
2714 |
{
|
|
2715 |
// Brush
|
|
2716 |
FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
|
|
2717 |
aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
|
|
2718 |
aGc.SetPenStyle(CGraphicsContext::ENullPen);
|
|
2719 |
rect.SetRect(pointTl,pointBr);
|
|
2720 |
aGc.DrawRect(rect);
|
|
2721 |
clipRect=rect;
|
|
2722 |
};
|
|
2723 |
|
|
2724 |
// Repeat draw, for double border.
|
|
2725 |
if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble) // Now have only got solid border, drawn as rect.
|
|
2726 |
{
|
|
2727 |
__ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError));
|
|
2728 |
(*ptrStartWidth)-=directionOut*widthInPixels[border];
|
|
2729 |
(*ptrEndWidth)-=directionOut*widthInPixels[border];
|
|
2730 |
(*ptrStartLength)+=widthInPixels[indexJoint1];
|
|
2731 |
(*ptrEndLength)-=widthInPixels[indexJoint2];
|
|
2732 |
|
|
2733 |
if (aBackground)
|
|
2734 |
{
|
|
2735 |
rect.SetRect(pointTl,pointBr);
|
|
2736 |
FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
|
|
2737 |
aGc.DrawRect(rect);
|
|
2738 |
}
|
|
2739 |
|
|
2740 |
(*ptrStartWidth)-=directionOut*widthInPixels[border];
|
|
2741 |
(*ptrEndWidth)-=directionOut*widthInPixels[border];
|
|
2742 |
|
|
2743 |
if (aBorder.iBorder[indexJoint1].iLineStyle==TParaBorder::EDouble)
|
|
2744 |
(*ptrStartLength)+=widthInPixels[indexJoint1];
|
|
2745 |
if (aBorder.iBorder[indexJoint2].iLineStyle==TParaBorder::EDouble)
|
|
2746 |
(*ptrEndLength)-=widthInPixels[indexJoint2];
|
|
2747 |
|
|
2748 |
rect.SetRect(pointTl,pointBr);
|
|
2749 |
FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
|
|
2750 |
aGc.DrawRect(rect);
|
|
2751 |
clipRect.BoundingRect(rect);
|
|
2752 |
};
|
|
2753 |
|
|
2754 |
|
|
2755 |
// Restore defaults
|
|
2756 |
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
|
|
2757 |
aGc.SetPenSize(TSize(1,1));
|
|
2758 |
// Should change to BACKGROUND colour.
|
|
2759 |
if (aBackground)
|
|
2760 |
FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
|
|
2761 |
// If have to clip region, then remove rectangles corresponding to the border region.
|
|
2762 |
|
|
2763 |
if (aClipRegion)
|
|
2764 |
{
|
|
2765 |
if (aDrawRect)
|
|
2766 |
clipRect.Intersection(*aDrawRect);
|
|
2767 |
aClipRegion->SubRect(clipRect);
|
|
2768 |
}
|
|
2769 |
|
|
2770 |
}};
|
|
2771 |
|
|
2772 |
if (aClipRegion)
|
|
2773 |
{
|
|
2774 |
aClipRegion->Tidy();
|
|
2775 |
((CWindowGc *) &aGc)->SetClippingRegion(*aClipRegion);
|
|
2776 |
}
|
|
2777 |
|
|
2778 |
}
|
|
2779 |
|
|
2780 |
/** Draws the text. Draws any lines that intersect aDrawRect, which is
|
|
2781 |
specified in window coordinates. The drawing parameters, including the graphics
|
|
2782 |
context, are given in aDrawTextLayoutContext. If aHighlight is non-null,
|
|
2783 |
highlights (by exclusive-ORing) the specified range of text.
|
|
2784 |
|
|
2785 |
@param aDrawRect The function draw the lines within the visible area, which
|
|
2786 |
intersect this rectangle (which is specified in window coordinates).
|
|
2787 |
@param aDrawTextLayoutContext Provides a graphics context and other parameters
|
|
2788 |
for the function.
|
|
2789 |
@param aHighlight If not NULL, this range of text is drawn highlighted. */
|
|
2790 |
EXPORT_C void CTextLayout::DrawL(const TRect& aDrawRect,const TDrawTextLayoutContext* aDrawTextLayoutContext,
|
|
2791 |
const TCursorSelection* aHighlight)
|
|
2792 |
{
|
|
2793 |
// Set the drawing parameters in the MTmSource interface.
|
|
2794 |
iSource->iFormParam = MFormParam::Get();
|
|
2795 |
iSource->iLabelsGutter = aDrawTextLayoutContext->iGutterMarginWidth;
|
|
2796 |
|
|
2797 |
// Calculate the top left corner of the text.
|
|
2798 |
TPoint top_left = aDrawTextLayoutContext->TopLeftText();
|
|
2799 |
top_left.iY -= iBandTop;
|
|
2800 |
|
|
2801 |
// Get the graphics context.
|
|
2802 |
CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
|
|
2803 |
|
|
2804 |
/*
|
|
2805 |
Clip the draw rectangle to the view rectangle, and clip it further to exclude
|
|
2806 |
a final partial line if necessary.
|
|
2807 |
*/
|
|
2808 |
TRect clip_rect(aDrawRect);
|
|
2809 |
clip_rect.Intersection(aDrawTextLayoutContext->iViewRect);
|
|
2810 |
|
|
2811 |
|
|
2812 |
if (aDrawTextLayoutContext->UseClippingRect())
|
|
2813 |
{
|
|
2814 |
gc->SetClippingRect(clip_rect);
|
|
2815 |
}
|
|
2816 |
|
|
2817 |
// Draw the text and background.
|
|
2818 |
|
|
2819 |
TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
|
|
2820 |
|
|
2821 |
if (isDrawingOnAWindowDC)
|
|
2822 |
{
|
|
2823 |
BeginRedraw(clip_rect);
|
|
2824 |
}
|
|
2825 |
|
|
2826 |
iText->DrawLayout(*gc,top_left,clip_rect,&aDrawTextLayoutContext->iBackgroundColor,TRUE, aHighlight, iHighlightExtensions);
|
|
2827 |
|
|
2828 |
if (isDrawingOnAWindowDC)
|
|
2829 |
{
|
|
2830 |
EndRedraw();
|
|
2831 |
}
|
|
2832 |
|
|
2833 |
iSource->iFormParam = NULL;
|
|
2834 |
}
|
|
2835 |
|
|
2836 |
/** Default constructor.
|
|
2837 |
|
|
2838 |
The start and end positions are set to zero - Set() should be called to
|
|
2839 |
initialise the object. */
|
|
2840 |
EXPORT_C CTextLayout::TRangeChange::TRangeChange()
|
|
2841 |
: iA(0), iB(0) {}
|
|
2842 |
|
|
2843 |
/** Sets the start and end positions and whether the highlighting should be
|
|
2844 |
set or cleared.
|
|
2845 |
|
|
2846 |
Called by the non-default constructor. The start and end positions can be
|
|
2847 |
specified in any order.
|
|
2848 |
|
|
2849 |
@param aStart The start of the range.
|
|
2850 |
@param aEnd The end of the range.
|
|
2851 |
@param aChange Whether the highlighting should be set or cleared. */
|
|
2852 |
EXPORT_C void CTextLayout::TRangeChange::Set(TInt aStart, TInt aEnd,
|
|
2853 |
CTextLayout::TRangeChange::TChangeType aChange)
|
|
2854 |
{
|
|
2855 |
if ((aChange == ESet && aStart < aEnd)
|
|
2856 |
|| (!(aChange == ESet) && !(aStart < aEnd)))
|
|
2857 |
{
|
|
2858 |
iA = aStart;
|
|
2859 |
iB = aEnd;
|
|
2860 |
}
|
|
2861 |
else
|
|
2862 |
{
|
|
2863 |
iA = aEnd;
|
|
2864 |
iB = aStart;
|
|
2865 |
}
|
|
2866 |
}
|
|
2867 |
|
|
2868 |
/** Constructor with a start and end position and whether the highlighting
|
|
2869 |
in the range should be set or cleared.
|
|
2870 |
|
|
2871 |
The start and end positions can be specified in any order.
|
|
2872 |
|
|
2873 |
@param aStart The start position.
|
|
2874 |
@param aEnd The end position.
|
|
2875 |
@param aChange Specifies whether the highlighting should be set or cleared.
|
|
2876 |
*/
|
|
2877 |
EXPORT_C CTextLayout::TRangeChange::TRangeChange(TInt aStart, TInt aEnd,
|
|
2878 |
CTextLayout::TRangeChange::TChangeType aChange)
|
|
2879 |
{
|
|
2880 |
Set(aStart, aEnd, aChange);
|
|
2881 |
}
|
|
2882 |
|
|
2883 |
/** Gets the start and end of the range and whether the highlighting should be
|
|
2884 |
set or cleared.
|
|
2885 |
|
|
2886 |
@param aStart On return, the start of the range. This is always the lesser of
|
|
2887 |
the two positions.
|
|
2888 |
@param aEnd On return, the end of the range. This is always the greater of the
|
|
2889 |
two positions.
|
|
2890 |
@return Specifies whether the highlighting should be set or cleared. */
|
|
2891 |
EXPORT_C CTextLayout::TRangeChange::TChangeType
|
|
2892 |
CTextLayout::TRangeChange::Get(TInt& aStart, TInt& aEnd) const
|
|
2893 |
{
|
|
2894 |
if (iA < iB)
|
|
2895 |
{
|
|
2896 |
aStart = iA;
|
|
2897 |
aEnd = iB;
|
|
2898 |
return ESet;
|
|
2899 |
}
|
|
2900 |
aStart = iB;
|
|
2901 |
aEnd = iA;
|
|
2902 |
return EClear;
|
|
2903 |
}
|
|
2904 |
|
|
2905 |
/** Tests whether the range is not null.
|
|
2906 |
|
|
2907 |
@return ETrue if the range is not of zero length, EFalse if the range is of zero
|
|
2908 |
length. */
|
|
2909 |
EXPORT_C TBool CTextLayout::TRangeChange::NonNull() const
|
|
2910 |
{
|
|
2911 |
return iA - iB;
|
|
2912 |
}
|
|
2913 |
|
|
2914 |
/** Clips the range so that its start and end positions are within the minimum
|
|
2915 |
and maximum positions specified.
|
|
2916 |
|
|
2917 |
@param aMin The minimum value for the start and end of the range.
|
|
2918 |
@param aMax The maximum value for the start and end of the range.
|
|
2919 |
@return ETrue if the resulting range is not of zero length, EFalse if it is of
|
|
2920 |
zero length. */
|
|
2921 |
EXPORT_C TBool CTextLayout::TRangeChange::Clip(TInt aMin, TInt aMax)
|
|
2922 |
{
|
|
2923 |
if (iA < aMin)
|
|
2924 |
iA = aMin;
|
|
2925 |
if (iB < aMin)
|
|
2926 |
iB = aMin;
|
|
2927 |
if (aMax < iA)
|
|
2928 |
iA = aMax;
|
|
2929 |
if (aMax < iB)
|
|
2930 |
iB = aMax;
|
|
2931 |
return iA - iB;
|
|
2932 |
}
|
|
2933 |
|
|
2934 |
/** Try to cancel out sections of the ranges that overlap Merges two ranges of
|
|
2935 |
characters.
|
|
2936 |
|
|
2937 |
Two successive calls to CTextLayout::Highlight() could cause unecessary flicker
|
|
2938 |
or redrawing if the arguments to each call overlap. For example, if extending a
|
|
2939 |
highlight involved removing the old highlight and then drawing the new one,
|
|
2940 |
this would cause visible flicker. This can be eliminated by calling this
|
|
2941 |
function to remove any overlap between the two ranges. If there is overlap,
|
|
2942 |
this range is set to the result of the merge, and the other range (aBuddy) is
|
|
2943 |
set to zero.
|
|
2944 |
|
|
2945 |
When calling this function, it does not matter whether or not the two ranges
|
|
2946 |
overlap. Also it does not matter which range is the parameter and which is the
|
|
2947 |
calling object. After calling OptimizeWith(), it is guaranteed that the
|
|
2948 |
resulting ranges will not overlap, and they will represent the same change to
|
|
2949 |
the highlight as the original two ranges.
|
|
2950 |
|
|
2951 |
See the code fragment in the class description for TRangeChange for an example
|
|
2952 |
of how this function is used.
|
|
2953 |
|
|
2954 |
@param aBuddy The range of characters to combine with this range. */
|
|
2955 |
EXPORT_C void CTextLayout::TRangeChange::OptimizeWith(TRangeChange& aBuddy)
|
|
2956 |
{
|
|
2957 |
// we make this have the minimum iA and iB, and aBuddy have the maximum
|
|
2958 |
if (aBuddy.iA < iA)
|
|
2959 |
{
|
|
2960 |
TInt temp = aBuddy.iA;
|
|
2961 |
aBuddy.iA = iA;
|
|
2962 |
iA = temp;
|
|
2963 |
}
|
|
2964 |
if (aBuddy.iB < iB)
|
|
2965 |
{
|
|
2966 |
TInt temp = aBuddy.iB;
|
|
2967 |
aBuddy.iB = iB;
|
|
2968 |
iB = temp;
|
|
2969 |
}
|
|
2970 |
// if they now overlap, we combine them into one and zero the other
|
|
2971 |
if (aBuddy.iB <= iA)
|
|
2972 |
iA = aBuddy.iB = aBuddy.iA;
|
|
2973 |
else if (aBuddy.iA <= iB)
|
|
2974 |
iB = aBuddy.iA = aBuddy.iB;
|
|
2975 |
}
|
|
2976 |
|
|
2977 |
|
|
2978 |
TBool CTextLayout::TRangeChange::IsJoinedTo(const TRangeChange aRange)
|
|
2979 |
{
|
|
2980 |
TInt a1 = (iA < iB) ? iA : iB;
|
|
2981 |
TInt b1 = (iA < iB) ? iB : iA;
|
|
2982 |
TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
|
|
2983 |
TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
|
|
2984 |
|
|
2985 |
return a2 <= b1 && a1 <= b2;
|
|
2986 |
}
|
|
2987 |
|
|
2988 |
void CTextLayout::TRangeChange::Join(const TRangeChange aRange)
|
|
2989 |
{
|
|
2990 |
TInt a1 = (iA < iB) ? iA : iB;
|
|
2991 |
TInt b1 = (iA < iB) ? iB : iA;
|
|
2992 |
TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
|
|
2993 |
TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
|
|
2994 |
|
|
2995 |
// type set to ESet
|
|
2996 |
iA = (a1 < a2) ? a1 : a2;
|
|
2997 |
iB = (b1 > b2) ? b1 : b2;
|
|
2998 |
}
|
|
2999 |
|
|
3000 |
|
|
3001 |
/** Sets or clears a highlight.
|
|
3002 |
|
|
3003 |
If the range of characters to highlight is of zero length, the function has no
|
|
3004 |
effect.
|
|
3005 |
|
|
3006 |
The function affects only those lines that intersect aDrawRect, which is
|
|
3007 |
specified in window coordinates. The drawing parameters, including the graphics
|
|
3008 |
context, are given in aDrawTextLayoutContext.
|
|
3009 |
|
|
3010 |
From v7.0, this function replaces InvertRangeL().
|
|
3011 |
|
|
3012 |
This function is not intended to be used to set any part of a highlight already
|
|
3013 |
set, nor to clear any piece of text not highlighted. It is intended to do
|
|
3014 |
either or both of: clear an existing selection, set a new selection. See the
|
|
3015 |
class description for TRangeChange for a code fragment showing how this
|
|
3016 |
function should be used.
|
|
3017 |
|
|
3018 |
@param aHighlight Specifies the range of characters to highlight or from which
|
|
3019 |
to remove the highlight.
|
|
3020 |
@param aDrawRect Only lines which intersect this rectangle are affected
|
|
3021 |
(specified in window coordinates).
|
|
3022 |
@param aDrawTextLayoutContext Provides a graphics context and other drawing
|
|
3023 |
parameters, e.g. the text and background colours for the highlighted region. */
|
|
3024 |
|
|
3025 |
EXPORT_C void CTextLayout::Highlight(const CTextLayout::TRangeChange& aChangeHighlight,
|
|
3026 |
const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext)
|
|
3027 |
{
|
|
3028 |
if (!aChangeHighlight.NonNull())
|
|
3029 |
return;
|
|
3030 |
|
|
3031 |
TRect clip_rect(aDrawRect);
|
|
3032 |
|
|
3033 |
CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
|
|
3034 |
if (aDrawTextLayoutContext->UseClippingRect())
|
|
3035 |
gc->SetClippingRect(clip_rect);
|
|
3036 |
|
|
3037 |
TInt visible_start;
|
|
3038 |
TInt visible_length = PosRangeInBand(visible_start);
|
|
3039 |
|
|
3040 |
TInt start_pos;
|
|
3041 |
TInt end_pos;
|
|
3042 |
|
|
3043 |
CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
|
|
3044 |
start_pos = start_pos < visible_start? visible_start : start_pos;
|
|
3045 |
end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
|
|
3046 |
TCursorSelection selection(start_pos, end_pos);
|
|
3047 |
|
|
3048 |
TPoint top_left = aDrawTextLayoutContext->TopLeftText();
|
|
3049 |
top_left.iY -= iBandTop;
|
|
3050 |
|
|
3051 |
TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
|
|
3052 |
|
|
3053 |
TRect boundingRect;
|
|
3054 |
iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
|
|
3055 |
iHighlightExtensions->AbsExtendRect(boundingRect);
|
|
3056 |
boundingRect.Intersection(clip_rect);
|
|
3057 |
if (! boundingRect.IsEmpty())
|
|
3058 |
{
|
|
3059 |
if (isDrawingOnAWindowDC)
|
|
3060 |
{
|
|
3061 |
BeginRedraw(boundingRect);
|
|
3062 |
}
|
|
3063 |
iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, NULL);
|
|
3064 |
if (isDrawingOnAWindowDC)
|
|
3065 |
{
|
|
3066 |
EndRedraw();
|
|
3067 |
}
|
|
3068 |
}
|
|
3069 |
}
|
|
3070 |
|
|
3071 |
void CTextLayout::HighlightUsingExtensions(const CTextLayout::TRangeChange& aChangeHighlight,const TRangeChange& aFullHighlight,
|
|
3072 |
const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext)
|
|
3073 |
{
|
|
3074 |
if (!aChangeHighlight.NonNull())
|
|
3075 |
return;
|
|
3076 |
|
|
3077 |
TRect clip_rect(aDrawRect);
|
|
3078 |
clip_rect.Intersection(aDrawTextLayoutContext->TextArea());
|
|
3079 |
|
|
3080 |
CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
|
|
3081 |
if (aDrawTextLayoutContext->UseClippingRect())
|
|
3082 |
{
|
|
3083 |
gc->SetClippingRect(clip_rect);
|
|
3084 |
}
|
|
3085 |
|
|
3086 |
TInt visible_start;
|
|
3087 |
TInt visible_length = PosRangeInBand(visible_start);
|
|
3088 |
TInt start_pos;
|
|
3089 |
TInt end_pos;
|
|
3090 |
CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
|
|
3091 |
start_pos = start_pos < visible_start? visible_start : start_pos;
|
|
3092 |
end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
|
|
3093 |
|
|
3094 |
TInt full_start_pos;
|
|
3095 |
TInt full_end_pos;
|
|
3096 |
(void)aFullHighlight.Get(full_start_pos, full_end_pos);
|
|
3097 |
full_start_pos = full_start_pos < visible_start? visible_start : full_start_pos;
|
|
3098 |
full_end_pos = full_end_pos < visible_start + visible_length? full_end_pos : full_start_pos + visible_length;
|
|
3099 |
TCursorSelection selection(full_start_pos, full_end_pos);
|
|
3100 |
|
|
3101 |
TPoint top_left = aDrawTextLayoutContext->TopLeftText();
|
|
3102 |
top_left.iY -= iBandTop;
|
|
3103 |
|
|
3104 |
TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
|
|
3105 |
|
|
3106 |
TRect boundingRect;
|
|
3107 |
iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
|
|
3108 |
iHighlightExtensions->AbsExtendRect(boundingRect);
|
|
3109 |
boundingRect.Intersection(clip_rect);
|
|
3110 |
if (! boundingRect.IsEmpty())
|
|
3111 |
{
|
|
3112 |
if (isDrawingOnAWindowDC)
|
|
3113 |
{
|
|
3114 |
BeginRedraw(boundingRect);
|
|
3115 |
}
|
|
3116 |
iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, iHighlightExtensions);
|
|
3117 |
if (isDrawingOnAWindowDC)
|
|
3118 |
{
|
|
3119 |
EndRedraw();
|
|
3120 |
}
|
|
3121 |
}
|
|
3122 |
|
|
3123 |
if (aDrawTextLayoutContext->UseClippingRect())
|
|
3124 |
{
|
|
3125 |
gc->CancelClippingRect();
|
|
3126 |
}
|
|
3127 |
}
|
|
3128 |
|
|
3129 |
/** Toggles the selection highlight for the range of text in aHighlight.
|
|
3130 |
|
|
3131 |
Highlights only those lines that intersect aDrawRect, which is specified in
|
|
3132 |
window coordinates. The drawing parameters, including the graphics context, are
|
|
3133 |
given in aDrawTextLayoutContext.
|
|
3134 |
|
|
3135 |
In v7.0 and onwards, this function is deprecated -Highlight() should be used
|
|
3136 |
instead.
|
|
3137 |
@deprecated
|
|
3138 |
@param aHighlight The range of characters for which to invert the highlighting.
|
|
3139 |
@param aDrawRect Only lines which intersect this rectangle are affected;
|
|
3140 |
specified in window coordinates.
|
|
3141 |
@param aDrawTextLayoutContext Provides a graphics context and other drawing
|
|
3142 |
parameters. */
|
|
3143 |
EXPORT_C void CTextLayout::InvertRangeL(const TCursorSelection& aHighlight,const TRect& aDrawRect,
|
|
3144 |
const TDrawTextLayoutContext* aDrawTextLayoutContext)
|
|
3145 |
{
|
|
3146 |
TRangeChange range(aHighlight.iAnchorPos, aHighlight.iCursorPos, TRangeChange::ESet);
|
|
3147 |
HighlightUsingExtensions(range,range,aDrawRect,aDrawTextLayoutContext);
|
|
3148 |
}
|
|
3149 |
|
|
3150 |
/**
|
|
3151 |
Return the FORM major version number. This function is not generally useful. It
|
|
3152 |
is used in test code and was used while making a transition between this and
|
|
3153 |
the former version of FORM. The return value is always 2.
|
|
3154 |
*/
|
|
3155 |
EXPORT_C TInt CTextLayout::MajorVersion() const
|
|
3156 |
{
|
|
3157 |
return 2;
|
|
3158 |
}
|
|
3159 |
|
|
3160 |
/**
|
|
3161 |
This method allows Form clients to register an object able to
|
|
3162 |
create or return references to customisation objects used within Form for
|
|
3163 |
various tasks e.g. inline text.
|
|
3164 |
@param aProvider
|
|
3165 |
Reference to interface provider object to register with Formm.
|
|
3166 |
*/
|
|
3167 |
EXPORT_C void CTextLayout::SetInterfaceProvider( MFormCustomInterfaceProvider* aProvider )
|
|
3168 |
{
|
|
3169 |
iSource->iInterfaceProvider = aProvider;
|
|
3170 |
}
|
|
3171 |
|
|
3172 |
/** Gets the width and height of the bounding box of the text, including
|
|
3173 |
indents and margins, when formatted to the specified wrap width.
|
|
3174 |
|
|
3175 |
This is useful for applications like a web browser that need to determine the
|
|
3176 |
minimum width for a piece of text: if you specify zero as the wrap width, the
|
|
3177 |
returned aSize.iWidth contains the minimum width that could be used for the
|
|
3178 |
text without illegal line breaks, and if you specify KMaxTInt for aWrapWidth,
|
|
3179 |
the returned aSize.iHeight contains the minimum height: the height when each
|
|
3180 |
paragraph is a single line of unlimited length.
|
|
3181 |
@since 6.0
|
|
3182 |
@param aWrapWidth The wrap width for the bounding box.
|
|
3183 |
@param aSize On return, contains the width and height of the bounding box. */
|
|
3184 |
EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TSize& aSize)
|
|
3185 |
{
|
|
3186 |
//
|
|
3187 |
//Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
|
|
3188 |
//The width may be greater than aWrapWidth. To find the minimum width for the text,
|
|
3189 |
//pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
|
|
3190 |
//
|
|
3191 |
iText->GetMinimumLayoutSizeL(aWrapWidth,aSize);
|
|
3192 |
}
|
|
3193 |
|
|
3194 |
/** Gets the width and height of the bounding box of the text, including
|
|
3195 |
indents and margins, when formatted to the specified wrap width.
|
|
3196 |
|
|
3197 |
This is useful for applications like a web browser that need to determine the
|
|
3198 |
minimum width for a piece of text: if you specify zero as the wrap width, the
|
|
3199 |
returned aSize.iWidth contains the minimum width that could be used for the
|
|
3200 |
text, and if you specify KMaxTInt for aWrapWidth, the returned aSize.iHeight
|
|
3201 |
contains the minimum height: the height when each paragraph is a single
|
|
3202 |
line of unlimited length. Use aAllowLegalLineBreaksOnly to set whether or
|
|
3203 |
not illegal line breaks should be considered when determining aSize.
|
|
3204 |
@since 6.0
|
|
3205 |
@param aWrapWidth The wrap width for the bounding box.
|
|
3206 |
@param aAllowLegalLineBreaksOnly ETrue to only allow legal line breaks, or EFalse to also allow illegal line breaks.
|
|
3207 |
@param aSize On return, contains the width and height of the bounding box. */
|
|
3208 |
EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TBool aAllowLegalLineBreaksOnly,TSize& aSize)
|
|
3209 |
{
|
|
3210 |
//
|
|
3211 |
//Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
|
|
3212 |
//The width may be greater than aWrapWidth. To find the minimum width for the text,
|
|
3213 |
//pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
|
|
3214 |
//
|
|
3215 |
iText->GetMinimumLayoutSizeL(aWrapWidth,aAllowLegalLineBreaksOnly,aSize);
|
|
3216 |
}
|
|
3217 |
|
|
3218 |
/** Sets the custom drawing object, for customising the way text and its
|
|
3219 |
background are drawn.
|
|
3220 |
@since 6.0
|
|
3221 |
@param aCustomDraw Pointer to a custom drawing object. */
|
|
3222 |
EXPORT_C void CTextLayout::SetCustomDraw(const MFormCustomDraw* aCustomDraw)
|
|
3223 |
{
|
|
3224 |
iSource->iCustomDraw = aCustomDraw;
|
|
3225 |
}
|
|
3226 |
|
|
3227 |
/** Returns a pointer to the current custom drawing implementation. Returns
|
|
3228 |
NULL if custom drawing is not in force.
|
|
3229 |
@since 6.0
|
|
3230 |
@return Pointer to the custom drawing object. */
|
|
3231 |
EXPORT_C const MFormCustomDraw* CTextLayout::CustomDraw() const
|
|
3232 |
{
|
|
3233 |
return iSource->iCustomDraw;
|
|
3234 |
}
|
|
3235 |
|
|
3236 |
/** Sets custom line breaking.
|
|
3237 |
|
|
3238 |
If this function is not called, default line breaking behaviour is used.
|
|
3239 |
|
|
3240 |
Ownership of the custom line breaking object is not transferred to this object.
|
|
3241 |
|
|
3242 |
@param aCustomWrap A pointer to an object that implements the custom line
|
|
3243 |
breaking interface. Specify NULL to disable custom line breaking. */
|
|
3244 |
EXPORT_C void CTextLayout::SetCustomWrap(const MFormCustomWrap* aCustomWrap)
|
|
3245 |
{
|
|
3246 |
iSource->iCustomWrap = aCustomWrap;
|
|
3247 |
}
|
|
3248 |
|
|
3249 |
/** Gets the custom line breaking object, as set using SetCustomWrap().
|
|
3250 |
|
|
3251 |
@return A pointer to the custom line breaking object, or NULL if custom line
|
|
3252 |
breaking is not in effect. */
|
|
3253 |
EXPORT_C const MFormCustomWrap* CTextLayout::CustomWrap() const
|
|
3254 |
{
|
|
3255 |
return iSource->iCustomWrap;
|
|
3256 |
}
|
|
3257 |
|
|
3258 |
/**
|
|
3259 |
@internalAll
|
|
3260 |
@released
|
|
3261 |
*/
|
|
3262 |
EXPORT_C void MFormCustomDraw::MFormCustomDraw_Reserved_2()
|
|
3263 |
{
|
|
3264 |
}
|
|
3265 |
|
|
3266 |
/** This function is called whenever part of the background of a CTextLayout or
|
|
3267 |
CTextView object needs to be drawn. The default implementation fills
|
|
3268 |
aParam.iDrawRect with the colour specified in aBackground.
|
|
3269 |
|
|
3270 |
The default background colour is contained in aBackground. This is the
|
|
3271 |
background colour of the paragraph if drawing text, or the background colour
|
|
3272 |
specified in the TDrawTextLayoutContext object passed to CTextLayout::DrawL()
|
|
3273 |
if drawing outside the text area.
|
|
3274 |
|
|
3275 |
The rectangle which is drawn by this function, (this may not be the whole of
|
|
3276 |
aParam.iDrawRect) must be returned in aDrawn; areas not drawn by you are
|
|
3277 |
automatically filled using the colour aBackground.
|
|
3278 |
|
|
3279 |
@param aParam Contains the drawing parameters: aParam.iGc is the graphics
|
|
3280 |
context to use. aParam.iMap is the graphics device map, which allows you to
|
|
3281 |
convert between pixels and twips and create fonts. aParam.iTextLayoutTopLeft is
|
|
3282 |
the origin of the text; bitmaps and other graphics must be drawn relative to
|
|
3283 |
this position. aParam.iDrawRect is the area to be drawn; do not draw outside
|
|
3284 |
this rectangle.
|
|
3285 |
@param aBackground The default background colour. This is the background colour
|
|
3286 |
of the paragraph if drawing text, or the background colour specified in the
|
|
3287 |
TDrawTextLayoutContext object passed to CTextLayout::DrawL() if drawing outside
|
|
3288 |
the text area.
|
|
3289 |
@param aDrawn Must return the rectangle you actually draw. This may not be the
|
|
3290 |
whole of aParam.iDrawRect (for instance, if you are drawing a non-tiled bitmap
|
|
3291 |
that occupies only part of aRect). */
|
|
3292 |
EXPORT_C void MFormCustomDraw::DrawBackground(const TParam& aParam,const TRgb& aBackground,TRect& aDrawn) const
|
|
3293 |
{
|
|
3294 |
MTmCustom c;
|
|
3295 |
c.DrawBackground(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,aBackground,aDrawn);
|
|
3296 |
}
|
|
3297 |
|
|
3298 |
/** This function is called after the background has been drawn by
|
|
3299 |
DrawBackground(), and before drawing the text. This function might be used to
|
|
3300 |
draw a ruled line under each line of text.
|
|
3301 |
|
|
3302 |
The default implementation of this function does nothing.
|
|
3303 |
|
|
3304 |
@param aParam Contains the drawing parameters. You should only draw to
|
|
3305 |
aParam.iDrawRect. There is no need to fill aParam.iDrawRect or to indicate the
|
|
3306 |
rectangle drawn.
|
|
3307 |
@param aLineInfo Contains the line metrics: aLineInfo.iOuterLineRect specifies
|
|
3308 |
the bounding rectangle of the line, including margins, indents and automatic
|
|
3309 |
space above and below paragraphs, aLineInfo.iInnerLineRect specifies the bounds
|
|
3310 |
of the text only, aLineInfo.iBaseline specifies the baseline of the text. */
|
|
3311 |
EXPORT_C void MFormCustomDraw::DrawLineGraphics(const TParam& /*aParam*/,const TLineInfo& /*aLineInfo*/) const
|
|
3312 |
{
|
|
3313 |
// do nothing
|
|
3314 |
}
|
|
3315 |
|
|
3316 |
/** This function is called to draw the text and its highlighted background, if
|
|
3317 |
any, after bidirectional reordering and other character mappings have taken
|
|
3318 |
place.
|
|
3319 |
|
|
3320 |
The default implementation of this function draws the text with no special
|
|
3321 |
effects and supports standard, round-cornered and shadowed highlighting only.
|
|
3322 |
The text is drawn with the left end of its baseline located at aTextOrigin
|
|
3323 |
after drawing the background, if any, in aParam.iDrawRect.
|
|
3324 |
|
|
3325 |
The main reason to override this function is to apply custom text highlighting,
|
|
3326 |
(for this, aFormat.iFontPresentation.iHighlightStyle should be in the range
|
|
3327 |
EFontHighlightFirstCustomStyle to EFontHighlightLastCustomStyle).
|
|
3328 |
|
|
3329 |
The horizontal spacing between the characters in the text string is increased
|
|
3330 |
by the number of pixels specified in aExtraPixels. The standard way to do this
|
|
3331 |
is by calling CGraphicsContext::SetCharJustification().
|
|
3332 |
|
|
3333 |
The font and other graphics parameters (e.g. pen colour, font style), are
|
|
3334 |
specified in aParam.iGc but a character format container (aFormat) is supplied
|
|
3335 |
so that a different font can be used. Note that any graphics drawn cannot
|
|
3336 |
exceed the bounds of aParam.iDrawRect, so changes are usually restricted to
|
|
3337 |
drawing shadows, outlines, etc. if custom highlighting is in use.
|
|
3338 |
|
|
3339 |
@param aParam Contains the drawing parameters. Drawing can only occur within
|
|
3340 |
aParam.iDrawRect.
|
|
3341 |
@param aLineInfo Contains the line metrics.
|
|
3342 |
@param aFormat Specifies the character formatting to apply to the text,
|
|
3343 |
including the type of text highlighting.
|
|
3344 |
@param aText The text string to be drawn.
|
|
3345 |
@param aTextOrigin The point at which the left end of the baseline of the text
|
|
3346 |
should be drawn.
|
|
3347 |
@param aExtraPixels The number of additional pixels to insert between the
|
|
3348 |
characters in the text string, in order to increase its length. */
|
|
3349 |
EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
|
|
3350 |
const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
|
|
3351 |
{
|
|
3352 |
TTmLineInfo info;
|
|
3353 |
info.iOuterRect = aLineInfo.iOuterRect;
|
|
3354 |
info.iInnerRect = aLineInfo.iInnerRect;
|
|
3355 |
info.iBaseline = aLineInfo.iBaseline;
|
|
3356 |
|
|
3357 |
MTmCustom c;
|
|
3358 |
c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
|
|
3359 |
aText,aTextOrigin,aExtraPixels);
|
|
3360 |
}
|
|
3361 |
|
|
3362 |
EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
|
|
3363 |
const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
|
|
3364 |
{
|
|
3365 |
TTmLineInfo info;
|
|
3366 |
info.iOuterRect = aLineInfo.iOuterRect;
|
|
3367 |
info.iInnerRect = aLineInfo.iInnerRect;
|
|
3368 |
info.iBaseline = aLineInfo.iBaseline;
|
|
3369 |
|
|
3370 |
MTmCustomExtension c;
|
|
3371 |
c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
|
|
3372 |
aText,aStart,aEnd,aTextOrigin,aExtraPixels);
|
|
3373 |
}
|
|
3374 |
|
|
3375 |
/** This function translates logical colours specified in FORM objects into
|
|
3376 |
real colours. The default implementation just returns the default colour that
|
|
3377 |
is passed in and ignores aColorIndex.
|
|
3378 |
|
|
3379 |
Overriding implementations may use aColorIndex in any desired way, either to
|
|
3380 |
replace or modify aDefaultColor. The values used in aColorIndex are taken from
|
|
3381 |
the top byte of a TLogicalRgb object and are thus in the range 0...255. The
|
|
3382 |
TLogicalRgb class defines two reserved values:
|
|
3383 |
TLogicalRgb::ESystemForegroundIndex = 254 and
|
|
3384 |
TLogicalRgb::ESystemBackgroundIndex = 255.
|
|
3385 |
*/
|
|
3386 |
EXPORT_C TRgb MFormCustomDraw::SystemColor(TUint /*aColorIndex*/,TRgb aDefaultColor) const
|
|
3387 |
{
|
|
3388 |
return aDefaultColor;
|
|
3389 |
}
|
|
3390 |
|
|
3391 |
void CTextLayout::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect,
|
|
3392 |
const TLogicalRgb& aBackground) const
|
|
3393 |
{
|
|
3394 |
TPoint top_left(aTopLeft);
|
|
3395 |
top_left.iY -= iBandTop;
|
|
3396 |
iText->DrawBackground(aGc,top_left,aClipRect,aBackground);
|
|
3397 |
}
|
|
3398 |
|
|
3399 |
/** Returns the line break class for a Unicode character.
|
|
3400 |
|
|
3401 |
For convenience, it also gets the range of consecutive characters (if any)
|
|
3402 |
according to the Unicode standard, including aCode, that share the same line
|
|
3403 |
break class.
|
|
3404 |
|
|
3405 |
The Unicode line break classes are enumerated in class MTmCustom.
|
|
3406 |
|
|
3407 |
Each character's line break class is obtained using LineBreakClass(). To find
|
|
3408 |
out whether a line break is allowed between two adjacent characters, call
|
|
3409 |
LineBreakPossible() with the line break classes of the two characters as
|
|
3410 |
arguments. For example, the line break class EClLineBreakClass (closing
|
|
3411 |
punctuation) applies to characters such as ")", "]" and ";". Line breaks are
|
|
3412 |
typically allowed after these characters, but not before, so a call to
|
|
3413 |
LineBreakPossible() with the arguments (EAlLineBreakClass, EClLineBreakClass)
|
|
3414 |
would return EFalse in the default implementation, but a call with
|
|
3415 |
(EClLineBreakClass, EAlLineBreakClass) would return ETrue.
|
|
3416 |
|
|
3417 |
@param aCode The Unicode character code of interest.
|
|
3418 |
@param aRangeStart On return, contains the Unicode character code at the start
|
|
3419 |
of the range including aCode that shares the same line break class as aCode.
|
|
3420 |
@param aRangeEnd On return, contains the Unicode character code at the end of
|
|
3421 |
the range including aCode that shares the same line break class as aCode.
|
|
3422 |
@return The line break class assigned to the character. Line break classes are
|
|
3423 |
enumerated in class MTmCustom. */
|
|
3424 |
EXPORT_C TUint MFormCustomWrap::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
|
|
3425 |
{
|
|
3426 |
// Create an instance of MTmCustom and then call the MTmCustom's functions for getting a Line Break class
|
|
3427 |
MTmCustom c;
|
|
3428 |
TUint temp;
|
|
3429 |
temp=c.LineBreakClass(aCode,aRangeStart,aRangeEnd);
|
|
3430 |
return temp;
|
|
3431 |
}
|
|
3432 |
|
|
3433 |
/** Tests whether a line break is possible between two characters.
|
|
3434 |
|
|
3435 |
If aHaveSpaces is true, the characters are not adjacent one or more space
|
|
3436 |
characters (with a line break class of ESpLineBreakClass) occur between them.
|
|
3437 |
|
|
3438 |
The aPrevClass and aNextClass arguments never have the value ESpLineBreakClass.
|
|
3439 |
Instead, this function is called with the classes of the characters on either
|
|
3440 |
side of the space or run of spaces, (and if so, aHaveSpaces is true). This is
|
|
3441 |
so that line breaks can be prohibited between certain characters with
|
|
3442 |
intervening spaces, for instance an alphabetic character (EAlLineBreakClass,
|
|
3443 |
such as 'a') and a closing bracket, with a space inbetween.
|
|
3444 |
|
|
3445 |
Additionally, the arguments to this function never have a value of
|
|
3446 |
ESaLineBreakClass. For such characters, GetLineBreakInContext() is called
|
|
3447 |
instead.
|
|
3448 |
|
|
3449 |
@param aPrevClass The line break class of the previous non-space character.
|
|
3450 |
@param aNextClass The line break class of the next non-space character.
|
|
3451 |
@param aHaveSpaces ETrue if there are one or more space characters (with a line
|
|
3452 |
break class of ESpLineBreakClass) between aPrevClass and aNextClass. EFalse if
|
|
3453 |
not.
|
|
3454 |
@return ETrue if a line break is possible between characters with the two line
|
|
3455 |
break classes, EFalse if not. */
|
|
3456 |
EXPORT_C TBool MFormCustomWrap::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
|
|
3457 |
{
|
|
3458 |
MTmCustom c;
|
|
3459 |
TBool temp;
|
|
3460 |
temp=c.LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
|
|
3461 |
return temp;
|
|
3462 |
}
|
|
3463 |
|
|
3464 |
/** Gets the position of the first or last possible line break position in a
|
|
3465 |
text string.
|
|
3466 |
|
|
3467 |
This function is called instead of LineBreakPossible() for runs of characters
|
|
3468 |
of class ESaLineBreakClass. It is used for South Asian languages like Thai, Lao
|
|
3469 |
and Khmer that have no spaces between words, so that line breaks must be
|
|
3470 |
calculated using dictionary lookup or a linguistic algorithm.
|
|
3471 |
|
|
3472 |
The default implementation of this function just returns false.
|
|
3473 |
|
|
3474 |
@param aText A string containing characters of class ESaLineBreakClass.
|
|
3475 |
@param aMinBreakPos A position within aText at which to begin searching for a
|
|
3476 |
possible line break position.
|
|
3477 |
@param aMaxBreakPos A position within aText at which to stop searching for a
|
|
3478 |
possible line break position.
|
|
3479 |
@param aForwards If ETrue, the function gets the first possible line break
|
|
3480 |
position (searches forwards from aMinBreakPos); if EFalse, gets the last one
|
|
3481 |
(searches backwards from aMaxBreakPos).
|
|
3482 |
@param aBreakPos On return, the position of the first or last possible line
|
|
3483 |
break within aText. This must be greater than zero and less than aText.Length()
|
|
3484 |
- 1, and must also be in the range aMinBreakPos to aMaxBreakPos.
|
|
3485 |
@return ETrue if a possible line break position is found, EFalse if not. */
|
|
3486 |
EXPORT_C TBool MFormCustomWrap::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
|
|
3487 |
TBool aForwards,TInt& aBreakPos) const
|
|
3488 |
{
|
|
3489 |
MTmCustom c;
|
|
3490 |
TBool temp;
|
|
3491 |
temp=c.GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
|
|
3492 |
return temp;
|
|
3493 |
}
|
|
3494 |
|
|
3495 |
/** Tests whether a character can overhang the right margin.
|
|
3496 |
|
|
3497 |
This function can be overridden to customise the line breaking behaviour for
|
|
3498 |
closing punctuation in Japanese. Any characters for which this function returns
|
|
3499 |
ETrue are allowed to overhang the right margin. The rest will be moved to the
|
|
3500 |
next line.
|
|
3501 |
|
|
3502 |
The default implementation of this function just returns false.
|
|
3503 |
|
|
3504 |
@param aChar The Unicode character code of interest.
|
|
3505 |
@return ETrue if the character specified can overhang the right margin, EFalse if
|
|
3506 |
not. */
|
|
3507 |
EXPORT_C TBool MFormCustomWrap::IsHangingCharacter(TUint aChar) const
|
|
3508 |
{
|
|
3509 |
MTmCustom c;
|
|
3510 |
TBool temp;
|
|
3511 |
temp=c.IsHangingCharacter(aChar);
|
|
3512 |
return temp;
|
|
3513 |
}
|
|
3514 |
|
|
3515 |
// Reserved functions are private until they are used
|
|
3516 |
/**
|
|
3517 |
@internalAll
|
|
3518 |
@released
|
|
3519 |
*/
|
|
3520 |
EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_1()
|
|
3521 |
{
|
|
3522 |
// reserved functions
|
|
3523 |
}
|
|
3524 |
// Reserved functions are private until they are used.
|
|
3525 |
/**
|
|
3526 |
@internalAll
|
|
3527 |
@released
|
|
3528 |
*/
|
|
3529 |
|
|
3530 |
EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_2()
|
|
3531 |
{
|
|
3532 |
// reserved functions
|
|
3533 |
}
|
|
3534 |
|
|
3535 |
#ifdef _DEBUG
|
|
3536 |
TBool CTextLayout::__DbgIsFormattingUpToDate() const
|
|
3537 |
{
|
|
3538 |
return iUnformattedStart == KMaxTInt;
|
|
3539 |
}
|
|
3540 |
#endif
|
|
3541 |
|
|
3542 |
// TLayDocTextSource stuff begins here.
|
|
3543 |
TLayDocTextSource::TLayDocTextSource():
|
|
3544 |
iLayDoc(NULL),
|
|
3545 |
iFlags(EWrap),
|
|
3546 |
iWidth(KMaxTInt),
|
|
3547 |
iEllipsis(0x2026),
|
|
3548 |
iLabelsWidth(0),
|
|
3549 |
iLabelsGutter(0),
|
|
3550 |
iFormatMode(CLayoutData::EFScreenMode),
|
|
3551 |
iImageDevice(NULL),
|
|
3552 |
iLabelsDevice(NULL),
|
|
3553 |
iFormatDevice(NULL),
|
|
3554 |
iFontHeightIncreaseFactor(EDefaultFontHeightIncreaseFactor),
|
|
3555 |
iMinimumLineDescent(EDefaultMinimumLineDescent),
|
|
3556 |
iNonPrintingCharVisibility(),
|
|
3557 |
iFormParam(NULL),
|
|
3558 |
iCustomDraw(NULL),
|
|
3559 |
iCustomWrap(NULL),
|
|
3560 |
iInterfaceProvider(NULL),
|
|
3561 |
iDrawOpaque(EFalse),
|
|
3562 |
iExcessHeightRequired(0),
|
|
3563 |
iInvisibleCharacterRemapper(NULL)
|
|
3564 |
{
|
|
3565 |
}
|
|
3566 |
|
|
3567 |
MGraphicsDeviceMap& TLayDocTextSource::FormatDevice() const
|
|
3568 |
{
|
|
3569 |
if (!iFormatDevice)
|
|
3570 |
CTextLayout::Panic(CTextLayout::EFormatDeviceNotSet);
|
|
3571 |
if (iLabelsDevice && (iFlags & EUseLabelsDevice))
|
|
3572 |
return *iLabelsDevice;
|
|
3573 |
else
|
|
3574 |
return *iFormatDevice;
|
|
3575 |
}
|
|
3576 |
|
|
3577 |
MGraphicsDeviceMap& TLayDocTextSource::InterpretDevice() const
|
|
3578 |
{
|
|
3579 |
if (!iImageDevice)
|
|
3580 |
CTextLayout::Panic(CTextLayout::EImageDeviceNotSet);
|
|
3581 |
if (iLabelsDevice && (iFlags & EUseLabelsDevice))
|
|
3582 |
return *iLabelsDevice;
|
|
3583 |
else
|
|
3584 |
return *iImageDevice;
|
|
3585 |
}
|
|
3586 |
|
|
3587 |
TInt TLayDocTextSource::DocumentLength() const
|
|
3588 |
{
|
|
3589 |
return iLayDoc->LdDocumentLength();
|
|
3590 |
}
|
|
3591 |
|
|
3592 |
void TLayDocTextSource::GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const
|
|
3593 |
{
|
|
3594 |
TCharFormat f;
|
|
3595 |
iLayDoc->GetChars(aText,f,aPos);
|
|
3596 |
aFormat = f;
|
|
3597 |
}
|
|
3598 |
|
|
3599 |
void TLayDocTextSource::GetParagraphFormatL(TInt aPos,RTmParFormat& aFormat) const
|
|
3600 |
{
|
|
3601 |
CParaFormat f;
|
|
3602 |
iLayDoc->GetParagraphFormatL(&f,aPos);
|
|
3603 |
|
|
3604 |
// Labels should not have a forced line height or borders so remove these (this is necessary for Agenda).
|
|
3605 |
if (iFlags & EUseLabelsDevice)
|
|
3606 |
{
|
|
3607 |
f.iLineSpacingInTwips = 0;
|
|
3608 |
f.iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips;
|
|
3609 |
f.RemoveAllBorders();
|
|
3610 |
}
|
|
3611 |
|
|
3612 |
aFormat.CopyL(f);
|
|
3613 |
f.Reset();
|
|
3614 |
}
|
|
3615 |
|
|
3616 |
TRgb TLayDocTextSource::SystemColor(TUint aColorIndex,TRgb aDefaultColor) const
|
|
3617 |
{
|
|
3618 |
if (iCustomDraw)
|
|
3619 |
return iCustomDraw->SystemColor(aColorIndex,aDefaultColor);
|
|
3620 |
else if (iFormParam)
|
|
3621 |
return iFormParam->SystemColor(aColorIndex,aDefaultColor);
|
|
3622 |
else
|
|
3623 |
return aDefaultColor;
|
|
3624 |
}
|
|
3625 |
|
|
3626 |
CPicture* TLayDocTextSource::PictureL(TInt aPos) const
|
|
3627 |
{
|
|
3628 |
return iLayDoc->PictureHandleL(aPos,MLayDoc::EForceLoadTrue);
|
|
3629 |
}
|
|
3630 |
|
|
3631 |
TInt TLayDocTextSource::GetPictureSizeInTwipsL(TInt aPos,TSize& aSize) const
|
|
3632 |
{
|
|
3633 |
return iLayDoc->GetPictureSizeInTwips(aSize,aPos);
|
|
3634 |
}
|
|
3635 |
|
|
3636 |
TInt TLayDocTextSource::ParagraphStart(TInt aPos) const
|
|
3637 |
{
|
|
3638 |
iLayDoc->LdToParagraphStart(aPos);
|
|
3639 |
return aPos;
|
|
3640 |
}
|
|
3641 |
|
|
3642 |
TBool TLayDocTextSource::LabelModeSelect(TLabelType aType, TInt aPos)
|
|
3643 |
{
|
|
3644 |
if (!(iFlags & EUseLabelsDevice) && aType == EParLabel)
|
|
3645 |
{
|
|
3646 |
// Labels are not allowed on zero-length documents;
|
|
3647 |
// this is required for Agenda (see ER5U defect EDNGASR-482LSF).
|
|
3648 |
if (iLayDoc->LdDocumentLength() == 0)
|
|
3649 |
return FALSE;
|
|
3650 |
|
|
3651 |
if (iLayDoc->SelectParagraphLabel(aPos))
|
|
3652 |
{
|
|
3653 |
iFlags |= EUseLabelsDevice;
|
|
3654 |
return TRUE;
|
|
3655 |
}
|
|
3656 |
}
|
|
3657 |
|
|
3658 |
return FALSE;
|
|
3659 |
}
|
|
3660 |
|
|
3661 |
void TLayDocTextSource::LabelMetrics(TLabelType aType, TSize& aLabelSize, TInt& aMarginSize) const
|
|
3662 |
{
|
|
3663 |
if (aType == EParLabel)
|
|
3664 |
{
|
|
3665 |
aLabelSize.iWidth = iLabelsWidth;
|
|
3666 |
aLabelSize.iHeight = KMaxTInt;
|
|
3667 |
aMarginSize = iLabelsWidth + iLabelsGutter;
|
|
3668 |
}
|
|
3669 |
else
|
|
3670 |
{
|
|
3671 |
aLabelSize.iWidth = 0;
|
|
3672 |
aLabelSize.iHeight = 0;
|
|
3673 |
aMarginSize = 0;
|
|
3674 |
}
|
|
3675 |
}
|
|
3676 |
|
|
3677 |
void TLayDocTextSource::LabelModeCancel()
|
|
3678 |
{
|
|
3679 |
iLayDoc->CancelSelectLabel();
|
|
3680 |
iFlags &= ~EUseLabelsDevice;
|
|
3681 |
}
|
|
3682 |
|
|
3683 |
/**
|
|
3684 |
This method is responsible for discovering interface extension objects
|
|
3685 |
requried by Form for the specified interface Uid.
|
|
3686 |
@param aInterfaceId
|
|
3687 |
Identifier for the optional interface requried.
|
|
3688 |
@return
|
|
3689 |
Pointer to object supporting the requested interface,
|
|
3690 |
or 0 if not supported.
|
|
3691 |
*/
|
|
3692 |
TAny* TLayDocTextSource::GetExtendedInterface(const TUid& aInterfaceId)
|
|
3693 |
{
|
|
3694 |
TAny* interfacePtr = 0;
|
|
3695 |
|
|
3696 |
// First check to see if their is an external interface provider
|
|
3697 |
// registered and ask it for the interface.
|
|
3698 |
if (iInterfaceProvider)
|
|
3699 |
{
|
|
3700 |
interfacePtr = iInterfaceProvider->GetExtendedInterface( aInterfaceId );
|
|
3701 |
}
|
|
3702 |
|
|
3703 |
// If interface still not supplied check self and parent to provide it
|
|
3704 |
if (!interfacePtr)
|
|
3705 |
{
|
|
3706 |
if (aInterfaceId == KFormLabelApiExtensionUid)
|
|
3707 |
{
|
|
3708 |
return static_cast<MFormLabelApi*>(this);
|
|
3709 |
}
|
|
3710 |
else if(aInterfaceId == KTmTextDrawExtId)
|
|
3711 |
{
|
|
3712 |
return static_cast <MTmTextDrawExt*> (this);
|
|
3713 |
}
|
|
3714 |
else if(aInterfaceId == KTmCustomExtensionUid)
|
|
3715 |
{
|
|
3716 |
return static_cast <MTmCustomExtension*> (this);
|
|
3717 |
}
|
|
3718 |
else
|
|
3719 |
{
|
|
3720 |
// In this instance, calling the parent class will always return NULL
|
|
3721 |
// but the pattern should be followed by all implementors for safety
|
|
3722 |
return MTmSource::GetExtendedInterface(aInterfaceId);
|
|
3723 |
}
|
|
3724 |
}
|
|
3725 |
|
|
3726 |
// Return the interface object or 0 if not supported.
|
|
3727 |
return interfacePtr;
|
|
3728 |
}
|
|
3729 |
|
|
3730 |
void TLayDocTextSource::SetLineHeight(const TLineHeightParam& aParam,TInt& aAscent,TInt& aDescent) const
|
|
3731 |
{
|
|
3732 |
// Increase the ascent by the font height increase percentage.
|
|
3733 |
TLineHeightParam p = aParam;
|
|
3734 |
p.iFontMaxAscent += ((p.iFontMaxAscent + p.iFontMaxDescent) * iFontHeightIncreaseFactor) / 100;
|
|
3735 |
|
|
3736 |
// Call the standard SetLineHeight.
|
|
3737 |
MTmSource::SetLineHeight(p,aAscent,aDescent);
|
|
3738 |
|
|
3739 |
// iExcessHeightRequired is used when height of the highest glyph can be
|
|
3740 |
// greater than CFont::AscentInPixels() and in iExactLineSpacing mode
|
|
3741 |
// This value is set via CTextView::SetExcessHeightRequired()
|
|
3742 |
if ( aParam.iExactLineHeight )
|
|
3743 |
{
|
|
3744 |
aAscent += iExcessHeightRequired;
|
|
3745 |
aDescent -= iExcessHeightRequired;
|
|
3746 |
}
|
|
3747 |
|
|
3748 |
// Enforce the minimum descent; the following logic is borrowed from CLineLayout::WrapLineL in old FORM.
|
|
3749 |
if (aAscent + aDescent <= iMinimumLineDescent && aDescent == 0)
|
|
3750 |
{
|
|
3751 |
aDescent = 1;
|
|
3752 |
aAscent--;
|
|
3753 |
}
|
|
3754 |
else if (aDescent < iMinimumLineDescent)
|
|
3755 |
aDescent = iMinimumLineDescent;
|
|
3756 |
|
|
3757 |
/*
|
|
3758 |
Ensure the line is at least 1 pixel high and ascent and descent are non-negative so that assertion
|
|
3759 |
TCursorPosition::GetLineRectL that cursor pos is contained in line rect doesn't fire.
|
|
3760 |
*/
|
|
3761 |
if (aAscent < 0)
|
|
3762 |
aAscent = 0;
|
|
3763 |
if (aDescent < 0)
|
|
3764 |
aDescent = 0;
|
|
3765 |
if (aAscent + aDescent == 0)
|
|
3766 |
aDescent = 1;
|
|
3767 |
}
|
|
3768 |
|
|
3769 |
TBool TLayDocTextSource::CanMap() const
|
|
3770 |
{
|
|
3771 |
return iFormatMode == CLayoutData::EFScreenMode || iFormatMode == CLayoutData::EFWysiwygMode;
|
|
3772 |
}
|
|
3773 |
|
|
3774 |
TBool TLayDocTextSource::PageBreakInRange(TInt aStartPos,TInt aEndPos) const
|
|
3775 |
{
|
|
3776 |
if (CanMap() && iNonPrintingCharVisibility.PageBreaksVisible())
|
|
3777 |
return iLayDoc->EnquirePageBreak(aStartPos,aEndPos - aStartPos);
|
|
3778 |
else
|
|
3779 |
return FALSE;
|
|
3780 |
}
|
|
3781 |
|
|
3782 |
void TLayDocTextSource::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
|
|
3783 |
const TLogicalRgb& aBackground,TRect& aDrawn) const
|
|
3784 |
{
|
|
3785 |
ResetOpaque(aGc);
|
|
3786 |
if (iCustomDraw)
|
|
3787 |
{
|
|
3788 |
MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
|
|
3789 |
TLogicalRgb background = aBackground;
|
|
3790 |
FormUtil::LogicalToActualColor(iFormParam,background);
|
|
3791 |
iCustomDraw->DrawBackground(param,background,aDrawn);
|
|
3792 |
}
|
|
3793 |
else
|
|
3794 |
MTmSource::DrawBackground(aGc,aTopLeft,aRect,aBackground,aDrawn);
|
|
3795 |
}
|
|
3796 |
|
|
3797 |
void TLayDocTextSource::DrawLineGraphics(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
|
|
3798 |
const TTmLineInfo& aLineInfo) const
|
|
3799 |
{
|
|
3800 |
SetOpaque(aGc);
|
|
3801 |
if (iCustomDraw)
|
|
3802 |
{
|
|
3803 |
MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
|
|
3804 |
MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
|
|
3805 |
iCustomDraw->DrawLineGraphics(param,lineinfo);
|
|
3806 |
}
|
|
3807 |
else
|
|
3808 |
MTmSource::DrawLineGraphics(aGc,aTopLeft,aRect,aLineInfo);
|
|
3809 |
ResetOpaque(aGc);
|
|
3810 |
}
|
|
3811 |
|
|
3812 |
void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
|
|
3813 |
const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
|
|
3814 |
const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
|
|
3815 |
{
|
|
3816 |
SetOpaque(aGc);
|
|
3817 |
if (iCustomDraw)
|
|
3818 |
{
|
|
3819 |
MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
|
|
3820 |
MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
|
|
3821 |
TCharFormat f;
|
|
3822 |
aFormat.GetTCharFormat(f);
|
|
3823 |
iCustomDraw->DrawText(param,lineinfo,f,aText,aTextOrigin,aExtraPixels);
|
|
3824 |
}
|
|
3825 |
else
|
|
3826 |
MTmSource::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aTextOrigin,aExtraPixels);
|
|
3827 |
ResetOpaque(aGc);
|
|
3828 |
}
|
|
3829 |
|
|
3830 |
void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
|
|
3831 |
const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
|
|
3832 |
const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
|
|
3833 |
{
|
|
3834 |
SetOpaque(aGc);
|
|
3835 |
if (iCustomDraw)
|
|
3836 |
{
|
|
3837 |
MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
|
|
3838 |
MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
|
|
3839 |
TCharFormat f;
|
|
3840 |
aFormat.GetTCharFormat(f);
|
|
3841 |
iCustomDraw->DrawText(param,lineinfo,f,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
|
|
3842 |
}
|
|
3843 |
else
|
|
3844 |
MTmCustomExtension::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
|
|
3845 |
ResetOpaque(aGc);
|
|
3846 |
}
|
|
3847 |
|
|
3848 |
TBool TLayDocTextSource::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
|
|
3849 |
|
|
3850 |
{
|
|
3851 |
TBool temp;
|
|
3852 |
if (iCustomWrap)
|
|
3853 |
temp=iCustomWrap->LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
|
|
3854 |
else
|
|
3855 |
temp=MTmSource::LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
|
|
3856 |
return temp;
|
|
3857 |
}
|
|
3858 |
|
|
3859 |
TUint TLayDocTextSource::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
|
|
3860 |
{
|
|
3861 |
TUint temp;
|
|
3862 |
if (iCustomWrap)
|
|
3863 |
temp=iCustomWrap->LineBreakClass(aCode,aRangeStart,aRangeEnd);
|
|
3864 |
else
|
|
3865 |
temp=MTmSource::LineBreakClass(aCode,aRangeStart,aRangeEnd);
|
|
3866 |
return temp;
|
|
3867 |
}
|
|
3868 |
|
|
3869 |
|
|
3870 |
TBool TLayDocTextSource::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
|
|
3871 |
TBool aForwards,TInt& aBreakPos) const
|
|
3872 |
{
|
|
3873 |
TBool temp;
|
|
3874 |
if (iCustomWrap)
|
|
3875 |
temp=iCustomWrap->GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
|
|
3876 |
else
|
|
3877 |
temp=MTmSource::GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
|
|
3878 |
return temp;
|
|
3879 |
}
|
|
3880 |
|
|
3881 |
TBool TLayDocTextSource::IsHangingCharacter(TUint aChar) const
|
|
3882 |
{
|
|
3883 |
TBool temp;
|
|
3884 |
if (iCustomWrap)
|
|
3885 |
temp=iCustomWrap->IsHangingCharacter(aChar);
|
|
3886 |
else
|
|
3887 |
temp=MTmSource::IsHangingCharacter(aChar);
|
|
3888 |
return temp;
|
|
3889 |
}
|
|
3890 |
|
|
3891 |
|
|
3892 |
TUint TLayDocTextSource::Map(TUint aChar) const
|
|
3893 |
{
|
|
3894 |
// Check if custom formatting has been installed
|
|
3895 |
if (iInvisibleCharacterRemapper)
|
|
3896 |
{ // Then use the supplied custom invisible character remapping
|
|
3897 |
return iInvisibleCharacterRemapper->Remap(aChar, iNonPrintingCharVisibility, *this);
|
|
3898 |
}
|
|
3899 |
else // Use the default
|
|
3900 |
return MFormCustomInvisibleCharacterRemapper::DefaultMapping(aChar, iNonPrintingCharVisibility, *this);
|
|
3901 |
}
|
|
3902 |
|
|
3903 |
void TLayDocTextSource::DrawPicture(CGraphicsContext& aGc,
|
|
3904 |
const TPoint& aTextLayoutTopLeft, const TRect& aRect,
|
|
3905 |
MGraphicsDeviceMap& aDevice, const CPicture& aPicture) const
|
|
3906 |
{
|
|
3907 |
SetOpaque(aGc);
|
|
3908 |
MTmSource::DrawPicture(aGc, aTextLayoutTopLeft, aRect, aDevice, aPicture);
|
|
3909 |
ResetOpaque(aGc);
|
|
3910 |
}
|
|
3911 |
|
|
3912 |
//MTmTextDrawExt implementations
|
|
3913 |
|
|
3914 |
/**
|
|
3915 |
Draws a line. Implements MTmTextDrawExt::DrawLine().
|
|
3916 |
If the opaque drawing mode is active, then the line color will stay unchanged (it will not be
|
|
3917 |
alpha-blended in a case of a transparent window).
|
|
3918 |
@param aGc A reference to a graphics context. If the drawing mode is opaque, then this is a
|
|
3919 |
CWindowGc reference.
|
|
3920 |
@param aPt1 Line start point
|
|
3921 |
@param aPt2 Line end point
|
|
3922 |
*/
|
|
3923 |
void TLayDocTextSource::DrawLine(CGraphicsContext& aGc, const TPoint& aPt1, const TPoint& aPt2) const
|
|
3924 |
{
|
|
3925 |
SetOpaque(aGc);
|
|
3926 |
aGc.DrawLine(aPt1, aPt2);
|
|
3927 |
ResetOpaque(aGc);
|
|
3928 |
}
|
|
3929 |
|
|
3930 |
/**
|
|
3931 |
Draws a text. Implements MTmTextDrawExt::DrawText().
|
|
3932 |
If the opaque drawing mode is active, then the text color will stay unchanged (it will not be
|
|
3933 |
alpha-blended in a case of a transparent window).
|
|
3934 |
@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
|
|
3935 |
CWindowGc reference.
|
|
3936 |
@param aPt1 Text start point
|
|
3937 |
*/
|
|
3938 |
void TLayDocTextSource::DrawText(CGraphicsContext& aGc, const TDesC& aText, const TPoint& aPt) const
|
|
3939 |
{
|
|
3940 |
SetOpaque(aGc);
|
|
3941 |
aGc.DrawText(aText, aPt);
|
|
3942 |
ResetOpaque(aGc);
|
|
3943 |
}
|
|
3944 |
|
|
3945 |
/**
|
|
3946 |
Draws a rectangle. Implements MTmTextDrawExt::DrawRect().
|
|
3947 |
If the opaque drawing mode is active, then the rectabgle color will stay unchanged (it will not be
|
|
3948 |
alpha-blended in a case of a transparent window).
|
|
3949 |
@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
|
|
3950 |
CWindowGc reference.
|
|
3951 |
@param aRc Rectangle coordinates
|
|
3952 |
*/
|
|
3953 |
void TLayDocTextSource::DrawRect(CGraphicsContext& aGc, const TRect& aRc) const
|
|
3954 |
{
|
|
3955 |
SetOpaque(aGc);
|
|
3956 |
aGc.DrawRect(aRc);
|
|
3957 |
ResetOpaque(aGc);
|
|
3958 |
}
|
|
3959 |
|
|
3960 |
/**
|
|
3961 |
Sets opaque drawing mode.
|
|
3962 |
@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
|
|
3963 |
CWindowGc reference.
|
|
3964 |
*/
|
|
3965 |
void TLayDocTextSource::SetOpaque(CGraphicsContext& aGc) const
|
|
3966 |
{
|
|
3967 |
if(iDrawOpaque)
|
|
3968 |
{
|
|
3969 |
static_cast <CWindowGc&> (aGc).SetOpaque(ETrue);
|
|
3970 |
}
|
|
3971 |
}
|
|
3972 |
|
|
3973 |
/**
|
|
3974 |
Resets opaque drawing mode.
|
|
3975 |
@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
|
|
3976 |
CWindowGc reference.
|
|
3977 |
*/
|
|
3978 |
void TLayDocTextSource::ResetOpaque(CGraphicsContext& aGc) const
|
|
3979 |
{
|
|
3980 |
if(iDrawOpaque)
|
|
3981 |
{
|
|
3982 |
static_cast <CWindowGc&> (aGc).SetOpaque(EFalse);
|
|
3983 |
}
|
|
3984 |
}
|
|
3985 |
|
|
3986 |
// Private CTextLayout functions start here.
|
|
3987 |
|
|
3988 |
void CTextLayout::Panic(TPanicNumber aNumber)
|
|
3989 |
{
|
|
3990 |
_LIT(KPanicNumber,"CTextLayout using TAGMA");
|
|
3991 |
User::Panic(KPanicNumber,aNumber);
|
|
3992 |
}
|
|
3993 |
|
|
3994 |
void CTextLayout::GetParagraphRect(const TTmDocPos& aDocPos,TRect& aRect) const
|
|
3995 |
{
|
|
3996 |
aRect.SetRect(0,0,0,0);
|
|
3997 |
TTmLineInfo info, info2;
|
|
3998 |
if (!iText->DocPosToLine(aDocPos,info))
|
|
3999 |
return;
|
|
4000 |
aRect = info.iOuterRect;
|
|
4001 |
if (!(info.iFlags & TTmLineInfo::EParStart))
|
|
4002 |
{
|
|
4003 |
iText->ParNumberToLine(info.iParNumber,0,info2);
|
|
4004 |
aRect.iTl = info2.iOuterRect.iTl;
|
|
4005 |
}
|
|
4006 |
if (!(info.iFlags & TTmLineInfo::EParEnd))
|
|
4007 |
{
|
|
4008 |
iText->ParNumberToLine(info.iParNumber,KMaxTInt,info2);
|
|
4009 |
aRect.iBr = info2.iOuterRect.iBr;
|
|
4010 |
}
|
|
4011 |
aRect.Move(0,-iBandTop);
|
|
4012 |
}
|
|
4013 |
|
|
4014 |
/**
|
|
4015 |
Scroll aDy pixels (positive = text moves down); return number of pixels
|
|
4016 |
actually scrolled. Create a new formatted band if necessary.
|
|
4017 |
*/
|
|
4018 |
TInt CTextLayout::ScrollL(TInt aDy,TAllowDisallow aScrollBlankSpace,
|
|
4019 |
TBool aTopNoLimitBorder/*=EFalse*/,
|
|
4020 |
TBool aBottomNoLimitBorder/*=EFalse*/)
|
|
4021 |
{
|
|
4022 |
if ( EFDisallowScrollingBlankSpace == aScrollBlankSpace )
|
|
4023 |
{
|
|
4024 |
aTopNoLimitBorder = EFalse;
|
|
4025 |
aBottomNoLimitBorder = EFalse;
|
|
4026 |
}
|
|
4027 |
int old_bandtop = iBandTop;
|
|
4028 |
int desired_bandtop = iBandTop - aDy;
|
|
4029 |
int pixels_scrolled = 0;
|
|
4030 |
int height_increase = 0;
|
|
4031 |
int paragraphs_increase = 0;
|
|
4032 |
TTmFormatParamBase param;
|
|
4033 |
InitFormatParam(param);
|
|
4034 |
// Refuse to scroll if the width is illegal. This prevents
|
|
4035 |
// time being taken in certain situations where it does
|
|
4036 |
// not matter. Once the formatting is capable of
|
|
4037 |
// adding smaller chunks of text at a time, this early-out
|
|
4038 |
// should become unnecessary.
|
|
4039 |
if ((param.iWrapWidth < 1 || param.iMaxHeight < 1)
|
|
4040 |
&& param.iFlags & TTmFormatParamBase::EWrap)
|
|
4041 |
return 0;
|
|
4042 |
param.iMaxHeight = KMaxTInt;
|
|
4043 |
int visible_height = VisibleHeightInPixels();
|
|
4044 |
if (aDy > 0) // text moves down; iBandTop decreases
|
|
4045 |
{
|
|
4046 |
if (aTopNoLimitBorder)
|
|
4047 |
iBandTop = desired_bandtop;
|
|
4048 |
else
|
|
4049 |
iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border
|
|
4050 |
|
|
4051 |
pixels_scrolled = old_bandtop - iBandTop;
|
|
4052 |
while (pixels_scrolled < aDy)
|
|
4053 |
{
|
|
4054 |
if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
|
|
4055 |
break;
|
|
4056 |
pixels_scrolled += height_increase;
|
|
4057 |
}
|
|
4058 |
if (pixels_scrolled > aDy)
|
|
4059 |
{
|
|
4060 |
iBandTop = pixels_scrolled - aDy;
|
|
4061 |
pixels_scrolled = aDy;
|
|
4062 |
}
|
|
4063 |
}
|
|
4064 |
else if (aDy < 0) // text moves up; iBandTop increases
|
|
4065 |
{
|
|
4066 |
if (aBottomNoLimitBorder)
|
|
4067 |
iBandTop = desired_bandtop;
|
|
4068 |
else
|
|
4069 |
iBandTop = Min(iText->LayoutHeight(),desired_bandtop);//Disallow text scrolled beyond bottom border
|
|
4070 |
|
|
4071 |
pixels_scrolled = old_bandtop - iBandTop;
|
|
4072 |
while (pixels_scrolled > aDy)
|
|
4073 |
{
|
|
4074 |
if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
|
|
4075 |
break;
|
|
4076 |
pixels_scrolled -= height_increase;
|
|
4077 |
if (pixels_scrolled < aDy)
|
|
4078 |
{
|
|
4079 |
height_increase -= aDy - pixels_scrolled;
|
|
4080 |
pixels_scrolled = aDy;
|
|
4081 |
}
|
|
4082 |
iBandTop += height_increase;
|
|
4083 |
}
|
|
4084 |
|
|
4085 |
// Fill in missing part of visible height.
|
|
4086 |
while (iText->LayoutHeight() - iBandTop < visible_height)
|
|
4087 |
{
|
|
4088 |
if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
|
|
4089 |
break;
|
|
4090 |
}
|
|
4091 |
}
|
|
4092 |
|
|
4093 |
// Scroll blank space off the display if desired.
|
|
4094 |
if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height)
|
|
4095 |
{
|
|
4096 |
int new_bandtop = iText->LayoutHeight() - visible_height;
|
|
4097 |
if (new_bandtop < 0)
|
|
4098 |
new_bandtop = 0;
|
|
4099 |
pixels_scrolled += iBandTop - new_bandtop;
|
|
4100 |
iBandTop = new_bandtop;
|
|
4101 |
}
|
|
4102 |
|
|
4103 |
PruneFormatL(aDy < 0);
|
|
4104 |
return pixels_scrolled + SetBandTop();
|
|
4105 |
}
|
|
4106 |
|
|
4107 |
TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos)
|
|
4108 |
{
|
|
4109 |
__ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(),
|
|
4110 |
Panic(EInvalidDocPos));
|
|
4111 |
TTmLineInfo info;
|
|
4112 |
ExtendFormattingToCoverPosL(aDocPos.iPos);
|
|
4113 |
if (!iText->DocPosToLine(aDocPos,info))
|
|
4114 |
{
|
|
4115 |
__ASSERT_DEBUG(iText->Source()->DocumentLength() == 0,
|
|
4116 |
Panic(ECharacterNotFormatted));
|
|
4117 |
return ScrollL(iBandTop, EFDisallowScrollingBlankSpace);
|
|
4118 |
}
|
|
4119 |
TRect line_rect = info.iOuterRect;
|
|
4120 |
line_rect.Move(0,-iBandTop);
|
|
4121 |
int visible_height = VisibleHeightInPixels();
|
|
4122 |
// if the line is taller than the screen, we must not scroll the
|
|
4123 |
// baseline off the screen.
|
|
4124 |
if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
|
|
4125 |
return ScrollL(iBandTop + visible_height - info.iBaseline,
|
|
4126 |
EFDisallowScrollingBlankSpace);
|
|
4127 |
if (line_rect.iTl.iY < 0)
|
|
4128 |
return ScrollL(-line_rect.iTl.iY, EFDisallowScrollingBlankSpace);
|
|
4129 |
if (line_rect.iBr.iY > visible_height)
|
|
4130 |
{
|
|
4131 |
int available = line_rect.iTl.iY;
|
|
4132 |
int desired = line_rect.iBr.iY - visible_height;
|
|
4133 |
if (available > 0)
|
|
4134 |
return ScrollL(-Min(desired,available), EFDisallowScrollingBlankSpace);
|
|
4135 |
}
|
|
4136 |
return 0;
|
|
4137 |
}
|
|
4138 |
|
|
4139 |
EXPORT_C TInt CTextLayout::GetLineNumber(TInt aDocPos)
|
|
4140 |
{
|
|
4141 |
TTmLineInfo info;
|
|
4142 |
TTmDocPos pos(aDocPos,TRUE);
|
|
4143 |
if (iText->DocPosToLine(pos,info))
|
|
4144 |
return info.iLineNumber;
|
|
4145 |
return 0;
|
|
4146 |
};
|
|
4147 |
|
|
4148 |
|
|
4149 |
/*
|
|
4150 |
Prune the formatted band, if not formatting all the text, to the required size. If aFromStart is ETrue
|
|
4151 |
prune from the start, otherwise prune from the end.
|
|
4152 |
*/
|
|
4153 |
void CTextLayout::PruneFormatL(TBool aFromStart)
|
|
4154 |
{
|
|
4155 |
if (IsFormattingBand())
|
|
4156 |
{
|
|
4157 |
int pixels_to_prune = 0;
|
|
4158 |
if (aFromStart)
|
|
4159 |
pixels_to_prune = iBandTop;
|
|
4160 |
else
|
|
4161 |
pixels_to_prune = iText->LayoutHeight() - iBandTop - BandHeightInPixels();
|
|
4162 |
if (pixels_to_prune <= 0)
|
|
4163 |
return;
|
|
4164 |
TTmFormatParamBase param;
|
|
4165 |
InitFormatParam(param);
|
|
4166 |
int height_decrease = 0;
|
|
4167 |
if(aFromStart)
|
|
4168 |
{
|
|
4169 |
while (pixels_to_prune > 0 && iText->DeletePar(param,aFromStart,pixels_to_prune,height_decrease))
|
|
4170 |
{
|
|
4171 |
pixels_to_prune -= height_decrease;
|
|
4172 |
if (aFromStart)
|
|
4173 |
iBandTop -= height_decrease;
|
|
4174 |
}
|
|
4175 |
}
|
|
4176 |
else
|
|
4177 |
{
|
|
4178 |
if (pixels_to_prune > (iBandHeight/2))
|
|
4179 |
{
|
|
4180 |
iText->DeleteFormattingFromEndL(param,pixels_to_prune,height_decrease);
|
|
4181 |
}
|
|
4182 |
}
|
|
4183 |
}
|
|
4184 |
}
|
|
4185 |
|
|
4186 |
/** Sets the hotspot.
|
|
4187 |
|
|
4188 |
@param aHotSpot Which part of the line (top, baseline or bottom) should appear
|
|
4189 |
at a vertical pixel position. */
|
|
4190 |
EXPORT_C void TViewYPosQualifier::SetHotSpot(TPartOfLine aHotSpot)
|
|
4191 |
{
|
|
4192 |
iHotSpot = aHotSpot;
|
|
4193 |
}
|
|
4194 |
|
|
4195 |
/** Sets whether blank space should be allowed at the bottom of the view. This
|
|
4196 |
applies if the document is more than one page long and the last line is
|
|
4197 |
visible.
|
|
4198 |
|
|
4199 |
@param aFillScreen ETrue (the default) tries to fill the screen, by ensuring
|
|
4200 |
that there is as little blank space as possible at the bottom of the view.
|
|
4201 |
EFalse allows blank space at the bottom. */
|
|
4202 |
EXPORT_C void TViewYPosQualifier::SetFillScreen(TBool aFillScreen)
|
|
4203 |
{
|
|
4204 |
iFillScreen = aFillScreen;
|
|
4205 |
}
|
|
4206 |
|
|
4207 |
/** Forces the top line in the view to become fully visible if it is partially
|
|
4208 |
above the top of the view rectangle.
|
|
4209 |
|
|
4210 |
@param aMakeLineFullyVisible EFViewForceLineFullyVisible (the default) forces
|
|
4211 |
the top line to be fully visible EFViewDontForceLineFullyVisible does not. */
|
|
4212 |
EXPORT_C void TViewYPosQualifier::SetMakeLineFullyVisible(TFullyVisible aMakeLineFullyVisible)
|
|
4213 |
{
|
|
4214 |
iFullyVisible = aMakeLineFullyVisible;
|
|
4215 |
}
|
|
4216 |
|
|
4217 |
void CTextLayout::InitFormatParam(TTmFormatParamBase& aParam)
|
|
4218 |
{
|
|
4219 |
aParam.iMaxHeight = BandHeightInPixels();
|
|
4220 |
iSource->iExcessHeightRequired = iExcessHeightRequired;
|
|
4221 |
|
|
4222 |
aParam.iFlags = TTmFormatParamBase::EAtLeastMaxHeight;
|
|
4223 |
aParam.iWrapWidth = iSource->iWidth;
|
|
4224 |
if (iSource->iFlags & TLayDocTextSource::EWrap)
|
|
4225 |
aParam.iFlags |= TTmFormatParamBase::EWrap;
|
|
4226 |
if (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis)
|
|
4227 |
{
|
|
4228 |
aParam.iFlags |= TTmFormatParamBase::ETruncateWithEllipsis;
|
|
4229 |
aParam.iEllipsis = iSource->iEllipsis;
|
|
4230 |
}
|
|
4231 |
}
|
|
4232 |
|
|
4233 |
TInt CTextLayout::VisibleHeightInPixels() const
|
|
4234 |
{
|
|
4235 |
if (iSource->iFormatMode == CLayoutData::EFScreenMode || iSource->iFormatMode == CLayoutData::EFWysiwygMode)
|
|
4236 |
return iVisibleHeight;
|
|
4237 |
else
|
|
4238 |
return iSource->InterpretDevice().VerticalTwipsToPixels(iVisibleHeight);
|
|
4239 |
}
|
|
4240 |
|
|
4241 |
TInt CTextLayout::BandHeightInPixels() const
|
|
4242 |
{
|
|
4243 |
if (iBandHeight == CLayoutData::EFHeightForFormattingAllText)
|
|
4244 |
return CLayoutData::EFHeightForFormattingAllText;
|
|
4245 |
else
|
|
4246 |
return VisibleHeightInPixels();
|
|
4247 |
}
|
|
4248 |
|
|
4249 |
/**
|
|
4250 |
Sets offsets for the edges of the selection highlight.
|
|
4251 |
@param aLeftExtension
|
|
4252 |
Number of pixels to move the left edge of the highlight to the left.
|
|
4253 |
@param aRightExtension
|
|
4254 |
Number of pixels to move the right edge of the highlight to the right.
|
|
4255 |
@param aTopExtension
|
|
4256 |
Number of pixels to move the top edge of the highlight to up.
|
|
4257 |
@param aBottomExtension
|
|
4258 |
Number of pixels to move the bottom edge of the highlight down.
|
|
4259 |
*/
|
|
4260 |
EXPORT_C void CTextLayout::SetHighlightExtensions(TInt aLeftExtension,
|
|
4261 |
TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension)
|
|
4262 |
{
|
|
4263 |
iHighlightExtensions->SetLeftExtension(aLeftExtension);
|
|
4264 |
iHighlightExtensions->SetRightExtension(aRightExtension);
|
|
4265 |
iHighlightExtensions->SetTopExtension(aTopExtension);
|
|
4266 |
iHighlightExtensions->SetBottomExtension(aBottomExtension);
|
|
4267 |
}
|
|
4268 |
|
|
4269 |
/**
|
|
4270 |
Set the delta required to position the baseline so there is enough
|
|
4271 |
space for the highset glyph in pixels. This is the height of the highest glyph -
|
|
4272 |
CFont::AscentInPixels(). Only used when using TLineSpacingControl::EAttLineSpacingControl.
|
|
4273 |
By default zero.
|
|
4274 |
@param aExcessHeightRequired
|
|
4275 |
Extra height above CFont::AscentInPixels() required for the highest glyph in pixels.
|
|
4276 |
*/
|
|
4277 |
void CTextLayout::SetExcessHeightRequired(TInt aExcessHeightRequired)
|
|
4278 |
{
|
|
4279 |
iExcessHeightRequired = aExcessHeightRequired;
|
|
4280 |
}
|
|
4281 |
|
|
4282 |
/**
|
|
4283 |
For any rectangle, aRect, which may be extended, calculate
|
|
4284 |
the "remainder" rectanges when the view rectangle is intersected with the
|
|
4285 |
extended rect and then subtracted.
|
|
4286 |
The remainder rectangles are returned via aRemainderRects, which is required
|
|
4287 |
to be a pointer to an array of 4 TRect's.
|
|
4288 |
aRemainderRects[0] is top remainder, ...[1] is bottom, ...[2] is left, ...[3] is right
|
|
4289 |
*/
|
|
4290 |
void CTextLayout::GetHighlightRemnants(const TRect& aRect, const TDrawTextLayoutContext& aDrawTextLayoutContext,
|
|
4291 |
TRect* aRemainderRects) const
|
|
4292 |
{
|
|
4293 |
ASSERT(aRemainderRects);
|
|
4294 |
/*
|
|
4295 |
overlap is the portion of the view rect that aRect intersects with
|
|
4296 |
subtract this from the aRect, giving 4 non-overlapping remainder rectangles,
|
|
4297 |
aRemainderRects, any or all of which may be empty. Copied from SubtractRect in TAGMA
|
|
4298 |
*/
|
|
4299 |
TRect overlap(aDrawTextLayoutContext.iViewRect);
|
|
4300 |
overlap.Intersection(aRect);
|
|
4301 |
if (overlap.IsEmpty())
|
|
4302 |
overlap.SetRect(aRect.iTl,aRect.iTl);
|
|
4303 |
aRemainderRects[0] = aRect;
|
|
4304 |
aRemainderRects[0].iBr.iY = overlap.iTl.iY;
|
|
4305 |
aRemainderRects[1] = aRect;
|
|
4306 |
aRemainderRects[1].iTl.iY = overlap.iBr.iY;
|
|
4307 |
aRemainderRects[2] = overlap;
|
|
4308 |
aRemainderRects[2].iTl.iX = aRect.iTl.iX;
|
|
4309 |
aRemainderRects[2].iBr.iX = overlap.iTl.iX;
|
|
4310 |
aRemainderRects[3] = overlap;
|
|
4311 |
aRemainderRects[3].iTl.iX = overlap.iBr.iX;
|
|
4312 |
aRemainderRects[3].iBr.iX = aRect.iBr.iX;
|
|
4313 |
}
|
|
4314 |
|
|
4315 |
/**
|
|
4316 |
Cleanup method for the opaque flag.
|
|
4317 |
*/
|
|
4318 |
void CTextLayout::ResetOpaque(void* aThis)
|
|
4319 |
{
|
|
4320 |
ASSERT(aThis != NULL);
|
|
4321 |
CTextLayout* p = reinterpret_cast <CTextLayout*> (aThis);
|
|
4322 |
p->iSource->iDrawOpaque = EFalse;
|
|
4323 |
}
|
|
4324 |
|
|
4325 |
/**
|
|
4326 |
Sets opaque drawing flag for CTextLayout object. It will used later when the
|
|
4327 |
content/background has to be drawn.
|
|
4328 |
Until the flag is not reseted, the opaque drawing will be used
|
|
4329 |
for all the content except the background - the flag has an useful meaning only for transparent
|
|
4330 |
editors.
|
|
4331 |
A TCleanupItem object will be pushed into the Cleanup Stack, which will reset the opaque
|
|
4332 |
flag durring its destruction.
|
|
4333 |
*/
|
|
4334 |
void CTextLayout::SetOpaqueLC()
|
|
4335 |
{
|
|
4336 |
iSource->iDrawOpaque = ETrue;
|
|
4337 |
CleanupStack::PushL(TCleanupItem(&CTextLayout::ResetOpaque, this));
|
|
4338 |
}
|
|
4339 |
|
|
4340 |
void FormPanic(TFormPanic aPanic)
|
|
4341 |
{
|
|
4342 |
_LIT(KFormPanic,"Form");
|
|
4343 |
User::Panic(KFormPanic,aPanic);
|
|
4344 |
}
|
|
4345 |
|
|
4346 |
/**
|
|
4347 |
Default implementation of mapping invisible character to its specified alternate.
|
|
4348 |
|
|
4349 |
Called by TLayDocTextSource::Map() unless overidden by custom mapping class.
|
|
4350 |
May be called by custom mapping class
|
|
4351 |
@param aChar
|
|
4352 |
Invisible character to be remapped
|
|
4353 |
@param aNonPrintingCharVisibility
|
|
4354 |
Current state of flags showing visibility of invisible characters
|
|
4355 |
@param aLayDoc
|
|
4356 |
Const ref to the calling CLayDocTextSource
|
|
4357 |
@return
|
|
4358 |
The replacement character if remapping has taken place, else return original character
|
|
4359 |
*/
|
|
4360 |
EXPORT_C TUint MFormCustomInvisibleCharacterRemapper::DefaultMapping( TUint aChar, const TNonPrintingCharVisibility aNonPrintingCharVisibility, const TLayDocTextSource& aLayDoc )
|
|
4361 |
{
|
|
4362 |
// If mapping special characters is possible, use the specified flags.
|
|
4363 |
if (!aNonPrintingCharVisibility.NoneVisible() && aLayDoc.CanMap())
|
|
4364 |
{
|
|
4365 |
switch (aChar)
|
|
4366 |
{
|
|
4367 |
case CEditableText::EParagraphDelimiter:
|
|
4368 |
if (aNonPrintingCharVisibility.ParagraphDelimitersVisible())
|
|
4369 |
return KVisibleParagraphBreak;
|
|
4370 |
break;
|
|
4371 |
|
|
4372 |
case CEditableText::ELineBreak:
|
|
4373 |
if (aNonPrintingCharVisibility.LineBreaksVisible())
|
|
4374 |
return KVisibleLineBreak;
|
|
4375 |
break;
|
|
4376 |
|
|
4377 |
case CEditableText::ENonBreakingSpace:
|
|
4378 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4379 |
return KVisibleNonBreakSpace;
|
|
4380 |
break;
|
|
4381 |
|
|
4382 |
case CEditableText::EPotentialHyphen:
|
|
4383 |
if (aNonPrintingCharVisibility.PotentialHyphensVisible())
|
|
4384 |
return KVisiblePotentialHyphen;
|
|
4385 |
break;
|
|
4386 |
|
|
4387 |
case CEditableText::ENonBreakingHyphen:
|
|
4388 |
if (aNonPrintingCharVisibility.NonBreakingHyphensVisible())
|
|
4389 |
return KVisibleNonBreakHyphen;
|
|
4390 |
break;
|
|
4391 |
|
|
4392 |
case CEditableText::ETabCharacter:
|
|
4393 |
if (aNonPrintingCharVisibility.TabsVisible())
|
|
4394 |
return KVisibleTab;
|
|
4395 |
break;
|
|
4396 |
|
|
4397 |
case CEditableText::EPictureCharacter:
|
|
4398 |
return KVisiblePicture;
|
|
4399 |
|
|
4400 |
case 0x200B: // Zero Width Space: the same behaviour as 0x20, while different category from 0x20.
|
|
4401 |
if (aNonPrintingCharVisibility.SpacesVisible())
|
|
4402 |
return KVisibleSpace;
|
|
4403 |
break;
|
|
4404 |
|
|
4405 |
/*
|
|
4406 |
For the moment, treat bidirectional controls as if they were non-break spaces, as far as visibility is
|
|
4407 |
concerned, and map as follows: LRE=<, RLE=>, PDF=currency symbol, LRO=left guillemet, RLO=right guillemet.
|
|
4408 |
*/
|
|
4409 |
case 0x202A: // LRE
|
|
4410 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4411 |
return 0x003C;
|
|
4412 |
break;
|
|
4413 |
case 0x202B: // RLE
|
|
4414 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4415 |
return 0x003E;
|
|
4416 |
break;
|
|
4417 |
case 0x202C: // PDF
|
|
4418 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4419 |
return 0x00A4;
|
|
4420 |
break;
|
|
4421 |
case 0x202D: // LRO
|
|
4422 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4423 |
return 0x00AB;
|
|
4424 |
break;
|
|
4425 |
case 0x202E: // RLO
|
|
4426 |
if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
|
|
4427 |
return 0x00BB;
|
|
4428 |
break;
|
|
4429 |
|
|
4430 |
default:
|
|
4431 |
if (aNonPrintingCharVisibility.SpacesVisible() && TChar(aChar).GetCategory() == TChar::EZsCategory)
|
|
4432 |
return KVisibleSpace;
|
|
4433 |
break;
|
|
4434 |
}
|
|
4435 |
}
|
|
4436 |
|
|
4437 |
// If not mapping special characters, or not mapping this particular character, use the default mapping.
|
|
4438 |
return aLayDoc.MTmSource::Map(aChar);
|
|
4439 |
}
|
|
4440 |
|
|
4441 |
|
|
4442 |
/**
|
|
4443 |
Allows Form clients to register an invisible character remapper object to
|
|
4444 |
customize the visible display of invisible characters such as paragraph marks.
|
|
4445 |
@param aInvisibleCharacterRemapper
|
|
4446 |
Pointer to custom invisible character remapper to use
|
|
4447 |
*/
|
|
4448 |
EXPORT_C void CTextLayout::SetCustomInvisibleCharacterRemapper( MFormCustomInvisibleCharacterRemapper* aInvisibleCharacterRemapper )
|
|
4449 |
{
|
|
4450 |
iSource->iInvisibleCharacterRemapper = aInvisibleCharacterRemapper;
|
|
4451 |
}
|
|
4452 |
|
|
4453 |
/**
|
|
4454 |
Allows Form clients to see which character remapper object is currently
|
|
4455 |
registered.
|
|
4456 |
*/
|
|
4457 |
EXPORT_C MFormCustomInvisibleCharacterRemapper* CTextLayout::GetCustomInvisibleCharacterRemapper()
|
|
4458 |
{
|
|
4459 |
return iSource->iInvisibleCharacterRemapper;
|
|
4460 |
}
|
|
4461 |
|
|
4462 |
/** INC092568: CTextView::SetPendingSelection is not honoured
|
|
4463 |
Sets the cursor position member added for this fix that allows the text layout object
|
|
4464 |
to access any pending selection made by the owning text view object
|
|
4465 |
@param aPos:- pointer to the owning textview's iCursorPos
|
|
4466 |
*/
|
|
4467 |
void CTextLayout::SetTextViewCursorPos(TCursorPosition* aPos)
|
|
4468 |
{
|
|
4469 |
iTextViewCursorPos = aPos;
|
|
4470 |
}
|
|
4471 |
|
|
4472 |
/**
|
|
4473 |
This is the function used by CTextLayout when it wants to extend the formatted range downwards.
|
|
4474 |
It just calls CTmTextLayout::AddParL, but restricts the maximum height of the new formatting to the
|
|
4475 |
band height/2. If the next paragraph is bigger than this, AddParL will only format part of that
|
|
4476 |
paragraph, and the formatting will end in the middle of the paragraph.
|
|
4477 |
*/
|
|
4478 |
TBool CTextLayout::AddFormattingAtEndL(TTmFormatParamBase& aFormatParam, TInt& aHeightIncrease, TInt& aParagraphsIncrease)
|
|
4479 |
{
|
|
4480 |
aFormatParam.iMaxHeight = iBandHeight/2;
|
|
4481 |
return iText->AddParL(aFormatParam, EFalse, aHeightIncrease, aParagraphsIncrease);
|
|
4482 |
}
|
|
4483 |
|
|
4484 |
/**
|
|
4485 |
Stops or allows text to be drawn. Included to allow users to control visibility
|
|
4486 |
if text is part of an invisible control.
|
|
4487 |
|
|
4488 |
@param aVisible ETrue to make the text visible, EFalse to make it invisible.
|
|
4489 |
@see CCoeControl::MakeVisible()
|
|
4490 |
*/
|
|
4491 |
EXPORT_C void CTextLayout::MakeVisible(TBool aVisible)
|
|
4492 |
{
|
|
4493 |
iText->MakeVisible(aVisible);
|
|
4494 |
}
|
|
4495 |
|