diff options
author | Nicolas Pena <npm@chromium.org> | 2017-02-06 12:01:21 -0500 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-02-06 18:12:42 +0000 |
commit | f9baca8709472f71fe0e5bcae95717b7f712b4a5 (patch) | |
tree | 19c773256d3063fa67ada0500cd4f162584bec06 /core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | |
parent | 3c056ae5599be463216fb1883c710157f019acc2 (diff) | |
download | pdfium-f9baca8709472f71fe0e5bcae95717b7f712b4a5.tar.xz |
Add support for fill and stroke RGBA in CPDF_PageContentGenerator
CPDF_PageObject is a CPDF_GraphicStates, which allows us to add graphics
information to the object itself. The RGB can be added easily in the stream.
The alpha parameter needs to be in a dictionary contained in the ExtGState,
which should be part of the page's resources.
BUG=pdfium:661
Change-Id: Id99b2ece7aa201e3550c765ac2b5eeff4b43fc48
Reviewed-on: https://pdfium-review.googlesource.com/2530
Reviewed-by: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Nicolás Peña <npm@chromium.org>
Diffstat (limited to 'core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp')
-rw-r--r-- | core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index e2354e1b50..9dba6e0ceb 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -6,6 +6,9 @@ #include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" +#include <tuple> +#include <utility> + #include "core/fpdfapi/page/cpdf_docpagedata.h" #include "core/fpdfapi/page/cpdf_image.h" #include "core/fpdfapi/page/cpdf_imageobject.h" @@ -15,6 +18,7 @@ #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" @@ -27,6 +31,19 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& ar, const CFX_Matrix& matrix) { return ar; } +bool GetColor(const CPDF_Color* pColor, FX_FLOAT* rgb) { + int intRGB[3]; + if (!pColor || + pColor->GetColorSpace() != CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB) || + !pColor->GetRGB(intRGB[0], intRGB[1], intRGB[2])) { + return false; + } + rgb[0] = intRGB[0] / 255.0f; + rgb[1] = intRGB[1] / 255.0f; + rgb[2] = intRGB[2] / 255.0f; + return true; +} + } // namespace CPDF_PageContentGenerator::CPDF_PageContentGenerator(CPDF_Page* pPage) @@ -123,8 +140,10 @@ void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf* buf, // "h" closes the subpath (appends a line from current to starting point) // Path painting operators: "S", "n", "B", "f", "B*", "f*", depending on // the filling mode and whether we want stroking the path or not. +// "Q" restores the graphics state imposed by the ProcessGraphics method. void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf, CPDF_PathObject* pPathObj) { + ProcessGraphics(buf, pPathObj); const FX_PATHPOINT* pPoints = pPathObj->m_Path.GetPoints(); if (pPathObj->m_Path.IsRect()) { *buf << pPoints[0].m_PointX << " " << pPoints[0].m_PointY << " " @@ -166,5 +185,55 @@ void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf, *buf << (pPathObj->m_bStroke ? " B" : " f"); else if (pPathObj->m_FillType == FXFILL_ALTERNATE) *buf << (pPathObj->m_bStroke ? " B*" : " f*"); - *buf << "\n"; + *buf << " Q\n"; +} + +// This method supports color operators rg and RGB from Table 4.24 of PDF spec +// 1.7. A color will not be set if the colorspace is not DefaultRGB or the RGB +// values cannot be obtained. The method also adds an external graphics +// dictionary, as described in Section 4.3.4. +// "rg" sets the fill color, "RG" sets the stroke color (using DefaultRGB) +// "ca" sets the fill alpha, "CA" sets the stroke alpha. +// "q" saves the graphics state, so that the settings can later be reversed +void CPDF_PageContentGenerator::ProcessGraphics(CFX_ByteTextBuf* buf, + CPDF_PageObject* pPageObj) { + *buf << "q "; + FX_FLOAT fillColor[3]; + if (GetColor(pPageObj->m_ColorState.GetFillColor(), fillColor)) { + *buf << fillColor[0] << " " << fillColor[1] << " " << fillColor[2] + << " rg "; + } + FX_FLOAT strokeColor[3]; + if (GetColor(pPageObj->m_ColorState.GetStrokeColor(), strokeColor)) { + *buf << strokeColor[0] << " " << strokeColor[1] << " " << strokeColor[2] + << " RG "; + } + + GraphicsData graphD; + graphD.fillAlpha = pPageObj->m_GeneralState.GetFillAlpha(); + graphD.strokeAlpha = pPageObj->m_GeneralState.GetStrokeAlpha(); + if (graphD.fillAlpha == 1.0f && graphD.strokeAlpha == 1.0f) + return; + + CFX_ByteString name; + auto it = m_GraphicsMap.find(graphD); + if (it != m_GraphicsMap.end()) { + name = it->second; + } else { + auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>(); + gsDict->SetNewFor<CPDF_Number>("ca", graphD.fillAlpha); + gsDict->SetNewFor<CPDF_Number>("CA", graphD.strokeAlpha); + CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict)); + uint32_t dwObjNum = pDict->GetObjNum(); + name = RealizeResource(dwObjNum, "ExtGState"); + m_GraphicsMap[graphD] = name; + } + *buf << "/" << PDF_NameEncode(name) << " gs "; +} + +bool CPDF_PageContentGenerator::GraphicsData::operator<( + const GraphicsData& other) const { + if (fillAlpha != other.fillAlpha) + return fillAlpha < other.fillAlpha; + return strokeAlpha < other.strokeAlpha; } |