00001 /**************************************************************************** 00002 ** $Id: qcomplextext.cpp,v 1.4 2004/04/04 13:54:45 mickeyl Exp $ 00003 ** 00004 ** Implementation of some internal classes 00005 ** 00006 ** Created : 00007 ** 00008 ** Copyright (C) 2001 Trolltech AS. All rights reserved. 00009 ** 00010 ** This file is part of the kernel module of the Qt GUI Toolkit. 00011 ** 00012 ** This file may be distributed under the terms of the Q Public License 00013 ** as defined by Trolltech AS of Norway and appearing in the file 00014 ** LICENSE.QPL included in the packaging of this file. 00015 ** 00016 ** This file may be distributed and/or modified under the terms of the 00017 ** GNU General Public License version 2 as published by the Free Software 00018 ** Foundation and appearing in the file LICENSE.GPL included in the 00019 ** packaging of this file. 00020 ** 00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition 00022 ** licenses may use this file in accordance with the Qt Commercial License 00023 ** Agreement provided with the Software. 00024 ** 00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00027 ** 00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 00029 ** information about Qt Commercial License Agreements. 00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information. 00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information. 00032 ** 00033 ** Contact info@trolltech.com if any conditions of this licensing are 00034 ** not clear to you. 00035 ** 00036 **********************************************************************/ 00037 00038 00039 #include "qrichtext_p.h" 00040 00041 #include <stdlib.h> 00042 00043 using namespace Qt3; 00044 00045 // ----------------------------------------------------- 00046 00047 /* a small helper class used internally to resolve Bidi embedding levels. 00048 Each line of text caches the embedding level at the start of the line for faster 00049 relayouting 00050 */ 00051 QBidiContext::QBidiContext( uchar l, QChar::Direction e, QBidiContext *p, bool o ) 00052 : level(l) , override(o), dir(e) 00053 { 00054 if ( p ) 00055 p->ref(); 00056 parent = p; 00057 count = 0; 00058 } 00059 00060 QBidiContext::~QBidiContext() 00061 { 00062 if( parent && parent->deref() ) 00063 delete parent; 00064 } 00065 00066 /* 00067 Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on 00068 arabic). 00069 00070 Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent). 00071 transparent joining is not encoded in QChar::joining(), but applies to all combining marks and format marks. 00072 00073 Right join-causing: dual + center 00074 Left join-causing: dual + right + center 00075 00076 Rules are as follows (for a string already in visual order, as we have it here): 00077 00078 R1 Transparent characters do not affect joining behaviour. 00079 R2 A right joining character, that has a right join-causing char on the right will get form XRight 00080 (R3 A left joining character, that has a left join-causing char on the left will get form XLeft) 00081 Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode 00082 R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on 00083 the right will get form XMedial 00084 R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left 00085 will get form XRight 00086 R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right 00087 will get form XLeft 00088 R7 Otherwise the character will get form XIsolated 00089 00090 Additionally we have to do the minimal ligature support for lam-alef ligatures: 00091 00092 L1 Transparent characters do not affect ligature behaviour. 00093 L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft) 00094 L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated) 00095 00096 The two functions defined in this class do shaping in visual and logical order. For logical order just replace right with 00097 previous and left with next in the above rules ;-) 00098 */ 00099 00100 /* 00101 Two small helper functions for arabic shaping. They get the next shape causing character on either 00102 side of the char in question. Implements rule R1. 00103 00104 leftChar() returns true if the char to the left is a left join-causing char 00105 rightChar() returns true if the char to the right is a right join-causing char 00106 */ 00107 static inline const QChar *prevChar( const QString &str, int pos ) 00108 { 00109 //odebug << "leftChar: pos=" << pos << "" << oendl; 00110 pos--; 00111 const QChar *ch = str.unicode() + pos; 00112 while( pos > -1 ) { 00113 if( !ch->isMark() ) 00114 return ch; 00115 pos--; 00116 ch--; 00117 } 00118 return &QChar::replacement; 00119 } 00120 00121 static inline const QChar *nextChar( const QString &str, int pos) 00122 { 00123 pos++; 00124 int len = str.length(); 00125 const QChar *ch = str.unicode() + pos; 00126 while( pos < len ) { 00127 //odebug << "rightChar: " << pos << " isLetter=" << ch.isLetter() << ", joining=" << ch.joining() << "" << oendl; 00128 if( !ch->isMark() ) 00129 return ch; 00130 // assume it's a transparent char, this might not be 100% correct 00131 pos++; 00132 ch++; 00133 } 00134 return &QChar::replacement; 00135 } 00136 00137 static inline bool prevVisualCharJoins( const QString &str, int pos) 00138 { 00139 return ( prevChar( str, pos )->joining() != QChar::OtherJoining ); 00140 } 00141 00142 static inline bool nextVisualCharJoins( const QString &str, int pos) 00143 { 00144 QChar::Joining join = nextChar( str, pos )->joining(); 00145 return ( join == QChar::Dual || join == QChar::Center ); 00146 }
1.4.2