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