textrendering/textformatting/group/CustomWrapping.rtf
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 02:02:46 +0200
changeset 0 1fb32624e06b
child 40 91ef7621b7fc
permissions -rw-r--r--
Revision: 201003 Kit: 201005

{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f82\froman\fcharset238\fprq2 Times New Roman CE;}{\f83\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f85\froman\fcharset161\fprq2 Times New Roman Greek;}
{\f86\froman\fcharset162\fprq2 Times New Roman Tur;}{\f87\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f88\fswiss\fcharset238\fprq2 Arial CE;}{\f89\fswiss\fcharset204\fprq2 Arial Cyr;}{\f91\fswiss\fcharset161\fprq2 Arial Greek;}
{\f92\fswiss\fcharset162\fprq2 Arial Tur;}{\f93\fswiss\fcharset186\fprq2 Arial Baltic;}{\f94\fmodern\fcharset238\fprq1 Courier New CE;}{\f95\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f97\fmodern\fcharset161\fprq1 Courier New Greek;}
{\f98\fmodern\fcharset162\fprq1 Courier New Tur;}{\f99\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;
\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{
\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\i\f1\cgrid \sbasedon0 \snext0 heading 2;}{\*\cs10 \additive Default Paragraph Font;}}{\*\listtable{\list\listtemplateid134807567\listsimple{\listlevel
\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\fi-360\li360\jclisttab\tx360 }{\listname ;}\listid275217526}}{\*\listoverridetable{\listoverride\listid275217526\listoverridecount0\ls1}}
{\info{\title Introduction}{\author Arunsakh Sachamuneewongse}{\operator Arunsakh Sachamuneewongse}{\creatim\yr2001\mo3\dy28\hr11\min50}{\revtim\yr2001\mo3\dy29\hr16\min33}{\version3}{\edmins146}{\nofpages3}{\nofwords928}{\nofchars5292}
{\*\company Symbian}{\nofcharsws0}{\vern113}}\paperw11906\paperh16838 \widowctrl\ftnbj\aenddoc\hyphcaps0\formshade\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang
{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9
\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \widctlpar\adjustright \fs20\cgrid {Author:\tab  Arunsakh Sachamuneewongse\line Date: \tab 29}{\super th}{ March 2001
\par {\pntext\pard\plain\s2 \b\i\f1\lang1033\cgrid \hich\af1\dbch\af0\loch\f1 1.\tab}}\pard\plain \s2\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec\pnstart1\pnindent360\pnhang{\pntxta .}}
\ls1\outlinelevel1\adjustright \b\i\f1\cgrid {Introduction
\par }\pard\plain \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \fs20\cgrid {
\par One of the functional requirements in 6.2, as requested by the Pearl and the Crystal DFRDs, was auto-
hyphenation. Since the Pearl and Crystal devices screens are smaller, they wanted to avoid a jagged white space on the right hand side of a text editable screen introduced when the lines are broken. The following was what was happening:
\par 
\par 
\par }\trowd \trgaph108\trleft1350\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr
\brdrs\brdrw10 \cltxlrtb \cellx5130\pard \widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {An example of how
 in text boxes, the extremely long words at the end of a line are wrapped to the next line leaving an uneven jagged white space on the right hand side of the screen which is undesirable.\cell }\pard \widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0
\pndec }\adjustright {\row }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {
\par 
\par After a little consideration, it was decided that a fully fledge a
uto-hyphenation was out of the scope of the project for 6.2. An alternative solution was suggested, Custom Wrapping or Custom line breaking, which would allow a line to be broken in any way required to eliminate the jagged white spaces.  
\par 
\par 
\par {\pntext\pard\plain\s2 \b\i\f1\lang1033\cgrid \hich\af1\dbch\af0\loch\f1 2.\tab}}\pard\plain \s2\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec\pnstart1\pnindent360\pnhang{\pntxta .}}
\ls1\outlinelevel1\adjustright \b\i\f1\cgrid {Custom Wrapping
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {
\par The class }{\f2\cf2 MTmCustom}{ in FORM defines the four virtual functions involving line breaking. These four functions are: 
\par 
\par }{\cf2 TUint LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const;
\par TBool LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const;
\par TBool GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
\par \tab \tab \tab \tab \tab TBool aForwards,TInt& aBreakPos) const;
\par TBool IsHangingCharacter(TUint aChar) const;
\par }{
\par The function LineBreakClass returns the assigned line breaking class value for the character aCode. It also returns the range of characters that share the same line breaking class, starting from aRangeStart till aRangeEnd. 
\par 
\par LineBreakPossible returns TRUE if a line break is possible between characters of the two specified classes. If aHaveSpaces is TRUE, one or more characters in ESpLineBreakClass was found between the characters in the two specified classes.
\par 
\par GetLineBreakInCo
ntext returns the first (if aForwards is TRUE) or last (if aForwards is FALSE) linebreak in aText, this must be in the range aMinBreakPos...aMaxBreakPos, which is a run of characters in the class ESaLineBreakClass, usually employed for Thai, Lao and Khmer

\par letters, because these scripts don't use word spaces and need dictionary-based line breaking.
\par The break position is returned in aBreakPos, which must be > 0 and < aText.Length() - 1.
\par Return TRUE if a break is found, FALSE otherwise.
\par 
\par IsHangingCharacter return TRUE if this character, aChar, can overhang the measured right end of the line.
\par 
\par To change the line breaking behaviour one/all of these functions need to be overridden. It was decided to provide a new Interface class to override these line-breaking functions. So a new interface was added in FORM. This is the class MFormCustomWrap.

\par 
\par 
\par 
\par 
\par 
\par }{\cf2 class MFormCustomWrap
\par \tab \{
\par public:
\par \tab IMPORT_C virtual TUint LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const;
\par \tab IMPORT_C virtual TBool LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const;
\par \tab IMPORT_C virtual TBool GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,TBool aForwards,TInt& aBreakPos) const;
\par \tab IMPORT_C virtual TBool IsHangingCharacter(TUint aChar) const;
\par private:
\par \tab IMPORT_C virtual void MFormCustomWrap_Reserved_1();
\par \tab IMPORT_C virtual void MFormCustomWrap_Reserved_2();\tab 
\par \tab \};
\par }{
\par Besides adding the new interface, a few more changes were made in FORM to allow custom wrapping to take place. The following were the changes made in FORM. 
\par 
\par 
\par A new member was added in class }{\f2\cf2 TLayDocTextSource}{, which is internal to Symbian. This class  is derived from the class }{\f2\cf2 MTmSource}{, which is derived from }{\f2\cf2 MTmCustom}{ where the line breaking functions are defined. 
\par 
\par }{\cf2 const MFormCustomWrap* iCustomWrap;\tab      // if non-null, points to custom wrapping routines
\par }{
\par Also added in the class TLayDocTextSource were 4 function overrides 
\par 
\par }{\cf2 TUint LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const;
\par TBool LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const;
\par TBool GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
\par \tab \tab \tab \tab \tab TBool aForwards,TInt& aBreakPos) const;
\par TBool IsHangingCharacter(TUint aChar) const;}{
\par 
\par If iCustomWrap is set then the override implementations are called, else the base implementation of these functions are called, which is the implementation in MTmCustom. 
\par 
\par 2 new functions were added in class CTextLayout: 
\par 
\par }{\cf2 IMPORT_C void SetCustomWrap(const MFormCustomWrap* aCustomWrap);
\par IMPORT_C const MFormCustomWrap* CustomWrap() const;
\par }{
\par The class CTextLayout is the lowest-level text formatting class provided by FORM. It has as its member a pointer to TLayDocTextSource, iSource. 
\par 
\par }{\cf2 SetCustomWrap(const MFormCustomWrap* aCustomWrap)}{ sets 
\par iSource.iCustomWrap = aCustomWrap and  }{\cf2 CustomWrap()}{ returns iSource.iCustomWrap. 
\par 
\par 
\par In order to use the custom wrapping interface, a class has to implement the custom wrapping interface MFormCustomWrap. That class then needs to be set as the custom wrapper by passing a pointer to that class in the function SetCustomWrap in CTextLayout.  

\par 
\par \line 
\par 
\par 
\par 
\par 
\par The following are the changes made in UIKLAF and UIKON to allow the text editable window \endash  Edwin \endash  to eliminate the jagged white space on the right hand side of the screen by implementing the custom wrapping interface. 
\par 
\par A new class implementing the MFormCustomWrap interface was added in the UIKLAFGT component. 
\par 
\par }{\cf2 // Lafmain.h
\par class CLafEdwinCustomWrapBase : public CBase, public MFormCustomWrap
\par \tab \{
\par \'85
\par \'85
\par \tab IMPORT_C TBool LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const;
\par \'85
\par \'85
\par \tab \};
\par }{
\par 
\par CLafEdwinCustomWrapBase implements MFormCustomWrap and overrides the interfaces virtual functions. Her
e I have shown one of the functions that have been overridden. LineBreakPossible returns TRUE if it is possible to break line between the two classes. The overridden implementation returns TRUE all the time, thus allowing a line break anywhere. 
\par 
\par In UIKON, in the class CEikEdwin the following changes were made.
\par 
\par A New flag was added to the enum TFlags: - }{\cf2 ENoCustomWrap\tab  \tab =0x02000000
\par 
\par }{CEikEdwin has a pointer to CTextLayout \endash  iLayout.  So what was needed now was to add a new member data to CEikEdwin, a pointer
 to CLafEdwinCustomWrapBase and call CTextLayouts SetCustomWrap function passing the pointer to CLafEdwinCustomWrapBase.  When creating a CEikEdwin, the flag ENoCustomWrap can be used to establish whether the Edwin is allowed custom wrapping or not.  

\par }}