Properly write floats in CFX_PSRenderer.
Use WriteFloat() and friends to write out float, CFX_Matrix, and
CFX_PointF values properly to a PostScript stream. Move
cpdf_contentstream_write_utils.* from core/fpdfapi/edit/ to core/fxge/
to make the layering work correctly.
This fixes a variant of https:://crbug.com/pdfium/937
Change-Id: I58afaeee4161493e0fb5a6103f423e2783a064fd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63471
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/BUILD.gn b/core/fpdfapi/edit/BUILD.gn
index b83b89a..7e2528a 100644
--- a/core/fpdfapi/edit/BUILD.gn
+++ b/core/fpdfapi/edit/BUILD.gn
@@ -7,8 +7,6 @@
source_set("edit") {
sources = [
- "cpdf_contentstream_write_utils.cpp",
- "cpdf_contentstream_write_utils.h",
"cpdf_creator.cpp",
"cpdf_creator.h",
"cpdf_pagecontentgenerator.cpp",
@@ -21,7 +19,6 @@
configs += [ "../../../:pdfium_core_config" ]
deps = [
"../../../constants",
- "../../../third_party:skia_shared",
"../../fxcrt",
"../../fxge",
"../font",
diff --git a/core/fpdfapi/edit/DEPS b/core/fpdfapi/edit/DEPS
deleted file mode 100644
index bcfd0a2..0000000
--- a/core/fpdfapi/edit/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-specific_include_rules = {
- "cpdf_contentstream_write_utils.cpp": [
- '+third_party/skia_shared',
- ]
-}
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index c804c05..a67697a 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -12,7 +12,6 @@
#include <tuple>
#include <utility>
-#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
#include "core/fpdfapi/edit/cpdf_pagecontentmanager.h"
#include "core/fpdfapi/edit/cpdf_stringarchivestream.h"
#include "core/fpdfapi/font/cpdf_truetypefont.h"
@@ -34,6 +33,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
+#include "core/fxge/cfx_contentstream_write_utils.h"
#include "core/fxge/render_defines.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index ad47e0a..ead8abe 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -22,6 +22,8 @@
"cfx_cliprgn.h",
"cfx_color.cpp",
"cfx_color.h",
+ "cfx_contentstream_write_utils.cpp",
+ "cfx_contentstream_write_utils.h",
"cfx_defaultrenderdevice.h",
"cfx_face.cpp",
"cfx_face.h",
@@ -119,6 +121,7 @@
]
deps = [
+ "../../third_party:skia_shared",
"../fxcrt",
]
diff --git a/core/fxge/DEPS b/core/fxge/DEPS
index 6492756..f02b93c 100644
--- a/core/fxge/DEPS
+++ b/core/fxge/DEPS
@@ -1,3 +1,9 @@
include_rules = [
'+third_party/skia/include'
]
+
+specific_include_rules = {
+ "cfx_contentstream_write_utils.cpp": [
+ '+third_party/skia_shared',
+ ]
+}
diff --git a/core/fpdfapi/edit/cpdf_contentstream_write_utils.cpp b/core/fxge/cfx_contentstream_write_utils.cpp
similarity index 93%
rename from core/fpdfapi/edit/cpdf_contentstream_write_utils.cpp
rename to core/fxge/cfx_contentstream_write_utils.cpp
index 28165b1..f06c039 100644
--- a/core/fpdfapi/edit/cpdf_contentstream_write_utils.cpp
+++ b/core/fxge/cfx_contentstream_write_utils.cpp
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
+#include "core/fxge/cfx_contentstream_write_utils.h"
#include "third_party/skia_shared/SkFloatToDecimal.h"
diff --git a/core/fpdfapi/edit/cpdf_contentstream_write_utils.h b/core/fxge/cfx_contentstream_write_utils.h
similarity index 69%
rename from core/fpdfapi/edit/cpdf_contentstream_write_utils.h
rename to core/fxge/cfx_contentstream_write_utils.h
index 3e14c9f..2e94295 100644
--- a/core/fpdfapi/edit/cpdf_contentstream_write_utils.h
+++ b/core/fxge/cfx_contentstream_write_utils.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CORE_FPDFAPI_EDIT_CPDF_CONTENTSTREAM_WRITE_UTILS_H_
-#define CORE_FPDFAPI_EDIT_CPDF_CONTENTSTREAM_WRITE_UTILS_H_
+#ifndef CORE_FXGE_CFX_CONTENTSTREAM_WRITE_UTILS_H_
+#define CORE_FXGE_CFX_CONTENTSTREAM_WRITE_UTILS_H_
#include <ostream>
@@ -13,4 +13,4 @@
std::ostream& operator<<(std::ostream& ar, const CFX_Matrix& matrix);
std::ostream& operator<<(std::ostream& ar, const CFX_PointF& point);
-#endif // CORE_FPDFAPI_EDIT_CPDF_CONTENTSTREAM_WRITE_UTILS_H_
+#endif // CORE_FXGE_CFX_CONTENTSTREAM_WRITE_UTILS_H_
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index f9f7de2..237c9f8 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -12,6 +12,7 @@
#include <utility>
#include "core/fxcrt/maybe_owned.h"
+#include "core/fxge/cfx_contentstream_write_utils.h"
#include "core/fxge/cfx_fontcache.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_glyphcache.h"
@@ -121,7 +122,7 @@
if (pObject2Device)
pos = pObject2Device->Transform(pos);
- buf << pos.x << " " << pos.y;
+ buf << pos;
switch (type) {
case FXPT_TYPE::MoveTo:
buf << " m ";
@@ -138,8 +139,7 @@
pos1 = pObject2Device->Transform(pos1);
pos2 = pObject2Device->Transform(pos2);
}
- buf << " " << pos1.x << " " << pos1.y << " " << pos2.x << " " << pos2.y
- << " c";
+ buf << " " << pos1 << " " << pos2 << " c";
if (closing)
buf << " h";
buf << "\n";
@@ -178,9 +178,7 @@
SetGraphState(pGraphState);
std::ostringstream buf;
- buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " "
- << pObject2Device->c << " " << pObject2Device->d << " "
- << pObject2Device->e << " " << pObject2Device->f << "]cm ";
+ buf << "mx Cm [" << *pObject2Device << "]cm ";
WriteToStream(&buf);
OutputPath(pPathData, nullptr);
@@ -211,9 +209,7 @@
SetGraphState(pGraphState);
if (pObject2Device) {
std::ostringstream buf;
- buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " "
- << pObject2Device->c << " " << pObject2Device->d << " "
- << pObject2Device->e << " " << pObject2Device->f << "]cm ";
+ buf << "mx Cm [" << *pObject2Device << "]cm ";
WriteToStream(&buf);
}
}
@@ -254,9 +250,10 @@
if (!m_bGraphStateSet ||
m_CurGraphState.m_DashArray != pGraphState->m_DashArray) {
buf << "[";
- for (const auto& dash : pGraphState->m_DashArray)
- buf << dash << " ";
- buf << "]" << pGraphState->m_DashPhase << " d\n";
+ for (float dash : pGraphState->m_DashArray)
+ WriteFloat(buf, dash);
+ buf << "]";
+ WriteFloat(buf, pGraphState->m_DashPhase) << " d\n";
}
if (!m_bGraphStateSet ||
m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) {
@@ -264,11 +261,11 @@
}
if (!m_bGraphStateSet ||
m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) {
- buf << pGraphState->m_LineWidth << " w\n";
+ WriteFloat(buf, pGraphState->m_LineWidth) << " w\n";
}
if (!m_bGraphStateSet ||
m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) {
- buf << pGraphState->m_MiterLimit << " M\n";
+ WriteFloat(buf, pGraphState->m_MiterLimit) << " M\n";
}
m_CurGraphState = *pGraphState;
m_bGraphStateSet = true;
@@ -316,8 +313,7 @@
m_pStream->WriteString("q\n");
std::ostringstream buf;
- buf << "[" << matrix.a << " " << matrix.b << " " << matrix.c << " "
- << matrix.d << " " << matrix.e << " " << matrix.f << "]cm ";
+ buf << "[" << matrix << "]cm ";
int width = pSource->GetWidth();
int height = pSource->GetHeight();
@@ -448,13 +444,14 @@
if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) {
std::ostringstream buf;
if (bCMYK) {
- buf << FXSYS_GetCValue(color) / 255.0 << " "
- << FXSYS_GetMValue(color) / 255.0 << " "
- << FXSYS_GetYValue(color) / 255.0 << " "
- << FXSYS_GetKValue(color) / 255.0 << " k\n";
+ WriteFloat(buf, FXSYS_GetCValue(color) / 255.0f) << " ";
+ WriteFloat(buf, FXSYS_GetMValue(color) / 255.0f) << " ";
+ WriteFloat(buf, FXSYS_GetYValue(color) / 255.0f) << " ";
+ WriteFloat(buf, FXSYS_GetKValue(color) / 255.0f) << " k\n";
} else {
- buf << FXARGB_R(color) / 255.0 << " " << FXARGB_G(color) / 255.0 << " "
- << FXARGB_B(color) / 255.0 << " rg\n";
+ WriteFloat(buf, FXARGB_R(color) / 255.0f) << " ";
+ WriteFloat(buf, FXARGB_G(color) / 255.0f) << " ";
+ WriteFloat(buf, FXARGB_B(color) / 255.0f) << " rg\n";
}
if (bCMYK == m_bCmykOutput) {
m_bColorSet = true;
@@ -548,18 +545,17 @@
CFX_PointF point = TransformedPath.GetPoint(p);
switch (TransformedPath.GetType(p)) {
case FXPT_TYPE::MoveTo: {
- buf << point.x << " " << point.y << " m\n";
+ buf << point << " m\n";
break;
}
case FXPT_TYPE::LineTo: {
- buf << point.x << " " << point.y << " l\n";
+ buf << point << " l\n";
break;
}
case FXPT_TYPE::BezierTo: {
CFX_PointF point1 = TransformedPath.GetPoint(p + 1);
CFX_PointF point2 = TransformedPath.GetPoint(p + 2);
- buf << point.x << " " << point.y << " " << point1.x << " " << point1.y
- << " " << point2.x << " " << point2.y << " c\n";
+ buf << point << " " << point1 << " " << point2 << " c\n";
p += 2;
break;
}
@@ -597,9 +593,7 @@
SetColor(color);
std::ostringstream buf;
- buf << "q[" << mtObject2Device.a << " " << mtObject2Device.b << " "
- << mtObject2Device.c << " " << mtObject2Device.d << " "
- << mtObject2Device.e << " " << mtObject2Device.f << "]cm\n";
+ buf << "q[" << mtObject2Device << "]cm\n";
CFX_FontCache* pCache = CFX_GEModule::Get()->GetFontCache();
RetainPtr<CFX_GlyphCache> pGlyphCache = pCache->GetGlyphCache(pFont);
@@ -612,7 +606,7 @@
buf << "/X" << ps_fontnum << " Ff " << font_size << " Fs Sf ";
last_fontnum = ps_fontnum;
}
- buf << pCharPos[i].m_Origin.x << " " << pCharPos[i].m_Origin.y << " m";
+ buf << pCharPos[i].m_Origin << " m";
ByteString hex = ByteString::Format("<%02X>", ps_glyphindex);
buf << hex.AsStringView() << "Tj\n";
}
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index 424e1b4..374e103 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -14,7 +14,6 @@
#include "constants/annotation_common.h"
#include "constants/annotation_flags.h"
#include "constants/page_object.h"
-#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/parser/cpdf_array.h"
@@ -26,6 +25,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fxge/cfx_contentstream_write_utils.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
enum FPDF_TYPE { MAX, MIN };
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 496b89e..3670533 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -11,7 +11,6 @@
#include <vector>
#include "constants/page_object.h"
-#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
#include "core/fpdfapi/page/cpdf_clippath.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
@@ -22,6 +21,7 @@
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fxge/cfx_contentstream_write_utils.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/render_defines.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp
index fbf3897..e5caa5a 100644
--- a/fpdfsdk/fpdf_view_embeddertest.cpp
+++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -1226,9 +1226,11 @@
"q\n"
"Q\n"
"q\n"
- "281 106.7 m 331 106.7 l 331 56.7 l 281 56.7 l 281 106.7 l h W* n\n"
+ "281 106.700012 m "
+ "331 106.700012 l 331 56.700012 l 281 56.700012 l 281 106.700012 l "
+ "h W* n\n"
"q\n"
- "[49.9 0 0 -50 281.1 106.6]cm 50 50 8[50 0 0 -50 0 "
+ "[49.900002 0 0 -50 281.10001 106.599976]cm 50 50 8[50 0 0 -50 0 "
"50]currentfile/ASCII85Decode filter /DCTDecode filter false 3 "
"colorimage\n"
"s4IA0!\"_al8O`[\\!<<*#!!*'\"s4[N@!!ic5#6k>;#6tJ?#m^kH'FbHY$Odmc'+Yct)"
@@ -1293,9 +1295,9 @@
q
Q
q
-281 106.7 m 331 106.7 l 331 56.7 l 281 56.7 l 281 106.7 l h W* n
+281 106.700012 m 331 106.700012 l 331 56.700012 l 281 56.700012 l 281 106.700012 l h W* n
q
-[49.9 0 0 -50 281.1 106.6]cm 50 50 8[50 0 0 -50 0 50]currentfile/ASCII85Decode filter /FlateDecode filter false 3 colorimage
+[49.900002 0 0 -50 281.10001 106.599976]cm 50 50 8[50 0 0 -50 0 50]currentfile/ASCII85Decode filter /FlateDecode filter false 3 colorimage
Gb"0;0`_7S!5bE%:[N')TE"rlzGQSs[!!*~>
Q
Q