| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 dispatchEventsForPrintingOnAllFrames(); | 297 dispatchEventsForPrintingOnAllFrames(); |
| 298 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) | 298 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) |
| 299 return 0; | 299 return 0; |
| 300 | 300 |
| 301 frame()->view()->updateAllLifecyclePhasesExceptPaint(); | 301 frame()->view()->updateAllLifecyclePhasesExceptPaint(); |
| 302 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) | 302 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) |
| 303 return 0; | 303 return 0; |
| 304 | 304 |
| 305 // The page rect gets scaled and translated, so specify the entire | 305 // The page rect gets scaled and translated, so specify the entire |
| 306 // print content area here as the recording rect. | 306 // print content area here as the recording rect. |
| 307 IntRect printedPageRect(0, 0, m_printedPageHeight, m_printedPageWidth); | 307 IntRect bounds(0, 0, m_printedPageHeight, m_printedPageWidth); |
| 308 PaintRecordBuilder builder(printedPageRect, &canvas->getMetaData()); | 308 PaintRecordBuilder builder(bounds, &canvas->getMetaData()); |
| 309 builder.context().setPrinting(true); | 309 builder.context().setPrinting(true); |
| 310 | 310 builder.context().beginRecording(bounds); |
| 311 float scale = spoolPage(builder, pageNumber); | 311 float scale = spoolPage(builder.context(), pageNumber, bounds); |
| 312 canvas->PlaybackPaintRecord(builder.endRecording()); | 312 canvas->PlaybackPaintRecord(builder.context().endRecording()); |
| 313 return scale; | 313 return scale; |
| 314 } | 314 } |
| 315 | 315 |
| 316 void spoolAllPagesWithBoundaries(WebCanvas* canvas, | 316 void spoolAllPagesWithBoundaries(WebCanvas* canvas, |
| 317 const FloatSize& pageSizeInPixels) { | 317 const FloatSize& pageSizeInPixels) { |
| 318 dispatchEventsForPrintingOnAllFrames(); | 318 dispatchEventsForPrintingOnAllFrames(); |
| 319 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) | 319 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) |
| 320 return; | 320 return; |
| 321 | 321 |
| 322 frame()->view()->updateAllLifecyclePhasesExceptPaint(); | 322 frame()->view()->updateAllLifecyclePhasesExceptPaint(); |
| 323 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) | 323 if (!frame()->document() || frame()->document()->layoutViewItem().isNull()) |
| 324 return; | 324 return; |
| 325 | 325 |
| 326 float pageHeight; | 326 float pageHeight; |
| 327 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, | 327 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, |
| 328 pageHeight); | 328 pageHeight); |
| 329 | 329 |
| 330 const float pageWidth = pageSizeInPixels.width(); | 330 const float pageWidth = pageSizeInPixels.width(); |
| 331 size_t numPages = pageRects().size(); | 331 size_t numPages = pageRects().size(); |
| 332 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1; | 332 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1; |
| 333 IntRect allPagesRect(0, 0, pageWidth, totalHeight); | 333 IntRect allPagesRect(0, 0, pageWidth, totalHeight); |
| 334 | 334 |
| 335 PaintRecordBuilder builder(allPagesRect, &canvas->getMetaData()); | 335 PaintRecordBuilder builder(allPagesRect, &canvas->getMetaData()); |
| 336 builder.context().setPrinting(true); | |
| 337 | |
| 338 { | 336 { |
| 339 GraphicsContext& context = builder.context(); | 337 GraphicsContext& context = builder.context(); |
| 340 DisplayItemCacheSkipper skipper(context); | 338 context.setPrinting(true); |
| 339 context.beginRecording(allPagesRect); |
| 341 | 340 |
| 342 // Fill the whole background by white. | 341 // Fill the whole background by white. |
| 343 { | 342 context.fillRect(FloatRect(0, 0, pageWidth, totalHeight), Color::white); |
| 344 DrawingRecorder backgroundRecorder( | |
| 345 context, builder, DisplayItem::kPrintedContentBackground, | |
| 346 allPagesRect); | |
| 347 context.fillRect(FloatRect(0, 0, pageWidth, totalHeight), Color::white); | |
| 348 } | |
| 349 | 343 |
| 350 int currentHeight = 0; | 344 int currentHeight = 0; |
| 351 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) { | 345 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) { |
| 352 // Draw a line for a page boundary if this isn't the first page. | 346 // Draw a line for a page boundary if this isn't the first page. |
| 353 if (pageIndex > 0) { | 347 if (pageIndex > 0) { |
| 354 DrawingRecorder lineBoundaryRecorder( | |
| 355 context, builder, DisplayItem::kPrintedContentLineBoundary, | |
| 356 allPagesRect); | |
| 357 context.save(); | 348 context.save(); |
| 358 context.setStrokeColor(Color(0, 0, 255)); | 349 context.setStrokeColor(Color(0, 0, 255)); |
| 359 context.setFillColor(Color(0, 0, 255)); | 350 context.setFillColor(Color(0, 0, 255)); |
| 360 context.drawLine(IntPoint(0, currentHeight), | 351 context.drawLine(IntPoint(0, currentHeight), |
| 361 IntPoint(pageWidth, currentHeight)); | 352 IntPoint(pageWidth, currentHeight)); |
| 362 context.restore(); | 353 context.restore(); |
| 363 } | 354 } |
| 364 | 355 |
| 365 AffineTransform transform; | 356 AffineTransform transform; |
| 366 transform.translate(0, currentHeight); | 357 transform.translate(0, currentHeight); |
| 367 #if OS(WIN) || OS(MACOSX) | 358 #if OS(WIN) || OS(MACOSX) |
| 368 // Account for the disabling of scaling in spoolPage. In the context | 359 // Account for the disabling of scaling in spoolPage. In the context |
| 369 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied. | 360 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied. |
| 370 float scale = getPageShrink(pageIndex); | 361 float scale = getPageShrink(pageIndex); |
| 371 transform.scale(scale, scale); | 362 transform.scale(scale, scale); |
| 372 #endif | 363 #endif |
| 373 TransformRecorder transformRecorder(context, builder, transform); | 364 context.save(); |
| 374 spoolPage(builder, pageIndex); | 365 context.concatCTM(transform); |
| 366 |
| 367 spoolPage(context, pageIndex, allPagesRect); |
| 368 |
| 369 context.restore(); |
| 375 | 370 |
| 376 currentHeight += pageSizeInPixels.height() + 1; | 371 currentHeight += pageSizeInPixels.height() + 1; |
| 377 } | 372 } |
| 373 canvas->PlaybackPaintRecord(context.endRecording()); |
| 378 } | 374 } |
| 379 canvas->PlaybackPaintRecord(builder.endRecording()); | |
| 380 } | 375 } |
| 381 | 376 |
| 382 protected: | 377 protected: |
| 383 // Spools the printed page, a subrect of frame(). Skip the scale step. | 378 // Spools the printed page, a subrect of frame(). Skip the scale step. |
| 384 // NativeTheme doesn't play well with scaling. Scaling is done browser side | 379 // NativeTheme doesn't play well with scaling. Scaling is done browser side |
| 385 // instead. Returns the scale to be applied. | 380 // instead. Returns the scale to be applied. |
| 386 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit | 381 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit |
| 387 // do the scaling and ignore the return value. | 382 // do the scaling and ignore the return value. |
| 388 virtual float spoolPage(PaintRecordBuilder& builder, int pageNumber) { | 383 virtual float spoolPage(GraphicsContext& context, |
| 384 int pageNumber, |
| 385 const IntRect& bounds) { |
| 389 IntRect pageRect = m_pageRects[pageNumber]; | 386 IntRect pageRect = m_pageRects[pageNumber]; |
| 390 float scale = m_printedPageWidth / pageRect.width(); | 387 float scale = m_printedPageWidth / pageRect.width(); |
| 391 GraphicsContext& context = builder.context(); | |
| 392 | 388 |
| 393 AffineTransform transform; | 389 AffineTransform transform; |
| 394 #if OS(POSIX) && !OS(MACOSX) | 390 #if OS(POSIX) && !OS(MACOSX) |
| 395 transform.scale(scale); | 391 transform.scale(scale); |
| 396 #endif | 392 #endif |
| 397 transform.translate(static_cast<float>(-pageRect.x()), | 393 transform.translate(static_cast<float>(-pageRect.x()), |
| 398 static_cast<float>(-pageRect.y())); | 394 static_cast<float>(-pageRect.y())); |
| 399 TransformRecorder transformRecorder(context, builder, transform); | 395 context.save(); |
| 396 context.concatCTM(transform); |
| 397 context.clipRect(pageRect); |
| 400 | 398 |
| 401 ClipRecorder clipRecorder(context, builder, DisplayItem::kClipPrintedPage, | 399 PaintRecordBuilder builder(bounds, &context.canvas()->getMetaData()); |
| 402 pageRect); | |
| 403 | 400 |
| 404 frame()->view()->paintContents(context, GlobalPaintNormalPhase, pageRect); | 401 // The local scope is so that the cache skipper is destroyed before |
| 402 // we call endRecording(). |
| 403 { |
| 404 DisplayItemCacheSkipper skipper(builder.context()); |
| 405 frame()->view()->paintContents(builder.context(), GlobalPaintNormalPhase, |
| 406 pageRect); |
| 405 | 407 |
| 406 { | |
| 407 DrawingRecorder lineBoundaryRecorder( | 408 DrawingRecorder lineBoundaryRecorder( |
| 408 context, builder, DisplayItem::kPrintedContentDestinationLocations, | 409 builder.context(), builder, |
| 409 pageRect); | 410 DisplayItem::kPrintedContentDestinationLocations, pageRect); |
| 410 outputLinkedDestinations(context, pageRect); | 411 outputLinkedDestinations(builder.context(), pageRect); |
| 411 } | 412 } |
| 413 context.drawRecord(builder.endRecording()); |
| 414 |
| 415 context.restore(); |
| 412 | 416 |
| 413 return scale; | 417 return scale; |
| 414 } | 418 } |
| 415 | 419 |
| 416 private: | 420 private: |
| 417 void dispatchEventsForPrintingOnAllFrames() { | 421 void dispatchEventsForPrintingOnAllFrames() { |
| 418 HeapVector<Member<Document>> documents; | 422 HeapVector<Member<Document>> documents; |
| 419 for (Frame* currentFrame = frame(); currentFrame; | 423 for (Frame* currentFrame = frame(); currentFrame; |
| 420 currentFrame = currentFrame->tree().traverseNext(frame())) { | 424 currentFrame = currentFrame->tree().traverseNext(frame())) { |
| 421 if (currentFrame->isLocalFrame()) | 425 if (currentFrame->isLocalFrame()) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 | 474 |
| 471 void computePageRectsWithPageSize( | 475 void computePageRectsWithPageSize( |
| 472 const FloatSize& pageSizeInPixels) override { | 476 const FloatSize& pageSizeInPixels) override { |
| 473 NOTREACHED(); | 477 NOTREACHED(); |
| 474 } | 478 } |
| 475 | 479 |
| 476 protected: | 480 protected: |
| 477 // Spools the printed page, a subrect of frame(). Skip the scale step. | 481 // Spools the printed page, a subrect of frame(). Skip the scale step. |
| 478 // NativeTheme doesn't play well with scaling. Scaling is done browser side | 482 // NativeTheme doesn't play well with scaling. Scaling is done browser side |
| 479 // instead. Returns the scale to be applied. | 483 // instead. Returns the scale to be applied. |
| 480 float spoolPage(PaintRecordBuilder& builder, int pageNumber) override { | 484 float spoolPage(GraphicsContext& context, |
| 485 int pageNumber, |
| 486 const IntRect& bounds) override { |
| 481 IntRect pageRect = m_pageRects[pageNumber]; | 487 IntRect pageRect = m_pageRects[pageNumber]; |
| 482 m_plugin->printPage(pageNumber, builder.context(), pageRect); | 488 PaintRecordBuilder builder(bounds, &context.canvas()->getMetaData()); |
| 489 // The local scope is so that the cache skipper is destroyed before |
| 490 // we call endRecording(). |
| 491 { |
| 492 DisplayItemCacheSkipper skipper(builder.context()); |
| 493 m_plugin->printPage(pageNumber, builder.context(), pageRect); |
| 494 } |
| 495 context.drawRecord(builder.endRecording()); |
| 483 | 496 |
| 484 return 1.0; | 497 return 1.0; |
| 485 } | 498 } |
| 486 | 499 |
| 487 private: | 500 private: |
| 488 // Set when printing. | 501 // Set when printing. |
| 489 Member<WebPluginContainerImpl> m_plugin; | 502 Member<WebPluginContainerImpl> m_plugin; |
| 490 WebPrintParams m_printParams; | 503 WebPrintParams m_printParams; |
| 491 }; | 504 }; |
| 492 | 505 |
| (...skipping 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2503 createMarkup(startPosition, endPosition, AnnotateForInterchange, | 2516 createMarkup(startPosition, endPosition, AnnotateForInterchange, |
| 2504 ConvertBlocksToInlines::NotConvert, ResolveNonLocalURLs); | 2517 ConvertBlocksToInlines::NotConvert, ResolveNonLocalURLs); |
| 2505 } else { | 2518 } else { |
| 2506 clipHtml = | 2519 clipHtml = |
| 2507 createMarkup(endPosition, startPosition, AnnotateForInterchange, | 2520 createMarkup(endPosition, startPosition, AnnotateForInterchange, |
| 2508 ConvertBlocksToInlines::NotConvert, ResolveNonLocalURLs); | 2521 ConvertBlocksToInlines::NotConvert, ResolveNonLocalURLs); |
| 2509 } | 2522 } |
| 2510 } | 2523 } |
| 2511 | 2524 |
| 2512 } // namespace blink | 2525 } // namespace blink |
| OLD | NEW |