mi32/bidi.h

Go to the documentation of this file.
00001 /**
00002  * \file bidi.h <mi32/bidi.h>
00003  * \brief BiDirectional text conversion
00004  *
00005  * \if NODOC
00006  * $Id: bidi.h_v 1.15 2006/02/16 16:11:10 dwilliss Exp $
00007  *
00008  * $Log: bidi.h_v $
00009  * Revision 1.15  2006/02/16 16:11:10  dwilliss
00010  * renamed obsolete #define
00011  *
00012  * Revision 1.14  2005/03/31 16:57:09  fileserver!dwilliss
00013  * Rename one of our types to MIUNICODE because it conflicted with a Microsoft #define
00014  *
00015  * Revision 1.13  2003/09/15 13:49:56  fileserver!dwilliss
00016  * Doxygen
00017  *
00018  * Revision 1.12  2003/07/09 14:36:20  mju
00019  * Fix endif.
00020  * Use conventional name for classlibexport.
00021  *
00022  * Revision 1.11  2003/07/09 14:34:26  dwilliss
00023  * Define and undefine MUSYSTEMCLASSEXPORT ourselves.  Don't expect ucstring
00024  * to do it for us, cause it shouldn't have been leaving it defined in the
00025  * first place
00026  *
00027  * Revision 1.10  2002/07/05 14:34:20  dwilliss
00028  * Undefine USEEXPORTPRAGMA before end of include file
00029  *
00030  * Revision 1.9  2000/12/07 22:51:00  dwilliss
00031  * Added method to get cursor position relative to visual string
00032  *
00033  * Revision 1.8  2000/12/01 22:21:24  dwilliss
00034  * Added method to set cursor position in visual units.
00035  *
00036  * Revision 1.7  2000/10/13 16:43:52  dwilliss
00037  * Must use "friend class NAME", not "friend NAME"
00038  *
00039  * Revision 1.6  2000/06/07 20:00:22  dwilliss
00040  * Renamed a #define for Mike
00041  *
00042  * Revision 1.5  2000/05/22 16:55:33  dwilliss
00043  * Cleaned up. Split out BIDI cursor into a derived class so we don't
00044  * have to keep track of cursor info in "normal" cases
00045  *
00046  * \endif
00047  */
00048 
00049 #ifndef INC_MI32_BIDI_H
00050 #define INC_MI32_BIDI_H
00051 
00052 #ifndef INC_MI32_UCSTRING_H
00053 #include <mi32/ucstring.h>
00054 #endif
00055 
00056 #ifdef MISYSTEMDLL
00057    #define CLASSLIBEXPORT MI_DLLCLASSEXPORT
00058 #else
00059    #define CLASSLIBEXPORT MI_DLLCLASSIMPORT
00060 #endif
00061 
00062 class BIDICURSOR;
00063 
00064 //!
00065 //! This class handles the Bi-Directional ("BiDi") issues of rendering
00066 //! strings which have a mixture of Left-To-Right and Right-To-Left
00067 //! text (such as Hebrew and Arabic)
00068 //!
00069 //! Besides flipping the string as necessary, it can also keep track
00070 //! or a cursor position within the string and resolve the logical 
00071 //! position of the cursor withing the string while moving in visual
00072 //! order.
00073 //!
00074 class CLASSLIBEXPORT BIDISTRING {
00075 public:
00076    // Enums
00077    
00078    enum DIRECTION {
00079       DIRECTION_LTR,
00080       DIRECTION_RTL 
00081       };
00082 
00083    enum ORDER {
00084       ORDER_VISUAL,
00085       ORDER_LOGICAL
00086       };
00087 
00088    // Constructors
00089 
00090    BIDISTRING();
00091 
00092    //! Construct with initial values
00093    BIDISTRING (
00094       const MIUNICODE* source,
00095       DIRECTION DefaultDirection = DIRECTION_LTR,
00096       ORDER StringOrder = ORDER_LOGICAL
00097       );
00098 
00099    // Destructor
00100    
00101    virtual ~BIDISTRING();
00102 
00103    // Methods
00104 
00105    //! Clear the string.
00106    void Clear (
00107       );
00108 
00109    //! Get the primary direction of the string.
00110    DIRECTION GetStringDirection (
00111       ) const;
00112 
00113    //! Return a copy of the string in logical order.
00114    //! Caller should free the returned string.
00115    MIUNICODE* GetStringLogical (
00116       ) const;
00117 
00118    //! Return a copy of the string in visual order.
00119    //! Caller should free the returned string.
00120    MIUNICODE* GetStringVisual (
00121       ) const;
00122 
00123    //! Set the string from a logical order string.
00124    //!
00125    //! Note: Normally, the directionality of a string is determined by the first
00126    //! strongly directional character in the string.  In this case, the DefaultDirection
00127    //! is only used as a fallback, unless bForceDirection is true.
00128    //! 
00129    void SetStringLogical (
00130       const MIUNICODE* source,
00131       DIRECTION DefaultDirection = DIRECTION_LTR,
00132       bool bForceDirection = false
00133       );
00134 
00135    //! Set the string from a visual order string.
00136    //! Nore: The DefaultDirection is VERY important with a visual order string.
00137    //! This is because it is impossible to tell by looking at a visual order
00138    //! string if it was supposed to be right-to-left or left-to-right.  Take
00139    //! the following examples: (assume lowercase letters are left-to-right and
00140    //! capital letters are right to left)
00141    //!
00142    //! <table>
00143    //! <tr><td></td><td>logical</td><td>visual</td></tr>
00144    //! <tr><td>1</td><td>ABC abc DEF</td><td>FED abc CBA</td></tr>
00145    //! <tr><td>2</td><td>ABC abc DEF def</td><td>def FED abc CBA</td></tr>
00146    //! <tr><td>3</td><td>abc ABC def</td><td>abc CBA def</td></tr>
00147    //! <tr><td>4</td><td>abc ABC def DEF def</td><td>abc CBA def FED</td></tr>
00148    //! </table>
00149    //!
00150    //!  Strings 1 and 2 are right-to-left, 3 and 4 are left to right (based
00151    //!  on the first character in the logical order string).  Without prior
00152    //!  knowledge of the source strings, you can't tell what direction they
00153    //!  were by looking at the visual order strings.
00154    //!
00155    void SetStringVisual (
00156       const MIUNICODE* source,
00157       DIRECTION DefaultDirection = DIRECTION_LTR
00158       );
00159 
00160 private:
00161    #ifndef GENERATING_DOXYGEN_OUTPUT
00162    class SPAN {
00163       public:
00164 
00165       SPAN (
00166          BIDISTRING* str,
00167          const MIUNICODE* src,
00168          UINT32 start,
00169          UINT32 end,
00170          DIRECTION direction,
00171          ORDER format
00172          );
00173 
00174       ~SPAN();
00175 
00176       // Members
00177       SPAN *m_VisualPrev;  //!< Pointer to the previous visual run.    
00178       SPAN *m_VisualNext;  //!< Pointer to the next visual run.       
00179 
00180       SPAN *m_LogicalPrev; //!< Pointer to the previous logical run. 
00181       SPAN *m_LogicalNext; //!< Pointer to the next logical run.    
00182 
00183       DIRECTION m_direction;           //!< Direction of the run.            
00184 
00185       INT32 m_cursor;             //!< Position of "cursor" in the string. (-1 means just before first char)
00186                               
00187 
00188       MIUNICODE *m_chars;          //!< List of characters for the run.  
00189       UINT32 *m_positions;      //!< List of original positions in source.
00190 
00191       UINT32 m_start;           //!< Beginning offset in the source string.
00192       UINT32 m_end;             //!< Ending offset in the source string.  
00193       };
00194 
00195    void AddLTRLogicalSegment (
00196       const MIUNICODE* source,
00197       UINT32 start,
00198       UINT32 end
00199       );
00200 
00201    void AddRTLLogicalSegment (
00202       const MIUNICODE* source,
00203       UINT32 start,
00204       UINT32 end
00205       );
00206 
00207    void AddLTRVisualSegment (
00208       const MIUNICODE* source,
00209       UINT32 start,
00210       UINT32 end
00211       );
00212 
00213    void AddRTLVisualSegment (
00214       const MIUNICODE* source,
00215       UINT32 start,
00216       UINT32 end
00217       );
00218 
00219    //! Set the string
00220    //! SetStringLogical() first calls Clear() then calls SetStringLogicalNoClear()
00221    //! The constructor doesn't bother to call Clear()
00222    void SetStringLogicalNoClear (
00223       const MIUNICODE* source,
00224       DIRECTION DefaultDirection = DIRECTION_LTR,
00225       bool bForceDirection = false
00226       );
00227 
00228    //! Set the string
00229    //! SetStringVisual() first calls Clear() then calls SetStringVisualNoClear()
00230    void SetStringVisualNoClear (
00231       const MIUNICODE* source,
00232       DIRECTION DefaultDirection = DIRECTION_LTR
00233       );
00234 
00235 
00236    // Members
00237    DIRECTION m_direction;            //!< Overall direction of the string. 
00238 
00239 
00240    SPAN *m_cursor;              //!< The run containing the "cursor."    
00241 
00242    SPAN *m_LogicalFirst;       //!< First run in the logical order.    
00243    SPAN *m_LogicalLast;        //!< Last run in the logical order.    
00244 
00245    SPAN *m_VisualFirst;        //!< First run in the visual order.   
00246    SPAN *m_VisualLast;         //!< Last run in the visual order.   
00247 
00248    MIUNICODE *m_source;          //!< The logical order string.           
00249    UINT32 m_start;            //!< The beginning offset in the source. (always 0)
00250    UINT32 m_end;              //!< The ending offset in the source.  
00251    bool m_bNeedCursorInfo;
00252 
00253    friend class BIDISTRING::SPAN;
00254    friend class BIDICURSOR;
00255    #endif // GENERATING_DOXYGEN_OUTPUT
00256    };
00257 
00258 
00259 //!
00260 //! An extention of BIDISTRING to handle cursor support.
00261 //!
00262 //!   This takes a lot more memory than BIDISTRING itself.
00263 //!
00264 class CLASSLIBEXPORT BIDICURSOR : public BIDISTRING {
00265 public:
00266    // Constructors
00267    BIDICURSOR ();
00268 
00269 
00270    //! Construct with initial values.
00271    //! Note, this one doesn't let you specify the string order.
00272    //! The string passed to the constructor must be in logical order.
00273    BIDICURSOR (
00274       const MIUNICODE* source,
00275       DIRECTION DefaultDirection = DIRECTION_LTR
00276       );
00277 
00278    // Destructor
00279    virtual ~BIDICURSOR();
00280 
00281    // Methods
00282 
00283    //! Move the cursor to the left.
00284    //!
00285    //! This method moves the cursor to the left in either the logical or
00286    //! visual order depending on the current setting of CursorMotion.
00287    //! It moves the cursor "count" spaces to the left and returns the
00288    //! new offset from the beginning of the logical string.
00289    UINT32 CursorLeft (
00290       UINT32 count
00291       );
00292 
00293    //! Move the cursor to the right.
00294    //!
00295    //! This method moves the cursor to the right in either the logical or
00296    //! visual order depending on the current setting of CursorMotion.
00297    //! It moves the cursor "count" spaces to the right and returns the
00298    //! new offset from the beginning of the logical string.
00299    UINT32 CursorRight (
00300       UINT32 count
00301       );
00302 
00303    //! Return the direction of the text under the cursor.
00304    //! Returns the direction that the text under the cursor should
00305    //! be read.
00306    DIRECTION GetCursorDirection (
00307       ) const;
00308 
00309    //! Returns the current CursorMotion setting.
00310    //! Logical cursor motion means that moving to the right will step
00311    //! through the data in the order it is in memory, which may or may
00312    //! not be the same as on the screen.  Visual motion is what you
00313    //! expect on the screen.
00314    ORDER GetCursorMotion (
00315       ) const;
00316 
00317    
00318    //! Get the current cursor position relative to the start of the string in
00319    //! it's logical order.  The cursor should be thought of as a box covering
00320    //! the character position returned.
00321    UINT32 GetCursorPosition (
00322       ) const;
00323 
00324    //! Get the current cursor position relative to the start of the string in
00325    //! it's visual order.  The cursor should be thought of as a box covering
00326    //! the character position returned.
00327    UINT32 GetCursorPositionVisual (
00328       ) const;
00329 
00330    //! Set the cursor motion.
00331    //! Returns the previous value
00332    ORDER SetCursorMotion (
00333       ORDER CursorMotion
00334       );
00335 
00336    //! Set the cursor position (visual order, left-most glyph == 0)
00337    void SetCursorPositionVisual (
00338       UINT32 pos
00339       );
00340 
00341 private:
00342    #ifndef GENERATING_DOXYGEN_OUTPUT
00343    UINT32 CursorLeftLogical (
00344       UINT32 count
00345       );
00346 
00347    UINT32 CursorRightLogical (
00348       UINT32 count
00349       );
00350 
00351    UINT32 CursorLeftVisual (
00352       UINT32 count
00353       );
00354 
00355    UINT32 CursorRightVisual (
00356       UINT32 count
00357       );
00358 
00359    ORDER m_CursorMotion;        //!< Logical or visual cursor motion flag.
00360    #endif // GENERATING_DOXYGEN_OUTPUT
00361    };
00362 
00363 
00364 
00365 #undef CLASSLIBEXPORT 
00366 
00367 
00368 #endif //!<  INC_MI32_BIDI_H 
00369 

Generated on Thu Apr 26 04:44:52 2007 for TNTsdk by  doxygen 1.5.2