Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414)
Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can
arrange to use the same source file name in sfimage, without having to export over the original
Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need
for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.
// Copyright (c) 1997-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:
//
#include <conarc.h>
#include <s32file.h>
#include <e32std.h>
#include <e32uid.h>
#include "TXCONV.H"
//
// class CEtToTxtCnv
//
CEtToTxtCnv::~CEtToTxtCnv()
{
delete iTextTranFromEra;
}
void CEtToTxtCnv::ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream,MConverterUiObserver* /*aObserver*/)
{
iReadStream = &aReadStream;
iPos=0;
iLength=aReadStream.Source()->SizeL();
delete iTextTranFromEra;
iTextTranFromEra=NULL;
iTextTranFromEra=TTextTranFromEra::NewL(CPlainText::EOrganiseByParagraph, aWriteStream,0);
}
const TInt KBufSize=256;
TBool CEtToTxtCnv::DoConvertL()
{
__ASSERT_DEBUG(iTextTranFromEra, User::Invariant());
TBuf<KBufSize> buf;
TInt read = Min(iLength - iPos, KBufSize);
#if defined _UNICODE
TBuf8<KBufSize> buf8;
iReadStream->ReadL(buf8, read);
for(TInt i = 0; i < (buf8.Size() - 1); i += 2)
{
buf.Append(buf8[i] | (buf8[i + 1] << 8));
}
#else
iReadStream->ReadL(buf,read);
#endif
iPos += read;
iTextTranFromEra->Initialise(buf);
return iTextTranFromEra->DoTranslateL();
}
TUid CEtToTxtCnv::Uid()
{
return KUidEtextToText;
}
TInt CEtToTxtCnv::Capabilities()
{
return EConvertsObjects;
}
CEtToTxtCnv::CEtToTxtCnv()
{}
//
// class CTxtToEtCnv
//
CTxtToEtCnv::~CTxtToEtCnv()
{
delete iTextTranToEra;
}
void CTxtToEtCnv::ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream, MConverterUiObserver* /*aObserver*/)
{
iReadStream = &aReadStream;
iWriteStream = &aWriteStream;
iLength=iReadStream->Source()->SizeL();
iPos=0;
delete iTextTranToEra;
iTextTranToEra=NULL;
iTextTranToEra=new(ELeave) TTextTranToEra(CPlainText::EOrganiseByParagraph, iNoTrim);
}
TBool CTxtToEtCnv::DoConvertL()
{
__ASSERT_DEBUG(iTextTranToEra, User::Invariant());
TBuf<KBufSize> buf;
TInt read = Min(iLength - iPos, KBufSize);
#if defined _UNICODE
TBuf8<KBufSize> buf8;
iReadStream->ReadL(buf8, read);
TInt i = 0;
for(; i < (buf8.Size() - 1); i += 2)
{
buf.Append(buf8[i] | (buf8[i + 1] << 8));
}
#else
iReadStream->ReadL(buf, read);
#endif
iPos += read;
iTextTranToEra->Translate(buf);
#if defined _UNICODE
buf8.Zero();
for (i = 0; i < buf.Length(); i++)
{
buf8.Append(buf[i] & 0x00FF);
buf8.Append((buf[i] >> 8) & 0x00FF);
}
iWriteStream->WriteL(buf8);
#else
iWriteStream->WriteL(buf);
#endif
if (iPos < iLength)
return ETrue; // more to do
return EFalse;
}
TUid CTxtToEtCnv::Uid()
{
return KUidTextToEtext;
}
TInt CTxtToEtCnv::Capabilities()
{
return EConvertsObjects;
}
CTxtToEtCnv::CTxtToEtCnv()
{}
CTxtToEtCnv::CTxtToEtCnv(TBool aNoTrim) : iNoTrim(aNoTrim)
{}
TTextTran::TTextTran(CPlainText::TTextOrganisation aTextOrganisation)
// C'tor
//
: iTransMode(aTextOrganisation)
{}
void TTextTran::SetTranslationMode(CPlainText::TTextOrganisation aTextOrganisation)
//
{iTransMode=aTextOrganisation;}
CPlainText::TTextOrganisation TTextTran::TranslationMode()const
//
{return iTransMode;}
TTextTranToEra::TTextTranToEra(CPlainText::TTextOrganisation aTextOrganisation, TBool aNoTrim)
// C'tor
//
: TTextTran(aTextOrganisation)
{
iNoTrim=aNoTrim;
}
void TTextTranToEra::Translate(TDes& aBuf)
// Scans the passed buffer, replacing line delimiters with paragraph delimiters
// based on the translation mode that has been set. (Paragraph or line).
// Control characters in the source, that have meaning to ERA text are translated
// into 'blobs'.
// The descriptor aBuf will never be enlarged, only made smaller!
//
// Unicode specifies discontinuous control code regions.!!!
{
iReadPtr=CONST_CAST(TText*,aBuf.Ptr());
iWritePtr=CONST_CAST(TText*,iReadPtr);
const TText* basePtr=iReadPtr;
const TInt length=aBuf.Length();
while (iReadPtr<basePtr+length)
{
// __ASSERT_DEBUG(iReadPtr>=iWritePtr,Panic(EDebug));
if (*iReadPtr<0x20)
MapControlCode(); // This is a control character
else
{
*iWritePtr=*iReadPtr;
iWritePtr++;
}
iReadPtr++;
}
aBuf.SetLength(iWritePtr-basePtr);
}
void TTextTranToEra::MapControlCode()
// Translate any control codes encountered into something more reasonable.
// CR's are ignored completely, only LF's influence where paragraph delimiters occur.
//
{
switch (*iReadPtr)
{
case 0x0c: // FF
*iWritePtr=CEditableText::EPageBreak;
break;
case 0x09: // CEditableText::ETabCharacter
*iWritePtr=*iReadPtr;
break; // No translation required
case 0x0d: // CR - ignore this character.
iWritePtr--; // cos its incremented again outside the switch.
break;
case 0x0a: // LF
{
if (iTransMode==CPlainText::EOrganiseByParagraph)
{
if(!iNoTrim)
{
Trim(); // trims trailng white space preceeding this line delimter.
}
*iWritePtr=CEditableText::EParagraphDelimiter; // all line delimiters become paragraph delimiters
}
else
{// only consecutive line delimiters become paragraph delimiters
if (*(iReadPtr+1)==0x0a || (*(iReadPtr+1)==0x0d && *(iReadPtr+2)==0x0a))
{
Trim(); // trims trailng white space preceeding this line delimter.
*iWritePtr=CEditableText::EParagraphDelimiter; // Insert paragraph
iReadPtr+=(*(iReadPtr+1)==0x0a) ? 1 : 2; // consume this delimiter set.
}
else
*iWritePtr=0x20; // replace with white space.
}
break;
}
default:
// CEditableText::EParagraphDelimiter
// CEditableText::ELineBreak
// CEditableText::EPageBreak
// CEditableText::ENonBreakingTab
// CEditableText::ENonBreakingHyphen
// CEditableText::EPotentialHyphen
// CEditableText::ENonBreakingSpace
// CEditableText::EPictureCharacter
*iWritePtr=*iReadPtr;
break;
}
iWritePtr++;
}
void TTextTranToEra::Trim()
// Removes white space that has already been written before the line delimiter was encountered.
//
{
while (*(iWritePtr-1)==0x20)
iWritePtr--;
}
TTextTranFromEra* TTextTranFromEra::NewL(CPlainText::TTextOrganisation aTextOrganisation,RWriteStream& aOutStream,TInt aLineWrap)
// Create & initialise a new instance of this class.
//
{
TTextTranFromEra* self=new(ELeave) TTextTranFromEra(aTextOrganisation,aOutStream,aLineWrap);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
TTextTranFromEra::TTextTranFromEra(CPlainText::TTextOrganisation aTextOrganisation,RWriteStream& aOutStream,TInt aLineWrap)
// C'tor
//
: TTextTran(aTextOrganisation),iOutStream(aOutStream),iLineWrap(aLineWrap)
{
ResetExportBuffer();
if (aTextOrganisation==CPlainText::EOrganiseByParagraph)
iLineWrap=KMaxTInt;
}
void TTextTranFromEra::ConstructL()
// Initialise this object.
//
{}
TInt TTextTranFromEra::DoTranslateL()
// Scans the passed buffer, replacing paragraph delimiters with line delimiters (CR/LF)
// based on the translation mode that has been set. (Paragraph or line).
// Special characters in the source, that have meaning to ERA text are translated.
//
{
if(iReadPtr<iSBase+iSLen)
{
while (iReadPtr<(iSBase+iSLen))
{
DoTranslateSourceBufferL(); // returns when export buffer is full or aBuf is empty
CommitExportBufferToFileL(); // export buffer full
}
return ETrue;
}
CommitExportBufferToFileL();
return EFalse;
}
void TTextTranFromEra::NotifyEndOfSourceL()
// Flush the export buffer.
//
{CommitExportBufferToFileL();}
void TTextTranFromEra::Initialise(const TDesC& aBuf)
//
{
iReadPtr=CONST_CAST(TText*,aBuf.Ptr());
iSBase=iReadPtr;
iSLen=aBuf.Length();
}
void TTextTranFromEra::ResetExportBuffer()
//
{
iWritePtr=CONST_CAST(TText*,iExportBuffer.Ptr());
iTBase=iWritePtr;
}
void TTextTranFromEra::CommitExportBufferToFileL()
//
{
iExportBuffer.SetLength(iWritePtr - iTBase);
#if !defined(_UNICODE)
iOutStream.WriteL(iExportBuffer);
#else // Write wide descriptor to file as byte stream
TBuf8<KMaxExportBuffer> narrowBuffer;
TInt i = 0;
for (; i < (iExportBuffer.Length() / 2); i++)
{
narrowBuffer.Append(iExportBuffer[i] & 0x00FF);
narrowBuffer.Append((iExportBuffer[i] >> 8) & 0x00FF);
}
iOutStream.WriteL(narrowBuffer);
narrowBuffer.Zero();
for (i = (iExportBuffer.Length() / 2); i < iExportBuffer.Length(); i++)
{
narrowBuffer.Append(iExportBuffer[i] & 0x00FF);
narrowBuffer.Append((iExportBuffer[i] >> 8) & 0x00FF);
}
iOutStream.WriteL(narrowBuffer);
#endif
iExportBuffer.SetLength(0);
iWritePtr = iTBase; // Reset the write pointer - fundamental !!!!
}
void TTextTranFromEra::DoTranslateSourceBufferL()
// Translate the source buffer, writing to the export buffer.
// Returns when either the source has been consumed or the export buffer is full
//
{
while (iReadPtr<iSBase+iSLen && iWritePtr<iTBase+KMaxExportBuffer-2*KLineDelimiterLength)
{
if ((*iReadPtr<0x20) || (*iReadPtr==CEditableText::EParagraphDelimiter))
MapEraCodeL(); // May fill export buffer
else
{
*iWritePtr=*iReadPtr;
iWritePtr++;
}
if (iLineWrap!=KMaxTInt && iWritePtr>=iTBase+iLineWrap)
{
TText* ptr=iWritePtr;
TText* end=iWritePtr;
TText chr(0);
while ((*(--ptr))!=' ' && ptr>iTBase) //Allow for more general breaking character
{}
if (*ptr!=' ')
{
WriteCRLF(KLineDelimiterLength);
ptr=end; //So the while below is not executed
}
else
{
*ptr++=KCharacterCR;
chr=*ptr;
*ptr++=KCharacterLF;
iWritePtr=ptr;
}
CommitExportBufferToFileL();
if (ptr<=end)
{
*(iWritePtr++)=chr;
while (ptr<end)
{
*(iWritePtr++)=*(ptr++);
}
}
}
iReadPtr++;
}
}
void TTextTranFromEra::MapEraCodeL()
//
{
switch (*iReadPtr)
{
case CEditableText::EPictureCharacter:
case CEditableText::ELineBreak:
case CEditableText::EPageBreak:
case CEditableText::EPotentialHyphen:
return; // These characters are not emitted.
case CEditableText::ETabCharacter:
*iWritePtr=KCharacterTab;
break;
case CEditableText::ENonBreakingHyphen:
*iWritePtr=KCharacterHyphen;
break;
case CEditableText::ENonBreakingSpace:
*iWritePtr=KCharacterSpace;
break;
case CEditableText::EParagraphDelimiter:
{
TInt charsToWrite=KLineDelimiterLength;
if (iTransMode==CPlainText::EOrganiseByLine)
charsToWrite=2*KLineDelimiterLength;
WriteCRLF(charsToWrite);
if (iTransMode==CPlainText::EOrganiseByLine)
CommitExportBufferToFileL(); // export buffer
return;
}
default:
*iWritePtr=*iReadPtr;
break;
}
iWritePtr++;
}
void TTextTranFromEra::WriteCRLF(TInt aNumCharacters)
//
{
while (aNumCharacters>0)
{
if (aNumCharacters%2==1)
*iWritePtr=KCharacterLF;
else
*iWritePtr=KCharacterCR;
aNumCharacters--;
iWritePtr++;
}
}