From 940f559b985d4a742c21b21cb077a232e44dd289 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 14 Feb 2017 11:55:21 -0500 Subject: Reland Cleanup CPDF_MeshStream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL fixes up the bits of the CPDF_MeshStream CL that depended on the Origin CL and integrates the fixes for the Skia bots. Change-Id: I470e49c35b809f00fecbaeb303de15c0db3fe590 Reviewed-on: https://pdfium-review.googlesource.com/2698 Reviewed-by: Nicolás Peña Commit-Queue: dsinclair --- core/fpdfapi/page/cpdf_meshstream.cpp | 71 +++++++++++------- core/fpdfapi/page/cpdf_meshstream.h | 25 ++++--- core/fpdfapi/page/cpdf_streamcontentparser.cpp | 10 +-- core/fpdfapi/render/cpdf_renderstatus.cpp | 100 +++++++++++++------------ core/fxge/skia/fx_skia_device.cpp | 15 ++-- core/fxge/skia/fx_skia_device_unittest.cpp | 7 +- 6 files changed, 132 insertions(+), 96 deletions(-) diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp index b852901794..fbbd22276f 100644 --- a/core/fpdfapi/page/cpdf_meshstream.cpp +++ b/core/fpdfapi/page/cpdf_meshstream.cpp @@ -83,6 +83,12 @@ bool IsValidBitsPerFlag(uint32_t x) { } // namespace +CPDF_MeshVertex::CPDF_MeshVertex() = default; + +CPDF_MeshVertex::CPDF_MeshVertex(const CPDF_MeshVertex&) = default; + +CPDF_MeshVertex::~CPDF_MeshVertex() = default; + CPDF_MeshStream::CPDF_MeshStream( ShadingType type, const std::vector>& funcs, @@ -148,37 +154,47 @@ bool CPDF_MeshStream::Load() { return true; } -uint32_t CPDF_MeshStream::GetFlag() { +uint32_t CPDF_MeshStream::ReadFlag() { ASSERT(ShouldCheckBitsPerFlag(m_type)); return m_BitStream.GetBits(m_nFlagBits) & 0x03; } -void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { +CFX_PointF CPDF_MeshStream::ReadCoords() { ASSERT(ShouldCheckBPC(m_type)); + + CFX_PointF pos; if (m_nCoordBits == 32) { - x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * - (m_xmax - m_xmin) / (double)m_CoordMax); - y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * - (m_ymax - m_ymin) / (double)m_CoordMax); + pos.x = m_xmin + + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / + static_cast(m_CoordMax); + pos.y = m_ymin + + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / + static_cast(m_CoordMax); } else { - x = m_xmin + - m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; - y = m_ymin + - m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; + pos.x = m_xmin + + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; + pos.y = m_ymin + + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; } + return pos; } -void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { +std::tuple CPDF_MeshStream::ReadColor() { ASSERT(ShouldCheckBPC(m_type)); + FX_FLOAT color_value[kMaxComponents]; for (uint32_t i = 0; i < m_nComponents; ++i) { color_value[i] = m_ColorMin[i] + m_BitStream.GetBits(m_nComponentBits) * (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; } + + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; if (m_funcs.empty()) { m_pCS->GetRGB(color_value, r, g, b); - return; + return std::tuple(r, g, b); } FX_FLOAT result[kMaxComponents]; @@ -188,29 +204,34 @@ void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { if (func && func->CountOutputs() <= kMaxComponents) func->Call(color_value, 1, result, nResults); } + m_pCS->GetRGB(result, r, g, b); + return std::tuple(r, g, b); } -uint32_t CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex, - CFX_Matrix* pObject2Bitmap) { - uint32_t flag = GetFlag(); - GetCoords(vertex.x, vertex.y); - pObject2Bitmap->TransformPoint(vertex.x, vertex.y); - GetColor(vertex.r, vertex.g, vertex.b); +CPDF_MeshVertex CPDF_MeshStream::ReadVertex(const CFX_Matrix& pObject2Bitmap, + uint32_t* flag) { + *flag = ReadFlag(); + + CPDF_MeshVertex vertex; + vertex.position = ReadCoords(); + pObject2Bitmap.TransformPoint(vertex.position.x, vertex.position.y); + std::tie(vertex.r, vertex.g, vertex.b) = ReadColor(); m_BitStream.ByteAlign(); - return flag; + + return vertex; } -bool CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap) { +bool CPDF_MeshStream::ReadVertexRow(const CFX_Matrix& pObject2Bitmap, + int count, + CPDF_MeshVertex* vertex) { for (int i = 0; i < count; i++) { if (m_BitStream.IsEOF()) return false; - GetCoords(vertex[i].x, vertex[i].y); - pObject2Bitmap->TransformPoint(vertex[i].x, vertex[i].y); - GetColor(vertex[i].r, vertex[i].g, vertex[i].b); + vertex[i].position = ReadCoords(); + pObject2Bitmap.TransformPoint(vertex[i].position.x, vertex[i].position.y); + std::tie(vertex[i].r, vertex[i].g, vertex[i].b) = ReadColor(); m_BitStream.ByteAlign(); } return true; diff --git a/core/fpdfapi/page/cpdf_meshstream.h b/core/fpdfapi/page/cpdf_meshstream.h index 21a6c2fa8c..24f1d66cfd 100644 --- a/core/fpdfapi/page/cpdf_meshstream.h +++ b/core/fpdfapi/page/cpdf_meshstream.h @@ -8,6 +8,7 @@ #define CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ #include +#include #include #include "core/fpdfapi/page/cpdf_shadingpattern.h" @@ -15,9 +16,13 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_system.h" -struct CPDF_MeshVertex { - FX_FLOAT x; - FX_FLOAT y; +class CPDF_MeshVertex { + public: + CPDF_MeshVertex(); + CPDF_MeshVertex(const CPDF_MeshVertex&); + ~CPDF_MeshVertex(); + + CFX_PointF position; FX_FLOAT r; FX_FLOAT g; FX_FLOAT b; @@ -37,14 +42,14 @@ class CPDF_MeshStream { bool Load(); - uint32_t GetFlag(); - void GetCoords(FX_FLOAT& x, FX_FLOAT& y); - void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b); + uint32_t ReadFlag(); + CFX_PointF ReadCoords(); + std::tuple ReadColor(); - uint32_t GetVertex(CPDF_MeshVertex& vertex, CFX_Matrix* pObject2Bitmap); - bool GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap); + CPDF_MeshVertex ReadVertex(const CFX_Matrix& pObject2Bitmap, uint32_t* flag); + bool ReadVertexRow(const CFX_Matrix& pObject2Bitmap, + int count, + CPDF_MeshVertex* vertex); CFX_BitStream* BitStream() { return &m_BitStream; } uint32_t ComponentBits() const { return m_nComponentBits; } diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 61efb48529..0af43d08b2 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -99,7 +99,7 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, while (!stream.BitStream()->IsEOF()) { uint32_t flag = 0; if (type != kLatticeFormGouraudTriangleMeshShading) - flag = stream.GetFlag(); + flag = stream.ReadFlag(); if (!bGouraud && flag) { point_count -= 4; @@ -107,13 +107,11 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, } for (int i = 0; i < point_count; i++) { - FX_FLOAT x; - FX_FLOAT y; - stream.GetCoords(x, y); + CFX_PointF origin = stream.ReadCoords(); if (bStarted) { - rect.UpdateRect(x, y); + rect.UpdateRect(origin.x, origin.y); } else { - rect.InitRect(x, y); + rect.InitRect(origin.x, origin.y); bStarted = true; } } diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 60b7a49858..4f2638f276 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -369,67 +369,65 @@ void DrawFuncShading(CFX_DIBitmap* pBitmap, } bool GetScanlineIntersect(int y, - FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, + const CFX_PointF& first, + const CFX_PointF& second, FX_FLOAT* x) { - if (y1 == y2) + if (first.y == second.y) return false; - if (y1 < y2) { - if (y < y1 || y > y2) - return false; - } else { - if (y < y2 || y > y1) + if (first.y < second.y) { + if (y < first.y || y > second.y) return false; + } else if (y < second.y || y > first.y) { + return false; } - *x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1)); + *x = first.x + ((second.x - first.x) * (y - first.y) / (second.y - first.y)); return true; } void DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex triangle[3]) { - FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; + FX_FLOAT min_y = triangle[0].position.y; + FX_FLOAT max_y = triangle[0].position.y; for (int i = 1; i < 3; i++) { - if (min_y > triangle[i].y) { - min_y = triangle[i].y; - } - if (max_y < triangle[i].y) { - max_y = triangle[i].y; - } + min_y = std::min(min_y, triangle[i].position.y); + max_y = std::max(max_y, triangle[i].position.y); } - if (min_y == max_y) { + if (min_y == max_y) return; - } - int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); - if (min_yi < 0) { - min_yi = 0; - } - if (max_yi >= pBitmap->GetHeight()) { + + int min_yi = std::max(static_cast(FXSYS_floor(min_y)), 0); + int max_yi = static_cast(FXSYS_ceil(max_y)); + + if (max_yi >= pBitmap->GetHeight()) max_yi = pBitmap->GetHeight() - 1; - } + for (int y = min_yi; y <= max_yi; y++) { int nIntersects = 0; - FX_FLOAT inter_x[3], r[3], g[3], b[3]; + FX_FLOAT inter_x[3]; + FX_FLOAT r[3]; + FX_FLOAT g[3]; + FX_FLOAT b[3]; for (int i = 0; i < 3; i++) { CPDF_MeshVertex& vertex1 = triangle[i]; CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; - bool bIntersect = GetScanlineIntersect(y, vertex1.x, vertex1.y, vertex2.x, - vertex2.y, &inter_x[nIntersects]); + CFX_PointF& position1 = vertex1.position; + CFX_PointF& position2 = vertex2.position; + bool bIntersect = + GetScanlineIntersect(y, position1, position2, &inter_x[nIntersects]); if (!bIntersect) continue; - FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.y); + FX_FLOAT y_dist = (y - position1.y) / (position2.y - position1.y); r[nIntersects] = vertex1.r + ((vertex2.r - vertex1.r) * y_dist); g[nIntersects] = vertex1.g + ((vertex2.g - vertex1.g) * y_dist); b[nIntersects] = vertex1.b + ((vertex2.b - vertex1.b) * y_dist); nIntersects++; } - if (nIntersects != 2) { + if (nIntersects != 2) continue; - } + int min_x, max_x, start_index, end_index; if (inter_x[0] < inter_x[1]) { min_x = (int)FXSYS_floor(inter_x[0]); @@ -442,13 +440,12 @@ void DrawGouraud(CFX_DIBitmap* pBitmap, start_index = 1; end_index = 0; } - int start_x = min_x, end_x = max_x; - if (start_x < 0) { - start_x = 0; - } - if (end_x > pBitmap->GetWidth()) { + + int start_x = std::max(min_x, 0); + int end_x = max_x; + if (end_x > pBitmap->GetWidth()) end_x = pBitmap->GetWidth(); - } + uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); @@ -487,17 +484,18 @@ void DrawFreeGouraudShading( FXSYS_memset(triangle, 0, sizeof(triangle)); while (!stream.BitStream()->IsEOF()) { - CPDF_MeshVertex vertex; - uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap); + uint32_t flag; + CPDF_MeshVertex vertex = stream.ReadVertex(*pObject2Bitmap, &flag); if (flag == 0) { triangle[0] = vertex; for (int j = 1; j < 3; j++) { - stream.GetVertex(triangle[j], pObject2Bitmap); + uint32_t tflag; + triangle[j] = stream.ReadVertex(*pObject2Bitmap, &tflag); } } else { - if (flag == 1) { + if (flag == 1) triangle[0] = triangle[1]; - } + triangle[1] = triangle[2]; triangle[2] = vertex; } @@ -525,14 +523,14 @@ void DrawLatticeGouraudShading( std::unique_ptr vertex( FX_Alloc2D(CPDF_MeshVertex, row_verts, 2)); - if (!stream.GetVertexRow(vertex.get(), row_verts, pObject2Bitmap)) + if (!stream.ReadVertexRow(*pObject2Bitmap, row_verts, vertex.get())) return; int last_index = 0; while (1) { CPDF_MeshVertex* last_row = vertex.get() + last_index * row_verts; CPDF_MeshVertex* this_row = vertex.get() + (1 - last_index) * row_verts; - if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) + if (!stream.ReadVertexRow(*pObject2Bitmap, row_verts, this_row)) return; CPDF_MeshVertex triangle[3]; @@ -827,7 +825,7 @@ void DrawCoonPatchMeshes( CFX_PointF coords[16]; int point_count = type == kTensorProductPatchMeshShading ? 16 : 12; while (!stream.BitStream()->IsEOF()) { - uint32_t flag = stream.GetFlag(); + uint32_t flag = stream.ReadFlag(); int iStartPoint = 0, iStartColor = 0, i = 0; if (flag) { iStartPoint = 4; @@ -843,12 +841,16 @@ void DrawCoonPatchMeshes( FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2); } for (i = iStartPoint; i < point_count; i++) { - stream.GetCoords(coords[i].x, coords[i].y); + coords[i] = stream.ReadCoords(); pObject2Bitmap->TransformPoint(coords[i].x, coords[i].y); } + for (i = iStartColor; i < 4; i++) { - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; - stream.GetColor(r, g, b); + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; + std::tie(r, g, b) = stream.ReadColor(); + patch.patch_colors[i].comp[0] = (int32_t)(r * 255); patch.patch_colors[i].comp[1] = (int32_t)(g * 255); patch.patch_colors[i].comp[2] = (int32_t)(b * 255); diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index 40bd321f56..c8b16f5506 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp @@ -1749,7 +1749,7 @@ bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern, m_pCanvas->clipPath(skClip, SkClipOp::kIntersect, true); m_pCanvas->concat(skMatrix); while (!stream.BitStream()->IsEOF()) { - uint32_t flag = stream.GetFlag(); + uint32_t flag = stream.ReadFlag(); int iStartPoint = flag ? 4 : 0; int iStartColor = flag ? 2 : 0; if (flag) { @@ -1762,11 +1762,16 @@ bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern, tempColors[1] = colors[(flag + 1) % 4]; FXSYS_memcpy(colors, tempColors, sizeof(tempColors)); } - for (int i = iStartPoint; i < (int)SK_ARRAY_COUNT(cubics); i++) - stream.GetCoords(cubics[i].fX, cubics[i].fY); + for (int i = iStartPoint; i < (int)SK_ARRAY_COUNT(cubics); i++) { + CFX_PointF point = stream.ReadCoords(); + cubics[i].fX = point.x; + cubics[i].fY = point.y; + } for (int i = iStartColor; i < (int)SK_ARRAY_COUNT(colors); i++) { - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; - stream.GetColor(r, g, b); + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; + std::tie(r, g, b) = stream.ReadColor(); colors[i] = SkColorSetARGBInline(0xFF, (U8CPU)(r * 255), (U8CPU)(g * 255), (U8CPU)(b * 255)); } diff --git a/core/fxge/skia/fx_skia_device_unittest.cpp b/core/fxge/skia/fx_skia_device_unittest.cpp index 693cf1b616..3b799e6190 100644 --- a/core/fxge/skia/fx_skia_device_unittest.cpp +++ b/core/fxge/skia/fx_skia_device_unittest.cpp @@ -35,7 +35,12 @@ void EmptyTest(CFX_SkiaDeviceDriver* driver, const State&) { } void CommonTest(CFX_SkiaDeviceDriver* driver, const State& state) { - FXTEXT_CHARPOS charPos[] = {{{0, 0, 0, 0}, 0, 1, 1, 4, false, false}}; + FXTEXT_CHARPOS charPos[1]; + charPos[0].m_OriginX = 0; + charPos[0].m_OriginY = 1; + charPos[0].m_GlyphIndex = 1; + charPos[0].m_FontCharWidth = 4; + CFX_Font font; FX_FLOAT fontSize = 1; CFX_PathData clipPath, clipPath2; -- cgit v1.2.3