First public contribution.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Contains client-side shaper functionality.
18 #include "ShapeImpl.h"
19 #include "ShapeInfo.h"
23 GLREF_C void Panic(TInt aError);
25 /** Construct an RShapeInfo. */
26 /** @internalComponent */
27 EXPORT_C RShapeInfo::RShapeInfo()
28 : iFont(0), iHeader(0), iEndOfShapedText(-1), iContextualProcessFunc(0) {}
30 /** Perform shaping on the text in aText between aStartOfTextToShape and
31 aEndOfTextToShape, based on the script conventions implied by aScriptCode.
32 @param aFont The font to use for the shaping.
33 @param aText The text, including context.
34 @param aStartOfTextToShape
35 The start position within aText of the text to be shaped.
36 @param aEndOfTextToShape
37 The end position within aText of the text to be shaped.
38 @param aScriptCode The script code for the script being shaped.
39 @param aLanguageCode The language code for the language being shaped.
41 KErrNone if the text was successfully shaped, KErrNotSupported if aFont has
42 no shaper, KErrCouldNotConnect if the font bitmap server has not been
45 TInt RShapeInfo::Open(const CFont* aFont, const TDesC& aText,
46 TInt aStartOfTextToShape, TInt aEndOfTextToShape,
47 TInt aScriptCode, TInt aLanguageCode)
49 GDI_ASSERT_DEBUG(0 <= aStartOfTextToShape,
50 EGdiPanic_InvalidInputParam);
51 GDI_ASSERT_DEBUG(aStartOfTextToShape <= aEndOfTextToShape,
52 EGdiPanic_InvalidInputParam);
53 GDI_ASSERT_DEBUG(aEndOfTextToShape <= aText.Length(),
54 EGdiPanic_InvalidInputParam);
56 TFontShapeFunctionParameters param;
58 param.iStart = aStartOfTextToShape;
59 param.iEnd = aEndOfTextToShape;
60 param.iScript = aScriptCode;
61 param.iLanguage = aLanguageCode;
62 const TInt r = aFont->ExtendedFunction(KFontGetShaping, ¶m);
63 iHeader = r == KErrNone ? param.iShapeHeaderOutput : 0;
65 iEndOfShapedText = aEndOfTextToShape;
69 /** Frees the memory associated with this shaping information. */
70 /** @internalComponent */
71 EXPORT_C void RShapeInfo::Close()
75 TFontShapeDeleteFunctionParameters param;
76 param.iShapeHeader = iHeader;
77 iFont->ExtendedFunction(KFontDeleteShaping, ¶m);
79 iEndOfShapedText = -1;
80 // We don't reset iSingleContextChar because we want the context to remain throughout,
81 // even when the session is closed. It would eventually simply go out of scope.
85 /** Returns the number of glyphs in the shaped output.
86 @return The number of glyphs. Also equal to the size of the Glyphs() array and
87 the GlyphPositions() array. */
88 TInt RShapeInfo::GlyphCount() const
90 GDI_ASSERT_ALWAYS(iHeader, EGdiPanic_Invariant);
91 return iHeader->iGlyphCount;
94 /** Returns the array of glyphs. These must be ORed with 0x80000000 to make
95 glyph numbers that functions like CFbsFont::Rasterize can accept to avoid
96 confusing glyph numbers with Unicode character numbers.
97 @return The glyph array. The size of this array is RShapeInfo::GlyphCount
99 const TInt32* RShapeInfo::Glyphs() const
101 GDI_ASSERT_ALWAYS(iHeader, EGdiPanic_Invariant);
102 return reinterpret_cast<const TInt32*>(iHeader->iBuffer);
105 /** Returns the array of positions for the glyphs returned by Glyphs, and the
106 total advance for the text.
108 Array of glyph positions in pixels, relative to the pen position before
109 the glyphs are drawn. The array has GlyphCount() + 1 entries, as the
110 last entry represents the total advance of the text. */
111 const RShapeInfo::TPoint16* RShapeInfo::GlyphPositions() const
113 GDI_ASSERT_ALWAYS(iHeader, EGdiPanic_Invariant);
114 return reinterpret_cast<const RShapeInfo::TPoint16*>(iHeader->iBuffer
115 + ((iHeader->iGlyphCount) << 2));
118 /** Returns the pen advance these glyphs require.
119 @return The pen advance; where to move the pen after drawing all the glyphs. */
120 RShapeInfo::TPoint16 RShapeInfo::Advance() const
122 GDI_ASSERT_ALWAYS(iHeader, EGdiPanic_Invariant);
123 RShapeInfo::TPoint16 r;
124 r.iX = *reinterpret_cast<const TInt16*>(iHeader->iBuffer
125 + (iHeader->iGlyphCount << 3));
126 r.iY = *reinterpret_cast<const TInt16*>(iHeader->iBuffer
127 + (iHeader->iGlyphCount << 3) + 2);
131 /** Returns the array of indices.
133 Indices[n] is the position in the input text that produced Glyphs[n].
135 const TInt16* RShapeInfo::Indices() const
137 GDI_ASSERT_ALWAYS(iHeader, EGdiPanic_Invariant);
138 return reinterpret_cast<const TInt16*>(iHeader->iBuffer
139 + (iHeader->iGlyphCount << 3) + 4);
142 TInt RShapeInfo::EndOfShapedText()
144 return iEndOfShapedText;
147 /** Checks if this shaping information is still occupying memory. */
148 EXPORT_C TBool RShapeInfo::IsOpen()
150 if(iHeader && iHeader->iGlyphCount >= 0 && iHeader->iCharacterCount >=0)
157 void RShapeInfo::SetContext(TAny* aContextualProcessFunc)
159 iContextualProcessFunc = aContextualProcessFunc;
162 TAny* RShapeInfo::GetContext()
164 return iContextualProcessFunc;