summaryrefslogtreecommitdiff
path: root/core/fxge
diff options
context:
space:
mode:
authorrbpotter <rbpotter@chromium.org>2017-01-12 10:31:43 -0800
committerCommit bot <commit-bot@chromium.org>2017-01-12 10:31:43 -0800
commitdb7647083d0a5cd2221b94faa15c149214d21725 (patch)
tree427c0beeb82796e8e550e672195061186d7db076 /core/fxge
parente7fb8eb3e9f220a5f0c852f0238ab8d536a8bc9d (diff)
downloadpdfium-db7647083d0a5cd2221b94faa15c149214d21725.tar.xz
Add postscript path
This patch adds the additional functions required to make postscript printing functional. The most significant additions are are two added compression functions and a new API for setting the postscript level. Not currently called from Chromium, Chromium patch to come. BUG= Review-Url: https://codereview.chromium.org/2612243005
Diffstat (limited to 'core/fxge')
-rw-r--r--core/fxge/cfx_windowsdevice.h1
-rw-r--r--core/fxge/win32/cfx_psrenderer.cpp78
-rw-r--r--core/fxge/win32/fx_win32_device.cpp18
-rw-r--r--core/fxge/win32/fx_win32_print.cpp9
4 files changed, 52 insertions, 54 deletions
diff --git a/core/fxge/cfx_windowsdevice.h b/core/fxge/cfx_windowsdevice.h
index 5a4b901621..6240d84219 100644
--- a/core/fxge/cfx_windowsdevice.h
+++ b/core/fxge/cfx_windowsdevice.h
@@ -25,6 +25,7 @@ extern bool g_pdfium_print_text_with_gdi;
extern PDFiumEnsureTypefaceCharactersAccessible
g_pdfium_typeface_accessible_func;
#endif
+extern int g_pdfium_print_postscript_level;
class CFX_WindowsDevice : public CFX_RenderDevice {
public:
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index c0d7557541..b62d0cb8f5 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -39,7 +39,7 @@ CFX_PSRenderer::CFX_PSRenderer() {
CFX_PSRenderer::~CFX_PSRenderer() {}
-#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str - 1)
+#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof(str) - 1)
void CFX_PSRenderer::Init(CPSOutput* pOutput,
int pslevel,
@@ -125,11 +125,9 @@ void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData,
buf << " m ";
break;
case FXPT_LINETO:
- if (flag & FXPT_CLOSEFIGURE) {
- buf << " l h ";
- } else {
- buf << " l ";
- }
+ buf << " l ";
+ if (flag & FXPT_CLOSEFIGURE)
+ buf << "h ";
break;
case FXPT_BEZIERTO: {
FX_FLOAT x1 = pPathData->GetPointX(i + 1);
@@ -140,12 +138,10 @@ void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData,
pObject2Device->Transform(x1, y1);
pObject2Device->Transform(x2, y2);
}
- buf << " " << x1 << " " << y1 << " " << x2 << " " << y2;
- if (flag & FXPT_CLOSEFIGURE) {
- buf << " c h\n";
- } else {
- buf << " c\n";
- }
+ buf << " " << x1 << " " << y1 << " " << x2 << " " << y2 << " c";
+ if (flag & FXPT_CLOSEFIGURE)
+ buf << " h";
+ buf << "\n";
i += 2;
break;
}
@@ -160,10 +156,12 @@ void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData,
StartRendering();
OutputPath(pPathData, pObject2Device);
CFX_FloatRect rect = pPathData->GetBoundingBox();
- if (pObject2Device) {
+ if (pObject2Device)
rect.Transform(pObject2Device);
- }
- m_ClipBox.Intersect(rect.GetOuterRect());
+ m_ClipBox.left = static_cast<int>(rect.left);
+ m_ClipBox.right = static_cast<int>(rect.left + rect.right);
+ m_ClipBox.top = static_cast<int>(rect.top + rect.bottom);
+ m_ClipBox.bottom = static_cast<int>(rect.bottom);
if ((fill_mode & 3) == FXFILL_WINDING) {
OUTPUT_PS("W n\n");
} else {
@@ -263,7 +261,7 @@ void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) {
FXSYS_memcmp(m_CurGraphState.m_DashArray, pGraphState->m_DashArray,
sizeof(FX_FLOAT) * m_CurGraphState.m_DashCount)) {
buf << "[";
- for (int i = 0; i < pGraphState->m_DashCount; i++) {
+ for (int i = 0; i < pGraphState->m_DashCount; ++i) {
buf << pGraphState->m_DashArray[i] << " ";
}
buf << "]" << pGraphState->m_DashPhase << " d\n";
@@ -281,7 +279,7 @@ void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) {
buf << pGraphState->m_MiterLimit << " M\n";
}
m_CurGraphState.Copy(*pGraphState);
- m_bGraphStateSet = TRUE;
+ m_bGraphStateSet = true;
if (buf.GetSize()) {
m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
}
@@ -297,7 +295,7 @@ static void FaxCompressData(uint8_t* src_buf,
dest_buf, dest_size);
FX_Free(src_buf);
} else {
- (*dest_buf).reset(src_buf);
+ dest_buf->reset(src_buf);
*dest_size = (width + 7) / 8 * height;
}
}
@@ -315,7 +313,7 @@ static void PSCompressData(int PSLevel,
return;
}
CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- uint8_t* dest_buf = NULL;
+ uint8_t* dest_buf = nullptr;
uint32_t dest_size = src_size;
if (PSLevel >= 3) {
if (pEncoders &&
@@ -334,7 +332,7 @@ static void PSCompressData(int PSLevel,
*output_buf = dest_buf;
*output_size = dest_size;
} else {
- *filter = NULL;
+ *filter = nullptr;
FX_Free(dest_buf);
}
}
@@ -407,9 +405,10 @@ bool CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource,
}
buf << width << " 0 0 -" << height << " 0 " << height
<< "]currentfile/ASCII85Decode filter ";
- if (output_buf.get() != src_buf)
+ if (output_buf.get() != src_buf) {
buf << "<</K -1/EndOfBlock false/Columns " << width << "/Rows " << height
<< ">>/CCITTFaxDecode filter ";
+ }
if (pSource->IsAlphaMask()) {
buf << "iM\n";
} else {
@@ -419,23 +418,26 @@ bool CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource,
WritePSBinary(output_buf.get(), output_size);
output_buf.release();
} else {
- CFX_MaybeOwned<CFX_DIBSource> pConverted((CFX_DIBSource*)pSource);
+ CFX_DIBExtractor source_extractor(pSource);
+ CFX_MaybeOwned<CFX_DIBSource> pConverted(source_extractor.GetBitmap());
+ if (!pConverted.Get())
+ return false;
switch (pSource->GetFormat()) {
case FXDIB_1bppRgb:
case FXDIB_Rgb32:
- pConverted = pSource->CloneConvert(FXDIB_Rgb);
+ pConverted = pConverted->CloneConvert(FXDIB_Rgb).release();
break;
case FXDIB_8bppRgb:
if (pSource->GetPalette()) {
- pConverted = pSource->CloneConvert(FXDIB_Rgb);
+ pConverted = pConverted->CloneConvert(FXDIB_Rgb).release();
}
break;
case FXDIB_1bppCmyk:
- pConverted = pSource->CloneConvert(FXDIB_Cmyk);
+ pConverted = pConverted->CloneConvert(FXDIB_Cmyk).release();
break;
case FXDIB_8bppCmyk:
if (pSource->GetPalette()) {
- pConverted = pSource->CloneConvert(FXDIB_Cmyk);
+ pConverted = pConverted->CloneConvert(FXDIB_Cmyk).release();
}
break;
default:
@@ -445,26 +447,23 @@ bool CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource,
OUTPUT_PS("\nQ\n");
return false;
}
- int Bpp = pConverted->GetBPP() / 8;
+ int bpp = pConverted->GetBPP() / 8;
uint8_t* output_buf = nullptr;
FX_STRSIZE output_size = 0;
const FX_CHAR* filter = nullptr;
- if (flags & FXRENDER_IMAGE_LOSSY) {
- CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- if (pEncoders &&
- pEncoders->GetJpegModule()->JpegEncode(pConverted.Get(), &output_buf,
- &output_size)) {
- filter = "/DCTDecode filter ";
- }
+ if ((m_PSLevel == 2 || flags & FXRENDER_IMAGE_LOSSY) &&
+ CCodec_JpegModule::JpegEncode(pConverted.Get(), &output_buf,
+ &output_size)) {
+ filter = "/DCTDecode filter ";
}
if (!filter) {
- int src_pitch = width * Bpp;
+ int src_pitch = width * bpp;
output_size = height * src_pitch;
output_buf = FX_Alloc(uint8_t, output_size);
for (int row = 0; row < height; row++) {
const uint8_t* src_scan = pConverted->GetScanline(row);
uint8_t* dest_scan = output_buf + row * src_pitch;
- if (Bpp == 3) {
+ if (bpp == 3) {
for (int col = 0; col < width; col++) {
*dest_scan++ = src_scan[2];
*dest_scan++ = src_scan[1];
@@ -485,18 +484,13 @@ bool CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource,
output_buf = compressed_buf;
output_size = compressed_size;
}
- CFX_DIBSource* converted = pConverted.Get();
- if (converted != pSource) {
- delete converted;
- pConverted.Reset();
- }
buf << " 8[";
buf << width << " 0 0 -" << height << " 0 " << height << "]";
buf << "currentfile/ASCII85Decode filter ";
if (filter) {
buf << filter;
}
- buf << "false " << Bpp;
+ buf << "false " << bpp;
buf << " colorimage\n";
m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
WritePSBinary(output_buf, output_size);
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index 1bfb4b7d6d..c673a18d2d 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -14,10 +14,6 @@
#include "core/fxcrt/cfx_maybe_owned.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_system.h"
-#include "core/fxge/cfx_fontmapper.h"
-#include "core/fxge/cfx_gemodule.h"
-#include "core/fxge/cfx_graphstatedata.h"
-#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_windowsdevice.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/fx_font.h"
@@ -697,6 +693,8 @@ bool CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) {
} // namespace
+int g_pdfium_print_postscript_level = 0;
+
std::unique_ptr<IFX_SystemFontInfo> IFX_SystemFontInfo::CreateDefault(
const char** pUnused) {
if (IsGDIEnabled())
@@ -1387,7 +1385,13 @@ IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC) {
int obj_type = ::GetObjectType(hDC);
bool use_printer = device_type == DT_RASPRINTER ||
device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC;
- if (use_printer)
- return new CGdiPrinterDriver(hDC);
- return new CGdiDisplayDriver(hDC);
+
+ if (!use_printer)
+ return new CGdiDisplayDriver(hDC);
+
+ if (g_pdfium_print_postscript_level == 2 ||
+ g_pdfium_print_postscript_level == 3) {
+ return new CPSPrinterDriver(hDC, g_pdfium_print_postscript_level, false);
+ }
+ return new CGdiPrinterDriver(hDC);
}
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index a8cfb3d1b9..94c415b721 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -11,11 +11,11 @@
#include <vector>
#include "core/fxcrt/fx_system.h"
-#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/cfx_windowsdevice.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/fx_freetype.h"
#include "core/fxge/ge/fx_text_int.h"
+#include "core/fxge/win32/cpsoutput.h"
#include "core/fxge/win32/win32_int.h"
#include "third_party/base/ptr_util.h"
@@ -328,8 +328,8 @@ bool CGdiPrinterDriver::DrawDeviceText(int nChars,
#endif
}
-CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput) {
- m_hDC = hDC;
+CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput)
+ : m_hDC(hDC), m_bCmykOutput(bCmykOutput) {
m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
@@ -337,7 +337,6 @@ CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput) {
m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
m_pPSOutput = pdfium::MakeUnique<CPSOutput>(m_hDC);
m_PSRenderer.Init(m_pPSOutput.get(), pslevel, m_Width, m_Height, bCmykOutput);
- m_bCmykOutput = bCmykOutput;
HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1);
int ret = ::GetClipRgn(hDC, hRgn);
if (ret == 1) {
@@ -354,7 +353,7 @@ CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput) {
path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom,
(FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
}
- m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING);
+ m_PSRenderer.SetClip_PathFill(&path, nullptr, FXFILL_WINDING);
}
FX_Free(pData);
}