|
1 /* |
|
2 * Copyright (c) 2006-2007 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: THuiFont implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <coemain.h> |
|
21 #include <w32std.h> |
|
22 #include <AknBidiTextUtils.h> |
|
23 #include <AknFontAccess.h> |
|
24 #include <AknLayoutFont.h> |
|
25 |
|
26 #include "uiacceltk/HuiFont.h" |
|
27 #include "uiacceltk/HuiUtil.h" |
|
28 |
|
29 const TInt KHuiFontVerticalShiftInPixels = 1; |
|
30 |
|
31 /** |
|
32 * Structure containing Symbian Font instance and reference count. |
|
33 */ |
|
34 NONSHARABLE_STRUCT( THuiFont::TFontRef ) |
|
35 { |
|
36 /** |
|
37 * Constructor. Initializes both member variables to zero. |
|
38 */ |
|
39 inline TFontRef(); |
|
40 |
|
41 /** Symbian Font instance. */ |
|
42 CFont* iFontInstance; |
|
43 /** Reference count */ |
|
44 TInt iRefCount; |
|
45 }; |
|
46 |
|
47 EXPORT_C THuiFont::THuiFont(TInt aId, const TFontSpec& aFontSpec) |
|
48 : iId(aId), iFontSpec(aFontSpec), iFont(NULL), iTextPaneHeight(0), iCategory(EAknFontCategoryUndefined) |
|
49 { |
|
50 } |
|
51 |
|
52 EXPORT_C THuiFont::THuiFont() |
|
53 : iId(0), iFont(NULL), iTextPaneHeight(0), iCategory(EAknFontCategoryUndefined) |
|
54 { |
|
55 } |
|
56 |
|
57 EXPORT_C THuiFont::~THuiFont() |
|
58 { |
|
59 ReleaseFont(); |
|
60 iFont = NULL; |
|
61 } |
|
62 |
|
63 EXPORT_C THuiFont::THuiFont( const THuiFont& aFont ) |
|
64 : iId( aFont.iId ), iFontSpec( aFont.iFontSpec ), iFont( aFont.iFont ), |
|
65 iTextPaneHeight( aFont.iTextPaneHeight ), iCategory( aFont.iCategory ) |
|
66 { |
|
67 if ( iFont ) |
|
68 { |
|
69 iFont->iRefCount++; |
|
70 } |
|
71 } |
|
72 |
|
73 EXPORT_C THuiFont& THuiFont::operator=( const THuiFont& aFont ) |
|
74 { |
|
75 if ( this == &aFont ) |
|
76 { |
|
77 return *this; |
|
78 } |
|
79 |
|
80 ReleaseFont(); |
|
81 |
|
82 iId = aFont.iId; |
|
83 iFontSpec = aFont.iFontSpec; |
|
84 iFont = aFont.iFont; |
|
85 if ( iFont ) |
|
86 { |
|
87 iFont->iRefCount++; |
|
88 } |
|
89 |
|
90 iTextPaneHeight = aFont.iTextPaneHeight; |
|
91 iCategory = aFont.iCategory; |
|
92 return *this; |
|
93 } |
|
94 |
|
95 |
|
96 EXPORT_C TInt THuiFont::Id() const |
|
97 { |
|
98 return iId; |
|
99 } |
|
100 |
|
101 |
|
102 EXPORT_C TAknFontCategory THuiFont::Category() const |
|
103 { |
|
104 return iCategory; |
|
105 } |
|
106 |
|
107 |
|
108 EXPORT_C void THuiFont::SetCategory(const TAknFontCategory aCategory) |
|
109 { |
|
110 iCategory = aCategory; |
|
111 ReleaseFont(); |
|
112 } |
|
113 |
|
114 EXPORT_C TInt THuiFont::TextPaneHeight() const |
|
115 { |
|
116 return iTextPaneHeight; |
|
117 } |
|
118 |
|
119 EXPORT_C void THuiFont::SetTextPaneHeight(TInt aTextPaneHeight) |
|
120 { |
|
121 iTextPaneHeight = aTextPaneHeight; |
|
122 ReleaseFont(); |
|
123 } |
|
124 |
|
125 EXPORT_C void THuiFont::SetFontSpec(const TFontSpec& aFontSpec) |
|
126 { |
|
127 iFontSpec = aFontSpec; |
|
128 ReleaseFont(); |
|
129 } |
|
130 |
|
131 |
|
132 EXPORT_C TFontSpec THuiFont::FontSpec(MGraphicsDeviceMap* /*aMap*/) const |
|
133 { |
|
134 // @Todo need to implement the zooming here |
|
135 return iFontSpec; |
|
136 } |
|
137 |
|
138 |
|
139 EXPORT_C CFont* THuiFont::NearestFontL(TReal32 aTextMeshYScale) __SOFTFP |
|
140 { |
|
141 /// @todo Accessing the screen device during a display resizing event may |
|
142 /// result in a font that is suitable for the display size that |
|
143 /// was in use prior to the resize. Probably we should use |
|
144 /// AknLayoutUtils here. |
|
145 |
|
146 if(!iFont) |
|
147 { |
|
148 CWsScreenDevice* screenDev = 0; |
|
149 if (CCoeEnv::Static()) |
|
150 { |
|
151 screenDev = CCoeEnv::Static()->ScreenDevice(); |
|
152 } |
|
153 else |
|
154 { |
|
155 screenDev = CHuiStatic::ScreenDevice(); |
|
156 } |
|
157 User::LeaveIfNull(screenDev); |
|
158 |
|
159 TFontSpec spec = iFontSpec; |
|
160 |
|
161 if(aTextMeshYScale != 1) |
|
162 { |
|
163 spec.iHeight = HUI_ROUND_FLOAT_TO_INT( TReal32(iFontSpec.iHeight) * aTextMeshYScale ); |
|
164 } |
|
165 |
|
166 TFontRef* font = new (ELeave) TFontRef; |
|
167 CleanupStack::PushL( font ); |
|
168 font->iRefCount++; |
|
169 |
|
170 if (!CCoeEnv::Static()) |
|
171 { |
|
172 _LIT(KS60Digital, "Series 60 ZDigi"); // we assume that only FPS counter uses texts inside hui |
|
173 spec = TFontSpec(KS60Digital, 150); |
|
174 User::LeaveIfError( screenDev->GetNearestFontInTwips(font->iFontInstance, spec) ); |
|
175 iTextPaneHeight = screenDev->VerticalTwipsToPixels(spec.iHeight); |
|
176 } |
|
177 else |
|
178 { |
|
179 TAknFontSpecification aknFs(Category(), spec, screenDev); |
|
180 aknFs.SetTextPaneHeight( screenDev->VerticalTwipsToPixels(spec.iHeight)); |
|
181 aknFs.SetTextPaneHeightIsDesignHeight( ETrue ); |
|
182 font->iFontInstance = |
|
183 AknFontAccess::CreateLayoutFontFromSpecificationL( |
|
184 *screenDev, |
|
185 spec.iTypeface, |
|
186 aknFs ); |
|
187 } |
|
188 CleanupStack::Pop( font ); |
|
189 iFont = font; |
|
190 } |
|
191 return iFont->iFontInstance; |
|
192 } |
|
193 |
|
194 |
|
195 EXPORT_C void THuiFont::RasterizeLineL(const TDesC& aTextString, CFbsBitGc& aTargetContext) |
|
196 { |
|
197 // Retrieve the CFont object used when rasterizing this text mesh. |
|
198 CFont* font = NearestFontL(); |
|
199 |
|
200 // Draw the text |
|
201 aTargetContext.UseFont(font); |
|
202 |
|
203 TInt avkonMaxAscent = 0; |
|
204 if (CCoeEnv::Static()) |
|
205 { |
|
206 const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( font ); |
|
207 avkonMaxAscent = layoutFont->MaxAscent() + KHuiFontVerticalShiftInPixels; |
|
208 } |
|
209 else |
|
210 { |
|
211 avkonMaxAscent = iTextPaneHeight; |
|
212 } |
|
213 aTargetContext.DrawText(aTextString, TPoint(0, avkonMaxAscent )); |
|
214 aTargetContext.DiscardFont(); |
|
215 } |
|
216 |
|
217 EXPORT_C TSize THuiFont::LineExtentsL(const TDesC& aTextString) |
|
218 { |
|
219 if (aTextString.Length() == 0) |
|
220 { |
|
221 // Zero length strings have extents of zero. |
|
222 return TSize(0, 0); |
|
223 } |
|
224 |
|
225 // Retrieve the CFont object used when rasterizing this text mesh. |
|
226 CFont* font = NearestFontL(); |
|
227 TSize textSize( MeasureBidiTextBoundsWidth(*font, aTextString, CFont::TMeasureTextInput::EFVisualOrder), |
|
228 font->FontMaxHeight()); |
|
229 |
|
230 const CAknLayoutFont* layoutFont = 0; |
|
231 if (CCoeEnv::Static()) |
|
232 { |
|
233 layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( font ); |
|
234 } |
|
235 |
|
236 if ( layoutFont ) |
|
237 { |
|
238 textSize.iHeight = font->HeightInPixels(); |
|
239 TInt textPaneHeight = layoutFont->TextPaneHeight(); |
|
240 TInt textPaneTopToBaseline = layoutFont->TextPaneTopToBaseline(); |
|
241 |
|
242 textSize.iHeight += textPaneHeight - textPaneTopToBaseline; |
|
243 textSize.iHeight += KHuiFontVerticalShiftInPixels; |
|
244 } |
|
245 else |
|
246 { |
|
247 textSize.iHeight = Max(textSize.iHeight, font->HeightInPixels()); |
|
248 textSize.iHeight += 3; // the best approximation - fails on big (>=72) fonts |
|
249 } |
|
250 |
|
251 // Return the calculated text size. |
|
252 return textSize; |
|
253 } |
|
254 |
|
255 TInt THuiFont::MeasureBidiTextBoundsWidth( |
|
256 const CFont& aFont, |
|
257 const TDesC& aText, |
|
258 CFont::TMeasureTextInput::TFlags aOrder) const |
|
259 { |
|
260 CFont::TMeasureTextInput input; |
|
261 input.iFlags = aOrder; |
|
262 CFont::TMeasureTextOutput output; |
|
263 |
|
264 TInt textAdvance = aFont.MeasureText( aText, &input, &output ); |
|
265 |
|
266 TRect bounds = output.iBounds; |
|
267 bounds.iTl.iX = Min(bounds.iTl.iX, 0); |
|
268 bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance); |
|
269 return bounds.Width(); |
|
270 } |
|
271 |
|
272 EXPORT_C void THuiFont::ReleaseFont() |
|
273 { |
|
274 if(iFont) |
|
275 { |
|
276 iFont->iRefCount--; |
|
277 if ( !iFont->iRefCount ) |
|
278 { |
|
279 // No more references to iFont instance, we can release |
|
280 // Symbian Font instance & delete TFontRef object. |
|
281 |
|
282 const CAknLayoutFont* layoutFont = 0; |
|
283 if (CCoeEnv::Static()) |
|
284 { |
|
285 layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( iFont->iFontInstance ); |
|
286 } |
|
287 |
|
288 if ( layoutFont ) |
|
289 { |
|
290 delete layoutFont; |
|
291 } |
|
292 else |
|
293 { |
|
294 CWsScreenDevice* screenDev = 0; |
|
295 if (CCoeEnv::Static()) |
|
296 { |
|
297 screenDev = CCoeEnv::Static()->ScreenDevice(); |
|
298 } |
|
299 else |
|
300 { |
|
301 screenDev = CHuiStatic::ScreenDevice(); |
|
302 } |
|
303 |
|
304 screenDev->ReleaseFont( iFont->iFontInstance ); |
|
305 } |
|
306 delete iFont; |
|
307 } |
|
308 iFont = NULL; |
|
309 } |
|
310 } |
|
311 |
|
312 // Implementation of THuiFont::TFontRef: |
|
313 |
|
314 inline THuiFont::TFontRef::TFontRef() |
|
315 : iFontInstance( NULL ), iRefCount( 0 ) |
|
316 { |
|
317 } |
|
318 |