Hi

That's a good idea. I didn't think about implementing printing support
in test_shell. I see that you really took the time to investigate
before asking, that's really appreciated.

You don't need to buffer the commands into a EMF buffer. So you should
print directly into the context; e.g. use the third approach. The EMF
buffer is solely used to pass the buffer from one process to the
other. By using it inside test_shell, you multiply by 2x the memory
usage.

I looked at the code and I can't tell the exact reason you got correct
output with your first 2 examples. In theory, that's
PrintedDocument::RenderPrintedPage() that is doing the last fixup in
scale. This is done according to the expected dpi settings.

The code assumes a 72 dpi for display. In reality, it's much higher
than that but that's the ratio people are used to expect. The scaling
factor is directly dependent of the dpi of the printer.

72 dpi is specified in PrintSettings::desired_dpi.

Note that you will loose the headers and footers, what I call
overlays. They are generated on the browser side in
PrintedDocument::RenderPrintedPage(). They are manually scaled and
added over.

If you have any question, ping me on irc.

If you want to show me the current state of your prototype, you can
gcl change/gcl upload and send me the link to your review.

M-A

2008/9/10 Marshall <[EMAIL PROTECTED]>:
>
> Hi All,
>
> I'm in the process of adding printing support to the test_shell
> project as one of the precursors to developing a non-IPC embedded
> browser component based on chromium.  I've borrowed the
> printing::PrintingContext class and the following methods from the
> RenderView class:
>
> SwitchFrameToPrintMediaType
> SwitchFrameToDisplayMediaType
> PrintPage
> PrintPages
>
> I've gotten to the point where my PrintPage() equivalent works fine
> using a gfx::PlatformCanvasWin bitmap [example #1].
>
> My problems, however, are with the vector-based printing approaches:
> using gfx::VectorCanvas for rendering to either a gfx::Emf [example
> #2] or directly to the printer context [example #3].
>
> If I use the gfx::VectorCanvas class in combination with gfx::Emf as
> demonstrated in the RenderView::PrintPage() method then lines and
> bitmaps show up fine, but text does not display.  In fact, even though
> the ExtTextOut() function is being called in
> SkGraphicsContext::paintText(), no EMR_EXTTEXTOUTW record is being
> added to the gfx::Emf meta file (I've verified this by iterating
> through the gfx::Emf object and dumping the record types).  However,
> if I print the same page to the same printer using the chrome browser
> build (with IPC, of course) then gfx::VectorCanvas works as expected
> and I see the text along with everything else.
>
> I've also tried using the gfx::VectorCanvas class to render directly
> to the printer context.  In that case I see all objects including
> text, but everything appears very small. It seems that the
> ModifyWorldTransform() function call is being lost or ignored (If I
> remove the ModifyWorldTransform() call from example #2 then I get the
> same size output.)
>
> Does anyone have any suggestions on how I can get either of the
> gfx::VectorCanvas -based approaches working?  Or is there perhaps an
> even better approach for a non-IPC application?
>
> Thank you in advance for your time :-)
>
> Regards,
> Marshall
>
> Platform: Windows XP SP2
> Sources: /trunk rev 1823 (Sat, Sep 6)
>
>
> In the below examples "print_context_" is an instance of
> printing::PrintingContext.  I've tried to highlight only the relevant
> portions of the code -- if anyone thinks seeing the complete code
> would be helpful let me know and I'll make it available.
>
> [example #1] Using gfx::PlatformCanvasWin (works as expected):
>
>  gfx::Emf emf;
>
>  emf.CreateDc(NULL, NULL);
>  HDC hdc = emf.hdc();
>  DCHECK(hdc);
>  gfx::PlatformDeviceWin::InitializeDC(hdc);
>
>  // Mix of Skia and GDI based.
>  gfx::PlatformCanvasWin canvas(src_size_x, src_size_y, true);
>  canvas.drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
>  PlatformContextSkia context(&canvas);
>  if (!frame->SpoolPage(page_number, &context)) {
>    NOTREACHED() << "Printing page " << page_number << " failed.";
>    return;
>  }
>
>  // Create a BMP v4 header that we can serialize.
>  BITMAPV4HEADER bitmap_header;
>  gfx::CreateBitmapV4Header(src_size_x, src_size_y, &bitmap_header);
>  const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true);
>  SkAutoLockPixels src_lock(src_bmp);
>  int retval = StretchDIBits(hdc,
>                             0,
>                             0,
>                             src_size_x, src_size_y,
>                             0, 0,
>                             src_size_x, src_size_y,
>                             src_bmp.getPixels(),
>
> reinterpret_cast<BITMAPINFO*>(&bitmap_header),
>                             DIB_RGB_COLORS,
>                             SRCCOPY);
>
>  if (!emf.CloseDc()) {
>    NOTREACHED() << "EMF failed";
>  }
>
>  print_context_.NewPage();
>
>  HDC hDC = print_context_.context();
>
>  // Save the state to make sure the context this function call does
> not modify
>  // the device context.
>  int saved_state = SaveDC(hDC);
>  DCHECK_NE(saved_state, 0);
>
>  gfx::PlatformDeviceWin::InitializeDC(hDC);
>
>  // Setup the matrix to translate and scale to the right place. Take
> in
>  // account the actual shrinking factor.
>  XFORM xform = { 0 };
>  xform.eDx = static_cast<float>(src_size_x);
>  xform.eDy = static_cast<float>(src_size_y);
>  xform.eM11 = static_cast<float>(1. / shrink);
>  xform.eM22 = static_cast<float>(1. / shrink);
>  BOOL res = ModifyWorldTransform(hDC, &xform, MWT_LEFTMULTIPLY);
>  DCHECK_NE(res, 0);
>
>  if (!emf.SafePlayback(hDC)) {
>      NOTREACHED();
>  }
>
>  res = RestoreDC(hDC, saved_state);
>  DCHECK_NE(res, 0);
>
>  print_context_.PageDone();
>
>  emf.CloseEmf();
>
>
> [example #2] Using gfx::VectorCanvas (text is missing):
>
>  gfx::Emf emf;
>
>  emf.CreateDc(NULL, NULL);
>  HDC hdc = emf.hdc();
>  DCHECK(hdc);
>  gfx::PlatformDeviceWin::InitializeDC(hdc);
>
>  // 100% GDI based.
>  gfx::VectorCanvas canvas(hdc, src_size_x, src_size_y);
>  PlatformContextSkia context(&canvas);
>  // Set the clipping region to be sure to not overflow.
>  SkRect clip_rect;
>  clip_rect.set(0, 0, SkIntToScalar(src_size_x),
> SkIntToScalar(src_size_y));
>  canvas.clipRect(clip_rect);
>  if (!frame->SpoolPage(page_number, &context)) {
>    NOTREACHED() << "Printing page " << page_number << " failed.";
>    return;
>  }
>
>  if (!emf.CloseDc()) {
>    NOTREACHED() << "EMF failed";
>  }
>
>  print_context_.NewPage();
>
>  HDC hDC = print_context_.context();
>
>  // Save the state to make sure the context this function call does
> not modify
>  // the device context.
>  int saved_state = SaveDC(hDC);
>  DCHECK_NE(saved_state, 0);
>
>  gfx::PlatformDeviceWin::InitializeDC(hDC);
>
>  // Setup the matrix to translate and scale to the right place. Take
> in
>  // account the actual shrinking factor.
>  XFORM xform = { 0 };
>  xform.eDx = static_cast<float>(src_size_x);
>  xform.eDy = static_cast<float>(src_size_y);
>  xform.eM11 = static_cast<float>(1. / shrink);
>  xform.eM22 = static_cast<float>(1. / shrink);
>  BOOL res = ModifyWorldTransform(hDC, &xform, MWT_LEFTMULTIPLY);
>  DCHECK_NE(res, 0);
>
>  if (!emf.SafePlayback(hDC)) {
>      NOTREACHED();
>  }
>
>  res = RestoreDC(hDC, saved_state);
>  DCHECK_NE(res, 0);
>
>  print_context_.PageDone();
>
>  emf.CloseEmf();
>
>
> [example #3] Writing directly to the printer context without using
> gfx::Emf (everything is very small):
>
>  HDC hDC = print_context_.context();
>
>  print_context_.NewPage();
>
>  // Save the state to make sure the context this function call does
> not modify
>  // the device context.
>  int saved_state = SaveDC(hDC);
>  DCHECK_NE(saved_state, 0);
>
>  gfx::PlatformDeviceWin::InitializeDC(hDC);
>
>  // Setup the matrix to translate and scale to the right place. Take
> in
>  // account the actual shrinking factor.
>  XFORM xform = { 0 };
>  xform.eDx = static_cast<float>(src_size_x);
>  xform.eDy = static_cast<float>(src_size_y);
>  xform.eM11 = static_cast<float>(1. / shrink);
>  xform.eM22 = static_cast<float>(1. / shrink);
>  BOOL res = ModifyWorldTransform(hDC, &xform, MWT_LEFTMULTIPLY);
>  DCHECK_NE(res, 0);
>
>  // 100% GDI based.
>  gfx::VectorCanvas canvas(hDC, src_size_x, src_size_y);
>  PlatformContextSkia context(&canvas);
>  // Set the clipping region to be sure to not overflow.
>  SkRect clip_rect;
>  clip_rect.set(0, 0, SkIntToScalar(src_size_x),
> SkIntToScalar(src_size_y));
>  canvas.clipRect(clip_rect);
>
>  if (!frame->SpoolPage(page_number, &context)) {
>    NOTREACHED() << "Printing page " << page_number << " failed.";
>    return;
>  }
>
>  print_context_.PageDone();
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Chromium-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/chromium-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to