Update contrib.
2 * Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
24 #include "OstTraceDefinitions.h"
25 #ifdef OST_TRACE_COMPILER_IN_USE
26 #include "FRMPAGETraces.h"
29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
30 #include "FRMCONST_INTERNAL.H"
31 #include "FRMCONST_PARTNER.H"
34 /** Allocates and constructs a CTextPaginator object with a page list, the
35 printer device for which the document is to be paginated and an active object
38 @param aPrinterDevice Pointer to the printer device for which the document is
39 to be paginated. This must be provided.
40 @param aCharsPerPage The page list. This is a client-provided array into which
41 characters-per-page values are written. Ownership of the array remains with the
43 @param aPriority Integer specifying the active object priority. A number of
44 standard priorities are specified in CActive::TPriority.
45 @return Pointer to the new paginator object. */
46 EXPORT_C CTextPaginator* CTextPaginator::NewL(CPrinterDevice* aPrinterDevice,CArrayFix<TInt>* aPageList,TInt aPriority)
48 CTextPaginator* self=new(ELeave) CTextPaginator(aPriority);
49 CleanupStack::PushL(self);
50 self->ConstructL(aPrinterDevice,aPageList);
55 /** Destructor. Cancels the active object, if any. */
56 EXPORT_C CTextPaginator::~CTextPaginator()
60 delete iPageLineArray;
64 /** Sets a pagination observer (an instance of a class inherited from
65 MPaginateObserver). The use of an observer is optional.
67 An observer may be used when paginating a complete document in the background
68 using the function PaginateCompleteDocumentL(). The observer notifies
69 completion of pages, cancellation, errors, and on completion of multiple
72 @param aObserver Observer object inherited from MPaginateObserver. */
73 EXPORT_C void CTextPaginator::SetObserver(MPaginateObserver* aObserver)
79 /** Sets a pointer to the document which is to be paginated.
80 @param aLayDoc The document to paginate. */
81 EXPORT_C void CTextPaginator::SetDocumentL(MLayDoc* aLayDoc)
84 SetOrReplaceDocumentL(aLayDoc);
87 SetLayoutDimensions();
90 /** Sets a pointer to the printer device for which the document is to be
93 Note: This function must be called, and SetDocumentL() must have been called
96 @param aPrinterDevice The printer device. */
97 EXPORT_C void CTextPaginator::SetPrinterDevice(CPrinterDevice* aPrinterDevice)
101 OstTrace0( TRACE_FATAL, CTEXTPAGINATOR_SETPRINTERDEVICE, "EFDocumentToPaginateNotSet" );
103 __ASSERT_ALWAYS(iLayout,FormPanic(EFDocumentToPaginateNotSet));
104 iPrinterDevice=aPrinterDevice;
105 iLayout->SetImageDeviceMap(aPrinterDevice);
107 iPageSizeInTwips=aPrinterDevice->CurrentPageSpecInTwips().OrientedPageSize();
108 SetLayoutDimensions();
111 /** Sets the page width and height in twips, overriding the current values
112 specified in the printer device.
113 @param aPageSpec Contains the new page dimensions. */
114 EXPORT_C void CTextPaginator::SetPageSpecInTwips(const TPageSpec& aPageSpec)
117 iPageSizeInTwips=aPageSpec.OrientedPageSize();
118 SetLayoutDimensions();
121 /** Sets the widths of the page margins in twips.
123 The page margin exists on all four sides of the page. It does not include the
124 line cursor or labels margins. The labels and line cursor margins are set using
125 SetTextMarginWidthsInTwips().
127 @param aPageMargins The page margin widths. */
128 EXPORT_C void CTextPaginator::SetPageMarginsInTwips(const TMargins& aPageMargins)
130 iPageMarginsInTwips=aPageMargins;
131 SetLayoutDimensions();
134 /** Sets the widths in twips of:
136 the labels margin the area within which paragraph labels are displayed,
138 the gutter margin (also known as the line cursor margin) exists between the
139 labels margin and the text area.
141 @param aLabelMarginWidth The labels margin width.
142 @param aGutterMarginWidth The gutter margin width. */
143 EXPORT_C void CTextPaginator::SetTextMarginWidthsInTwips(TInt aLabelMarginWidth
144 ,TInt aGutterMarginWidth)
146 iLabelMarginWidthInTwips=aLabelMarginWidth;
147 iGutterMarginWidthInTwips=aGutterMarginWidth;
148 SetLayoutDimensions();
151 CTextPaginator::CTextPaginator(TInt aPriority)
156 void CTextPaginator::ConstructL(CPrinterDevice* aPrinterDevice,CArrayFix<TInt>* aPageList)
159 iPageLineArray=new(ELeave) CArrayFixFlat<TPageLine>(EPageLineArrayGranularity);
160 iTempPageList=new(ELeave) CArrayFixFlat<TInt>(EPageListArrayGranularity);
161 iPrinterDevice=aPrinterDevice;
164 iPaginator.SetArray(iTempPageList);
165 iPaginator.SetPageHeight(TextSizeInPixels().iHeight);
167 iPageSizeInTwips=iPrinterDevice->CurrentPageSpecInTwips().OrientedPageSize();
168 SetLayoutDimensions();
172 /** Initiates pagination of a complete document in the background using an
173 active object. To start pagination, use either this function, or else
174 incrementally paginate with AppendTextL() do not try to use both functions
177 Note: SetDocumentL() must have been called beforehand, or a panic occurs. */
178 EXPORT_C void CTextPaginator::PaginateCompleteDocumentL()
182 OstTrace0( TRACE_FATAL, CTEXTPAGINATOR_PAGINATECOMPLETEDOCUMENTL, "EFDocumentToPaginateNotSet" );
184 __ASSERT_ALWAYS(iLayout,FormPanic(EFDocumentToPaginateNotSet));
185 if (iPageList->Count()==0)
186 iPageList->AppendL(iLayDoc->LdDocumentLength());
188 CActiveScheduler::Add(this); // Adds itself to the active scheduler
189 iMode=EFPaginateCompleteDocument;
194 /** Paginates incrementally as a document is being constructed (by appending
195 paragraphs, for example). Call this function every time text is added to the
198 The function PaginationCompletedL() should be called at the end (in order to
199 complete the last entry in the characters-per-page array).
201 Use either this function, or else paginate in the background with
202 PaginateCompleteDocumentL() - do not try to use both functions together.
204 Note: SetDocumentL() must have been called beforehand, or a panic occurs.
206 @param aCumulativeDocPos The first time the function is called, this should be
207 given a value of zero. Returns the last document position which has been
209 @return A count of the current number of pages. */
210 EXPORT_C TInt CTextPaginator::AppendTextL(TInt& aCumulativeDocPos)
214 OstTrace0( TRACE_FATAL, CTEXTPAGINATOR_APPENDTEXTL, "EFDocumentToPaginateNotSet" );
216 __ASSERT_ALWAYS(iLayout,FormPanic(EFDocumentToPaginateNotSet));
217 if (aCumulativeDocPos>=iLayout->DocumentLength())
219 OstTrace0( TRACE_FATAL, DUP1_CTEXTPAGINATOR_APPENDTEXTL, "EFInvalidDocPos" );
221 __ASSERT_ALWAYS(aCumulativeDocPos<iLayout->DocumentLength(),FormPanic(EFInvalidDocPos));
222 iMode=EFPaginateIncrementally;
224 if (iPageList->Count()==0)
227 TBool moreToDo=ETrue;
230 moreToDo = iDocPos<=iLayDoc->LdDocumentLength();
233 TrapPaginateParagraphL();
237 if (iMode==EFPaginateCompleteDocument)
239 iPaginator.FlushL(iDocPos);
242 iPageLineArray->Reset();
243 iPageLineArray->Compress();
247 aCumulativeDocPos=iDocPos;
249 TRAPD(err,CopyTempPageListL());
254 return iPageList->Count();
257 /** This function should be called when incremental pagination has completed
258 (see AppendTextL()), to complete the final entry in the page list. If an
259 observer has been set, calls its NotifyCompletion() function.
261 @return Count of total number of pages. */
262 EXPORT_C TInt CTextPaginator::PaginationCompletedL()
264 TRAPD(err,iPaginator.FlushL(iDocPos));
267 iLayout->DiscardFormat();
268 TRAP(err,CopyTempPageListL());
272 iObserver->NotifyCompletion();
273 return iPageList->Count();
276 void CTextPaginator::RunL()
278 // Called by active scheduler.
279 // Paginates a document one paragraph at a time through succeeding
283 TBool moreToDo = iDocPos<=iLayDoc->LdDocumentLength();
286 TrapPaginateParagraphL();
290 if (iMode==EFPaginateCompleteDocument)
292 iPaginator.FlushL(iDocPos);
295 iPageLineArray->Reset();
296 iPageLineArray->Compress();
303 iLayout->DiscardFormat();
304 TRAPD(err,CopyTempPageListL());
308 iObserver->NotifyCompletion();
312 void CTextPaginator::DoCancel()
315 iLayout->DiscardFormat();
317 iPageBreakChar=EFalse;
320 iObserver->NotifyError(KErrCancel);
323 void CTextPaginator::SetLayoutDimensions()
325 iPaginator.SetPageHeight(TextSizeInPixels().iHeight);
327 iLayout->SetFormatMode(CLayoutData::EFPrintMode,TextRectInTwips().Width(),iPrinterDevice);
330 void CTextPaginator::SetOrReplaceDocumentL(MLayDoc* aLayDoc)
335 iLayout->SetLayDoc(aLayDoc);
337 iLayout=CTextLayout::NewL(aLayDoc,TextSizeInPixels().iWidth);
338 iLayout->SetImageDeviceMap(iPrinterDevice);
341 TRect CTextPaginator::TextRectInTwips() const
345 textRect.iTl.iX=iPageMarginsInTwips.iLeft+iGutterMarginWidthInTwips+iLabelMarginWidthInTwips;
346 textRect.iTl.iY=iPageMarginsInTwips.iTop;
347 textRect.iBr.iX=iPageSizeInTwips.iWidth-iPageMarginsInTwips.iRight;
348 textRect.iBr.iY=iPageSizeInTwips.iHeight-iPageMarginsInTwips.iBottom;
353 TSize CTextPaginator::TextSizeInPixels() const
355 TRect textRect=iPrinterDevice->TwipsToPixels(TextRectInTwips());
357 return textRect.Size();
360 void CTextPaginator::TrapPaginateParagraphL()
362 TRAPD(err,PaginateParagraphL());
367 void CTextPaginator::PaginateParagraphL()
370 TBool keepTogether; // Prevents page break in a paragraph when ETrue.
371 TBool keepWithNext; // Prevents page break between this & next para when ETrue.
372 TBool startNewPage; // Inserts page break before this paragraph when ETrue.
373 TBool widowOrphan; // Prevents widowing/orphaning of para. lines when ETrue.
376 CParaFormat* paraFormat=NULL;
378 paraFormat=CParaFormat::NewLC();
379 iLayDoc->GetParagraphFormatL(paraFormat,iDocPos);
381 TBool startOfPara=(iLayDoc->LdToParagraphStart(docPos)==0);
383 keepTogether=paraFormat->iKeepTogether;
384 keepWithNext=paraFormat->iKeepWithNext;
385 startNewPage=paraFormat->iStartNewPage;
386 widowOrphan=paraFormat->iWidowOrphan;
388 iPageLineArray->Reset(); // Better safe than sorry at the moment ###
389 iPageLineArray->Compress();
392 TBool moreToDo = ETrue;
395 pageLine.iDocPos=iDocPos;
396 pageLine.iStartNewPage=EFalse;
398 pageLine.iStartNewPage=ETrue;
399 moreToDo=iLayout->FormatLineL(paraFormat,iDocPos,lineHeight,iPageBreakChar);
401 pageLine.iLineHeight=lineHeight;
403 pageLine.iKeepWithNext=ETrue;
405 pageLine.iKeepWithNext=EFalse;
406 iPageLineArray->AppendL(pageLine);
407 } while (moreToDo && lines<EFMaximumNumberLinesInBlock);
410 TBool endOfPara=(!moreToDo);
411 TBool penultimateLine=EFalse;
412 numLines=iPageLineArray->Count();
417 penultimateLine=(!iLayout->FormatLineL(paraFormat,docPos,lineHeight,pageBreakChar));
420 if (startNewPage && startOfPara)
421 (*iPageLineArray)[0].iStartNewPage=ETrue;
423 if (keepTogether && endOfPara)
424 (*iPageLineArray)[numLines-1].iKeepWithNext=EFalse;
426 if (keepWithNext && endOfPara)
427 (*iPageLineArray)[numLines-1].iKeepWithNext=ETrue;
432 (*iPageLineArray)[0].iKeepWithNext=ETrue;
433 if (endOfPara && numLines>=2)
434 (*iPageLineArray)[numLines-2].iKeepWithNext=ETrue;
435 else if (penultimateLine)
436 (*iPageLineArray)[numLines-1].iKeepWithNext=ETrue;
439 TBool pageBreak = EFalse;
440 for (TInt i=0; i<numLines; i++)
442 pageBreak=iPaginator.AppendLineL((*iPageLineArray)[i]);
447 iPageLineArray->Reset();
448 iPageLineArray->Compress();
450 CleanupStack::PopAndDestroy(); // delete format;
453 void CTextPaginator::PageCompleted()
456 iObserver->NotifyPageCompletion(iTempPageList->Count());
459 void CTextPaginator::Reque()
461 // Called just before Paginate Process goes to sleep to set it active
464 TRequestStatus *pS=(&iStatus);
465 User::RequestComplete(pS,0);
469 void CTextPaginator::ResetPaginator()
474 iPageBreakChar=EFalse;
478 void CTextPaginator::CopyTempPageListL()
480 // Copies temp page list to one that external user sees
483 if (iTempPageList->Count()<1 && iMode!=EFPaginateIncrementally)
485 OstTrace0( TRACE_DUMP, CTEXTPAGINATOR_COPYTEMPPAGELISTL, "EFPageListEmpty" );
487 __ASSERT_DEBUG(iTempPageList->Count()>=1||iMode==EFPaginateIncrementally,FormPanic(EFPageListEmpty));
488 TRAPD(err,iPageList->ResizeL(iTempPageList->Count()));
492 {for(TInt ii=0;ii<iTempPageList->Count();ii++)
493 (*iPageList)[ii]=(*iTempPageList)[ii];
498 void CTextPaginator::LeaveL(TInt aErr)
500 // Something has left
505 iLayout->DiscardFormat();
508 iPageLineArray->Reset();
509 iPageLineArray->Compress();
510 iTempPageList->Reset();
511 iTempPageList->Compress();
514 iObserver->NotifyError(aErr);
516 OstTrace1( TRACE_FATAL, CTEXTPAGINATOR_LEAVEL, "CTextPaginator::LeaveL;aErr=%d", aErr );