|
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 |