ImagePrint/ImagePrintEngine/DeviceProtocols/xhtmlfilecomposer/src/cxhtmlfilecomposer.cpp
branchGCC_SURGE
changeset 25 59ea2209bb67
parent 23 08cc4cc059d4
parent 15 a92d00fca574
equal deleted inserted replaced
23:08cc4cc059d4 25:59ea2209bb67
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Defines the CXhtmlFileComposer class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <imageconversion.h>
       
    20 
       
    21 #ifdef _DEBUG
       
    22 #include <driveinfo.h>
       
    23 #include <pathinfo.h>
       
    24 #endif
       
    25 
       
    26 #include "cxhtmlfilecomposer.h"
       
    27 #include "printcapabilitycodes.h"
       
    28 #include "cxfclogger.h"
       
    29 
       
    30 //--------------------------------------------------------------------------------------------
       
    31 //
       
    32 // CXhtmlFileComposer::NewL
       
    33 //
       
    34 //--------------------------------------------------------------------------------------------
       
    35 EXPORT_C CXhtmlFileComposer* CXhtmlFileComposer::NewL(const TDesC& aPath)
       
    36 	{
       
    37 		CXhtmlFileComposer *self = NewLC(aPath);
       
    38 		CleanupStack::Pop();	// self
       
    39 
       
    40 		return self;
       
    41 	}
       
    42 
       
    43 //--------------------------------------------------------------------------------------------
       
    44 //
       
    45 // CXhtmlFileComposer::NewLC
       
    46 //
       
    47 //--------------------------------------------------------------------------------------------
       
    48 EXPORT_C CXhtmlFileComposer* CXhtmlFileComposer::NewLC(const TDesC& aPath)
       
    49 	{
       
    50 		CXhtmlFileComposer *self = new (ELeave) CXhtmlFileComposer();
       
    51 		CleanupStack::PushL(self);
       
    52 
       
    53 		if(0 >= aPath.Length())
       
    54 		{
       
    55 			self->ConstructL(KXFCDefaultResultPath());
       
    56 		}
       
    57 		else
       
    58 		{
       
    59 			self->ConstructL(aPath);
       
    60 		}
       
    61 
       
    62 		return self;
       
    63 	}
       
    64 
       
    65 //--------------------------------------------------------------------------------------------
       
    66 //
       
    67 // CXhtmlFileComposer::CreateXhtmlFileL
       
    68 //
       
    69 //--------------------------------------------------------------------------------------------
       
    70 EXPORT_C void CXhtmlFileComposer::CreateXhtmlFileL(const RArray<CImageInfo>& aImages, const TInt aLayout,
       
    71 								  const TInt aPaperSize, const TInt /*aQuality*/,
       
    72 								  const TDesC& aXhtmlPrintFile,TInt& aPageCount, TBool aDataFile)
       
    73 {
       
    74 	LOG("[CXhtmlFileComposer]\t WriteJobControlFileL");
       
    75 
       
    76 	// Get page and layout related data
       
    77 	PageData(aPaperSize);
       
    78 
       
    79 	RArray<TSizeReal> positions;
       
    80 	CleanupClosePushL(positions);
       
    81 	LayoutData(aLayout, positions);
       
    82 
       
    83 	ReadTemplateFileL();
       
    84 
       
    85 	// init counter variables
       
    86 	aPageCount = 0;
       
    87 	TInt posIx = 0;
       
    88 	TInt copies = 0;
       
    89 	TInt currentImgNum = 0;
       
    90 	TInt imageCount = aImages.Count();
       
    91 
       
    92 	// loop for images
       
    93 	for(TInt imgIx = 0; imgIx < aImages.Count(); imgIx++)
       
    94 	{
       
    95 		/**** Handle copies ****/
       
    96 		copies = aImages[imgIx].Copies();
       
    97 		imageCount += copies - 1; // decrease current image from copies
       
    98 
       
    99 		// Create template blocks for each copy
       
   100 		while(1 <= copies && imageCount > currentImgNum)
       
   101 		{
       
   102 			AddPageL(currentImgNum, posIx, aPageCount);
       
   103 			AddTemplateStringL(iFrameTemplate, KFrame());
       
   104 
       
   105 			// add frame position template once per position for all pages
       
   106 			if(1 == aPageCount)
       
   107 			{
       
   108 				AddTemplateStringL(iPositionTemplate, KFramePosition());
       
   109 				ComposePositionL(posIx, positions);
       
   110 			}
       
   111 			ComposeTemplateL(posIx+1, KPosId());
       
   112 			--copies;
       
   113 			++currentImgNum;
       
   114 		}
       
   115 
       
   116 		// add image details
       
   117 		AddTemplateStringL(iImageTemplate, KImgDetails());
       
   118 		ComposeTemplateL(1+imgIx, KDetId());
       
   119 
       
   120 		// Get correct name for the image
       
   121 		TFileName8 imageName;
       
   122 		GetImageNameL(aImages[imgIx], imageName, aDataFile);
       
   123 
       
   124 		/**** Image size and orientation ****/
       
   125 		TSizeReal imageSize(0,0);
       
   126 		TBool framePortrait = EFalse;
       
   127 
       
   128 		SizeAndOrientationL(aImages[imgIx], imageSize, framePortrait);
       
   129 
       
   130 		/**** Image scaling & cropping ****/
       
   131 		TSizeReal scaledSize;
       
   132 		GetRatioL(scaledSize, imageSize);
       
   133 
       
   134 		// Turn frame and scaled size in correct orientation again
       
   135 		if(framePortrait != iImagePortrait)
       
   136 		{
       
   137 			scaledSize.Reverse();
       
   138 			iImageFrame.Reverse();
       
   139 		}
       
   140 
       
   141 		ComposeFileL(imageName, scaledSize, aDataFile);
       
   142 
       
   143 	}// End of loop for images
       
   144 	CleanupStack::PopAndDestroy( &positions );
       
   145 
       
   146 	// Compose the correct unit in file
       
   147 	ComposeUnitL();
       
   148 
       
   149 	/**** Create result file ****/
       
   150 	RFile newFile;
       
   151 	CleanupClosePushL( newFile );
       
   152 	User::LeaveIfError( newFile.Replace( iFsSession, aXhtmlPrintFile, EFileWrite) );
       
   153 	newFile.Write( FinalizeBufferL() );
       
   154 	CleanupStack::PopAndDestroy( &newFile );
       
   155 }
       
   156 
       
   157 //--------------------------------------------------------------------------------------------
       
   158 //
       
   159 // CXhtmlFileComposer::~CXhtmlFileComposer
       
   160 //
       
   161 //--------------------------------------------------------------------------------------------
       
   162 EXPORT_C CXhtmlFileComposer::~CXhtmlFileComposer()
       
   163 {
       
   164 	iFsSession.Close();
       
   165 	if(iFileBuf)
       
   166 		delete iFileBuf;
       
   167 }
       
   168 
       
   169 //--------------------------------------------------------------------------------------------
       
   170 //
       
   171 // CXhtmlFileComposer::UnitToPixel
       
   172 //
       
   173 //--------------------------------------------------------------------------------------------
       
   174 EXPORT_C TReal CXhtmlFileComposer::UnitToPixel(TReal aValue)
       
   175 {
       
   176 	TReal tmp = aValue;
       
   177 	if(EUAMillis == iPaperType)
       
   178 		tmp = aValue/(TReal)KInchDivider;
       
   179 
       
   180 	tmp = tmp*(TReal)KDpiDivider;
       
   181 
       
   182 	return tmp;
       
   183 }
       
   184 
       
   185 //--------------------------------------------------------------------------------------------
       
   186 //
       
   187 // CXhtmlFileComposer::UnitToPixel
       
   188 //
       
   189 //--------------------------------------------------------------------------------------------
       
   190 EXPORT_C TSizeReal CXhtmlFileComposer::UnitToPixel(TSizeReal aValue)
       
   191 {
       
   192 	TSizeReal tmp = aValue;
       
   193 	if(EUAMillis == iPaperType)
       
   194 		tmp = aValue/(TReal)KInchDivider;
       
   195 
       
   196 	tmp = tmp*(TReal)KDpiDivider;
       
   197 
       
   198 	return tmp;
       
   199 }
       
   200 
       
   201 //--------------------------------------------------------------------------------------------
       
   202 //
       
   203 // CXhtmlFileComposer::PixelToUnit
       
   204 //
       
   205 //--------------------------------------------------------------------------------------------
       
   206 EXPORT_C TReal CXhtmlFileComposer::PixelToUnit(TReal aValue)
       
   207 {
       
   208 	TReal tmp = aValue/(TReal)KDpiDivider;
       
   209 	if(EUAMillis == iPaperType)
       
   210 		tmp = tmp*(TReal)KInchDivider;
       
   211 
       
   212 	return tmp;
       
   213 }
       
   214 
       
   215 //--------------------------------------------------------------------------------------------
       
   216 //
       
   217 // CXhtmlFileComposer::PixelToUnit
       
   218 //
       
   219 //--------------------------------------------------------------------------------------------
       
   220 EXPORT_C TSizeReal CXhtmlFileComposer::PixelToUnit(TSizeReal aValue)
       
   221 {
       
   222 	TSizeReal tmp = aValue/(TReal)KDpiDivider;
       
   223 	if(EUAMillis == iPaperType)
       
   224 		tmp = tmp*(TReal)KInchDivider;
       
   225 
       
   226 	return tmp;
       
   227 }
       
   228 
       
   229 // PROTECTED
       
   230 
       
   231 //--------------------------------------------------------------------------------------------
       
   232 //
       
   233 // CXhtmlFileComposer::ConstructL
       
   234 //
       
   235 //--------------------------------------------------------------------------------------------
       
   236 void CXhtmlFileComposer::ConstructL(const TDesC& aPath)
       
   237 {
       
   238 	LOG("[CXhtmlFileComposer::ConstructL]\t");
       
   239 
       
   240 	User::LeaveIfError( iFsSession.Connect() );
       
   241 	iFsSession.SetSessionPath( aPath );
       
   242 	iFsSession.MkDirAll( aPath );
       
   243 
       
   244 	iPaperSize.SetSize(0,0);
       
   245 	iPaperType = 0;
       
   246 	iPageMargin = 0;
       
   247 	iImageFrame.SetSize(0,0);
       
   248 	iFileBuf = NULL;
       
   249 	iImagesPerPage = 0;
       
   250 	iImagePortrait=EFalse;
       
   251 	iPagePortrait = ETrue;
       
   252 	iPageTemplate.Copy(KNullDesC8());
       
   253 	iFrameTemplate.Copy(KNullDesC8());
       
   254 	iPositionTemplate.Copy(KNullDesC8());
       
   255 	iImageTemplate.Copy(KNullDesC8());
       
   256 
       
   257 	LOG("[CXhtmlFileComposer::ConstructL]\t Done.");
       
   258 }
       
   259 
       
   260 // PRIVATE
       
   261 
       
   262 //--------------------------------------------------------------------------------------------
       
   263 //
       
   264 // CXhtmlFileComposer::CXhtmlFileComposer
       
   265 //
       
   266 //--------------------------------------------------------------------------------------------
       
   267 CXhtmlFileComposer::CXhtmlFileComposer()
       
   268 {
       
   269 }
       
   270 
       
   271 
       
   272 //--------------------------------------------------------------------------------------------
       
   273 //
       
   274 // CXhtmlFileComposer::GetRatioL
       
   275 //
       
   276 //--------------------------------------------------------------------------------------------
       
   277 void CXhtmlFileComposer::GetRatioL(TSizeReal &aNewSize, TSizeReal aImageSize)
       
   278 {
       
   279 	LOG("[CXhtmlFileComposer::GetRatioL]\t ********************************");
       
   280 
       
   281 	TRealX margin = 0;
       
   282 	TXhtmlSetting marginStr, tmpStr;
       
   283 
       
   284 	LOG2("[CXhtmlFileComposer::GetRatioL]\t aImageSize: %fx%f", PixelToUnit(aImageSize.iWidth), PixelToUnit(aImageSize.iHeight));
       
   285 	LOG2("[CXhtmlFileComposer::GetRatioL]\t iImageFrame: %fx%f", PixelToUnit(iImageFrame.iWidth), PixelToUnit(iImageFrame.iHeight));
       
   286 	LOG2("[CXhtmlFileComposer::GetRatioL]\t image ratio: %f vs. frame ratio %f", aImageSize.Ratio(), iImageFrame.Ratio());
       
   287 
       
   288 	TReal relativeRatio = aImageSize.Ratio() / iImageFrame.Ratio();
       
   289 	LOG2("[CXhtmlFileComposer::GetRatioL]\t relativeRatio: %f, iPageMargin %f", relativeRatio, iPageMargin);
       
   290 
       
   291 	// crop borderless: if iPageMargin == 0, the margin must be negative
       
   292 	if((1 < relativeRatio && iPageMargin) || (1 > relativeRatio && !iPageMargin))
       
   293 	{
       
   294 		LOG("[CXhtmlFileComposer::GetRatioL]\t *Match width*");
       
   295 		aNewSize.SetSize(iImageFrame.iWidth, iImageFrame.iWidth/aImageSize.Ratio());
       
   296 		margin = (iImageFrame.iHeight-aNewSize.iHeight)/2;
       
   297 
       
   298 	    if((!iPagePortrait && !iPageMargin && iImagePortrait) || iPagePortrait)
       
   299 	    	marginStr.Copy(KTop());
       
   300 		else
       
   301 	    	marginStr.Copy(KLeft());
       
   302 	}
       
   303 	else
       
   304 	{
       
   305 		LOG("[CXhtmlFileComposer::GetRatioL]\t *Match height*");
       
   306 		aNewSize.SetSize(iImageFrame.iHeight*aImageSize.Ratio(), iImageFrame.iHeight);
       
   307 		margin = (iImageFrame.iWidth-aNewSize.iWidth)/2;
       
   308 
       
   309 	    if((!iPagePortrait && !iPageMargin && iImagePortrait) || iPagePortrait)
       
   310 	    	marginStr.Copy(KLeft());
       
   311 		else
       
   312 	    	marginStr.Copy(KTop());
       
   313 	}
       
   314 
       
   315 	FormatReal(PixelToUnit(margin), tmpStr);
       
   316 	marginStr.Append(tmpStr);
       
   317 
       
   318 	LOG2("[CXhtmlFileComposer::GetRatioL]\t aNewSize: %fx%f", PixelToUnit(aNewSize.iWidth), PixelToUnit(aNewSize.iHeight));
       
   319 	LOG81("[CXhtmlFileComposer::GetRatioL]\t \"%S\"", &marginStr);
       
   320 
       
   321 	// margin not needed anymore: compose margin into file buffer
       
   322 	ComposeTemplateL(marginStr, KImgMargin());
       
   323 	LOG("[CXhtmlFileComposer::GetRatioL]\t ********************************");
       
   324 }
       
   325 
       
   326 //--------------------------------------------------------------------------------------------
       
   327 //
       
   328 // CXhtmlFileComposer::ComposeUnitL
       
   329 //
       
   330 //--------------------------------------------------------------------------------------------
       
   331 void CXhtmlFileComposer::ComposeUnitL()
       
   332 {
       
   333 	LOG("[CXhtmlFileComposer]\t ComposeUnit");
       
   334 
       
   335 	if(EUAMillis == iPaperType)
       
   336 	{
       
   337 		_LIT8(KMm, "mm");
       
   338 		ComposeTemplateL(KMm(), KUnit());
       
   339 	}
       
   340 	else
       
   341 	{
       
   342 		_LIT8(KIn, "in");
       
   343 		ComposeTemplateL(KIn(), KUnit());
       
   344 	}
       
   345 }
       
   346 
       
   347 //--------------------------------------------------------------------------------------------
       
   348 //
       
   349 // CXhtmlFileComposer::ComposeFile
       
   350 //
       
   351 //--------------------------------------------------------------------------------------------
       
   352 void CXhtmlFileComposer::ComposeFileL(const TDes8 &aImageName, TSizeReal aImgSize, TBool aDataFile)
       
   353 {
       
   354 	LOG("[CXhtmlFileComposer]\t ComposeFile");
       
   355 
       
   356 	// Format page settings in file
       
   357 	TXhtmlSetting pageWidthStr, pageHeightStr, pageMarginStr;
       
   358 
       
   359 	FormatReal(PixelToUnit(iPaperSize.iWidth), pageWidthStr);
       
   360 	ComposeTemplateL(pageWidthStr, KPageWidth());
       
   361 
       
   362 	FormatReal(PixelToUnit(iPaperSize.iHeight), pageHeightStr);
       
   363 	ComposeTemplateL(pageHeightStr, KPageHeight());
       
   364 
       
   365 	FormatReal(iPageMargin, pageMarginStr);
       
   366 	ComposeTemplateL(pageMarginStr, KPageMargin());
       
   367 
       
   368 	// Format image frame settings in file
       
   369 	TXhtmlSetting imgFrameWidthStr, imgFrameHeightStr;
       
   370 
       
   371 	FormatReal(PixelToUnit(iImageFrame.iWidth), imgFrameWidthStr);
       
   372 	ComposeTemplateL(imgFrameWidthStr, KImgFrameWidth());
       
   373 
       
   374 	FormatReal(PixelToUnit(iImageFrame.iHeight), imgFrameHeightStr);
       
   375 	ComposeTemplateL(imgFrameHeightStr, KImgFrameHeight());
       
   376 
       
   377 	// Format image settings in file
       
   378 	TXhtmlSetting imgWidthStr, imgHeightStr;
       
   379 
       
   380 	FormatReal(PixelToUnit(aImgSize.iWidth), imgWidthStr);
       
   381 	ComposeTemplateL(imgWidthStr, KImgWidth());
       
   382 
       
   383 	FormatReal(PixelToUnit(aImgSize.iHeight), imgHeightStr);
       
   384 	ComposeTemplateL(imgHeightStr, KImgHeight());
       
   385 
       
   386 ///////////
       
   387 	HBufC8* data = NULL;
       
   388 	if(aDataFile)
       
   389 	{
       
   390 
       
   391 		TFileName imgFile;
       
   392 		imgFile.Copy(aImageName);
       
   393 
       
   394 		LOG("[CXhtmlFileComposer]\t ComposeFileL - read image data");
       
   395 		// Open the template file and read it into buffer
       
   396 		RFile file;
       
   397 		CleanupClosePushL(file);
       
   398 
       
   399 		User::LeaveIfError( file.Open( iFsSession, imgFile, EFileRead | EFileShareReadersOnly ) );
       
   400 		LOG("[CXhtmlFileComposer]\t ComposeFileL - file opened");
       
   401 
       
   402 		TInt fileSize = 0;
       
   403 		User::LeaveIfError( file.Size(fileSize) );
       
   404 		LOG1("[CXhtmlFileComposer]\t ComposeFileL - file size %d",fileSize);
       
   405 
       
   406 		_LIT8(KDataUrl, "data:image/jpeg;base64,");
       
   407 
       
   408 		data = HBufC8::NewLC(fileSize + KDataUrl().Length());
       
   409 		TPtr8 dataPtr( data->Des() );
       
   410 
       
   411 		dataPtr.Zero();
       
   412 		file.Read(dataPtr);
       
   413 
       
   414 		dataPtr.Insert(0, KDataUrl());
       
   415 
       
   416 		ComposeTemplateL(dataPtr, KImgName());
       
   417 		LOG("[CXhtmlFileComposer]\t ComposeFileL - file composed");
       
   418 
       
   419 		CleanupStack::PopAndDestroy(2); // data, file
       
   420 	}
       
   421 ///////////
       
   422 	else
       
   423 	{
       
   424 		// Format image name in file
       
   425 		ComposeTemplateL(aImageName, KImgName());
       
   426 	}
       
   427 }
       
   428 
       
   429 //--------------------------------------------------------------------------------------------
       
   430 //
       
   431 // CXhtmlFileComposer::ComposeTemplateL
       
   432 //
       
   433 //--------------------------------------------------------------------------------------------
       
   434 void CXhtmlFileComposer::ComposeTemplateL(const TInt aValue, const TDesC8 &aTemplate)
       
   435 {
       
   436 //	LOG("[CXhtmlFileComposer]\t ComposeTemplateL");
       
   437 
       
   438 	TBuf8<KDefaultRealWidth> valueStr;
       
   439 	valueStr.Zero();
       
   440 	valueStr.AppendNum(aValue);
       
   441 
       
   442 	ComposeTemplateL(valueStr, aTemplate);
       
   443 }
       
   444 
       
   445 //--------------------------------------------------------------------------------------------
       
   446 //
       
   447 // CXhtmlFileComposer::ComposeTemplateL
       
   448 //
       
   449 //--------------------------------------------------------------------------------------------
       
   450 void CXhtmlFileComposer::ComposeTemplateL(const TDesC8 &aStr, const TDesC8 &aTemplate)
       
   451 {
       
   452 //	LOG("[CXhtmlFileComposer]\t ComposeTemplateL");
       
   453 
       
   454 	User::LeaveIfNull(iFileBuf);
       
   455 
       
   456 	TInt pos = iFileBuf->Find(aTemplate);
       
   457 	while(KErrNotFound != pos)
       
   458 	{
       
   459 		TInt requiredSize = iFileBuf->Des().Length() + aStr.Length();
       
   460 		if(iFileBuf->Des().MaxLength() < requiredSize)
       
   461 		{
       
   462 			iFileBuf = iFileBuf->ReAllocL(requiredSize);
       
   463 		}
       
   464 		iFileBuf->Des().Replace(pos, aTemplate.Length(), aStr);
       
   465 		pos = iFileBuf->Find(aTemplate);
       
   466 	}
       
   467 }
       
   468 
       
   469 //--------------------------------------------------------------------------------------------
       
   470 //
       
   471 // CXhtmlFileComposer::SetPageTypeL
       
   472 //
       
   473 //--------------------------------------------------------------------------------------------
       
   474 void CXhtmlFileComposer::SetPageTypeL()
       
   475 {
       
   476 	LOG("[CXhtmlFileComposer]\t SetPageTypeL");
       
   477 
       
   478 	User::LeaveIfNull(iFileBuf);
       
   479 
       
   480 	TXhtmlSetting pageType(KPageFirsts());
       
   481 
       
   482 	TInt pos = iFileBuf->Find(KPageType());
       
   483 	if(KErrNotFound >= pos)
       
   484 		User::Leave(KErrCorrupt);
       
   485 
       
   486 	while(KErrNotFound != pos)
       
   487 	{
       
   488 		// check if next exists to assign correct page type in template
       
   489 		TPtrC8 tmpBuf;
       
   490 		tmpBuf.Set(iFileBuf->Mid(pos+KPageType().Length()));
       
   491 
       
   492 		if(KErrNotFound == tmpBuf.Find(KPageType()))
       
   493 			pageType.Copy(KPageLast());
       
   494 
       
   495 		// replace correct page type in first found position
       
   496 		TInt requiredSize = iFileBuf->Des().Length() + pageType.Length();
       
   497 		if(iFileBuf->Des().MaxLength() < requiredSize)
       
   498 		{
       
   499 			iFileBuf = iFileBuf->ReAllocL(requiredSize);
       
   500 		}
       
   501 		iFileBuf->Des().Replace(pos, KPageType().Length(), pageType);
       
   502 		pos = iFileBuf->Find(KPageType());
       
   503 	}
       
   504 }
       
   505 
       
   506 //--------------------------------------------------------------------------------------------
       
   507 //
       
   508 // CXhtmlFileComposer::FinalizeBufferL
       
   509 //
       
   510 //--------------------------------------------------------------------------------------------
       
   511 TPtrC8 CXhtmlFileComposer::FinalizeBufferL()
       
   512 {
       
   513 	LOG("[CXhtmlFileComposer]\t FinalizeBufferL");
       
   514 
       
   515 	User::LeaveIfNull(iFileBuf);
       
   516 
       
   517 	SetPageTypeL();
       
   518 
       
   519 	// Remove markers from the buffer
       
   520 	TInt pos = iFileBuf->Find(KPage());
       
   521 	if(KErrNotFound != pos)
       
   522 		iFileBuf->Des().Delete(pos, KPage().Length());
       
   523 
       
   524 	pos = iFileBuf->Find(KFrame());
       
   525 	if(KErrNotFound != pos)
       
   526 		iFileBuf->Des().Delete(pos, KFrame().Length());
       
   527 
       
   528 	pos = iFileBuf->Find(KImgDetails());
       
   529 	if(KErrNotFound != pos)
       
   530 		iFileBuf->Des().Delete(pos, KImgDetails().Length());
       
   531 
       
   532 	pos = iFileBuf->Find(KFramePosition());
       
   533 	if(KErrNotFound != pos)
       
   534 		iFileBuf->Des().Delete(pos, KFramePosition().Length());
       
   535 
       
   536 	// Cut the template to the end tag
       
   537 	pos = iFileBuf->Find(KEndTag());
       
   538 	if(KErrNotFound == pos)
       
   539 		User::Leave(KErrCorrupt);
       
   540 
       
   541 	TInt dataLen = pos + KEndTag().Length();
       
   542 	TPtrC8 tail = iFileBuf->Des().Left(dataLen);
       
   543 
       
   544 	return tail;
       
   545 }
       
   546 
       
   547 //--------------------------------------------------------------------------------------------
       
   548 //
       
   549 // CXhtmlFileComposer::PageData
       
   550 //
       
   551 //--------------------------------------------------------------------------------------------
       
   552 void CXhtmlFileComposer::PageData(TInt aPaperSize)
       
   553 {
       
   554 	LOG("[CXhtmlFileComposer]\t PageData");
       
   555 
       
   556 	const TSizeReal KSizeA4(210.0, 297.0);
       
   557 	const TSizeReal KSizeA6(105.0, 148.5);
       
   558 	const TSizeReal KSizeLetter(8.5, 11.0);
       
   559 	const TSizeReal KSize4x6(4.0, 6.0);
       
   560 	const TSizeReal KSize5x7(5.0, 7.0);
       
   561 
       
   562 	switch(aPaperSize)
       
   563 	{
       
   564 		case EPrintCapabPaperSizeA4:
       
   565 			iPaperType = CXhtmlFileComposer::EUAMillis;
       
   566 			iPaperSize = UnitToPixel(KSizeA4);
       
   567 			iPageMargin = 3.0;
       
   568 			break;
       
   569 		case EPrintCapabPaperSizeA6:
       
   570 			iPaperType = CXhtmlFileComposer::EUAMillis;
       
   571 			iPaperSize = UnitToPixel(KSizeA6);
       
   572 			iPageMargin = 3.0;
       
   573 			break;
       
   574 		case EPrintCapabPaperSizeLetter:
       
   575 			iPaperType = CXhtmlFileComposer::EUAInches;
       
   576 			iPaperSize = UnitToPixel(KSizeLetter);
       
   577 			iPageMargin = 0.12;
       
   578 			break;
       
   579 		case EPrintCapabPaperSize5x7:
       
   580 			iPaperType = CXhtmlFileComposer::EUAInches;
       
   581 			iPaperSize = UnitToPixel(KSize5x7);
       
   582 			iPageMargin = 0.12;
       
   583 			break;
       
   584 		case EPrintCapabPaperSizeAuto:
       
   585 		case EPrintCapabPaperSizeSticker:
       
   586 		case EPrintCapabPaperSize4x6:
       
   587 		default:
       
   588 			iPaperType = CXhtmlFileComposer::EUAInches;
       
   589 			iPaperSize = UnitToPixel(KSize4x6);
       
   590 			iPageMargin = 0.12;
       
   591 			break;
       
   592 	}
       
   593 }
       
   594 
       
   595 //--------------------------------------------------------------------------------------------
       
   596 //
       
   597 // CXhtmlFileComposer::LayoutData
       
   598 //
       
   599 //--------------------------------------------------------------------------------------------
       
   600 void CXhtmlFileComposer::LayoutData(TInt aLayout, RArray<TSizeReal>& aPositions)
       
   601 {
       
   602 	LOG1("[CXhtmlFileComposer::LayoutData]\t aLayout: %d", aLayout);
       
   603 
       
   604 	TSizeReal pos(0,0);
       
   605 
       
   606 	switch(aLayout)
       
   607 	{
       
   608 		case EPrintCapabLayout1UpBorder:
       
   609 			iImagesPerPage = 1;
       
   610 			iPagePortrait = EFalse;
       
   611 			CreateMatrix(1/*rows*/, 1/*columns*/, aPositions);
       
   612 			break;
       
   613 		case EPrintCapabLayout2Up:
       
   614 			iImagesPerPage = 2;
       
   615 			iPagePortrait = ETrue;
       
   616 			CreateMatrix(2, 1, aPositions);
       
   617 			break;
       
   618 		case EPrintCapabLayout4Up:
       
   619 			iImagesPerPage = 4;
       
   620 			iPagePortrait = EFalse;
       
   621 			CreateMatrix(2, 2, aPositions);
       
   622 			break;
       
   623 		case EPrintCapabLayout6Up:
       
   624 			iImagesPerPage = 6;
       
   625 			iPagePortrait = ETrue;
       
   626 			CreateMatrix(3, 2, aPositions);
       
   627 			break;
       
   628 		case EPrintCapabLayout9Up:
       
   629 			iImagesPerPage = 9;
       
   630 			iPagePortrait = EFalse;
       
   631 			CreateMatrix(3, 3, aPositions);
       
   632 			break;
       
   633 		case EPrintCapabLayout12Up:
       
   634 			iImagesPerPage = 12;
       
   635 			iPagePortrait = ETrue;
       
   636 			CreateMatrix(4, 3, aPositions);
       
   637 			break;
       
   638 		case EPrintCapabLayout16Up:
       
   639 			iImagesPerPage = 16;
       
   640 			iPagePortrait = EFalse;
       
   641 			CreateMatrix(4, 4, aPositions);
       
   642 			break;
       
   643 		case EPrintCapabLayout1Up:
       
   644 		case EPrintCapabLayout1UpBorderless:
       
   645 		default:
       
   646 			iImagesPerPage = 1;
       
   647 			iPageMargin = 0;
       
   648 			iImageFrame = iPaperSize;
       
   649 			iPagePortrait = EFalse;
       
   650 			aPositions.Append(pos);
       
   651 			break;
       
   652 	}
       
   653 }
       
   654 
       
   655 //--------------------------------------------------------------------------------------------
       
   656 //
       
   657 // CXhtmlFileComposer::CreateMatrix
       
   658 //
       
   659 //--------------------------------------------------------------------------------------------
       
   660 void CXhtmlFileComposer::CreateMatrix(TInt aRows, TInt aColumns, RArray<TSizeReal>& aPositions)
       
   661 {
       
   662 	LOG("[CXhtmlFileComposer]\t CreateMatrix");
       
   663 
       
   664 	TSizeReal pos;
       
   665 	TSizeReal matrix(aColumns,aRows);
       
   666 	TSizeReal relativeSize(KFrameRatio, 1);
       
   667 
       
   668 	if(!iPagePortrait)
       
   669 	{
       
   670 		matrix.Reverse();
       
   671 		relativeSize.Reverse();
       
   672 	}
       
   673 
       
   674 	// count print area: paper size - margins
       
   675 	TSizeReal margins(matrix);
       
   676 	margins += 1; 
       
   677 	margins *= UnitToPixel(iPageMargin);
       
   678 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t margins: %fx%f", PixelToUnit(margins.iWidth), PixelToUnit(margins.iHeight));
       
   679 
       
   680 	TSizeReal printArea = (iPaperSize - margins);
       
   681 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t printArea: %fx%f", PixelToUnit(printArea.iWidth), PixelToUnit(printArea.iHeight));
       
   682 
       
   683 	// Count frame size
       
   684 
       
   685 	iImageFrame = printArea/matrix;
       
   686 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t iImageFrame bef. ratio: %fx%f", PixelToUnit(iImageFrame.iWidth), PixelToUnit(iImageFrame.iHeight));
       
   687 
       
   688 	LOG1("[CXhtmlFileComposer::CreateMatrix]\t frame ratio: %f", iImageFrame.Ratio());
       
   689 
       
   690 	// force frame ratio to KFrameRatio ratio
       
   691 	LOG1("[CXhtmlFileComposer::CreateMatrix]\t relativeRatio: %f", relativeSize.Ratio());
       
   692 
       
   693 	TReal relativeRatio = relativeSize.Ratio()/iImageFrame.Ratio();
       
   694 	if(1 < relativeRatio)
       
   695 	{
       
   696 		iImageFrame.iHeight /= relativeRatio;
       
   697 	}
       
   698 	else if(1 > relativeRatio)
       
   699 	{
       
   700 		iImageFrame.iWidth *= relativeRatio;
       
   701 	}
       
   702 
       
   703 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t iImageFrame aft. ratio: %fx%f", PixelToUnit(iImageFrame.iWidth), PixelToUnit(iImageFrame.iHeight));
       
   704 	LOG1("[CXhtmlFileComposer::CreateMatrix]\t --> ratio: %f (1.3325/0.7505)", iImageFrame.Ratio());
       
   705 
       
   706 	// Count the empty space on page to centerise the frame set
       
   707 	TSizeReal frameSetSize(iImageFrame*matrix);
       
   708 	TSizeReal emptySpace = (printArea - frameSetSize) / 2;
       
   709 
       
   710 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t frameSetSize:\t %fx%f", PixelToUnit(frameSetSize.iWidth), PixelToUnit(frameSetSize.iHeight));
       
   711 	LOG2("[CXhtmlFileComposer::CreateMatrix]\t emptySpace:\t %fx%f", PixelToUnit(emptySpace.iWidth), PixelToUnit(emptySpace.iHeight));
       
   712 
       
   713 	// if only one image/page, no need to calculate positions.
       
   714 	if(0 >= aColumns || 0 >= aRows)
       
   715 	{
       
   716 		aPositions.Append(pos);
       
   717 		return;
       
   718 	}
       
   719 
       
   720 	emptySpace.Reverse();
       
   721 	
       
   722 	for(TInt row = 0; row < aRows; ++row)
       
   723 	{
       
   724 		LOG1("[CXhtmlFileComposer::CreateMatrix]\t row: %d", row);
       
   725 		pos.iWidth = (iImageFrame.iHeight+UnitToPixel(iPageMargin)) * row;
       
   726 		pos.iWidth += emptySpace.iWidth;
       
   727 		for(TInt col = 0; col < aColumns; ++col)
       
   728 		{
       
   729 			pos.iHeight = (iImageFrame.iWidth+UnitToPixel(iPageMargin)) * col;
       
   730 			pos.iHeight += emptySpace.iHeight;
       
   731 			LOG2("[CXhtmlFileComposer::CreateMatrix]\t col: %fx%f", PixelToUnit(pos.iWidth), PixelToUnit(pos.iHeight));
       
   732 			aPositions.Append(pos);
       
   733 		}
       
   734 	}
       
   735 }
       
   736 
       
   737 //--------------------------------------------------------------------------------------------
       
   738 //
       
   739 // CXhtmlFileComposer::ReadTemplateL
       
   740 //
       
   741 //--------------------------------------------------------------------------------------------
       
   742 void CXhtmlFileComposer::ReadTemplateFileL()
       
   743 {
       
   744 	LOG("[CXhtmlFileComposer]\t ReadTemplateL");
       
   745 	// Open the template file and read it into buffer
       
   746 	RFile templateFile;
       
   747 	CleanupClosePushL(templateFile);
       
   748 
       
   749 #ifdef _DEBUG
       
   750 	//_LIT(KFile, "e:\\UPnPXHTMLTemplate.xhtml");
       
   751 	_LIT(KFileName, "UPnPXHTMLTemplate.xhtml");
       
   752 	TInt drive;
       
   753   TFileName path;
       
   754 
       
   755   DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRemovableMassStorage, drive);
       
   756   PathInfo::GetRootPath(path, drive);
       
   757   path.Append(KFileName());
       
   758     
       
   759   TInt e = templateFile.Open( iFsSession, path, EFileRead);
       
   760 	if(KErrNone != e)
       
   761 #endif
       
   762 	{
       
   763 		User::LeaveIfError( templateFile.Open( iFsSession, KXHTMLTemplate(), EFileRead) );
       
   764 	}
       
   765 	TInt fileSize = 0;
       
   766 	TInt err = templateFile.Size(fileSize);
       
   767 	if(KErrNone != err)
       
   768 		fileSize = KXFCMaxFileSize;
       
   769 
       
   770 	iFileBuf = HBufC8::NewL(fileSize);
       
   771 	TPtr8 bufferPtr( iFileBuf->Des() );
       
   772 
       
   773 	bufferPtr.Zero();
       
   774 	templateFile.Read(bufferPtr);
       
   775 
       
   776 	CleanupStack::PopAndDestroy(&templateFile);
       
   777 
       
   778 	// Separate page, frame position, image details and frame
       
   779 	// template elements from the template buffer
       
   780 	GetTemplateStringL(KPageStart(), KPageEnd(), iPageTemplate);
       
   781 	GetTemplateStringL(KFrameStart(), KFrameEnd(), iFrameTemplate);
       
   782 	GetTemplateStringL(KPositionStart(), KPositionEnd(),iPositionTemplate);
       
   783 	GetTemplateStringL(KImgStart(), KImgEnd(), iImageTemplate);
       
   784 }
       
   785 
       
   786 //--------------------------------------------------------------------------------------------
       
   787 //
       
   788 // CXhtmlFileComposer::GetTemplateStringL
       
   789 //
       
   790 //--------------------------------------------------------------------------------------------
       
   791 TPtrC8 CXhtmlFileComposer::GetTemplateStringL(const TDesC8 &aStart, const TDesC8 &aEnd, TDes8 &aTemplate)
       
   792 {
       
   793 	User::LeaveIfNull(iFileBuf);
       
   794 
       
   795 	TInt start = iFileBuf->Find(aStart);
       
   796 	if(KErrNotFound == start)
       
   797 		User::Leave(KErrCorrupt);
       
   798 
       
   799 	TInt end = iFileBuf->Find(aEnd);
       
   800 	if(KErrNotFound == end)
       
   801 		User::Leave(KErrCorrupt);
       
   802 
       
   803 	TPtrC8 ptr = iFileBuf->Des().Mid(start+aStart.Length(), end-start-aStart.Length());
       
   804 
       
   805 	if(aTemplate.MaxLength() < ptr.Length())
       
   806 		User::Leave(KErrOverflow);
       
   807 
       
   808 	aTemplate = ptr;
       
   809 	iFileBuf->Des().Delete(start, ptr.Length()+aStart.Length()+aEnd.Length());
       
   810 	return ptr;
       
   811 }
       
   812 
       
   813 //--------------------------------------------------------------------------------------------
       
   814 //
       
   815 // CXhtmlFileComposer::AddTemplateStringL
       
   816 //
       
   817 //--------------------------------------------------------------------------------------------
       
   818 void CXhtmlFileComposer::AddTemplateStringL(const TDesC8 &aTemplate,const TDesC8 &aTag)
       
   819 {
       
   820 	User::LeaveIfNull(iFileBuf);
       
   821 
       
   822 	TInt pos = iFileBuf->Find(aTag);
       
   823 	if(KErrNotFound == pos)
       
   824 		User::Leave(KErrCorrupt);
       
   825 
       
   826 	TInt requiredSize = iFileBuf->Des().Length() + aTemplate.Length();
       
   827 	if(iFileBuf->Des().MaxLength() < requiredSize)
       
   828 	{
       
   829 		iFileBuf = iFileBuf->ReAllocL(requiredSize);
       
   830 	}
       
   831 	iFileBuf->Des().Insert(pos, aTemplate);
       
   832 }
       
   833 
       
   834 //--------------------------------------------------------------------------------------------
       
   835 //
       
   836 // CXhtmlFileComposer::GetImageDataL
       
   837 //
       
   838 //--------------------------------------------------------------------------------------------
       
   839 TSizeReal CXhtmlFileComposer::GetImageSizeL(CImageInfo aImage)
       
   840 {
       
   841 	TSizeReal imageSize(0,0);
       
   842 	TFileName name;
       
   843 	aImage.GetFilePathL(name);
       
   844 	if(name.Compare(KNullDesC()))
       
   845 	{
       
   846 		// Test file existing
       
   847 		TEntry data;
       
   848 		TInt err = iFsSession.Entry(name, data);
       
   849 		User::LeaveIfError(err);
       
   850 
       
   851 		// Get image size in pixels
       
   852 		CImageDecoder *id = NULL;
       
   853 		TRAP(err, id = CImageDecoder::FileNewL(iFsSession, name, KMimeJpeg()));
       
   854 
       
   855 		if(KErrNone == err)
       
   856 		{
       
   857 			TFrameInfo frameInfo;
       
   858 			frameInfo = id->FrameInfo();
       
   859 			imageSize = frameInfo.iOverallSizeInPixels;
       
   860 		}
       
   861 
       
   862 		if(id)
       
   863 			delete id;
       
   864 	}
       
   865 	LOG2("[CXhtmlFileComposer]\t Image size: %fx%f", imageSize.iWidth, imageSize.iHeight);
       
   866 	return imageSize;
       
   867 }
       
   868 
       
   869 //--------------------------------------------------------------------------------------------
       
   870 //
       
   871 // CXhtmlFileComposer::AddPageL
       
   872 //
       
   873 //--------------------------------------------------------------------------------------------
       
   874 TBool CXhtmlFileComposer::AddPageL(TInt aCurrentImage, TInt& aPositionIndex, TInt& aPageCount)
       
   875 {
       
   876 	TBool ret = EFalse;
       
   877 	// increase position index by default and reset it in case of new page
       
   878 	++aPositionIndex;
       
   879 
       
   880 	User::LeaveIfNull(iFileBuf);
       
   881 	if(0 >= iImagesPerPage)
       
   882 		User::Leave(KErrArgument);
       
   883 
       
   884 	TInt modulo = aCurrentImage % iImagesPerPage;
       
   885 
       
   886 	if(0 == modulo)
       
   887 	{
       
   888 		//delete current page's frame marker before...
       
   889 		TInt pos = iFileBuf->Find(KFrame());
       
   890 		if(KErrNotFound != pos)
       
   891 			iFileBuf->Des().Delete(pos, KFrame().Length());
       
   892 
       
   893 		// ...add the new page template and reset position index
       
   894 		AddTemplateStringL(iPageTemplate, KPage());
       
   895 		aPositionIndex = 0;
       
   896 		++aPageCount;
       
   897 		ret = ETrue;
       
   898 	}
       
   899 	return ret;
       
   900 }
       
   901 
       
   902 //--------------------------------------------------------------------------------------------
       
   903 //
       
   904 // CXhtmlFileComposer::GetImageName
       
   905 //
       
   906 //--------------------------------------------------------------------------------------------
       
   907 void CXhtmlFileComposer::GetImageNameL(CImageInfo aImageInfo, TDes8 &aImageName, TBool aDataFile)
       
   908 {
       
   909 	aImageInfo.GetEncodedUriL(aImageName);
       
   910 	if(0 >= aImageName.Length() || aDataFile)
       
   911 	{
       
   912 		aImageInfo.GetFilePath(aImageName);
       
   913 		if(0 >= aImageName.Length())
       
   914 			User::Leave(KErrArgument);
       
   915 	}
       
   916 	
       
   917 	LOG81("[CXhtmlFileComposer]\t Image: %S", &aImageName);
       
   918 }
       
   919 
       
   920 //--------------------------------------------------------------------------------------------
       
   921 //
       
   922 // CXhtmlFileComposer::SizeAndOrientationL
       
   923 //
       
   924 //--------------------------------------------------------------------------------------------
       
   925 void CXhtmlFileComposer::SizeAndOrientationL(const CImageInfo aImageInfo, TSizeReal& aImageSize, TBool& aFramePortrait)
       
   926 {
       
   927 	aImageSize = GetImageSizeL(aImageInfo);
       
   928 
       
   929 	// If the size of any of the sides is zero, set the size as frame size
       
   930 	if(0 >= aImageSize.iWidth)
       
   931 		aImageSize = iImageFrame;
       
   932 
       
   933 	// orientations
       
   934 	iImagePortrait = (aImageSize.iWidth < aImageSize.iHeight ? ETrue : EFalse);
       
   935 	aFramePortrait = (iImageFrame.iWidth < iImageFrame.iHeight ? ETrue : EFalse);
       
   936 
       
   937 	// Set orientation in degrees
       
   938 	TInt orientation = KXFCZeroDeg;
       
   939 	if(aFramePortrait != iImagePortrait)
       
   940 		orientation = KXFC90Deg;
       
   941 
       
   942 	// Set orientation in template
       
   943 	TXhtmlSetting orientationStr;
       
   944 	orientationStr.Format(KDeg(), orientation);
       
   945 	ComposeTemplateL(orientationStr, KImgOrientation());
       
   946 
       
   947 	// Set image and image frame temporarily in same orientation
       
   948 	if(aFramePortrait != iImagePortrait)
       
   949 		iImageFrame.Reverse();
       
   950 }
       
   951 
       
   952 //--------------------------------------------------------------------------------------------
       
   953 //
       
   954 // CXhtmlFileComposer::GetImageName
       
   955 //
       
   956 //--------------------------------------------------------------------------------------------
       
   957 void CXhtmlFileComposer::ComposePositionL(TInt aPositionIndex, RArray<TSizeReal>& aPositions)
       
   958 {
       
   959 	TSizeReal position(0,0);
       
   960 	if(aPositions.Count() <= aPositionIndex)
       
   961 		aPositionIndex = 0;
       
   962 
       
   963 	if(0 < aPositions.Count())
       
   964 		position = aPositions[aPositionIndex];
       
   965 
       
   966 	// Format position
       
   967 	TXhtmlSetting  positionTopStr, positionLeftStr;
       
   968 
       
   969 	FormatReal(PixelToUnit(position.iWidth), positionTopStr);
       
   970 	ComposeTemplateL(positionTopStr, KPositionTop());
       
   971 
       
   972 	FormatReal(PixelToUnit(position.iHeight), positionLeftStr);
       
   973 	ComposeTemplateL(positionLeftStr, KPositionLeft());
       
   974 }
       
   975 
       
   976 //--------------------------------------------------------------------------------------------
       
   977 //
       
   978 // CXhtmlFileComposer::FormatReal
       
   979 //
       
   980 //--------------------------------------------------------------------------------------------
       
   981 void CXhtmlFileComposer::FormatReal(TRealX aNumber, TDes8& aString)
       
   982 {
       
   983 	TRealFormat form;
       
   984 	form.iPlaces = 4;
       
   985 	form.iPoint = TChar('.');
       
   986 	form.iType = KDoNotUseTriads | KRealFormatFixed;
       
   987 
       
   988 	aString.Num(aNumber, form);
       
   989 	aString.Append(KUnit());
       
   990 }
       
   991 
       
   992 // End of file