diff -r 000000000000 -r d46562c3d99d svgtopt/SVG/SVGImpl/src/SVGTextAreaElementImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/SVG/SVGImpl/src/SVGTextAreaElementImpl.cpp Thu Jan 07 16:19:02 2010 +0200 @@ -0,0 +1,1031 @@ +/* +* Copyright (c) 2003 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: SVG Implementation source file + * +*/ + + +#if !defined(__E32BASE_H__) +#include +#endif + +#include + +#include "SVGTextAreaElementImpl.h" +#include "SVGRectElementImpl.h" +#include "SVGTextElementImpl.h" +#include "SVGElementImpl.h" +#include "SVGDocumentImpl.h" +#include "SVGSchemaData.h" +#include "SVGEngineImpl.h" +#include "GfxAffineTransform.h" + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +CSvgTextAreaElementImpl* CSvgTextAreaElementImpl::NewL( const TUint8 aElemID, + CSvgDocumentImpl* aDoc ) +{ + CSvgTextAreaElementImpl*self = new ( ELeave ) CSvgTextAreaElementImpl( aDoc ); + CleanupStack::PushL( self ); + self->ConstructL( aElemID); + CleanupStack::Pop(); + + return self; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +CSvgTextAreaElementImpl* CSvgTextAreaElementImpl::NewLC( const TUint8 aElemID, + CSvgDocumentImpl* aDoc ) +{ + CSvgTextAreaElementImpl*self = new ( ELeave ) CSvgTextAreaElementImpl( aDoc ); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + + return self; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +CSvgTextAreaElementImpl::~CSvgTextAreaElementImpl() +{ + if ( iSvgStyleProperties ) + { + iSvgStyleProperties->Close(); + delete iSvgStyleProperties; + iSvgStyleProperties = NULL; + } + + if ( iInnerRectangle ) + { + this->RemoveChild(iInnerRectangle); + delete iInnerRectangle; + iInnerRectangle = NULL; + } + + if ( iBorderRectangle ) + { + this->RemoveChild(iBorderRectangle); + delete iBorderRectangle; + iBorderRectangle = NULL; + } + + if (iTextElementsArray) + { + iTextElementsArray->Reset(); + iTextElementsArray->Close(); + delete iTextElementsArray; + iTextElementsArray = NULL; + } + if (iAllText) + { + delete iAllText; + iAllText = NULL; + } + + ((CSvgDocumentImpl*)OwnerDocument())->RemoveInternalMouseListener( this ); + +} + +// ******************************************************* +// From SVG DOM +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::X() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->X(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::Y() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->Y(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::Width() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->Width(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::Height() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->Height(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::Rx() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->Rx(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgTextAreaElementImpl::Ry() +{ + if (!iInitialized) + { + return 0; + } + + return iBorderRectangle->Ry(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::IsEditable() +{ + return iEditable; +} + + +// --------------------------------------------------------------------------- +// For JSR support +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::SetTextAreaDimensions(TFloatFixPt aX, TFloatFixPt aY, TFloatFixPt aWidth, TFloatFixPt aHeight) +{ + if (!iInitialized) + { + TRAPD(err, InitializeL()); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::SetTextAreaDimensions Error in InitializeL()" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + } + + TRAPD(err, iBorderRectangle->SetAttributeFloatL(KAtrX, aX)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::SetTextAreaDimensions Error in SetAttributeFloatL" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + + TRAP(err, iBorderRectangle->SetAttributeFloatL(KAtrY, aY)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::SetTextAreaDimensions Error in SetAttributeFloatL" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + + TRAP(err, iBorderRectangle->SetAttributeFloatL(KAtrWidth, aWidth)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::SetTextAreaDimensions Error in SetAttributeFloatL" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + + TRAP(err, iBorderRectangle->SetAttributeFloatL(KAtrHeight, aHeight)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::SetTextAreaDimensions Error in SetAttributeFloatL" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } +} + +// From MXmlElementOpt +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::GetAttributeFloat( const TInt aNameId, + TFloatFixPt& aValue ) +{ + if (!iInitialized) + { + TRAPD(err, InitializeL()); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::GetAttributeFloat Error in InitializeL()" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + } + + switch ( aNameId ) + { + case KAtrX: + case KAtrRefX: + aValue = X(); + break; + case KAtrY: + case KAtrRefY: + aValue = Y(); + break; + case KAtrWidth: + aValue = Width(); + break; + case KAtrHeight: + aValue = Height(); + break; + // added as a part of get and Set api updation + case KAtrRx: + aValue = Rx(); + break; + case KAtrRy: + aValue = Ry(); + break; + default: + return CSvgElementImpl::GetAttributeFloat( aNameId, aValue ); + } + return KErrNone; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::SetAttributeFloatL( const TInt aNameId, + const TFloatFixPt aValue ) +{ + if (!iInitialized) + { + InitializeL(); + } + + switch ( aNameId ) + { + case KAtrX: + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + iInnerRectangle->SetAttributeFloatL(aNameId, aValue+TFloatFixPt(2)); + break; + case KAtrY: + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + iInnerRectangle->SetAttributeFloatL(aNameId, aValue+TFloatFixPt(2)); + break; + case KAtrRx: + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + //iInnerRectangle->SetAttributeFloatL(aNameId, aValue+TFloatFixPt(2)); + break; + case KAtrRy: + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + //iInnerRectangle->SetAttributeFloatL(aNameId, aValue+TFloatFixPt(2)); + break; + case KAtrWidth: + if(iReqAttrFlag == KAtrSVGRec) + { + iReqAttrFlag = KAtrHeight; + } + else + { + iReqAttrFlag = 0; + } + + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + iInnerRectangle->SetAttributeFloatL(aNameId, aValue-TFloatFixPt(4)); + break; + + case KAtrHeight: + if(iReqAttrFlag == KAtrSVGRec) + { + iReqAttrFlag = KAtrWidth; + } + else + { + iReqAttrFlag = 0; + } + iBorderRectangle->SetAttributeFloatL(aNameId, aValue); + iInnerRectangle->SetAttributeFloatL(aNameId, aValue-TFloatFixPt(4)); + break; + default: + return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue ); + } + return KErrNone; +} + + +// ******************************************************* +// From MXmlElement +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::SetAttributeL( const TDesC& aName, + const TDesC& aValue ) +{ + if (!iInitialized) + { + InitializeL(); + } + + CSvgElementImpl::SetAttributeL(aName,aValue); + return KErrNone; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::GetAttributeDes( const TInt aNameId, TPtrC16& aValue ) + { + if (!iInitialized) + { + return KErrNone; + } + + switch ( aNameId ) + { + case KAtrCdata: + aValue.Set(*iAllText); + break; + default: + return CSvgElementImpl::GetAttributeDes( aNameId, aValue ); + } + return KErrNone; + } +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::SetAttributeDesL( const TInt aNameId, + const TDesC& aValue ) + { + switch ( aNameId ) + { + case KAtrCdata: + SetTextL( aValue ); + break; + + default: + return CSvgElementImpl::SetAttributeDesL( aNameId, aValue ); + } + return KErrNone; + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::SetEditable( const TDesC& aValue ) +{ + if (aValue.FindF(_L("simple")) == KErrNotFound && aValue.FindF(_L("true")) == KErrNotFound) + { + iEditable = EFalse; + } + else + { + iEditable = ETrue; + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::LocalizedArrangeTextL( CGfx2dGc* /* aGc */ ) + { + if (!iInitialized) + { + return; + } + + //every time we call arrange text we will clear the previous text elements + //very expensive but easiest way to do this + if (iTextElementsArray) + { + TInt textEleArrayCnt = iTextElementsArray->Count(); + for (TInt i=0; i < textEleArrayCnt; i++) + { + this->RemoveChild( iTextElementsArray->operator[](i) ); + delete iTextElementsArray->operator[](i); + } + + iTextElementsArray->Reset(); + } + // If there is some text in the text area, we need to do the following operations + // a. calculate number of lines that can fit in the inner rectangle of textArea + // i. For this we need to get the dimension of Inner Rectangle + // ii. Then get the font corresponding to the current scale. This is obtained + // by creating a dummy text element and updating its CTM. + // + if (iAllText && iAllText->Length() > 0) + { + TFloatFixPt lInnerRectWidthF, lInnerRectHeightF; + iInnerRectangle->GetAttributeFloat( KAtrWidth, lInnerRectWidthF ); + iInnerRectangle->GetAttributeFloat( KAtrHeight, lInnerRectHeightF ); + + // Create a dummy text element to obtain the font + CSvgTextElementImpl* lTextElement = + (CSvgTextElementImpl*)iOwnerDocument->CreateElementL(KSvgTextElement); + CleanupStack::PushL(lTextElement); + lTextElement->SetAttributeDesL(KAtrCdata,iAllText->Des()); + + this->AppendChildL(lTextElement); + CleanupStack::Pop(lTextElement); + lTextElement->UpdateCTM(); + // Update the text element's font corresponding to the CTM. + lTextElement->UpdateCurrentScaledFont(); + + TFloatFixPt lScale = GetCurrentScale(); + + //Taken the widest charactor to check against the dimensions of the text area. + //There is no point in going futher, If the area of text area elelment + //is not big enough to fit the single char, + TChar ch('W'); + if ( lScale == TFloatFixPt( 0 ) || + ((TReal32)( lInnerRectWidthF * lScale)) < lTextElement->Font()->CharWidthInPixels( ch ) || + ((TReal32)( lInnerRectHeightF * lScale)) < lTextElement->Font()->FontMaxHeight()) + { + // Scale = 0 , means no drawing will take place. + // Cleanup the text element + this->RemoveChild(lTextElement); + delete lTextElement; + lTextElement = NULL; + return; + } + + // Store the current font's ascent and descent + TInt lTextAscent = lTextElement->Font()->FontMaxAscent(); + TInt lTextDescent = lTextElement->Font()->FontMaxDescent(); + + TReal32 lTextHeight = lTextAscent + lTextDescent; + + if (lTextHeight == 0) + { + //no text height so we need to not draw the text + this->RemoveChild(lTextElement); + delete lTextElement; + lTextElement = NULL; + return; + } + + // Calculate gap between two consecutive lines of text + // CFont provides FontLineGap() which is Font Height + Line Gap + + TInt lLineGap = lTextElement->Font()->FontLineGap(); + // Number of lines of text + TInt lNumOflines = (TReal32)( lInnerRectHeightF * lScale)/( lLineGap ) ; + + if( lNumOflines < 1) + { + //text is taller than the rectangle + this->RemoveChild(lTextElement); + delete lTextElement; + lTextElement = NULL; + return; + } + // Create a list of line widths and line texts to use with ConvertToVisualAndWrapToArrayL + CArrayFixFlat* lLineWidthArray = new ( ELeave ) CArrayFixFlat( lNumOflines ); + CleanupStack::PushL(lLineWidthArray); + + //one px offset is taken on Left & right ends w.r. to inner rect width. + lLineWidthArray->AppendL((TInt)( lInnerRectWidthF * lScale ) - 2,lNumOflines); + + CArrayFixFlat< TPtrC >* lWrappedArray = new ( ELeave ) CArrayFixFlat( lLineWidthArray->Count() ); + + CleanupStack::PushL(lWrappedArray); + + //ConvertToVisualAndWrapToArrayL requires KAknBidiExtraSpacePerLine. + //Refer the help of AknBidiTextUtils::ConvertToVisualAndWrapToArrayL + HBufC *lBuf = HBufC::NewLC(iAllText->Length() + (lNumOflines) * KAknBidiExtraSpacePerLine); + + TPtr buf = lBuf->Des(); + buf.Copy(iAllText->Des()); + // Below API fills the lWrappedArray with the lines of text. If no space + // is available in textArea, then trailing ellipsis(...) will be displayed. + AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(buf, *lLineWidthArray, + *lTextElement->iBitmapFont, *lWrappedArray, ETrue); + + // Dummy text element is no longer required. + this->RemoveChild(lTextElement); + delete lTextElement; + lTextElement = NULL; + + // Calculating the y offset for first line of text. + // Text is positioned wrt font baseline, hence the position = + // Inner Rectangle 's Y Coordinate + Unscaled Font Ascent + // The scaling will be taken care of by UpdateCTM on the text elements. + TInt lTextCurrentY = TReal32(iInnerRectangle->Y()) + (lTextAscent / (TReal32)lScale ); + TInt lWrappedArrayCnt = lWrappedArray->Count(); + + // lWrappedArrayCnt is guaranteed to be less than lNumOfLines. + // This loop creates Text elements as many as elements in lWrapppedArray. + // These elements are appended as child to the text area. + for( TInt i=0; i < lWrappedArrayCnt ; i++) + { + lTextElement = (CSvgTextElementImpl*)iOwnerDocument->CreateElementL(KSvgTextElement); + CleanupStack::PushL( lTextElement ); + iTextElementsArray->Append(lTextElement); + + TPtrC lineText = lWrappedArray->At(i); + lTextElement->SetAttributeDesL(KAtrCdata,lineText); + + //Text positioned from the inner rectangle's X- coordinate + 1 pixel gap + lTextElement->SetAttributeFloatL(KAtrX, TFloatFixPt(iInnerRectangle->X() + TFloatFixPt(1))); + + //need to set the next text element up to go down the height here too... + lTextElement->SetAttributeFloatL(KAtrY, TFloatFixPt(lTextCurrentY)); + + lTextElement->SetAttributeFloatL(KAtrWidth, TFloatFixPt(iInnerRectangle->Width() - TFloatFixPt(2))); + lTextElement->SetAttributeFloatL(KAtrHeight, lTextHeight); + + this->AppendChildL(lTextElement); + + lTextElement->UpdateCTM(); + lTextElement->UpdateCurrentScaledFont(); + + //The subsequent position calculated as lTextHeight( Ascent + descent ) / unscaled line gap + lTextCurrentY += (TInt)(( lLineGap )/(TReal32)lScale); + + CleanupStack::Pop( lTextElement ); + } + + //delete lBuf; + CleanupStack::PopAndDestroy(lBuf); + CleanupStack::Pop(lWrappedArray); + delete lWrappedArray; + CleanupStack::Pop(lLineWidthArray); + delete lLineWidthArray; + + } +} +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgTextAreaElementImpl::GetLength() + { + return iAllText->Length(); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::GetText( TDes& allText ) + { + if ( iAllText ) + { + if ( allText.MaxLength() < iAllText->Length() ) + { + allText = iAllText->Left( allText.MaxLength() ); + } + else + { + allText = *iAllText; + } + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::SetTextL( const TDesC& aText ) + { + + _LIT( KPreserve, "preserve" ); + _LIT( KDefault, "default"); + if ( iAllText ) + { + delete iAllText; + iAllText = NULL; + } + + iAllText = aText.AllocL(); + TPtr textDes = iAllText->Des(); + TBool def = ETrue; + + // Get the xml:space value. + TBuf<20> lXmlspace; + + if(XMLSpace() == KPreserve) + { + lXmlspace=KPreserve; + def=EFalse; + } + else if(XMLSpace() == KDefault) + { + lXmlspace=KDefault; + } + // xml:space is inherited if not specified + if ( lXmlspace!= KPreserve && lXmlspace != KDefault) + { + // Traverse to the nearest parent element which has the xml:space + // If no xml:space then render using xml:space="default" + CSvgElementImpl *lRoot=(CSvgElementImpl *)this->ParentNode(); + while(lRoot) + { + if ((lRoot->XMLSpace() == KPreserve)) + { + def = EFalse; + break; + } + else if(lRoot->XMLSpace()==KDefault) + { + break; + } + lRoot=(CSvgElementImpl *)lRoot->ParentNode(); + } + } + + _LIT(KSpace, " "); + // default + if ( def && lXmlspace != KPreserve ) + { + + // Remove leading, trailing and contiguous spaces + textDes.TrimAll(); + + for (TInt i = textDes.Length() - 1; i >= 0; i--) + { + + // Remove new line character + if (textDes[i] == '\n') + { + textDes.Delete(i,1); + } + + // Tab to be replaced with space. + if(textDes[i] == '\t') + { + textDes.Replace(i,1,KSpace); + } + } + } + // preserve + else + { + + for ( TInt i = 0; i < textDes.Length(); i++ ) + { + // ms-dos carriage return contains two characters: 13, 10 + const TInt KCarriageReturn1 = 13; + const TInt KCarriageReturn2 = 10; + + if ( i + 1 < textDes.Length() && + (TInt)textDes[i] == KCarriageReturn1 && + (TInt)textDes[i+1] == KCarriageReturn2 ) + { + textDes[i] = ' '; + textDes.Delete( i+1, 1 ); + } + + // New line and tab should be replaced by space character. + if (textDes[i] == '\n' ||textDes[i] == '\t') + { + textDes.Replace(i,1, KSpace); + } + } + } + + iNeedTextRearrange = ETrue; + + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::InitializeL() +{ + if (!iBorderRectangle && !iInnerRectangle) + { + iBorderRectangle = CSvgRectElementImpl::NewL(KSvgRectElement, (CSvgDocumentImpl*)iOwnerDocument); + this->AppendChildL(iBorderRectangle); + iInnerRectangle = CSvgRectElementImpl::NewL(KSvgRectElement, (CSvgDocumentImpl*)iOwnerDocument); + this->AppendChildL(iInnerRectangle); + + iInnerRectangle->SetAttributeFloatL(KAtrRx, 2); + iInnerRectangle->SetAttributeFloatL(KAtrRy, 2); + iInnerRectangle->SetPropertyL(KCSS_ATTR_FILL, _L("none")); + iInnerRectangle->SetPropertyL(KCSS_ATTR_STROKEWIDTH, _L(".02")); + iInnerRectangle->SetPropertyL(KCSS_ATTR_STROKE, _L("black")); + + iBorderRectangle->SetAttributeFloatL(KAtrRx, 2); + iBorderRectangle->SetAttributeFloatL(KAtrRy, 2); + iBorderRectangle->SetPropertyL(KCSS_ATTR_FILL, _L("none")); + iBorderRectangle->SetPropertyL(KCSS_ATTR_STROKEWIDTH, _L(".1")); + iBorderRectangle->SetPropertyL(KCSS_ATTR_STROKE, _L("black")); + + iInitialized = ETrue; + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement ) +{ + if (iBorderRectangle->Width() <= TFloatFixPt(0) || iBorderRectangle->Height() <= TFloatFixPt(0)) + { + return ETrue; + } + + TFloatFixPt scale = GetCurrentScale(); + TFloatFixPt width = iInnerRectangle->Width() * scale; + TFloatFixPt height = iInnerRectangle->Height() * scale; + + if ( width != iLastBBox.iWidth || height != iLastBBox.iHeight ) + { + iNeedTextRearrange = ETrue; + iLastBBox.iWidth = width; + iLastBBox.iHeight = height; + } + + DrawTextElements( aGc, aElement ); + + return ETrue; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::DrawTextElements( CGfx2dGc* aGc, CSvgElementImpl* /*aElement*/ ) +{ + //draw text elements...readjust their positions according the width and height of the inner rectangle... + if (iNeedTextRearrange) + { + //TRAPD(err, ArrangeTextL(aGc)); + TRAPD(err, LocalizedArrangeTextL(aGc)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::DrawTextElements Error in ArrangeTextL()" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + + iNeedTextRearrange = EFalse; + } + + //draw text until it reaches the inner border then start a new text element on the next line down + /*if (iTextElementsArray) + { + for (int i=0; i < iTextElementsArray->Count(); i++) + { + //draw text elements here... + TRAPD(err, iTextElementsArray->operator[](i)->DrawL(aGc, aElement)); + if (err) + { + #ifdef _DEBUG + _LIT( KErrMsg, "CSvgTextAreaElementImpl::DrawTextElements Error in DrawL()" ); + RDebug::Print(KErrMsg); + #endif //_DEBUG + } + + } + }*/ + + return ETrue; +} +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::ConstructL( const TUint8 aElemID ) +{ + CSvgElementImpl::InitializeL( aElemID ); + + iSvgStyleProperties = new(ELeave) RPointerArray(KCSS_MAX_ATTR ); + + User::LeaveIfError( iSvgStyleProperties->Append( NULL ) ); + iSvgStyleProperties->Remove( 0 ); + + iTextElementsArray = new (ELeave)RPointerArray (1); + iTextElementsArray->Reset(); + + iSvgTransformable = CSvgTransformableImpl::NewL(); + + iReqAttrFlag=KSVG_RECT_ELEMFLAG; + + iBorderRectangle = NULL; + iInnerRectangle = NULL; + + iNeedTextRearrange = ETrue; + iInitialized = EFalse; + + iAllText = HBufC::NewL( 2 ); + + iEditable = EFalse; + + // Add this as internal event receiver + //((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL( this, KSvgEventMaskExternalUI); + + ((CSvgDocumentImpl*)OwnerDocument())->AddInternalMouseListener( this ); + +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- + +CSvgTextAreaElementImpl::CSvgTextAreaElementImpl( CSvgDocumentImpl* aDoc ) +{ + SetOwnerDocument(aDoc); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::GetBBox( TGfxRectangle2D& aBbox ) +{ + if (!iInitialized) + { + TGfxRectangle2D myRect(0,0,0,0); + aBbox = myRect; + return; + } + + iBorderRectangle->GetBBox( aBbox ); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox ) +{ + if (!iInitialized) + { + TGfxRectangle2D myRect(0,0,0,0); + aBbox = myRect; + return; + } + + iBorderRectangle->GetUnscaledBBox(aBbox); +} + +// --------------------------------------------------------------------------- +// perform a deep clone of this object +// --------------------------------------------------------------------------- +MXmlElement* CSvgTextAreaElementImpl::CloneL(MXmlElement* aParentElement) +{ + // create new text area + CSvgTextAreaElementImpl* newElement = CSvgTextAreaElementImpl::NewL( this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) ); + + newElement->iParentNode = aParentElement; + // copy everything over + this->CopyL(newElement); + + return newElement; +} + +// --------------------------------------------------------------------------- +// perform a deep copy of this object +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::CopyL( CSvgTextAreaElementImpl* aDestElement ) +{ + // copy stuff from superclass + this->CSvgElementImpl::CopyL(aDestElement); + + // copy iRectangle items special to circle + aDestElement->iBorderRectangle = (CSvgRectElementImpl*)iBorderRectangle->CloneL((MXmlElement*)iBorderRectangle); + aDestElement->iInnerRectangle = (CSvgRectElementImpl*)iInnerRectangle->CloneL((MXmlElement*)iInnerRectangle); + + if (iTextElementsArray) + { + TInt textEleArrayCnt = iTextElementsArray->Count(); + for (int i=0; i < textEleArrayCnt; i++) + { + aDestElement->iTextElementsArray->Append((CSvgTextElementImpl*)iTextElementsArray->operator[](i)->CloneL((MXmlElement*)iTextElementsArray->operator[](i))); + } + } + + // copy the reference to idoc (CSvgDocumentImpl) + aDestElement->iOwnerDocument = this->iOwnerDocument; +} + +/*** FROM MSvgMouseListener ***/ +// --------------------------------------------------------------------------- +// mouse entered +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::MouseEntered( RPointerArray& aElements, + TInt /*aX*/, TInt /*aY*/ ) +{ + CSvgEngineImpl* engine = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine(); + + TInt eleCnt = aElements.Count(); + for (TInt i = 0; i < eleCnt; i++ ) + { + if ( aElements[i] == this ) + { + engine->NotifyTextAreaEntered(this); + return ETrue; + } + } + + return EFalse; +} + +// --------------------------------------------------------------------------- +// Notified when the mouse pointer exits a visible svg element. +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::MouseExited( RPointerArray& aElements, + TInt /*aX*/, TInt /*aY*/ ) +{ + CSvgEngineImpl* lEngine = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine(); + + TInt eleCnt = aElements.Count(); + for (TInt i = 0; i < eleCnt; i++ ) + { + if ( aElements[i] == this ) + { + lEngine->NotifyTextAreaExited(this); + return ETrue; + } + } + + return EFalse; +} + +// --------------------------------------------------------------------------- +// Notified when the mouse pointer is pressed down on visible svg element. +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::MouseMoved( RPointerArray& /*aElements*/, + TInt /*aX*/, TInt /*aY*/ ) +{ + return EFalse; +} +// --------------------------------------------------------------------------- +// Notified when the mouse pointer is pressed down on visible svg element. +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::MousePressed( RPointerArray& /*aElements*/, + TInt /*aX*/, TInt /*aY*/ ) +{ + return EFalse; +} + +// --------------------------------------------------------------------------- +// Notified when the mouse pointer is released on on visible svg element. +// --------------------------------------------------------------------------- +TBool CSvgTextAreaElementImpl::MouseReleased( RPointerArray& aElements, + TInt /*aX*/, TInt /*aY*/ ) +{ + CSvgEngineImpl* lEngine = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine(); + + TInt eleCnt = aElements.Count(); + for (TInt i = 0; i < eleCnt; i++ ) + { + if ( aElements[i] == this ) + { + lEngine->NotifyTextAreaActivated(this); + return ETrue; + } + } + + return EFalse; +} + +// --------------------------------------------------------------------------- +// void CSvgTextAreaElementImpl::Print() +// --------------------------------------------------------------------------- +void CSvgTextAreaElementImpl::Print( TBool aIsEncodeOn ) +{ + if (!aIsEncodeOn) + { + #ifdef _DEBUG + RDebug::Printf("", (int)X(), (int)Y(), (int)Width(), (int)Height(), (int)iEditable/*, iAllText*/); + #endif + } +}