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