layouts/aknlayout2/src/AknLayout2.cpp
changeset 0 05e9090e2422
child 38 a10f447f38bd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layouts/aknlayout2/src/AknLayout2.cpp	Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,514 @@
+/*
+* 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 "AknLayout2DataDef.h"
+#include "AknLayout2Def.h"
+#include <CdlEngine.h>
+#include "AknLayout2ScalableDef.h"
+#define AKNLAYOUT_DEFINE_BYTECODE(name,byte) const TUint8 name = byte;
+#include "AknLayoutByteCodes.h"
+
+const TInt KNumCells = 7;
+
+enum TLayoutPanic
+	{
+	ENegativeOffset,
+	EOffsetOutOfRange,
+	EIllegalLineIndex,
+	EMultiLineOffsetOutOfRange
+	};
+
+void Panic(TLayoutPanic aCode)
+	{
+	_LIT(KLayoutPanic, "Layout panic");
+	User::Panic(KLayoutPanic, aCode);
+	}
+
+// local functions
+
+TBool IsParentOffset(TInt16 aVal)
+	{
+	const TInt16 pLimits = 0x1000;
+	return ((p-pLimits) <= aVal && aVal <= (p+pLimits));
+	}
+
+void TAknWindowLineLayoutImp::SetlParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		il = TInt16(aRect.iTl.iX + aVal - p);
+	else
+		il = aVal;
+	}
+
+void TAknWindowLineLayoutImp::SettParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		it = TInt16(aRect.iTl.iY + aVal - p);
+	else
+		it = aVal;
+	}
+
+void TAknWindowLineLayoutImp::SetrParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		ir = TInt16(aRect.iBr.iX + aVal - p);
+	else
+		ir = aVal;
+	}
+
+void TAknWindowLineLayoutImp::SetbParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		ib = TInt16(aRect.iBr.iY + aVal - p);
+	else
+		ib = aVal;
+	}
+
+void TAknWindowLineLayoutImp::SetWParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		iW = TInt16(aRect.Width() + aVal - p);
+	else
+		iW = aVal;
+	}
+
+void TAknWindowLineLayoutImp::SetHParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		iH = TInt16(aRect.Height() + aVal - p);
+	else
+		iH = aVal;
+	}
+
+EXPORT_C void TAknWindowLineLayoutImp::SetAllParentOffsets(const TRect& aRect)
+	{
+	SetlParentOffset(il, aRect);
+	SettParentOffset(it, aRect);
+	SetrParentOffset(ir, aRect);
+	SetbParentOffset(ib, aRect);
+	SetWParentOffset(iW, aRect);
+	SetHParentOffset(iH, aRect);
+	}
+
+EXPORT_C TAknWindowLineLayout TAknWindowLineLayout::CombineLines(TAknWindowLineLayout aLine, TAknWindowLineLayout aLine2)
+	{
+	if (aLine2.iC != ELayoutEmpty) aLine.iC = aLine2.iC;
+	if (aLine2.il != ELayoutEmpty) aLine.il = aLine2.il;
+	if (aLine2.it != ELayoutEmpty) aLine.it = aLine2.it;
+	if (aLine2.ir != ELayoutEmpty) aLine.ir = aLine2.ir;
+	if (aLine2.ib != ELayoutEmpty) aLine.ib = aLine2.ib;
+	if (aLine2.iW != ELayoutEmpty) aLine.iW = aLine2.iW;
+	if (aLine2.iH != ELayoutEmpty) aLine.iH = aLine2.iH;
+	return aLine;
+	}
+
+//
+// TAknTextLineLayout
+//
+
+void TAknTextLineLayoutImp::SetlParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		il = TInt16(aRect.iTl.iX + aVal - p);
+	else
+		il = aVal;
+	}
+
+
+void TAknTextLineLayoutImp::SetrParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		ir = TInt16(aRect.iBr.iX + aVal - p);
+	else
+		ir = aVal;
+	}
+
+void TAknTextLineLayoutImp::SetBParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		iB = TInt16(aRect.iBr.iY + aVal - p);
+	else
+		iB = aVal;
+	}
+
+void TAknTextLineLayoutImp::SetWParentOffset(TInt16 aVal, const TRect& aRect)
+	{
+	if (IsParentOffset(aVal))
+		iW = TInt16(aRect.Width() + aVal - p);
+	else
+		iW = aVal;
+	}
+
+
+EXPORT_C void TAknTextLineLayoutImp::SetAllParentOffsets(const TRect& aRect)
+	{
+	SetlParentOffset(il, aRect);
+	SetrParentOffset(ir, aRect);
+	SetBParentOffset(iB, aRect);
+	SetWParentOffset(iW, aRect);
+	}
+
+TUint16 AknLayoutDecodeSupport::DecodeBytes(const TUint8*& aPtr)
+	{
+	TUint8 ch = *aPtr++;
+	switch (ch)
+		{
+		case KByteWord:
+			{
+			TUint16 high = *aPtr++;
+			TUint16 low = *aPtr++;
+			return TUint16((high<<8) | low);
+			}
+		case KByteEmpty:
+			return TUint16(ELayoutEmpty);
+		case KByteP1:
+			{
+			TInt8 offset = *aPtr++;
+			return TUint16(p+offset);
+			}
+		case KByteP2:
+			{
+			TInt16 high = *aPtr++;
+			TUint16 low = *aPtr++;
+			return TUint16(p+((high<<8) | low));
+			}
+		default:
+			return ch;
+		}
+	}
+
+const TUint8* AknLayoutDecodeSupport::DecodeTable(const SImplData* aImplData, TInt aLineIndex)
+	{
+	const TUint16* pApiId = aImplData->iDataLookup + CdlEngine::LastApiId();
+	const TUint8* pLimits = (const TUint8*)(pApiId-1);
+	__ASSERT_ALWAYS(pLimits[1] <= aLineIndex && aLineIndex <= pLimits[0], Panic(EIllegalLineIndex));
+	return aImplData->iByteCodedData + aImplData->iDataLookup[(*pApiId) + aLineIndex];
+	}
+
+const TUint8* AknLayoutDecodeSupport::DataPtr(const SImplData* aImplData)
+	{
+	return aImplData->iByteCodedData + aImplData->iDataLookup[CdlEngine::LastApiId()];
+	}
+
+void AknLayoutDecodeSupport::DecodeSimple(TUint16* aLine, const TUint8* aData)
+	{
+	// decode a non-parameterised line by decoding the bytes for each cell
+	for (TInt ii=0; ii<KNumCells; ii++)
+		*aLine++ = DecodeBytes(aData);
+	}
+
+void AknLayoutDecodeSupport::DecodeParams(TUint16* aLine, const TUint8* aData, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	// parameters are at the start of the byte coded data
+	const TUint8* paramsPtr = aData;
+	// the cell data follows
+	const TUint8* dataPtr = aData + (aNumParams*2);
+	// decode each cell
+	for (TInt ii=0; ii<KNumCells; ii++)
+		{
+		// calculate the requested and maximum paramter value for this cell
+		TInt max, param;
+		DecodeParam(ii, max, param, paramsPtr, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+		__ASSERT_ALWAYS(0 <= param && param < max, Panic(EOffsetOutOfRange));
+		// scan through all values for this cell and record the one indicated by the parameter
+		for (int jj=0; jj<max; jj++)
+			{
+			TUint16 val = DecodeBytes(dataPtr);
+			if (jj == param)
+				*aLine++ = val;
+			}
+		}
+	}
+
+void AknLayoutDecodeSupport::DecodeMultiLineParams(TAknTextLineLayoutImp& aLine, const TUint8* aData, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	// this function is similar to DecodeParams, except that extra processing is required
+	// for multiline parameters.
+	TUint16* linePtr = (TUint16*)&aLine;
+	// parameters are at the start of the byte coded data
+	const TUint8* paramsPtr = aData;
+	// the cell data follows
+	const TUint8* dataPtr = aData + (aNumParams*2);
+	TUint16 v0 = 0;
+	for (TInt ii=0; ii<KNumCells; ii++)
+		{
+		// calculate the requested and maximum paramter value for this cell
+		TInt max, param;
+		DecodeParam(ii, max, param, paramsPtr, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+		__ASSERT_ALWAYS(0 <= param && param < max, Panic(EMultiLineOffsetOutOfRange));
+		// scan through all values for this cell and record the one indicated by the parameter
+		for (int jj=0; jj<max; jj++)
+			{
+			TUint16 val = DecodeBytes(dataPtr);
+			// cell 3 is the "B" cell. 
+			// set baseline skip to the difference between the first and second values for cell B.
+			if (ii == 3 && jj < 2)
+				{
+				if (jj == 0)
+					v0 = val;
+				else
+					aLine.iBaselineSkip = val - v0;
+				}
+			if (jj == param)
+				*linePtr++ = val;
+			}
+		}
+	}
+
+TInt AknLayoutDecodeSupport::DecodeNumberOfLinesShown(const TUint8* aParamPtr, TInt& aIndex1, TInt& aIndex2, TInt& aIndex3, TInt& aIndex4)
+	{
+	// For multiline APIs, the parameter order may be changed
+	TInt numberOfLinesShownParamNumber = aParamPtr[0];
+	TInt numberOfLinesShown;
+	switch (numberOfLinesShownParamNumber)
+		{
+		case 0:
+			numberOfLinesShown = aIndex1;
+			break;
+		case 1:
+			numberOfLinesShown = aIndex2;
+			break;
+		case 2:
+			numberOfLinesShown = aIndex3;
+			break;
+		default:
+			numberOfLinesShown = aIndex4;
+			break;
+		}
+
+	// index_B will have been removed from the multiline API, so insert a 0 where it
+	// would have been, and shift up the other parameters.
+	TInt indexBParamNumber = aParamPtr[1];
+	switch (indexBParamNumber)
+		{
+		case 0:
+			aIndex4 = aIndex3;
+			aIndex3 = aIndex2;
+			aIndex2 = aIndex1;
+			aIndex1 = 0;
+			break;
+		case 1:
+			aIndex4 = aIndex3;
+			aIndex3 = aIndex2;
+			aIndex2 = 0;
+			break;
+		case 2:
+			aIndex4 = aIndex3;
+			aIndex3 = 0;
+			break;
+		case 3:
+			aIndex4 = 0;
+			break;
+		default:
+			break;
+		}
+
+	return numberOfLinesShown;
+	}
+
+void AknLayoutDecodeSupport::DecodeParam(TInt aCell, TInt& aMax, TInt& aParam, const TUint8* aParamsPtr, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	// Parameter coding is sequence of pairs of bytes, one for each parameter.
+	// The first byte is a bit field indicating which cells the parameter affects.
+	// The second is the number of items in the cell.
+	TInt ii=0;
+	// This is the bit in the bit-fields we are looking for
+	TInt bit = 1<<aCell;
+	// scan through the parameters and break if one has the relevant bit set for this cell
+	for (; ii<aNumParams; ii++)
+		{
+		if (aParamsPtr[0] & bit)
+			break;
+		aParamsPtr += 2;
+		}
+
+	if (ii == aNumParams)
+		{
+		// No parameter was found for this cell.
+		aMax = 1;
+		aParam = 0;
+		}
+	else
+		{
+		// A parameter was found for the cell, extract the number of items in the cell
+		// and the correct parameter index value.
+		aMax = aParamsPtr[1];
+		switch (ii)
+			{
+			case 0:
+				aParam = aIndex1;
+				break;
+			case 1:
+				aParam = aIndex2;
+				break;
+			case 2:
+				aParam = aIndex3;
+				break;
+			default:
+				aParam = aIndex4;
+				break;
+			}
+		}
+	}
+
+// 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 AknLayoutDecodeSupport::WindowLine(TAknWindowLineLayoutImp& aLine, const SImplData* aImplData)
+	{
+	DecodeSimple((TUint16*)&aLine, DataPtr(aImplData));
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::WindowLine(TAknWindowLineLayoutImp& aLine, const SImplData* aImplData, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	DecodeParams((TUint16*)&aLine, DataPtr(aImplData), aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::WindowLine(TAknWindowLineLayoutImp& aLine, const SImplData* aImplData, const TRect& aRect, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	DecodeParams((TUint16*)&aLine, DataPtr(aImplData), aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.SetAllParentOffsets(aRect);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::TextLine(TAknTextLineLayoutImp& aLine, const SImplData* aImplData)
+	{
+	DecodeSimple((TUint16*)&aLine, DataPtr(aImplData));
+	aLine.iBaselineSkip = 0;
+	aLine.iNumberOfLinesShown = 1;
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::TextLine(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	DecodeParams((TUint16*)&aLine, DataPtr(aImplData), aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.iBaselineSkip = 0;
+	aLine.iNumberOfLinesShown = 1;
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::TextLine(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, const TRect& aRect, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	DecodeParams((TUint16*)&aLine, DataPtr(aImplData), aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.SetAllParentOffsets(aRect);
+	aLine.iBaselineSkip = 0;
+	aLine.iNumberOfLinesShown = 1;
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::MultiLineTextLine(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	TInt lastApiId = CdlEngine::LastApiId();
+	const TUint8* pParamInfo = (const TUint8*)(aImplData->iDataLookup + lastApiId);
+	const TUint8* pData = aImplData->iByteCodedData + aImplData->iDataLookup[lastApiId-1];
+	aLine.iNumberOfLinesShown = DecodeNumberOfLinesShown(pParamInfo, aIndex1, aIndex2, aIndex3, aIndex4);
+	DecodeMultiLineParams(aLine, pData, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::MultiLineTextLine(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, const TRect& aRect, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	TInt lastApiId = CdlEngine::LastApiId();
+	const TUint8* pParamInfo = (const TUint8*)(aImplData->iDataLookup + lastApiId);
+	const TUint8* pData = aImplData->iByteCodedData + aImplData->iDataLookup[lastApiId-1];
+	aLine.iNumberOfLinesShown = DecodeNumberOfLinesShown(pParamInfo, aIndex1, aIndex2, aIndex3, aIndex4);
+	DecodeMultiLineParams(aLine, pData, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.SetAllParentOffsets(aRect);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::WindowTable(TAknWindowLineLayoutImp& aLine, const SImplData* aImplData, TInt aLineIndex, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	const TUint8* data = DecodeTable(aImplData, aLineIndex);
+	DecodeParams((TUint16*)&aLine, data, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::WindowTable(TAknWindowLineLayoutImp& aLine, const SImplData* aImplData, TInt aLineIndex, const TRect& aRect, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	const TUint8* data = DecodeTable(aImplData, aLineIndex);
+	DecodeParams((TUint16*)&aLine, data, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.SetAllParentOffsets(aRect);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::TextTable(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, TInt aLineIndex, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	const TUint8* data = DecodeTable(aImplData, aLineIndex);
+	DecodeParams((TUint16*)&aLine, data, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	}
+
+EXPORT_C void AknLayoutDecodeSupport::TextTable(TAknTextLineLayoutImp& aLine, const SImplData* aImplData, TInt aLineIndex, const TRect& aRect, TInt aNumParams, TInt aIndex1, TInt aIndex2, TInt aIndex3, TInt aIndex4)
+	{
+	const TUint8* data = DecodeTable(aImplData, aLineIndex);
+	DecodeParams((TUint16*)&aLine, data, aNumParams, aIndex1, aIndex2, aIndex3, aIndex4);
+	aLine.SetAllParentOffsets(aRect);
+	}
+
+EXPORT_C TAknLayoutTableLimits AknLayoutDecodeSupport::TableLimits(const TUint16* aDataLookup)
+	{
+	TUint8* encoded = (TUint8*)(aDataLookup + CdlEngine::LastApiId());
+	TAknLayoutTableLimits limits = { encoded[1], encoded[0] };
+	return limits;
+	}
+
+
+EXPORT_C TAknWindowLineLayout::TAknWindowLineLayout( const TAknWindowComponentLayout& aLine )
+    {
+    TAknWindowLineLayout line = aLine.LayoutLine();
+    iC = line.iC;
+    il = line.il;
+    it = line.it;
+    ir = line.ir;
+    ib = line.ib;
+    iW = line.iW;
+    iH = line.iH;
+    }
+
+
+EXPORT_C TAknWindowLineLayout TAknWindowLineLayout::operator=( const TAknWindowComponentLayout& aLine )
+    {
+    TAknWindowLineLayout line = aLine.LayoutLine();
+    iC = line.iC;
+    il = line.il;
+    it = line.it;
+    ir = line.ir;
+    ib = line.ib;
+    iW = line.iW;
+    iH = line.iH;
+    return *this;
+    }
+    
+    
+EXPORT_C TAknTextLineLayout::TAknTextLineLayout( const TAknTextComponentLayout& aLine )
+    {
+    TAknTextLineLayout line = aLine.LayoutLine();
+    iC = line.iC;
+    il = line.il;
+    ir = line.ir;
+    iB = line.iB;
+    iW = line.iW;
+    iJ = line.iJ;
+    iFont = line.iFont;
+    }
+
+
+EXPORT_C TAknTextLineLayout TAknTextLineLayout::operator=( const TAknTextComponentLayout& aLine )
+    {
+    TAknTextLineLayout line = aLine.LayoutLine();
+    iC = line.iC;
+    il = line.il;
+    ir = line.ir;
+    iB = line.iB;
+    iW = line.iW;
+    iJ = line.iJ;
+    iFont = line.iFont;
+    return *this;
+    }