diff -r 000000000000 -r 05e9090e2422 layouts/aknlayout2/src/AknLayout2Scalable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layouts/aknlayout2/src/AknLayout2Scalable.cpp Thu Dec 17 09:14:12 2009 +0200 @@ -0,0 +1,1893 @@ +/* +* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "AknLayout2ScalableDataDef.h" +#include "AknLayout2ScalableDef.h" +#include +#include + + +#define AKNLAYOUT_DEFINE_BYTECODE(name,byte) const TUint8 name = byte; +#include "AknLayoutByteCodes.h" + +// in the simple case, numCols and numRows are missing +const TInt KNumCellsNotSimple = 2; + +// first two cells are numCols and numRows +const TInt KNumCellsWindow = 7; +const TInt KNumCellsText = 9; + +// this is the total possible number +const TInt KNumCells = 11; + +#ifndef EKA2 +GLDEF_C TInt E32Dll(TDllReason) + { + return KErrNone; + } +#endif + +// +// Panic +// + +enum TLayoutScalablePanic + { + ENegativeOffset, + EOffsetOutOfRange, + EIllegalLineIndex, + EMultiLineOffsetOutOfRange, + EParameterOutOfRange, + EWrongType + }; + +void Panic(TLayoutScalablePanic aCode) + { + _LIT(KLayoutPanic, "Layout panic"); + User::Panic(KLayoutPanic, aCode); + } + + +// +// Helpers +// + +TInt16 Max(TInt16 aValue1, TInt16 aValue2) + { + if (aValue1 > aValue2) return aValue1; + return aValue2; + } +TInt16 MinusInt(TInt16 aValue1, TInt16 aValue2) + { + return TInt16(aValue1 - aValue2); + } + +TBool IsParentRelative(TInt aVal) + { + return aVal > ELayoutP-ELayoutPRange && aVal <= ELayoutP; + } + +struct TAknTextComponentLayoutAttrs + { + TInt32 iFontId; + TInt16 iJustification; + }; + +TAknTextComponentLayoutAttrs ExtractAttributes(TAknTextComponentLayout aText) + { + TAknTextComponentLayoutAttrs attrs; + attrs.iFontId = aText.Font(); + attrs.iJustification = aText.J(); + return attrs; + } + +TAknWindowComponentLayout TAknWindowComponentLayout::ExtractWindow(TAknTextComponentLayout aText) + { + TAknWindowComponentLayout layout; + layout.Setl(aText.l()); + layout.Sett(aText.t()); + layout.SetW(aText.W()); + layout.SetH(aText.H()); + layout.Setb(aText.b()); + layout.Setr(aText.r()); + + layout.SetC(aText.C()); // colour is separate. + return layout; + } + +TAknTextComponentLayout TAknWindowComponentLayout::CombineAttrs(TAknWindowComponentLayout aLine1, const TAknTextComponentLayoutAttrs &aAttrs) + { + TAknTextComponentLayout layout; + layout.Setl(aLine1.l()); + layout.Sett(aLine1.t()); + layout.SetW(aLine1.W()); + layout.SetH(aLine1.H()); + layout.Setb(aLine1.b()); + layout.Setr(aLine1.r()); + layout.SetC(aLine1.C()); + layout.SetJ(aAttrs.iJustification); + layout.SetFont(aAttrs.iFontId); + return layout; + } + +struct TAknWindowComponentLayoutAttrs + { + TInt16 iGap; + }; + +TAknWindowComponentLayout TAknWindowComponentLayout::RemoveLayoutEmptys(TAknWindowComponentLayout aLine1) + { + if (aLine1.r() == ELayoutEmpty) + { + aLine1.Setr( TInt16(ELayoutP - aLine1.W() - aLine1.l())); + } + if (aLine1.b() == ELayoutEmpty) + { + aLine1.Setb(TInt16(ELayoutP - aLine1.H() - aLine1.t())); + } + + if (aLine1.l() == ELayoutEmpty) + { + aLine1.Setl(TInt16(ELayoutP - aLine1.W() - aLine1.r())); + } + if (aLine1.t() == ELayoutEmpty) + { + aLine1.Sett(TInt16(ELayoutP - aLine1.H() - aLine1.b())); + } + if (aLine1.W() == ELayoutEmpty) + { + aLine1.SetW(TInt16(ELayoutP - aLine1.l() - aLine1.r())); + } + if (aLine1.H() == ELayoutEmpty) + { + aLine1.SetH(TInt16(ELayoutP - aLine1.t() - aLine1.b())); + } +#if defined (_DEBUG) + TBool noerror1 = aLine1.il + aLine1.iW + aLine1.ir == ELayoutP; + TBool noerror2 = aLine1.it + aLine1.iH + aLine1.ib == ELayoutP; + if (!noerror1 || !noerror2) + { + noerror1 = noerror1; // good place for breakpoint. + } +/* + __ASSERT_DEBUG(noerror1, Panic(EInvalidLayoutData)); + __ASSERT_DEBUG(noerror2, Panic(EInvalidLayoutData)); + +*/ +#endif + + return aLine1; + } + +EXPORT_C TAknTextComponentLayout TAknTextComponentLayout::RemoveLayoutEmptys(TAknTextComponentLayout aLine1) + { + if (aLine1.r() == ELayoutEmpty) + { + aLine1.Setr( TInt16(ELayoutP - aLine1.W() - aLine1.l())); + } + if (aLine1.b() == ELayoutEmpty) + { + aLine1.Setb(TInt16(ELayoutP - aLine1.H() - aLine1.t())); + } + + if (aLine1.l() == ELayoutEmpty) + { + aLine1.Setl(TInt16(ELayoutP - aLine1.W() - aLine1.r())); + } + if (aLine1.t() == ELayoutEmpty) + { + aLine1.Sett(TInt16(ELayoutP - aLine1.H() - aLine1.b())); + } + if (aLine1.W() == ELayoutEmpty) + { + aLine1.SetW(TInt16(ELayoutP - aLine1.l() - aLine1.r())); + } + if (aLine1.H() == ELayoutEmpty) + { + aLine1.SetH(TInt16(ELayoutP - aLine1.t() - aLine1.b())); + } + + + return aLine1; + + } + + +// +// class TAknLayoutScalableTableLimits +// + +EXPORT_C TAknLayoutScalableTableLimits::TAknLayoutScalableTableLimits(TInt aFirstIndex, TInt aLastIndex) + : + iFirstIndex(aFirstIndex), + iLastIndex(aLastIndex) + { + + } + +EXPORT_C TAknLayoutScalableTableLimits::TAknLayoutScalableTableLimits() + { + + } + +EXPORT_C TAknLayoutTableLimits TAknLayoutScalableTableLimits::LayoutLimits() const + { + TAknLayoutTableLimits limits; + limits.iFirstIndex = iFirstIndex; + limits.iLastIndex = iLastIndex; + return limits; + } + +EXPORT_C TInt TAknLayoutScalableTableLimits::FirstIndex() const + { + return iFirstIndex; + } + +EXPORT_C TInt TAknLayoutScalableTableLimits::LastIndex() const + { + return iLastIndex; + } + +EXPORT_C void TAknLayoutScalableTableLimits::SetFirstIndex(TInt aIndex) + { + iFirstIndex = aIndex; + } + +EXPORT_C void TAknLayoutScalableTableLimits::SetLastIndex(TInt aIndex) + { + iLastIndex = aIndex; + } + +// +// class TAknLayoutScalableParameterLimits +// + +EXPORT_C TAknLayoutScalableParameterLimits::TAknLayoutScalableParameterLimits() + : + iFirstVariety(0), iLastVariety(0), + iFirstColumn(0), iLastColumn(0), + iFirstRow(0), iLastRow(0) + { + + } + +EXPORT_C TAknLayoutScalableParameterLimits::TAknLayoutScalableParameterLimits( + TInt aFirstVariety, TInt aLastVariety, + TInt aFirstColumn, TInt aLastColumn, + TInt aFirstRow, TInt aLastRow) + : + iFirstVariety(aFirstVariety), iLastVariety(aLastVariety), + iFirstColumn(aFirstColumn), iLastColumn(aLastColumn), + iFirstRow(aFirstRow), iLastRow(aLastRow) + { + + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::FirstVariety() const + { + return iFirstVariety; + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::LastVariety() const + { + return iLastVariety; + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::FirstColumn() const + { + return iFirstColumn; + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::LastColumn() const + { + return iLastColumn; + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::FirstRow() const + { + return iFirstRow; + } + +EXPORT_C TInt TAknLayoutScalableParameterLimits::LastRow() const + { + return iLastRow; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetFirstVariety(TInt aFirstVariety) + { + iFirstVariety = aFirstVariety; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetLastVariety(TInt aLastVariety) + { + iLastVariety = aLastVariety; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetFirstColumn(TInt aFirstColumn) + { + iFirstColumn = aFirstColumn; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetLastColumn(TInt aLastColumn) + { + iLastColumn = aLastColumn; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetFirstRow(TInt aFirstRow) + { + iFirstRow = aFirstRow; + } + +EXPORT_C void TAknLayoutScalableParameterLimits::SetLastRow(TInt aLastRow) + { + iLastRow = aLastRow; + } + + + + +// +// class TAknWindowComponentLayout +// + +EXPORT_C TAknWindowComponentLayout::TAknWindowComponentLayout() + : + iC(ELayoutEmpty), + il(0), + it(0), + ir(0), + ib(0), + iW(ELayoutEmpty), + iH(ELayoutEmpty) + { + + } + +EXPORT_C TAknWindowLineLayout TAknWindowComponentLayout::LayoutLine() const + { + TAknWindowLineLayout line; + line.iC = iC; + line.il = il; + line.it = it; + line.ir = ir; + line.ib = ib; + line.iW = iW; + line.iH = iH; + + // Swap parent relative and empty based on equation l+W+r = p.W + TInt16 *empty = NULL; + if (line.il == ELayoutEmpty) empty = &line.il; + if (line.iW == ELayoutEmpty) empty = &line.iW; + if (line.ir == ELayoutEmpty) empty = &line.ir; + + TInt16 *parentRelative = NULL; + if (IsParentRelative(line.il)) parentRelative = &line.il; + if (IsParentRelative(line.iW)) parentRelative = &line.iW; + if (IsParentRelative(line.ir)) parentRelative = &line.ir; + + TInt16 *number = NULL; + if (&line.il != empty && (&line.il) != parentRelative) number=&line.il; + if (&line.iW != empty && (&line.iW) != parentRelative) number=&line.iW; + if (&line.ir != empty && (&line.ir) != parentRelative) number=&line.ir; + + if (empty && parentRelative && number) + { + *empty = TInt16(ELayoutP - *parentRelative - *number); + *parentRelative = ELayoutEmpty; + } + + // Swap parent relative and empty based on equation t+H+b = p.H + empty = NULL; + if (line.it == ELayoutEmpty) empty = &line.it; + if (line.iH == ELayoutEmpty) empty = &line.iH; + if (line.ib == ELayoutEmpty) empty = &line.ib; + + parentRelative = NULL; + if (IsParentRelative(line.it)) parentRelative = &line.it; + if (IsParentRelative(line.iH)) parentRelative = &line.iH; + if (IsParentRelative(line.ib)) parentRelative = &line.ib; + + number = NULL; + if (&line.it != empty && (&line.it) != parentRelative) number=&line.it; + if (&line.iH != empty && (&line.iH) != parentRelative) number=&line.iH; + if (&line.ib != empty && (&line.ib) != parentRelative) number=&line.ib; + + if (empty && parentRelative && number) + { + *empty = TInt16(ELayoutP - *parentRelative - *number); + *parentRelative = ELayoutEmpty; + } + + + + return line; + } + +EXPORT_C TAknWindowLineLayout TAknWindowComponentLayout::LayoutLineNoEmptys() const + { + TAknWindowLineLayout line; + line.iC = iC; + line.il = (il == ELayoutEmpty) ? TInt16(ELayoutP - iW - ir) : il; + line.it = (it == ELayoutEmpty) ? TInt16(ELayoutP - iH - ib) : it; + line.ir = (ir == ELayoutEmpty) ? TInt16(ELayoutP - iW - il) : ir; + line.ib = (ib == ELayoutEmpty) ? TInt16(ELayoutP - iH - it) : ib; + line.iW = (iW == ELayoutEmpty) ? TInt16(ELayoutP - il - ir) : iW; + line.iH = (iH == ELayoutEmpty) ? TInt16(ELayoutP - it - ib) : iH; + return line; + } + +EXPORT_C TAknLayoutScalableComponentType TAknWindowComponentLayout::LayoutComponentType() const + { + TAknLayoutScalableComponentType type = (TAknLayoutScalableComponentType)iType; + return type; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::C() const + { + return iC; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::l() const + { + return il; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::t() const + { + return it; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::r() const + { + return ir; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::b() const + { + return ib; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::W() const + { + return iW; + } + +EXPORT_C TInt16 TAknWindowComponentLayout::H() const + { + return iH; + } + +EXPORT_C void TAknWindowComponentLayout::SetC(TInt16 aC) + { + iC = aC; + } + +EXPORT_C void TAknWindowComponentLayout::Setl(TInt16 al) + { + il = al; + } + +EXPORT_C void TAknWindowComponentLayout::Sett(TInt16 at) + { + it = at; + } + +EXPORT_C void TAknWindowComponentLayout::Setr(TInt16 ar) + { + ir = ar; + } + +EXPORT_C void TAknWindowComponentLayout::Setb(TInt16 ab) + { + ib = ab; + } + +EXPORT_C void TAknWindowComponentLayout::SetW(TInt16 aW) + { + iW = aW; + } + +EXPORT_C void TAknWindowComponentLayout::SetH(TInt16 aH) + { + iH = aH; + } + + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::Compose(TAknWindowComponentLayout aLine1, TAknWindowComponentLayout aLine2) + { + if (aLine1.r() == ELayoutEmpty) + { + aLine1.Setr( TInt16(ELayoutP - aLine1.W() - aLine1.l())); + } + if (aLine1.b() == ELayoutEmpty) + { + aLine1.Setb(TInt16(ELayoutP - aLine1.H() - aLine1.t())); + } + + if (aLine1.l() == ELayoutEmpty) + { + aLine1.Setl(TInt16(ELayoutP - aLine1.W() - aLine1.r())); + } + if (aLine1.t() == ELayoutEmpty) + { + aLine1.Sett(TInt16(ELayoutP - aLine1.H() - aLine1.b())); + } + + + if (aLine2.r() == ELayoutEmpty) + { + aLine2.Setr(TInt16(ELayoutP /*-p2Xdiff*/ - aLine2.W() - aLine2.l())); + } + if (aLine2.b() == ELayoutEmpty) + { + aLine2.Setb(TInt16(ELayoutP /*-p2Ydiff*/ - aLine2.H() - aLine2.t())); + } + + if (aLine2.l() == ELayoutEmpty) + { + aLine2.Setl(TInt16(ELayoutP /*-p2Xdiff*/ - aLine2.W()- aLine2.r())); + } + if (aLine2.t() == ELayoutEmpty) + { + aLine2.Sett(TInt16(ELayoutP /*-p2Ydiff*/ - aLine2.H() - aLine2.b())); + } +#if defined(_DEBUG) + // these are only in debug build, because the rest of the Compose() does not need W and H; so this should have no effect. + if (aLine1.W() == ELayoutEmpty) + { + aLine1.SetW(TInt16(ELayoutP - aLine1.l() - aLine1.r()) ); + } + if (aLine1.H() == ELayoutEmpty) + { + aLine1.SetH(TInt16(ELayoutP - aLine1.t() - aLine1.b()) ); + } + if (aLine2.W() == ELayoutEmpty) + { + aLine2.SetW(TInt16(ELayoutP - aLine2.l() - aLine2.r()) ); + } + if (aLine2.H() == ELayoutEmpty) + { + aLine2.SetH(TInt16(ELayoutP - aLine2.t() - aLine2.b()) ); + } + TBool noerror1 = aLine1.il + aLine1.iW + aLine1.ir == ELayoutP; + TBool noerror2 = aLine1.it + aLine1.iH + aLine1.ib == ELayoutP; + TBool noerror3 = aLine2.il + aLine2.iW + aLine2.ir == ELayoutP; + TBool noerror4 = aLine2.it + aLine2.iH + aLine2.ib == ELayoutP; + if (!noerror1 || !noerror2 || !noerror3 || !noerror4) + { + noerror1 = noerror1; // good place for breakpoint. + } +/* + __ASSERT_DEBUG(noerror1, Panic(EInvalidLayoutData)); + __ASSERT_DEBUG(noerror2, Panic(EInvalidLayoutData)); + + __ASSERT_DEBUG(noerror3, Panic(EInvalidLayoutData)); + __ASSERT_DEBUG(noerror4, Panic(EInvalidLayoutData)); +*/ +#endif + + // Upgrade all p-XX type expressions, these are only for aLine2. Parent of aLine2 is different + // from aLine1's parent, so we need to do conversion from parent of aLine2 to parent of aLine1 + if (IsParentRelative(aLine2.r())) + { + TInt p2Xdiff = aLine1.l() + aLine1.r(); + aLine2.Setr(TInt16(aLine2.r() - p2Xdiff)); + } + if (IsParentRelative(aLine2.b())) + { + TInt p2Ydiff = aLine1.t() + aLine1.b(); + aLine2.Setb(TInt16(aLine2.b() - p2Ydiff)); + } + if (IsParentRelative(aLine2.l())) + { + TInt p2Xdiff = aLine1.l() + aLine1.r(); + aLine2.Setl(TInt16(aLine2.l() - p2Xdiff)); + } + if (IsParentRelative(aLine2.t())) + { + TInt p2Ydiff = aLine1.t() + aLine1.b(); + aLine2.Sett(TInt16(aLine2.t() - p2Ydiff)); + } + + if (IsParentRelative(aLine1.r()) && IsParentRelative(aLine2.r())) + { + aLine1.Setr(TInt16(aLine1.r() - ELayoutP)); + } + if (IsParentRelative(aLine1.b()) && IsParentRelative(aLine2.b())) + { + aLine1.Setb(TInt16(aLine1.b() - ELayoutP)); + } + + // It might be possible that here we need parent relative checks for t and l too. + // We might need to do some changes to allow multiply() to work, for example ELayoutEmpty's + // need to handle the p-values. (i.e. r == ElayoutEmpty -check doesnt work anymore etc) + + TAknWindowComponentLayout result; + result.Setl(TInt16(aLine1.l() + aLine2.l())); + result.Sett(TInt16(aLine1.t() + aLine2.t())); + result.Setr(TInt16(aLine1.r() + aLine2.r())); + result.Setb(TInt16(aLine1.b() + aLine2.b())); + result.SetW(ELayoutEmpty); + result.SetH(ELayoutEmpty); + result.SetC(aLine2.C()); + return result; + } + + +TBool IsValueEmpty(TInt aValue) +{ + return aValue >= ELayoutEmpty && aValue < (ELayoutEmpty +8192); + } +//TReal FromEmptyToDividingFloat(TInt aValue) +//{ +//} +//TReal MultiplyRealAndReal(TReal aReal, TReal aReal2) +//{ +// return aReal * aReal2; +//} + +//TInt MultiplyIntAndReal(TInt aValue, TReal aReal) +//{ +// return aValue * aReal; +//} +/* +class TScaledInt +{ +public: + TScaledInt(TInt16 aValue) : iValue(aValue) { } + + friend inline TScaledInt operator*(TScaledInt aValue, TScaledInt aValue2) + { + return TInt16( (TInt32(aValue.Value()) * TInt32(aValue2.Value())) >> 12 ); + } + + friend TInt16 MultiplyByScaled(TInt16 aValue, TScaledInt aValue2) + { + return TInt16( TInt32(aValue) * TInt32(aValue2.Value()) ); + } + + TInt16 Value() { return iValue; } + +private: + TInt16 iValue; +}; +*/ +/* +struct TTriplet + { + TScaledInt iX; + TScaledInt iY; + TScaledInt iP; + }; +*/ + TAknWindowComponentLayout::TTriplet::TTriplet(TInt16 aX, TInt16 aY, TInt16 aP) +: iX(aX), iY(aY), iP(aP) { } + TAknWindowComponentLayout::TTriplet::TTriplet(const TTriplet &aValue) +: iX(aValue.iX), iY(aValue.iY), iP(aValue.iP) + { + } + +TInt16 AddEmptyFlag(TInt16 aValue) { return (TInt16)(aValue + ELayoutEmpty); } +TInt16 RemoveEmptyFlag(TInt16 aValue) { return (TInt16)(aValue - ELayoutEmpty); } + +TInt16 AddPFlag(TInt16 aValue) { return (TInt16)(aValue + ELayoutP); } +TInt16 RemovePFlag(TInt16 aValue) { return (TInt16)(aValue - ELayoutP); } + + +TInt16 TAknWindowComponentLayout::MultiplyValue(TInt16 aValue, TAknWindowComponentLayout::TScaledInt aMultiplier, TAknWindowComponentLayout::TScaledInt aPMultiplier) + { + TInt16 result; + if (IsValueEmpty(aValue)) + { + // remove ELayoutEmpty flag from aValue + TInt16 newval = RemoveEmptyFlag(aValue); + + // Multiply aValue by aPMultiplier (aValue is scaled integer). + TAknWindowComponentLayout::TScaledInt sval(newval); + TAknWindowComponentLayout::TScaledInt res = sval * aPMultiplier; + + result = AddEmptyFlag((TInt16)res.Value()); + // add ELayoutEmpty flag + // done + } + else if (!IsParentRelative(aValue)) + { // normal values + // Multiply aValue by aMultiplier + result = MultiplyByScaled(aValue, aMultiplier).NonScaled(); + } + else + { // parent-relative values + // remove ELayoutP flag + TInt16 newval = RemovePFlag(aValue); + + // multiply aValue by aMultiplier + TInt16 res = MultiplyByScaled(newval, aMultiplier).NonScaled(); + + // add ELayoutP flag + result = AddPFlag(res); + // done + } + return result; + } + +// Multiply requires the following representation for TAknWindowComponentLayout: +// 1) There are 3 dimensions in each TAknWindowComponentLayout: +// a) X-dimension (l,W,r) +// b) Y-dimension (t,H,b) +// c) P-dimension p-XX expressions +// 2) In each empty cell, there are "value" for P encoded as a scaled int from 0.0 .. 1.0 +// 3) In each P-cell there are value encoding "p-10" expressions as a ELayoutP flag together with value 10. + +TAknWindowComponentLayout TAknWindowComponentLayout::Multiply(TAknWindowComponentLayout aLine, const TTriplet &aTriplet) + { + aLine = RemoveLayoutEmptys(aLine); + aLine.iW = ELayoutEmpty; + aLine.iH = ELayoutEmpty; + TAknWindowComponentLayout layout; + // multiply l,W,r by iX + layout.il = MultiplyValue(aLine.il, aTriplet.iX, aTriplet.iP); + layout.iW = MultiplyValue(aLine.iW, aTriplet.iX, aTriplet.iP); + layout.ir = MultiplyValue(aLine.ir, aTriplet.iX, aTriplet.iP); + + // multiply t,H,b by iY + layout.it = MultiplyValue(aLine.it, aTriplet.iY, aTriplet.iP); + layout.iH = MultiplyValue(aLine.iH, aTriplet.iY, aTriplet.iP); + layout.ib = MultiplyValue(aLine.ib, aTriplet.iY, aTriplet.iP); + + layout.iC = aLine.iC; + + // multiply p by iP + // nothing to be done, since MultiplyValue handles P-values. + + // REQUIRES THAT LAYOUT LINES HAVE ALWAYS ONE EMPTY CELL in l,W,r and in t,H,b + return layout; + } +/* +struct TRangeTriplet +{ + TInt16 iX; // 0.0 .. 1.0 + TInt16 iY; // 0.0 .. 1.0 + TInt16 iP; +}; +*/ +TAknWindowComponentLayout::TRangeTriplet OneMinus(TAknWindowComponentLayout::TRangeTriplet aValue) +{ + TAknWindowComponentLayout::TRangeTriplet triplet; + triplet.iX = (TInt16) ((1 << 12) - aValue.iX); + triplet.iY = (TInt16) ((1 << 12) - aValue.iY); + triplet.iP = (TInt16) ((1 << 12) - aValue.iP); + return triplet; +} +TAknWindowComponentLayout::TTriplet TAknWindowComponentLayout::FromRangeToTriplet(const TRangeTriplet &aRange) + { + TTriplet triplet(aRange.iX, aRange.iY, aRange.iP); + return triplet; + } + +/* +TRangeTriplet TripletFromPath(TPathDefinition aPath, TReal aPos) + { + + } +*/ + +TBool HasParentRelative(TInt alt, TInt aWH, TInt arb) + { + if (IsParentRelative(alt)) return ETrue; + if (IsParentRelative(aWH)) return ETrue; + if (IsParentRelative(arb)) return ETrue; + return EFalse; + } + +EXPORT_C TAknTextComponentLayout TAknTextComponentLayout::Anim(TAknTextComponentLayout aLine, + TAknTextComponentLayout aLine2, + const TAknWindowComponentLayout::TRangeTriplet &aTriplet) +{ + TAknTextComponentLayoutAttrs attrs = ExtractAttributes(aLine); + TAknWindowComponentLayout window1 = TAknWindowComponentLayout::ExtractWindow(aLine); + TAknWindowComponentLayout window2 = TAknWindowComponentLayout::ExtractWindow(aLine2); + TAknWindowComponentLayout animated = TAknWindowComponentLayout::Anim(window1, window2, aTriplet); + TAknTextComponentLayout text = TAknWindowComponentLayout::CombineAttrs(animated, attrs); + return text; +} + +// Layout animation should be something like this: +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::Anim(TAknWindowComponentLayout aLine, + TAknWindowComponentLayout aLine2, + const TRangeTriplet &aTriplet) +{ + TTriplet triplet(FromRangeToTriplet(aTriplet)); + TTriplet oneminustriplet(FromRangeToTriplet(OneMinus(aTriplet))); + TAknWindowComponentLayout m1 = Multiply(aLine, triplet); + TAknWindowComponentLayout m2 = Multiply(aLine2, oneminustriplet); + TAknWindowComponentLayout c = Compose(m1, m2); + + // the code below assumes that Compose() returns ELayoutEmpty as W and H. + + // X-dimension + if (HasParentRelative(m1.il, m1.iW, m1.ir) && + !HasParentRelative(m2.il, m2.iW, m2.ir)) + { + c.iW = (TInt16)(ELayoutEmpty + TInt16(triplet.iX.Value())); + } + if (!HasParentRelative(m1.il, m1.iW, m1.ir) && + HasParentRelative(m2.il, m2.iW, m2.ir)) + { + c.iW = (TInt16)(ELayoutEmpty + TInt16(oneminustriplet.iX.Value())); + } + + // Y-dimension + if (HasParentRelative(m1.it, m1.iH, m1.ib) && + !HasParentRelative(m2.it, m2.iH, m2.ib)) + { + c.iH = (TInt16)(ELayoutEmpty + TInt16(triplet.iY.Value())); + } + if (!HasParentRelative(m1.it, m1.iH, m1.ib) && + HasParentRelative(m2.it, m2.iH, m2.ib)) + { + c.iH = (TInt16)(ELayoutEmpty + TInt16(oneminustriplet.iY.Value())); + } + + // NOTE, to really make this work, AknLayoutUtils need to handle the ELayoutEmpty + triplet.iX in the following way: + /* + TInt FindMultiplier(TInt alt, TInt aWH, TInt arb) + { + TInt mult = 4096; + if (alt == ELayoutEmpty || aWH == ELayoutEmpty || arb == ELayoutEmpty) { return mult; } + if (IsValueEmpty(alt)) { mult = RemoveEmptyFlag(alt); } + if (IsValueEmpty(aWH)) { mult = RemoveEmptyFlag(aWH); } + if (IsValueEmpty(arb)) { mult = RemoveEmptyFlag(arb); } + return mult; + } + TInt MultiplyParent(TInt parent, TInt alt, TInt awh, TInt arb) + { + TInt16 multiplier = FindMultiplier(ilt,iWH,irb); + parent = MultiplyByScaled(parent, multiplier).NonScaled(); + return parent; + } + ... inside AknLayoutUtils (or RectFromCoords() method actually), need to put the following: + if (IsParentRelative(il)) { + TInt parent = aParent.Width(); + parent = MultiplyParent(parent, il, iW, ir); + il = il + parent - ELayoutP; + } + */ + // Or something like that. (and that for all the components il, it, ir, ib, iW, iH.) + // BUT, This is really quite complicated thing to do as we would need to do the same + // for TEXT LINES TOO. (a text line has a layout line inside them, so those probably would need to be animated too) + // TEXT LINES ARE CLEARLY SOMETHING WE NEED TO THINK ABOUT VERY CAREFULLY. Currently Anim() only works with window lines :-) + // TEXT LINES HAS A PROBLEM THAT THE FINDMULTIPLIER() is impossible to do with TAknTextLineLayout data structure. + // and the findmultiplier needs the aParent.Width() value which is only available at TextRectFromCoords. + // (in TAknTextLineLayout we only have ONE Dimension(x-dimension) fully implemented. y-dimension is missing top value.) + + // + // + // Anim method for text lines would work about the same as ComposeText() compared to Compose(). I.e. it'd separate + // window line layout first from the text line layout and then call Anim on the window line and then combine + // the results back to text line :-) (and then try to think of how to animate justification attribute :-) + // + + return c; +} + + + +EXPORT_C TAknTextComponentLayout TAknWindowComponentLayout::ComposeText(TAknWindowComponentLayout aLine1, TAknTextComponentLayout aLine2) + { + TAknTextComponentLayoutAttrs attrs = ExtractAttributes(aLine2); + TAknWindowComponentLayout window1 = ExtractWindow(aLine2); + TAknWindowComponentLayout combined = Compose(aLine1, window1); + TAknTextComponentLayout text = CombineAttrs(combined, attrs); + return text; + } + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::Intersect(TAknWindowComponentLayout aLine, TAknWindowComponentLayout aLine2) +{ + aLine = RemoveLayoutEmptys(aLine); + aLine2 = RemoveLayoutEmptys(aLine2); + // Should get rid of W and H + // Something to do with ELayoutEmpty's and p-10's. + TAknWindowComponentLayout result; + result.Setl(Max(aLine.l(), aLine2.l())); + result.Sett(Max(aLine.t(), aLine2.t())); + result.SetW(ELayoutEmpty); + result.SetH(ELayoutEmpty); + result.Setb(Max(aLine.b(), aLine2.b())); + result.Setr(Max(aLine.r(), aLine2.r())); + result.SetC(aLine2.C()); + return result; +} + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::Minus(TAknWindowComponentLayout aLine, TAknWindowComponentLayout aParentDiff) +{ + aLine = RemoveLayoutEmptys(aLine); + aParentDiff = RemoveLayoutEmptys(aParentDiff); + // Should get rid of W and H + // Something to do with ELayoutEmpty's and p-10's. + TAknWindowComponentLayout result; + result.Setl(MinusInt(aLine.l(),aParentDiff.l())); + result.Sett(MinusInt(aLine.t(),aParentDiff.t())); + result.SetW(ELayoutEmpty); + result.SetH(ELayoutEmpty); + result.Setb(MinusInt(aLine.b(),aParentDiff.b())); + result.Setr(MinusInt(aLine.r(),aParentDiff.r())); + result.SetC(aLine.C()); + + TInt16 pxdiff = TInt16(aParentDiff.l() + aParentDiff.r()); + TInt16 pydiff = TInt16(aParentDiff.t() + aParentDiff.b()); + if (IsParentRelative(result.l())) { result.Setl( TInt16( result.l() + pxdiff ) ); } + if (IsParentRelative(result.t())) { result.Sett( TInt16( result.t() + pydiff ) ); } + if (IsParentRelative(result.r())) { result.Setr( TInt16( result.r() + pxdiff ) ); } + if (IsParentRelative(result.b())) { result.Setb( TInt16( result.b() + pydiff ) ); } + + return result; +} + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::SiblingAsChild( + TAknWindowComponentLayout aLine1, + TAknWindowComponentLayout aLine2) +{ + aLine1 = RemoveLayoutEmptys(aLine1); + aLine2 = RemoveLayoutEmptys(aLine2); + TAknWindowComponentLayout result; + // Consider aLine2 as being wholly inside aLine1; Relative positions should all then be +ve + // From this you can see, somewhat counter-intuitively, that the orderings of the + // subtractions is line2 - line1. + result.Setl(MinusInt(aLine2.l(),aLine1.l())); + result.Sett(MinusInt(aLine2.t(),aLine1.t())); + result.SetW(ELayoutEmpty); + result.SetH(ELayoutEmpty); + result.Setb(MinusInt(aLine2.b(),aLine1.b())); + result.Setr(MinusInt(aLine2.r(),aLine1.r())); + result.SetC(aLine1.C()); + + return result; +} + +EXPORT_C void TAknWindowComponentLayout::SetZeroSized() + { + // Position is set to top left; size is 0,0 + Setl(0); + Sett(0); + Setr(ELayoutP); + Setb(ELayoutP); + SetW(0); + SetH(0); + SetC(ELayoutEmpty); + } + +// aValue is value 0..8: +// +// 0 1 2 +// 3 4 5 +// 6 7 8 +// + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::Split(TAknWindowComponentLayout aLine, TInt aValue) + { + __ASSERT_DEBUG(aValue >=0 && aValue <=8, Panic(EParameterOutOfRange)); + TAknWindowComponentLayout result = aLine; + + if (aLine.il == ELayoutEmpty) + { + aLine.il = TInt16(ELayoutP - result.ir - result.iW); + } + if (aLine.ir == ELayoutEmpty) + { + aLine.ir = TInt16(ELayoutP - result.il - result.iW); + } + if (aLine.iW == ELayoutEmpty) + { + aLine.iW = TInt16(ELayoutP - result.ir - result.il); + } + if (aLine.it == ELayoutEmpty) + { + aLine.it = TInt16(ELayoutP - result.ib - result.iH); + } + if (aLine.ib == ELayoutEmpty) + { + aLine.ib = TInt16(ELayoutP - result.it - result.iH); + } + if (aLine.iH == ELayoutEmpty) + { + aLine.iH = TInt16(ELayoutP - result.it - result.ib); + } + + + if (aValue == 0 || aValue == 1 || aValue == 2) + { + result.it = 0; + result.ib = ELayoutEmpty; + result.iH = aLine.it; + } + if (aValue == 6 || aValue == 7 || aValue == 8) + { + result.it = ELayoutEmpty; + result.ib = 0; + result.iH = aLine.ib; + } + if (aValue == 0 || aValue == 3 || aValue == 6) + { + result.il = 0; + result.ir = ELayoutEmpty; + result.iW = aLine.il; + } + if (aValue == 2 || aValue == 5 || aValue == 8) + { + result.il = ELayoutEmpty; + result.ir = 0; + result.iW = aLine.ir; + } + return result; + } + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::MultiLineGrid(TAknWindowComponentLayout aFirst, TInt aColumnIndex, TInt aRowIndex, TInt aGapBetweenColumns, TInt aGapBetweenRows) + { + TAknWindowComponentLayout layout = MultiLineX(aFirst, aColumnIndex, aGapBetweenColumns); + TAknWindowComponentLayout layout2 = MultiLineY(layout, aRowIndex, aGapBetweenRows); + return layout2; + } + + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::MultiLineY(TAknWindowComponentLayout aFirst, TInt aItem, TInt aGapBetweenItems) + { + TAknWindowComponentLayout first = RemoveLayoutEmptys(aFirst); + + TAknWindowComponentLayout layout; + layout.il = first.il; + layout.it = TInt16(first.it + aItem * (first.iH + aGapBetweenItems)); + layout.ib = ELayoutEmpty; + layout.ir = ELayoutEmpty; + layout.iW = first.iW; + layout.iH = first.iH; + return layout; + } + +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::MultiLineX(TAknWindowComponentLayout aFirst, TInt aItem, TInt aGapBetweenColumns) + { + TAknWindowComponentLayout first = RemoveLayoutEmptys(aFirst); + + TAknWindowComponentLayout layout; + layout.il = TInt16(first.il + aItem * (first.iW + aGapBetweenColumns)); + layout.it = first.it; + layout.ib = ELayoutEmpty; + layout.ir = ELayoutEmpty; + layout.iW = first.iW; + layout.iH = first.iH; + return layout; + } + + +// +// class TAknTextComponentLayout +// + +EXPORT_C TAknTextComponentLayout::TAknTextComponentLayout() + : + iC(ELayoutEmpty), + il(0), + it(0), + ir(0), + ib(0), + iW(ELayoutEmpty), + iH(ELayoutEmpty), + iJ(0), + iFont(0) + { + + } + +EXPORT_C TAknTextLineLayout TAknTextComponentLayout::LayoutLine() const + { + TAknTextLineLayout line; + line.iC = iC; + line.il = il; + // there is no top value + line.ir = ir; + if(ib == ELayoutEmpty) + { + line.iB = TInt16(ELayoutP - it - iH); + } + else + { + line.iB = ib; + } + line.iW = iW; + // there is no height value + line.iJ = iJ; + line.iFont = iFont; + + line.iBaselineSkip = 0; + line.iNumberOfLinesShown = 1; + return line; + } + +EXPORT_C TAknMultiLineTextLayout TAknTextComponentLayout::Multiline(const RArray &aLayouts) +{ + __ASSERT_ALWAYS(aLayouts.Count() >= 1, Panic(EParameterOutOfRange)); + TAknTextComponentLayout layout0 = aLayouts[0]; + TAknTextComponentLayout layout0NoEmptys = RemoveLayoutEmptys(layout0); + TAknTextLineLayout layout = layout0NoEmptys.LayoutLine(); + + + TAknMultiLineTextLayout multiline; + multiline.iC = layout.iC; + multiline.il = layout.il; + multiline.ir = layout.ir; + multiline.iB = layout.iB; + multiline.iW = layout.iW; + multiline.iJ = layout.iJ; + multiline.iFont = layout.iFont; + + if (aLayouts.Count() >= 2) + { + TAknTextComponentLayout layout1 = aLayouts[1]; + TAknTextComponentLayout layout1NoEmptys = RemoveLayoutEmptys(layout1); + multiline.iBaselineSkip = layout0NoEmptys.ib - layout1NoEmptys.ib; + multiline.iNumberOfLinesShown = aLayouts.Count(); + } + else + { + multiline.iBaselineSkip = 0; + multiline.iNumberOfLinesShown = 1; + } + return multiline; +} + +EXPORT_C TAknTextLineLayout TAknTextComponentLayout::LayoutLineNoEmptys() const + { + TAknTextLineLayout line; + line.iC = iC; + line.il = (il == ELayoutEmpty) ? TInt16(ELayoutP - iW - ir) : il; + // there is no top value + line.ir = (ir == ELayoutEmpty) ? TInt16(ELayoutP - iW - il) : ir; + line.iB = (ib == ELayoutEmpty) ? TInt16(ELayoutP - iH - it) : ib; + line.iW = (iW == ELayoutEmpty) ? TInt16(ELayoutP - il - ir) : iW; + // there is no height value + line.iJ = iJ; + line.iFont = iFont; + line.iBaselineSkip = 0; + line.iNumberOfLinesShown = 1; + return line; + } + +EXPORT_C TAknLayoutScalableComponentType TAknTextComponentLayout::LayoutComponentType() const + { + TAknLayoutScalableComponentType type = (TAknLayoutScalableComponentType)iType; + return type; + } + +EXPORT_C TInt16 TAknTextComponentLayout::C() const + { + return iC; + } + +EXPORT_C TInt16 TAknTextComponentLayout::l() const + { + return il; + } + +EXPORT_C TInt16 TAknTextComponentLayout::t() const + { + return it; + } + +EXPORT_C TInt16 TAknTextComponentLayout::r() const + { + return ir; + } + +EXPORT_C TInt16 TAknTextComponentLayout::b() const + { + return ib; + } + +EXPORT_C TInt16 TAknTextComponentLayout::W() const + { + return iW; + } + +EXPORT_C TInt16 TAknTextComponentLayout::H() const + { + return iH; + } + +EXPORT_C TInt16 TAknTextComponentLayout::J() const + { + return iJ; + } + +EXPORT_C TInt32 TAknTextComponentLayout::Font() const + { + return iFont; + } + +EXPORT_C void TAknTextComponentLayout::SetC(TInt16 aC) + { + iC = aC; + } + +EXPORT_C void TAknTextComponentLayout::Setl(TInt16 al) + { + il = al; + } + +EXPORT_C void TAknTextComponentLayout::Sett(TInt16 at) + { + it = at; + } + +EXPORT_C void TAknTextComponentLayout::Setr(TInt16 ar) + { + ir = ar; + } + +EXPORT_C void TAknTextComponentLayout::Setb(TInt16 ab) + { + ib = ab; + } + +EXPORT_C void TAknTextComponentLayout::SetW(TInt16 aW) + { + iW = aW; + } + +EXPORT_C void TAknTextComponentLayout::SetH(TInt16 aH) + { + iH = aH; + } + +EXPORT_C void TAknTextComponentLayout::SetJ(TInt16 aJ) + { + iJ = aJ; + } + +EXPORT_C void TAknTextComponentLayout::SetFont(TInt32 aFont) + { + iFont = aFont; + } + + +// +// class AknLayoutScalableDecodeSupport +// + +TInt32 AknLayoutScalableDecodeSupport::DecodeBytes(const TUint8*& aPtr) + { + TInt32 result = 0; + TUint16* pResult = (TUint16*)(&result); // assumes little endian, low word will get filled first + DecodeBytes(aPtr, pResult); + return result; + }; + +// ------------------------------------------------------------------------------------------------ +// This routine is slightly inefficient, as the main decode routine increments both pointers. +// However, this one is only called for ParamLimits, so there are in general less values +// to decode, and also SkipBytes is called more often. +// ------------------------------------------------------------------------------------------------ +TInt32 AknLayoutScalableDecodeSupport::SumBytes(const TUint8*& aPtr, TInt aNum) + { + TInt32 total = 0; + TInt32 result = 0; + for ( ; aNum ; --aNum) + { + TUint16* pResult = (TUint16*)(&result); // assumes little endian, low word will get filled first + DecodeBytes(aPtr, pResult); + total += result; + } + return total; + } + +void AknLayoutScalableDecodeSupport::DecodeBytes(const TUint8*& aPtr, TUint16*& aDecodedPtr) + { + if(!aDecodedPtr) + return; + TUint8 ch = *aPtr++; + switch (ch) + { + case KByteWord: + { + TUint16 high = *aPtr++; + TUint16 low = *aPtr++; + *aDecodedPtr++ = TUint16((high<<8) | low); + break; + } + case KByteEmpty: + { + *aDecodedPtr++ = TUint16(ELayoutEmpty); + break; + } + case KByteP1: + { + TInt8 offset = *aPtr++; + *aDecodedPtr++ = TUint16(p+offset); + break; + } + case KByteP2: + { + TInt16 high = *aPtr++; + TUint16 low = *aPtr++; + *aDecodedPtr++ = TUint16(p+((high<<8) | low)); + break; + } + case KByteLong: + { + TUint16 maskFF000000 = *aPtr++; + TUint16 mask00FF0000 = *aPtr++; + TUint16 mask0000FF00 = *aPtr++; + TUint16 mask000000FF = *aPtr++; + // assume little endian, so start with the low word + *aDecodedPtr++ = TUint16((mask0000FF00<<8) | mask000000FF); + *aDecodedPtr++ = TUint16((maskFF000000<<8) | mask00FF0000); + break; + } + default: + *aDecodedPtr++ = ch; + } + } + +void AknLayoutScalableDecodeSupport::SkipBytes(const TUint8*& aPtr, TInt aNum) + { + for ( ; aNum ; --aNum) + { + TUint8 ch = *aPtr++; + switch (ch) + { + case KByteWord: + { + aPtr+=2; + break; + } + case KByteP1: + { + ++aPtr; + break; + } + case KByteP2: + { + aPtr+=2; + break; + } + case KByteLong: + { + aPtr+=4; + break; + } + default: + break; + } + } + } + + +const TUint8* AknLayoutScalableDecodeSupport::DecodeTable(const SCompDataImplData* aImplData, TInt aLineIndex) + { + const TUint8* data = DataPtr(aImplData); + TUint16 numElements = DecodeBytes(data); + __ASSERT_ALWAYS(aLineIndex < numElements, Panic(EIllegalLineIndex)); + const TUint8* tableOffsetData = data+(aLineIndex*2); + TUint16 high = *tableOffsetData++; + TUint16 low = *tableOffsetData++; + TUint16 tableOffset = TUint16 ((high<<8) | low); + return aImplData->iByteCodedData + tableOffset; + } + + +const TUint8* AknLayoutScalableDecodeSupport::DataPtr(const SCompDataImplData* aImplData) + { + return aImplData->iByteCodedData + aImplData->iDataLookup[CdlEngine::LastApiId()]; + } + +const TUint8* AknLayoutScalableDecodeSupport::DataPtr(const SCompDataImplData* aImplData, TInt aComponentId) + { + return aImplData->iByteCodedData + aImplData->iDataLookup[aComponentId]; + } + +void AknLayoutScalableDecodeSupport::DecodeTypeId(TInt16& aType, TBool& aHasHeaderBlock, const TUint8*& aData) + { + TUint16 typeBitfield = *aData++; + aHasHeaderBlock = typeBitfield & 1; + aType = typeBitfield >> 1; + } + +void AknLayoutScalableDecodeSupport::DecodeSimple(TUint16* aLine, const TUint8* aData, TInt aNumCells) + { + TInt16 type; + TBool hasHeaderBlock; + DecodeTypeId(type, hasHeaderBlock, aData); + DecodeSimpleCells(aLine, aData, type, aNumCells); + } + +void AknLayoutScalableDecodeSupport::DecodeSimpleCells(TUint16* aLine, const TUint8* aData, TUint16 aType, TInt aNumCells) + { + // header block data is not used, and there are five 16bit values to skip + // iFirstChildID;iNextSiblingID;iParentID;iParentVariety;iAttributeSetID; + aLine+=5; + *aLine++ = aType; + + // decode a non-parameterised line by decoding the bytes for each cell + for (TInt ii=0; ii varietyOffsets; + TInt ii=0; + for(; ii> 2; + + // the variety offset must be re-calculated in the case of compressed calcs + TInt actualVarietyOffset = optimizedCalcs ? aVariety : aVarietyOffset; + + // if optimized, we can ignore the variety as they're all the same + // otherwise, just start counting from the variety offset + aParam = aOptimizedVarieties ? 0 : actualVarietyOffset; + + // if optimized, we can ingore the index, as they're all the same + aParam += optimizedCalcs ? 0 : aMulti; + } + } + +void AknLayoutScalableDecodeSupport::DecodeCell(TInt& aMax, TInt& aParam, const TUint8*& aDataPtr, TUint16*& aDecodedPtr) + { + __ASSERT_ALWAYS(0 <= aParam && aParam < aMax, Panic(EOffsetOutOfRange)); + + if (aParam) + { + SkipBytes(aDataPtr, aParam); + } + DecodeBytes(aDataPtr, aDecodedPtr); // increments ptr + TInt post = aMax - (aParam+1); + if (post) + { + SkipBytes(aDataPtr, post); + } + } + +void AknLayoutScalableDecodeSupport::DecodeParamLimitsCell(TInt aVariety, TInt aMax, TInt& aParam, const TUint8*& aDataPtr, TUint32*& aDecodedPtr, TInt& aVarietyOffset) + { + __ASSERT_ALWAYS(0 <= aParam && aParam < aMax, Panic(EOffsetOutOfRange)); + + // In the case of only one value being stored, it might be optimized. + // Either way, the variety offset will be 0. + aVarietyOffset = 0; + + // However, if more than one value is stored, need to + // accumulate the previous values + if (aParam) + { + // must be not optimized + aVarietyOffset = SumBytes(aDataPtr, aParam); + } + + TInt32 value = 0; + TUint16* pValue = (TUint16*)(&value); // assumes little endian, low word will get filled first + DecodeBytes(aDataPtr, pValue); // increments ptr + + // Record the position of the start of the variety that we're looking for (in the actual cells). + // if this cell is optimized or only has one value, we simulate the location of the required variety + // and if there is only one variety, then aVariety will always be 0. + if(aMax == 1) + { + aVarietyOffset = aVariety * value; + } + + // record the actual value + *aDecodedPtr++ = value; + + // we don't need to know the total for all the varieties, so we can just skip + // the last few, without accumulating + TInt post = aMax - (aParam+1); + if (post) + { + SkipBytes(aDataPtr, post); + } + } + +void AknLayoutScalableDecodeSupport::DecodeParamLimits(TInt* aLimits, const TUint8* aData, TInt aVariety) + { + TInt16 type; + TBool hasHeaderBlock; + DecodeTypeId(type, hasHeaderBlock, aData); + // *aLine++ = aType; + + if(hasHeaderBlock) + { + TInt numVarieties = 0; + TInt numMultiValues = 0; + const TUint8* paramsPtr = 0; + DecodeHeaderBlock(aLimits, numVarieties, numMultiValues, paramsPtr, aData, aVariety); + + // decode the param limits, always cols then rows + TInt ii = 0; + for (ii=0; ii<2; ii++) + { + TInt unusedVarietyOffset; + DecodeParamLimitParam(aLimits, numMultiValues, paramsPtr, aData, aVariety, ii, unusedVarietyOffset); + } + } + } + +void AknLayoutScalableDecodeSupport::MirrorValues(TAknWindowComponentLayoutImp& aLine) + { + // data is currently mirrored in separate layout instances + // but if the instance is mirrored, it will be stored with l and r swapped, so unswap them + if(Layout_Meta_Data::IsMirrored()) + { + TInt16 temp = aLine.il; + aLine.il = aLine.ir; + aLine.ir = temp; + } + } + +void AknLayoutScalableDecodeSupport::MirrorValues(TAknTextComponentLayoutImp& aLine) + { + // data is currently mirrored in separate layout instances + // but if the instance is mirrored, it will be stored with l and r swapped, + // and justification reversed, so unswap them + if(Layout_Meta_Data::IsMirrored()) + { + TInt16 temp = aLine.il; + aLine.il = aLine.ir; + aLine.ir = temp; + if(aLine.iJ == ELayoutAlignLeft) + aLine.iJ = ELayoutAlignRight; + else if(aLine.iJ == ELayoutAlignRight) + aLine.iJ = ELayoutAlignLeft; + } + } + +// The following functions could be factorised, but that would extend the call depth +// of an already tricky calculation, with expensive function calls. +// So these functions are individually coded - they're short anyway. +EXPORT_C void AknLayoutScalableDecodeSupport::WindowLine(TAknWindowComponentLayoutImp& aLine, const SCompDataImplData* aImplData) + { + DecodeSimple((TUint16*)&aLine, DataPtr(aImplData), KNumCellsWindow); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::WindowLine(TAknWindowComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aVariety, TInt aColumn, TInt aRow) + { + DecodeParams((TUint16*)&aLine, DataPtr(aImplData), KNumCellsWindow, aVariety, aColumn, aRow); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::TextLine(TAknTextComponentLayoutImp& aLine, const SCompDataImplData* aImplData) + { + DecodeSimple((TUint16*)&aLine, DataPtr(aImplData), KNumCellsText); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::TextLine(TAknTextComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aVariety, TInt aColumn, TInt aRow) + { + DecodeParams((TUint16*)&aLine, DataPtr(aImplData), KNumCellsText, aVariety, aColumn, aRow); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::WindowTable(TAknWindowComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aLineIndex) + { + const TUint8* data = DecodeTable(aImplData, aLineIndex); + DecodeSimple((TUint16*)&aLine, data, KNumCellsWindow); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::WindowTable(TAknWindowComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aLineIndex, TInt aVariety, TInt aColumn, TInt aRow) + { + const TUint8* data = DecodeTable(aImplData, aLineIndex); + DecodeParams((TUint16*)&aLine, data, KNumCellsWindow, aVariety, aColumn, aRow); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::TextTable(TAknTextComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aLineIndex) + { + const TUint8* data = DecodeTable(aImplData, aLineIndex); + DecodeSimple((TUint16*)&aLine, data, KNumCellsText); + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::TextTable(TAknTextComponentLayoutImp& aLine, const SCompDataImplData* aImplData, TInt aLineIndex, TInt aVariety, TInt aColumn, TInt aRow) + { + const TUint8* data = DecodeTable(aImplData, aLineIndex); + DecodeParams((TUint16*)&aLine, data, KNumCellsText, aVariety, aColumn, aRow); + MirrorValues(aLine); + } + +EXPORT_C TAknLayoutScalableTableLimits AknLayoutScalableDecodeSupport::TableLimits(const TUint16* aDataLookup) + { + TUint8* encoded = (TUint8*)(aDataLookup + CdlEngine::LastApiId()); + TAknLayoutScalableTableLimits limits(encoded[1], encoded[0]); + return limits; + } + + +EXPORT_C void AknLayoutScalableDecodeSupport::ParameterLimits(TAknLayoutScalableParameterLimitsImp& aLimits, const SCompDataImplData* aImplData, TInt aVariety) + { + DecodeParamLimits((TInt*)&aLimits, DataPtr(aImplData), aVariety); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::ParameterLimitsTable(TAknLayoutScalableParameterLimitsImp& aLimits, const SCompDataImplData* aImplData, TInt aLineIndex, TInt aVariety) + { + const TUint8* data = DecodeTable(aImplData, aLineIndex); + DecodeParamLimits((TInt*)&aLimits, data, aVariety); + } + + +EXPORT_C void AknLayoutScalableDecodeSupport::GetComponentTypeById(TAknLayoutScalableComponentType& aType, const SCompDataImplData* aImplData, TInt aComponentId) + { + TInt16 type(0); + TBool hasHeaderBlock; + const TUint8* dataPtr = DataPtr(aImplData, aComponentId); + DecodeTypeId(type, hasHeaderBlock, dataPtr); + aType = (TAknLayoutScalableComponentType)type; + } + +EXPORT_C void AknLayoutScalableDecodeSupport::GetParamLimitsById(TAknLayoutScalableParameterLimitsImp& aLimits, const SCompDataImplData* aImplData, TInt aComponentId, TInt aVariety) + { + const TUint8* dataPtr = DataPtr(aImplData, aComponentId); + DecodeParamLimits((TInt*)&aLimits, dataPtr, aVariety); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::GetWindowComponentById(TAknWindowComponentLayoutImp & aLine, const SCompDataImplData* aImplData, TInt aComponentId, TInt aVariety, TInt aCol, TInt aRow) + { + const TUint8* dataPtr = DataPtr(aImplData, aComponentId); + + TInt16 type(0); + TBool hasHeaderBlock; + DecodeTypeId(type, hasHeaderBlock, dataPtr); + + TAknLayoutScalableComponentType compType((TAknLayoutScalableComponentType)type); + TInt numCells = (compType == EAknLayoutScalableComponentTypeText) ? KNumCellsText : KNumCellsWindow; + + if(hasHeaderBlock) + DecodeParamCells((TUint16*)&aLine, dataPtr, type, numCells + KNumCellsNotSimple, aVariety, aCol, aRow); + else + DecodeSimpleCells((TUint16*)&aLine, dataPtr, type, numCells); + + MirrorValues(aLine); + } + +EXPORT_C void AknLayoutScalableDecodeSupport::GetTextComponentById(TAknTextComponentLayoutImp & aLine, const SCompDataImplData* aImplData, TInt aComponentId, TInt aVariety, TInt aCol, TInt aRow) + { + const TUint8* dataPtr = DataPtr(aImplData, aComponentId); + + TInt16 type(0); + TBool hasHeaderBlock; + DecodeTypeId(type, hasHeaderBlock, dataPtr); + + __ASSERT_DEBUG(type == EAknLayoutScalableComponentTypeText, Panic(EWrongType)); + + if(hasHeaderBlock) + DecodeParamCells((TUint16*)&aLine, dataPtr, type, KNumCellsText + KNumCellsNotSimple, aVariety, aCol, aRow); + else + DecodeSimpleCells((TUint16*)&aLine, dataPtr, type, KNumCellsText); + + MirrorValues(aLine); + } + + +// +// struct implementations +// + +EXPORT_C TAknTextComponentLayout TAknTextComponentLayout::MultiLineY(TAknTextComponentLayout aFirst, TInt aItem, TInt aGapBetweenItems) + { + TAknTextComponentLayout first = TAknTextComponentLayout::RemoveLayoutEmptys(aFirst); + + TAknTextComponentLayout layout; + layout.SetC(first.C()); + layout.Setl(first.l()); + layout.Sett(TInt16(first.t() + aItem * (first.H() + aGapBetweenItems))); + layout.Setb(ELayoutEmpty); + layout.Setr(ELayoutEmpty); + layout.SetW(first.W()); + layout.SetH(first.H()); + layout.SetJ(first.J()); + layout.SetFont(first.Font()); + return layout; + } +EXPORT_C TAknWindowComponentLayout TAknWindowComponentLayout::operator=( TAknWindowLineLayout aLine ) + { + iC = aLine.iC; + il = aLine.il; + it = aLine.it; + ir = aLine.ir; + ib = aLine.ib; + iW = aLine.iW; + iH = aLine.iH; + return *this; + } + +EXPORT_C TAknWindowComponentLayout::TAknWindowComponentLayout( TAknWindowLineLayout aLine ) + { + iC = aLine.iC; + il = aLine.il; + it = aLine.it; + ir = aLine.ir; + ib = aLine.ib; + iW = aLine.iW; + iH = aLine.iH; + } +EXPORT_C TAknTextComponentLayout::TAknTextComponentLayout( TAknTextLineLayout aLine ) + { + iC = aLine.iC; + il = aLine.il; + ir = aLine.ir; + ib = aLine.iB; + iW = aLine.iW; + iJ = aLine.iJ; + iFont = aLine.iFont; + } + + +EXPORT_C TAknTextComponentLayout TAknTextComponentLayout::operator=( TAknTextLineLayout aLine ) + { + iC = aLine.iC; + il = aLine.il; + ir = aLine.ir; + ib = aLine.iB; + iW = aLine.iW; + iJ = aLine.iJ; + iFont = aLine.iFont; + return *this; + }