|
1 /* |
|
2 * Copyright (c) 1999-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 * The standard internal header for TAGMA. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 #ifndef TMSTD_H__ |
|
24 #define TMSTD_H__ |
|
25 |
|
26 #include "TAGMA.H" |
|
27 #include <txtfrmat.h> |
|
28 #include <txtetext.h> |
|
29 #include <fbs.h> |
|
30 #include <bidi.h> |
|
31 |
|
32 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
33 #include "TAGMA_INTERNAL.H" |
|
34 #endif |
|
35 |
|
36 static const TUint KZeroWidthJoiner = 0x200d; |
|
37 static const TUint KZeroWidthNonJoiner = 0x200C; |
|
38 |
|
39 /** |
|
40 @internalComponent |
|
41 */ |
|
42 NONSHARABLE_CLASS(CTmBufferBase) : public CBase |
|
43 |
|
44 { |
|
45 public: |
|
46 ~CTmBufferBase(); |
|
47 void Truncate(TInt aLength); |
|
48 void Reset() { iLength = 0; } |
|
49 TInt Length() const { return iLength; } |
|
50 |
|
51 protected: |
|
52 CTmBufferBase(TInt aExpandSize): iExpandSize(aExpandSize) { } |
|
53 TAny* Data() const { return iData; } |
|
54 TAny* ExtendL(TInt aSizeOfData); |
|
55 void DoAppendL(const TAny* aItem,TInt aCount,TInt aSizeOfData); |
|
56 |
|
57 private: |
|
58 void GrowL(TInt aExtra,TInt aSizeOfData); |
|
59 |
|
60 TAny* iData; |
|
61 TInt iLength; |
|
62 TInt iAllocated; |
|
63 TInt iExpandSize; |
|
64 }; |
|
65 |
|
66 /** |
|
67 An expandable buffer. |
|
68 @internalComponent |
|
69 */ |
|
70 template<class T> class CTmBuffer: public CTmBufferBase |
|
71 |
|
72 { |
|
73 public: |
|
74 CTmBuffer(TInt aExpandSize): CTmBufferBase(aExpandSize) { } |
|
75 void AppendL(const T& aItem) { *STATIC_CAST(T*,ExtendL(sizeof(T)))=aItem; } |
|
76 void AppendL(const T* aItem,TInt aCount) { DoAppendL(aItem,aCount,sizeof(T)); } |
|
77 T* Ptr() { return (T*)Data(); } |
|
78 const T* Ptr() const { return (const T*)Data(); } |
|
79 T& operator[](TInt aIndex) { return Ptr()[aIndex]; } |
|
80 }; |
|
81 |
|
82 /** |
|
83 @internalComponent |
|
84 */ |
|
85 enum TTmPanic |
|
86 { |
|
87 EInvariant, |
|
88 ENoSource, |
|
89 EBadArg, |
|
90 EBadLineBreak, |
|
91 EFormatNotFound, |
|
92 EBadTruncationLength, |
|
93 EBadChunkType, |
|
94 EBadCodePos, |
|
95 EZeroLengthTextSupplied, |
|
96 EBadLineBreakRangeTable, |
|
97 ETextWidthBufferOverflow, |
|
98 ETextRunNotFound, |
|
99 EInvalidTextRunLength, |
|
100 EInvalidTextRunIndex, |
|
101 EUnimplemented, |
|
102 EParagraphFormatRequired, |
|
103 EIndexOutOfRange, |
|
104 EBadReturnValue, |
|
105 EBadPtrLen, |
|
106 EBadClusterBufLen, |
|
107 ENotImplemented |
|
108 }; |
|
109 |
|
110 /** |
|
111 @internalComponent |
|
112 */ |
|
113 static inline void TmPanic(TTmPanic aPanic) |
|
114 { |
|
115 _LIT(KTmPanic,"Tagma"); |
|
116 User::Panic(KTmPanic,aPanic); |
|
117 } |
|
118 |
|
119 /** |
|
120 Maximum size for text chunks, and hence the maximum size needed for buffers when measuring or drawing text. |
|
121 @internalComponent |
|
122 */ |
|
123 const TInt KMaxTextChunkSize = 128; |
|
124 |
|
125 class RTmTextCache; |
|
126 class CTmTextFontCache |
|
127 { |
|
128 public: |
|
129 static CTmTextFontCache* New(MGraphicsDeviceMap& aDevice, CFont& aFont); |
|
130 CFont& Font(); |
|
131 void Open(); |
|
132 void Close(); |
|
133 private: |
|
134 CTmTextFontCache(MGraphicsDeviceMap& aDevice, CFont& aFont); |
|
135 ~CTmTextFontCache(); |
|
136 TInt iRefCount; |
|
137 MGraphicsDeviceMap& iDevice; |
|
138 CFont& iFont; |
|
139 }; |
|
140 |
|
141 /** |
|
142 A class for caching text and formats extracted from a text source. |
|
143 That it is an R class shows that it must be closed after use; call Close(). |
|
144 @internalComponent |
|
145 */ |
|
146 class RTmTextCache |
|
147 { |
|
148 public: |
|
149 enum TDisplayedTextDirectionality |
|
150 { |
|
151 // For requesting left-to-right text whether logical or visual |
|
152 ELeftToRight = 0, |
|
153 // For requesting right-to-left text in visual order |
|
154 EVisualRightToLeft = 1, |
|
155 // For requesting right-to-left text in logical order |
|
156 ELogicalRightToLeft = 2 |
|
157 }; |
|
158 RTmTextCache(MTmSource& aSource,MGraphicsDeviceMap& aDevice): |
|
159 iSource(aSource), |
|
160 iDevice(aDevice), |
|
161 iDocumentLength(aSource.DocumentLength()), |
|
162 iText(NULL), |
|
163 iTextStart(-1), |
|
164 iTextLength(0), |
|
165 iFont(NULL), |
|
166 iContextCharPerChunk(NULL), |
|
167 iContextCharInByteCode(NULL) |
|
168 { |
|
169 } |
|
170 #ifdef _DEBUG |
|
171 ~RTmTextCache() { if (iFont) TmPanic(EInvariant); } |
|
172 #endif |
|
173 TInt AdvanceWidthL(TInt aStart, TInt aEnd, TBool aRightToLeft, |
|
174 TInt aMaxWidth = KMaxTInt, CFbsFont::TMeasureTextOutput* aOutput = 0, |
|
175 TInt aExtraChar = 0); |
|
176 TInt TotalWidthL(TInt aStart, TInt aEnd, TBool aRightToLeft); |
|
177 MTmSource& Source() { return iSource; } |
|
178 TInt GetText(TInt aPos,TInt aMaxEndChar,TPtrC& aText,TTmCharFormat* aFormat = NULL,CTmTextFontCache** aFont = NULL); |
|
179 TInt GetTextL(TInt aPos, TInt aMaxEndChar, TPtrC& aText, |
|
180 TTmCharFormat* aFormat = 0, CTmTextFontCache** aFont = 0); |
|
181 TInt GetDisplayedText(TInt aStart, TInt aEnd, |
|
182 TDisplayedTextDirectionality aDirectionality, TText* aBuffer,TUint aContextChar, |
|
183 TTmCharFormat* aFormat = 0, CTmTextFontCache** aFont = NULL); |
|
184 TUint Char(TInt aPos); |
|
185 const TTmCharFormat& Format() const { return iFormat; } |
|
186 MGraphicsDeviceMap& Device() { return iDevice; } |
|
187 void ReleaseFont() { if (iFont) { iFont->Close(); iFont = NULL; } } |
|
188 void Close() { ReleaseFont(); iTextBuffer.Close(); } |
|
189 |
|
190 TBool static IsArabicPoint(TInt aChar); |
|
191 void SetContextChar(TUint aContextChar); |
|
192 TUint GetContextChar() const { return iContextCharPerChunk; } |
|
193 TUint GetContextForByteCode() const { return iContextCharInByteCode; } |
|
194 private: |
|
195 MTmSource& iSource; // text source |
|
196 MGraphicsDeviceMap& iDevice; // device used for getting fonts |
|
197 TInt iDocumentLength; // length of the document, not including final paragraph delimiter if any |
|
198 const TText* iText; // current text |
|
199 TInt iTextStart; // start position of current text |
|
200 TInt iTextLength; // length of current text |
|
201 TTmCharFormat iFormat; // current text format |
|
202 CTmTextFontCache* iFont; // if non-null, current font |
|
203 RBuf iTextBuffer; // buffer for GetTextL (if appropriate) |
|
204 TInt iTextBufferStart; // start position of where iTextBuffer is copied from |
|
205 TBool iTextBufferEndsInFormatChange; |
|
206 // Context characters: These one character context data members are used by the rendering code in GDI |
|
207 // to render punctuation marks based on the context. The context here represents the script in which to render the punctuation. |
|
208 TUint iContextCharPerChunk; // One character of context stored temporarily to pass on to |
|
209 // the rendering code along with the text, and back to the TmChunk |
|
210 // object being rendered. See TmChunk::SetL() and RTmTextCache::AdvanceWidthL() |
|
211 TUint iContextCharInByteCode; // One character of context stored temporarily to pass on to |
|
212 // the TmChunk object after rendering the text with context, to be |
|
213 // put into the byte code. See TmChunk::SetL() and RTmTextCache::AdvanceWidthL() |
|
214 }; |
|
215 |
|
216 /** |
|
217 @internalComponent |
|
218 */ |
|
219 class TTmCodeReader |
|
220 |
|
221 { |
|
222 public: |
|
223 TTmCodeReader(const CTmCode& aCode,TInt aCodeStart,TInt aCodeEnd): |
|
224 iCode(aCode), iCodePos(aCodeStart), iCodeEndPos(aCodeEnd), |
|
225 iCodeSegPtr(NULL), iCodeSegEndPtr(NULL) { } |
|
226 const CTmCode& Code() const { return iCode; } |
|
227 TInt CodePos() const { return iCodePos; } |
|
228 TInt CodeEndPos() const { return iCodeEndPos; } |
|
229 TUint8 ReadByte() { if (iCodeSegPtr == iCodeSegEndPtr) SetCodePtr(); iCodePos++; return *iCodeSegPtr++; } |
|
230 TUint8 PeekByte() { if (iCodeSegPtr == iCodeSegEndPtr) SetCodePtr(); return *iCodeSegPtr; } |
|
231 int ReadNumber(); |
|
232 TRect ReadRect(); |
|
233 void SetCodePos(TInt aNewCodePos); |
|
234 |
|
235 private: |
|
236 void SetCodePtr(); |
|
237 |
|
238 const CTmCode& iCode; // the bytecode |
|
239 TInt iCodePos; // current index into the bytecode |
|
240 TInt iCodeEndPos; // index to the end of the bytecode being interpreted |
|
241 const TUint8* iCodeSegPtr; // pointer to the current position in the current bytecode segment |
|
242 const TUint8* iCodeSegEndPtr; // end of the current bytecode segment |
|
243 }; |
|
244 |
|
245 /** |
|
246 End-of-line information required for bidirectional reformatting. |
|
247 @internalComponent |
|
248 */ |
|
249 class TBidirectionalEndOfLineContext |
|
250 { |
|
251 public: |
|
252 TBidirectionalEndOfLineContext() { Reset(); } |
|
253 void Set(RTmTextCache& aText, TInt aStartPos); |
|
254 void Reset() |
|
255 { |
|
256 iFirstCategory = iFirstStrongCategory = TChar::EOtherNeutral; |
|
257 } |
|
258 void ExternalizeL(RWriteStream& aDest); |
|
259 void InternalizeL(RReadStream& aSource); |
|
260 TBool operator==(const TBidirectionalEndOfLineContext& aState) const |
|
261 { |
|
262 return iFirstCategory == aState.iFirstCategory |
|
263 && iFirstStrongCategory == aState.iFirstStrongCategory; |
|
264 } |
|
265 TChar::TBdCategory FirstCategory() const { return iFirstCategory; } |
|
266 TChar::TBdCategory FirstStrongCategory() { return iFirstStrongCategory; } |
|
267 private: |
|
268 TChar::TBdCategory iFirstCategory; |
|
269 TChar::TBdCategory iFirstStrongCategory; |
|
270 TInt iPositionOfLastStrongCategory; |
|
271 TInt iStartPosOfThisLine; |
|
272 }; |
|
273 |
|
274 /** |
|
275 Extended TBidirectionalState for most situations in Tagma. |
|
276 @internalComponent |
|
277 */ |
|
278 class TBidirectionalContext : public TBidirectionalState |
|
279 { |
|
280 public: |
|
281 TBidirectionalContext() {} |
|
282 void Reset() |
|
283 { |
|
284 TBidirectionalState::Reset(); |
|
285 iEndOfLine.Reset(); |
|
286 } |
|
287 void InternalizeL(RReadStream& aSource); |
|
288 void Set(const TBidirectionalState& aState, |
|
289 const TBidirectionalEndOfLineContext& aEndOfLine) |
|
290 { |
|
291 *static_cast<TBidirectionalState*>(this) = aState; |
|
292 iEndOfLine = aEndOfLine; |
|
293 } |
|
294 TBool operator==(const TBidirectionalContext& aState) const |
|
295 { |
|
296 return *static_cast<const TBidirectionalState*>(this) == aState |
|
297 && iEndOfLine == aState.iEndOfLine; |
|
298 } |
|
299 TBool ContextMatches(const TBidirectionalEndOfLineContext& aTest) |
|
300 { |
|
301 return aTest == iEndOfLine; |
|
302 } |
|
303 |
|
304 private: |
|
305 TBidirectionalEndOfLineContext iEndOfLine; |
|
306 }; |
|
307 |
|
308 /** |
|
309 @internalComponent |
|
310 */ |
|
311 void TmGetBorderWidth(const MGraphicsDeviceMap& aDevice,const RTmParFormat& aParFormat,RTmParFormat::TBorderIndex aSide, |
|
312 TInt& aSingle,TInt& aFull); |
|
313 void TmGetMarginsL(MGraphicsDeviceMap& aDevice,const RTmParFormat& aParFormat, |
|
314 TInt& aLeftMargin,TInt& aRightMargin, |
|
315 TInt& aFirstLineLeftMargin,TInt& aFirstLineRightMargin, |
|
316 TInt& aBulletMargin,TInt& aBulletWidth, |
|
317 TInt& aBulletAscent,TInt& aBulletDescent,CFont** aFont = NULL); |
|
318 void SubtractRect(const TRect& aP,const TRect& aQ,TRect* aR); |
|
319 |
|
320 #include "TMSTD.inl" |
|
321 |
|
322 #endif // __TMSTD_H__ |