textrendering/textformatting/tagma/TMCODE.CPP
changeset 0 1fb32624e06b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/textformatting/tagma/TMCODE.CPP	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 1999-2009 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: 
+* TAGMA's text layout bytecode storage class.
+*
+*/
+
+
+#include "TMSTD.H"
+
+void CTmCode::AppendByteL(TUint8 aByte)
+	{
+	InsertByteL(aByte,Size());
+	}
+
+TInt CTmCode::AppendNumberL(TInt aNumber)
+	{
+	return InsertNumberL(aNumber,Size());
+	}
+
+TInt CTmCode::AppendRectL(const TRect& aRect)
+	{
+	return InsertRectL(aRect,Size());
+	}
+
+TInt CTmCode::Size() const
+	{
+	return iBuffer ? iBuffer->Size() : 0;
+	}
+
+void CTmCode::Delete(TInt aPos,TInt aLength)
+	{
+	if (iBuffer) iBuffer->Delete(aPos,aLength);
+	}
+
+void CTmCode::Reset()
+	{
+	delete iBuffer; iBuffer = NULL;
+	}
+
+void CTmCode::CreateBufferL()
+	{
+	if (!iBuffer) iBuffer = new(ELeave) CTmBufSeg(EExpandSize);
+	}
+
+void CTmCode::InsertByteL(TUint8 aByte,TInt aPos)
+	{
+	iBuffer->InsertL(aPos,&aByte,1);
+	}
+
+/*
+Write a number in bytecode, using as few bytes as possible. Each byte assigns the low seven bits
+to data and uses the high bit as a continuation bit. Return the position after the number.
+*/
+TInt CTmCode::InsertNumberL(TInt aNumber,TInt aPos)
+	{
+	TUint8 buffer[5];
+	int bytes = WriteNumber(aNumber,buffer);
+	iBuffer->InsertL(aPos,buffer,bytes);
+	return aPos + bytes;
+	}
+
+// Write aNumber to aBuffer and return the number of bytes written (from 1 to 5).
+TInt CTmCode::WriteNumber(TInt aNumber,TUint8* aBuffer)
+	{
+	int bytes;
+	if (aNumber >= -64 && aNumber <= 63)
+		bytes = 1;
+	else if (aNumber >= -8192 && aNumber <= 8191)
+		bytes = 2;
+	else if (aNumber >= -1048576 && aNumber <= 1048575)
+		bytes = 3;
+	else if (aNumber >= -134217728 && aNumber <= 134217727)
+		bytes = 4;
+	else
+		bytes = 5;
+	int shift = 0;
+	for (int i = 0; i < bytes; i++)
+		{
+		aBuffer[i] = (TUint8)((aNumber >> shift) & 0x7F);
+		if (i > 0)
+			aBuffer[i - 1] |= 0x80;
+		shift += 7;
+		}
+	return bytes;
+	}
+
+// Write a rectangle in bytecode as left, top, width, height. Return the position after the rectangle.
+TInt CTmCode::InsertRectL(const TRect& aRect,TInt aPos)
+	{
+	TUint8 buffer[20];
+	int bytes = WriteNumber(aRect.iTl.iX,buffer);
+	bytes += WriteNumber(aRect.iTl.iY,buffer + bytes);
+	bytes += WriteNumber(aRect.Width(),buffer + bytes);
+	bytes += WriteNumber(aRect.Height(),buffer + bytes);
+	iBuffer->InsertL(aPos,buffer,bytes);
+	return aPos + bytes;
+	}
+
+// Delete bytecode from aStart to aEnd and replace it with aNewCode, which is consumed by the operation.
+void CTmCode::ChangeL(TInt aStart,TInt aEnd,CTmCode& aNewCode)
+	{
+	if (aStart <= 0 && aEnd >= Size())
+		{
+		delete iBuffer;
+		iBuffer = aNewCode.iBuffer;
+		aNewCode.iBuffer = NULL;
+		}
+	else
+		{
+		CreateBufferL();
+		if (aEnd > aStart)
+			iBuffer->Delete(aStart,aEnd - aStart);
+		while (aNewCode.Size() > 0)
+			{
+			TPtrC8 p = aNewCode.Ptr(0);
+			iBuffer->InsertL(aStart,p);
+			aStart += p.Length();
+			aNewCode.Delete(0,p.Length());
+			}
+		}
+	}
+
+TInt CTmBufSeg::MemoryUsed() const
+	{
+	TInt bytes = sizeof(*this) + iSize;
+	TInt pos = 0;
+	while (pos < iSize)
+		{
+		TPtr8 p = (CONST_CAST(CTmBufSeg*,this))->Ptr(pos);
+		bytes += 8;
+		pos += p.Length();
+		}
+	return bytes;
+	}
+
+// Return the amount of memory used in bytes, allowing 8 bytes overhead per heap object
+TInt CTmCode::MemoryUsed() const
+	{
+	TInt bytes = sizeof(*this);
+	if (iBuffer)
+		bytes += iBuffer->MemoryUsed();
+	return bytes;
+	}
+
+int TTmCodeReader::ReadNumber()
+	{
+	TUint byte = ReadByte();
+	if (!(byte & 0xC0))
+		return byte;
+
+	int n = 0;
+	int shift = 0;
+	do
+		{
+		if (shift)
+			byte = ReadByte();
+		n |= ((byte & 0x7F) << shift);
+		shift += 7;
+		} while (byte & 0x80);
+	if ((byte & 0x40) && shift < 32)	// if bit 6 of the last byte is set, the number is negative
+		n |= (0xFFFFFFFF << shift);
+	return n;
+	}
+
+
+TRect TTmCodeReader::ReadRect()
+	{
+	TRect r;
+	r.iTl.iX = ReadNumber();
+	r.iTl.iY = ReadNumber();
+	r.iBr.iX = r.iTl.iX + ReadNumber();
+	r.iBr.iY = r.iTl.iY + ReadNumber();
+	return r;
+	}
+
+void TTmCodeReader::SetCodePtr()
+	{
+	if (iCodePos > iCodeEndPos)
+		TmPanic(EBadCodePos);
+	TPtrC8 p = CONST_CAST(CTmCode&,iCode).Ptr(iCodePos);
+	iCodeSegPtr = p.Ptr();
+	iCodeSegEndPtr = p.Ptr() + p.Length();
+	}
+
+void TTmCodeReader::SetCodePos(TInt aNewCodePos)
+	{
+	int bytes_to_skip = aNewCodePos - iCodePos;
+	iCodePos = aNewCodePos;
+	if (bytes_to_skip >= 0 && bytes_to_skip <= iCodeSegEndPtr - iCodeSegPtr)
+		iCodeSegPtr += bytes_to_skip;
+	else
+		SetCodePtr();
+	}