Mass suppress unsafe buffers in fxge drivers.
Bug: 42271175
Change-Id: I419a299ef88c870563621bff96c031a3eb8819a9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/120210
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 76d8ea1..908a129 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -4,11 +4,6 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2154): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
#include "core/fxge/agg/fx_agg_driver.h"
#include <math.h>
@@ -20,6 +15,7 @@
#include "build/build_config.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_2d_size.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/notreached.h"
@@ -80,58 +76,61 @@
int Bpp = pBitmap->GetBPP() / 8;
int dib_argb = FXARGB_TOBGRORDERDIB(argb);
pdfium::span<uint8_t> pBuffer = pBitmap->GetWritableBuffer();
- if (src_alpha == 255) {
+ UNSAFE_TODO({
+ if (src_alpha == 255) {
+ for (int row = rect.top; row < rect.bottom; row++) {
+ uint8_t* dest_scan =
+ pBuffer.subspan(row * pBitmap->GetPitch() + rect.left * Bpp).data();
+ if (Bpp == 4) {
+ std::fill_n(reinterpret_cast<uint32_t*>(dest_scan), width, dib_argb);
+ } else {
+ for (int col = 0; col < width; col++) {
+ *dest_scan++ = src_r;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_b;
+ }
+ }
+ }
+ return;
+ }
+ bool bAlpha = pBitmap->IsAlphaFormat();
for (int row = rect.top; row < rect.bottom; row++) {
uint8_t* dest_scan =
pBuffer.subspan(row * pBitmap->GetPitch() + rect.left * Bpp).data();
- if (Bpp == 4) {
- std::fill_n(reinterpret_cast<uint32_t*>(dest_scan), width, dib_argb);
- } else {
+ if (bAlpha) {
for (int col = 0; col < width; col++) {
- *dest_scan++ = src_r;
- *dest_scan++ = src_g;
- *dest_scan++ = src_b;
+ uint8_t back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SetRGBOrderDIB(dest_scan, argb);
+ dest_scan += 4;
+ continue;
+ }
+ uint8_t dest_alpha =
+ back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan += 2;
}
+ continue;
}
- }
- return;
- }
- bool bAlpha = pBitmap->IsAlphaFormat();
- for (int row = rect.top; row < rect.bottom; row++) {
- uint8_t* dest_scan =
- pBuffer.subspan(row * pBitmap->GetPitch() + rect.left * Bpp).data();
- if (bAlpha) {
for (int col = 0; col < width; col++) {
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SetRGBOrderDIB(dest_scan, argb);
- dest_scan += 4;
- continue;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
+ dest_scan++;
+ if (Bpp == 4) {
+ dest_scan++;
}
- uint8_t dest_alpha =
- back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan += 2;
}
- continue;
}
- for (int col = 0; col < width; col++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
- dest_scan++;
- if (Bpp == 4)
- dest_scan++;
- }
- }
+ });
}
void RgbByteOrderTransferBitmap(RetainPtr<CFX_DIBitmap> pBitmap,
@@ -159,59 +158,79 @@
pdfium::span<uint8_t> dest_span = pBitmap->GetWritableBuffer()
.subspan(dest_y_offset)
.subspan(dest_x_offset);
- if (dest_format == src_format) {
- const size_t src_x_offset = Fx2DSizeOrDie(src_left, Bpp);
- for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_span.data();
- const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
- if (Bpp == 4) {
- for (int col = 0; col < width; col++) {
- FXARGB_SetRGBOrderDIB(dest_scan,
- *reinterpret_cast<const uint32_t*>(src_scan));
- dest_scan += 4;
- src_scan += 4;
+ UNSAFE_TODO({
+ if (dest_format == src_format) {
+ const size_t src_x_offset = Fx2DSizeOrDie(src_left, Bpp);
+ for (int row = 0; row < height; row++) {
+ uint8_t* dest_scan = dest_span.data();
+ const uint8_t* src_scan =
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
+ if (Bpp == 4) {
+ for (int col = 0; col < width; col++) {
+ FXARGB_SetRGBOrderDIB(dest_scan,
+ *reinterpret_cast<const uint32_t*>(src_scan));
+ dest_scan += 4;
+ src_scan += 4;
+ }
+ } else {
+ for (int col = 0; col < width; col++) {
+ *dest_scan++ = src_scan[2];
+ *dest_scan++ = src_scan[1];
+ *dest_scan++ = src_scan[0];
+ src_scan += 3;
+ }
}
- } else {
+ dest_span = dest_span.subspan(dest_pitch);
+ }
+ return;
+ }
+
+ if (dest_format == FXDIB_Format::kRgb) {
+ DCHECK_EQ(src_format, FXDIB_Format::kRgb32);
+ const size_t src_x_offset = Fx2DSizeOrDie(src_left, 4);
+ for (int row = 0; row < height; row++) {
+ uint8_t* dest_scan = dest_span.data();
+ const uint8_t* src_scan =
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
*dest_scan++ = src_scan[2];
*dest_scan++ = src_scan[1];
*dest_scan++ = src_scan[0];
- src_scan += 3;
+ src_scan += 4;
+ }
+ if (row < height - 1) {
+ // Since `dest_scan` was initialized in a way that takes
+ // `dest_x_offset` and `dest_y_offset` into account, it may go past
+ // the end of the span after processing the last row.
+ dest_span = dest_span.subspan(dest_pitch);
}
}
- dest_span = dest_span.subspan(dest_pitch);
+ return;
}
- return;
- }
- if (dest_format == FXDIB_Format::kRgb) {
- DCHECK_EQ(src_format, FXDIB_Format::kRgb32);
- const size_t src_x_offset = Fx2DSizeOrDie(src_left, 4);
- for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_span.data();
- const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
- for (int col = 0; col < width; col++) {
- *dest_scan++ = src_scan[2];
- *dest_scan++ = src_scan[1];
- *dest_scan++ = src_scan[0];
- src_scan += 4;
- }
- if (row < height - 1) {
- // Since `dest_scan` was initialized in a way that takes `dest_x_offset`
- // and `dest_y_offset` into account, it may go past the end of the span
- // after processing the last row.
+ DCHECK(dest_format == FXDIB_Format::kArgb ||
+ dest_format == FXDIB_Format::kRgb32);
+ if (src_format == FXDIB_Format::kRgb) {
+ const size_t src_x_offset = Fx2DSizeOrDie(src_left, 3);
+ for (int row = 0; row < height; row++) {
+ uint8_t* dest_scan = dest_span.data();
+ const uint8_t* src_scan =
+ pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
+ for (int col = 0; col < width; col++) {
+ FXARGB_SetDIB(dest_scan, ArgbEncode(0xff, src_scan[0], src_scan[1],
+ src_scan[2]));
+ dest_scan += 4;
+ src_scan += 3;
+ }
dest_span = dest_span.subspan(dest_pitch);
}
+ return;
}
- return;
- }
-
- DCHECK(dest_format == FXDIB_Format::kArgb ||
- dest_format == FXDIB_Format::kRgb32);
- if (src_format == FXDIB_Format::kRgb) {
- const size_t src_x_offset = Fx2DSizeOrDie(src_left, 3);
+ if (src_format != FXDIB_Format::kRgb32) {
+ return;
+ }
+ DCHECK_EQ(dest_format, FXDIB_Format::kArgb);
+ const size_t src_x_offset = Fx2DSizeOrDie(src_left, 4);
for (int row = 0; row < height; row++) {
uint8_t* dest_scan = dest_span.data();
const uint8_t* src_scan =
@@ -219,29 +238,12 @@
for (int col = 0; col < width; col++) {
FXARGB_SetDIB(dest_scan,
ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
+ src_scan += 4;
dest_scan += 4;
- src_scan += 3;
}
dest_span = dest_span.subspan(dest_pitch);
}
- return;
- }
- if (src_format != FXDIB_Format::kRgb32)
- return;
- DCHECK_EQ(dest_format, FXDIB_Format::kArgb);
- const size_t src_x_offset = Fx2DSizeOrDie(src_left, 4);
- for (int row = 0; row < height; row++) {
- uint8_t* dest_scan = dest_span.data();
- const uint8_t* src_scan =
- pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
- for (int col = 0; col < width; col++) {
- FXARGB_SetDIB(dest_scan,
- ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
- src_scan += 4;
- dest_scan += 4;
- }
- dest_span = dest_span.subspan(dest_pitch);
- }
+ });
}
void RasterizeStroke(agg::rasterizer_scanline_aa* rasterizer,
@@ -421,14 +423,15 @@
}
inline int GetSrcAlpha(const uint8_t* clip_scan, int col) const {
- return clip_scan ? m_Alpha * clip_scan[col] / 255 : m_Alpha;
+ return clip_scan ? m_Alpha * UNSAFE_TODO(clip_scan[col]) / 255 : m_Alpha;
}
inline int GetSourceAlpha(const uint8_t* cover_scan,
const uint8_t* clip_scan,
int col) const {
- return clip_scan ? m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255
- : m_Alpha * cover_scan[col] / 255;
+ return UNSAFE_TODO(clip_scan ? m_Alpha * cover_scan[col] * clip_scan[col] /
+ 255 / 255
+ : m_Alpha * cover_scan[col] / 255);
}
inline int GetColStart(int span_left, int clip_left) const {
@@ -468,136 +471,139 @@
const uint8_t* clip_scan) {
int col_start = GetColStart(span_left, clip_left);
int col_end = GetColEnd(span_left, span_len, clip_right);
- if (Bpp) {
- dest_scan += col_start * Bpp;
- backdrop_scan += col_start * Bpp;
- } else {
- dest_scan += col_start / 8;
- backdrop_scan += col_start / 8;
- }
- if (m_bRgbByteOrder) {
- if (Bpp == 4 && bDestAlpha) {
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSrcAlpha(clip_scan, col);
- uint8_t dest_alpha =
- backdrop_scan[3] + src_alpha - backdrop_scan[3] * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (m_bFullCover) {
- *dest_scan++ =
- FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, alpha_ratio);
- *dest_scan++ =
- FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, alpha_ratio);
- *dest_scan++ =
- FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, alpha_ratio);
- dest_scan++;
- backdrop_scan++;
- } else {
- int r = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, alpha_ratio);
- int g = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, alpha_ratio);
- int b = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, alpha_ratio);
- backdrop_scan++;
+ UNSAFE_TODO({
+ if (Bpp) {
+ dest_scan += col_start * Bpp;
+ backdrop_scan += col_start * Bpp;
+ } else {
+ dest_scan += col_start / 8;
+ backdrop_scan += col_start / 8;
+ }
+ if (m_bRgbByteOrder) {
+ if (Bpp == 4 && bDestAlpha) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSrcAlpha(clip_scan, col);
+ uint8_t dest_alpha =
+ backdrop_scan[3] + src_alpha - backdrop_scan[3] * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (m_bFullCover) {
+ *dest_scan++ =
+ FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, alpha_ratio);
+ *dest_scan++ =
+ FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, alpha_ratio);
+ *dest_scan++ =
+ FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, alpha_ratio);
+ dest_scan++;
+ backdrop_scan++;
+ } else {
+ int r = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, alpha_ratio);
+ int g = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, alpha_ratio);
+ int b = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, alpha_ratio);
+ backdrop_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
+ dest_scan += 2;
+ }
+ }
+ return;
+ }
+ if (Bpp == 3 || Bpp == 4) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSrcAlpha(clip_scan, col);
+ int r = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, src_alpha);
+ int g = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, src_alpha);
+ int b = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Blue, src_alpha);
+ backdrop_scan += Bpp - 2;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
dest_scan++;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
dest_scan++;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
- dest_scan += 2;
+ dest_scan += Bpp - 2;
}
}
return;
}
+ if (Bpp == 4 && bDestAlpha) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSrcAlpha(clip_scan, col);
+ int src_alpha_covered = src_alpha * cover_scan[col] / 255;
+ if (src_alpha_covered == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ if (cover_scan[col] == 255) {
+ dest_scan[3] = src_alpha_covered;
+ *dest_scan++ = m_Blue;
+ *dest_scan++ = m_Green;
+ *dest_scan = m_Red;
+ dest_scan += 2;
+ continue;
+ }
+ if (dest_scan[3] == 0) {
+ dest_scan[3] = src_alpha_covered;
+ *dest_scan++ = m_Blue;
+ *dest_scan++ = m_Green;
+ *dest_scan = m_Red;
+ dest_scan += 2;
+ continue;
+ }
+ uint8_t cover = cover_scan[col];
+ dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover);
+ dest_scan += 2;
+ }
+ return;
+ }
if (Bpp == 3 || Bpp == 4) {
for (int col = col_start; col < col_end; col++) {
int src_alpha = GetSrcAlpha(clip_scan, col);
- int r = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Red, src_alpha);
+ if (m_bFullCover) {
+ *dest_scan++ = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, src_alpha);
+ *dest_scan++ =
+ FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, src_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Red, src_alpha);
+ dest_scan += Bpp - 2;
+ backdrop_scan += Bpp - 2;
+ continue;
+ }
+ int b = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, src_alpha);
int g = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, src_alpha);
- int b = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Blue, src_alpha);
+ int r = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Red, src_alpha);
backdrop_scan += Bpp - 2;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
dest_scan++;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
dest_scan += Bpp - 2;
}
+ return;
}
- return;
- }
- if (Bpp == 4 && bDestAlpha) {
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSrcAlpha(clip_scan, col);
- int src_alpha_covered = src_alpha * cover_scan[col] / 255;
- if (src_alpha_covered == 0) {
- dest_scan += 4;
- continue;
+ if (Bpp == 1) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSrcAlpha(clip_scan, col);
+ if (m_bFullCover) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Gray, src_alpha);
+ continue;
+ }
+ int gray = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Gray, src_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]);
+ dest_scan++;
}
- if (cover_scan[col] == 255) {
- dest_scan[3] = src_alpha_covered;
- *dest_scan++ = m_Blue;
- *dest_scan++ = m_Green;
- *dest_scan = m_Red;
- dest_scan += 2;
- continue;
- }
- if (dest_scan[3] == 0) {
- dest_scan[3] = src_alpha_covered;
- *dest_scan++ = m_Blue;
- *dest_scan++ = m_Green;
- *dest_scan = m_Red;
- dest_scan += 2;
- continue;
- }
- uint8_t cover = cover_scan[col];
- dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover);
- dest_scan += 2;
+ return;
}
- return;
- }
- if (Bpp == 3 || Bpp == 4) {
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSrcAlpha(clip_scan, col);
- if (m_bFullCover) {
- *dest_scan++ = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, src_alpha);
- *dest_scan++ = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, src_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Red, src_alpha);
- dest_scan += Bpp - 2;
- backdrop_scan += Bpp - 2;
- continue;
- }
- int b = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Blue, src_alpha);
- int g = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Green, src_alpha);
- int r = FXDIB_ALPHA_MERGE(*backdrop_scan, m_Red, src_alpha);
- backdrop_scan += Bpp - 2;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
- dest_scan += Bpp - 2;
- }
- return;
- }
- if (Bpp == 1) {
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSrcAlpha(clip_scan, col);
- if (m_bFullCover) {
- *dest_scan = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Gray, src_alpha);
- continue;
- }
- int gray = FXDIB_ALPHA_MERGE(*backdrop_scan++, m_Gray, src_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]);
- dest_scan++;
- }
- return;
- }
- CompositeSpan1bppHelper(dest_scan, col_start, col_end, cover_scan, clip_scan,
- span_left);
+ CompositeSpan1bppHelper(dest_scan, col_start, col_end, cover_scan,
+ clip_scan, span_left);
+ });
}
void CFX_Renderer::CompositeSpan1bpp(uint8_t* dest_scan,
@@ -611,7 +617,7 @@
DCHECK(!m_bRgbByteOrder);
int col_start = GetColStart(span_left, clip_left);
int col_end = GetColEnd(span_left, span_len, clip_right);
- dest_scan += col_start / 8;
+ UNSAFE_TODO(dest_scan += col_start / 8);
CompositeSpan1bppHelper(dest_scan, col_start, col_end, cover_scan, clip_scan,
span_left);
}
@@ -627,17 +633,20 @@
DCHECK(!m_bRgbByteOrder);
int col_start = GetColStart(span_left, clip_left);
int col_end = GetColEnd(span_left, span_len, clip_right);
- dest_scan += col_start;
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
- if (src_alpha) {
- if (src_alpha == 255)
- *dest_scan = m_Gray;
- else
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha);
+ UNSAFE_TODO({
+ dest_scan += col_start;
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
+ if (src_alpha) {
+ if (src_alpha == 255) {
+ *dest_scan = m_Gray;
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha);
+ }
+ }
+ dest_scan++;
}
- dest_scan++;
- }
+ });
}
void CFX_Renderer::CompositeSpanARGB(uint8_t* dest_scan,
@@ -650,8 +659,34 @@
const uint8_t* clip_scan) {
int col_start = GetColStart(span_left, clip_left);
int col_end = GetColEnd(span_left, span_len, clip_right);
- dest_scan += col_start * Bpp;
- if (m_bRgbByteOrder) {
+ UNSAFE_TODO({
+ dest_scan += col_start * Bpp;
+ if (m_bRgbByteOrder) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = m_bFullCover
+ ? GetSrcAlpha(clip_scan, col)
+ : GetSourceAlpha(cover_scan, clip_scan, col);
+ if (src_alpha) {
+ if (src_alpha == 255) {
+ *(reinterpret_cast<uint32_t*>(dest_scan)) = m_Color;
+ } else {
+ uint8_t dest_alpha =
+ dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
+ dest_scan += 2;
+ continue;
+ }
+ }
+ dest_scan += 4;
+ }
+ return;
+ }
for (int col = col_start; col < col_end; col++) {
int src_alpha = m_bFullCover ? GetSrcAlpha(clip_scan, col)
: GetSourceAlpha(cover_scan, clip_scan, col);
@@ -659,53 +694,30 @@
if (src_alpha == 255) {
*(reinterpret_cast<uint32_t*>(dest_scan)) = m_Color;
} else {
+ if (dest_scan[3] == 0) {
+ dest_scan[3] = src_alpha;
+ *dest_scan++ = m_Blue;
+ *dest_scan++ = m_Green;
+ *dest_scan = m_Red;
+ dest_scan += 2;
+ continue;
+ }
uint8_t dest_alpha =
dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255;
dest_scan[3] = dest_alpha;
int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
dest_scan++;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
dest_scan += 2;
continue;
}
}
- dest_scan += 4;
+ dest_scan += Bpp;
}
- return;
- }
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = m_bFullCover ? GetSrcAlpha(clip_scan, col)
- : GetSourceAlpha(cover_scan, clip_scan, col);
- if (src_alpha) {
- if (src_alpha == 255) {
- *(reinterpret_cast<uint32_t*>(dest_scan)) = m_Color;
- } else {
- if (dest_scan[3] == 0) {
- dest_scan[3] = src_alpha;
- *dest_scan++ = m_Blue;
- *dest_scan++ = m_Green;
- *dest_scan = m_Red;
- dest_scan += 2;
- continue;
- }
- uint8_t dest_alpha =
- dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
- dest_scan += 2;
- continue;
- }
- }
- dest_scan += Bpp;
- }
+ });
}
void CFX_Renderer::CompositeSpanRGB(uint8_t* dest_scan,
@@ -718,59 +730,61 @@
const uint8_t* clip_scan) {
int col_start = GetColStart(span_left, clip_left);
int col_end = GetColEnd(span_left, span_len, clip_right);
- dest_scan += col_start * Bpp;
- if (m_bRgbByteOrder) {
+ UNSAFE_TODO({
+ dest_scan += col_start * Bpp;
+ if (m_bRgbByteOrder) {
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
+ if (src_alpha) {
+ if (src_alpha == 255) {
+ if (Bpp == 4) {
+ *(uint32_t*)dest_scan = m_Color;
+ } else if (Bpp == 3) {
+ *dest_scan++ = m_Red;
+ *dest_scan++ = m_Green;
+ *dest_scan++ = m_Blue;
+ continue;
+ }
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
+ dest_scan++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
+ dest_scan += Bpp - 2;
+ continue;
+ }
+ }
+ dest_scan += Bpp;
+ }
+ return;
+ }
for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
+ int src_alpha = m_bFullCover ? GetSrcAlpha(clip_scan, col)
+ : GetSourceAlpha(cover_scan, clip_scan, col);
if (src_alpha) {
if (src_alpha == 255) {
if (Bpp == 4) {
*(uint32_t*)dest_scan = m_Color;
} else if (Bpp == 3) {
- *dest_scan++ = m_Red;
- *dest_scan++ = m_Green;
*dest_scan++ = m_Blue;
+ *dest_scan++ = m_Green;
+ *dest_scan++ = m_Red;
continue;
}
} else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
dest_scan++;
*dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
dest_scan += Bpp - 2;
continue;
}
}
dest_scan += Bpp;
}
- return;
- }
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = m_bFullCover ? GetSrcAlpha(clip_scan, col)
- : GetSourceAlpha(cover_scan, clip_scan, col);
- if (src_alpha) {
- if (src_alpha == 255) {
- if (Bpp == 4) {
- *(uint32_t*)dest_scan = m_Color;
- } else if (Bpp == 3) {
- *dest_scan++ = m_Blue;
- *dest_scan++ = m_Green;
- *dest_scan++ = m_Red;
- continue;
- }
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
- dest_scan++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
- dest_scan += Bpp - 2;
- continue;
- }
- }
- dest_scan += Bpp;
- }
+ });
}
CFX_Renderer::CFX_Renderer(const RetainPtr<CFX_DIBitmap>& pDevice,
@@ -819,39 +833,43 @@
bool bDestAlpha = m_pDevice->IsAlphaFormat() || m_pDevice->IsMaskFormat();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
- while (true) {
- if (span->len <= 0)
- break;
+ UNSAFE_TODO({
+ while (true) {
+ if (span->len <= 0) {
+ break;
+ }
- int x = span->x;
- uint8_t* dest_pos = nullptr;
- const uint8_t* backdrop_pos = nullptr;
- if (Bpp) {
- backdrop_pos = backdrop_scan ? backdrop_scan + x * Bpp : nullptr;
- dest_pos = dest_scan + x * Bpp;
- } else {
- dest_pos = dest_scan + x / 8;
- backdrop_pos = backdrop_scan ? backdrop_scan + x / 8 : nullptr;
- }
- const uint8_t* clip_pos = nullptr;
- if (m_pClipMask) {
- // TODO(crbug.com/1382604): use subspan arithmetic.
- clip_pos = m_pClipMask->GetBuffer().data() +
- (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x -
- m_ClipBox.left;
- }
- if (backdrop_pos) {
- CompositeSpan(dest_pos, backdrop_pos, Bpp, bDestAlpha, x, span->len,
- span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos);
- } else {
- (this->*m_CompositeSpanFunc)(dest_pos, Bpp, x, span->len, span->covers,
- m_ClipBox.left, m_ClipBox.right, clip_pos);
- }
- if (--num_spans == 0)
- break;
+ int x = span->x;
+ uint8_t* dest_pos = nullptr;
+ const uint8_t* backdrop_pos = nullptr;
+ if (Bpp) {
+ backdrop_pos = backdrop_scan ? backdrop_scan + x * Bpp : nullptr;
+ dest_pos = dest_scan + x * Bpp;
+ } else {
+ dest_pos = dest_scan + x / 8;
+ backdrop_pos = backdrop_scan ? backdrop_scan + x / 8 : nullptr;
+ }
+ const uint8_t* clip_pos = nullptr;
+ if (m_pClipMask) {
+ // TODO(crbug.com/1382604): use subspan arithmetic.
+ clip_pos = m_pClipMask->GetBuffer().data() +
+ (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x -
+ m_ClipBox.left;
+ }
+ if (backdrop_pos) {
+ CompositeSpan(dest_pos, backdrop_pos, Bpp, bDestAlpha, x, span->len,
+ span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos);
+ } else {
+ (this->*m_CompositeSpanFunc)(dest_pos, Bpp, x, span->len, span->covers,
+ m_ClipBox.left, m_ClipBox.right, clip_pos);
+ }
+ if (--num_spans == 0) {
+ break;
+ }
- ++span;
- }
+ ++span;
+ }
+ });
}
void CFX_Renderer::CompositeSpan1bppHelper(uint8_t* dest_scan,
@@ -870,16 +888,19 @@
index = (static_cast<uint8_t>(m_Color) == 0xff) ? 1 : 0;
}
uint8_t* dest_scan1 = dest_scan;
- for (int col = col_start; col < col_end; col++) {
- int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
- if (src_alpha) {
- if (!index)
- *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8));
- else
- *dest_scan1 |= 1 << (7 - (col + span_left) % 8);
+ UNSAFE_TODO({
+ for (int col = col_start; col < col_end; col++) {
+ int src_alpha = GetSourceAlpha(cover_scan, clip_scan, col);
+ if (src_alpha) {
+ if (!index) {
+ *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8));
+ } else {
+ *dest_scan1 |= 1 << (7 - (col + span_left) % 8);
+ }
+ }
+ dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8;
}
- dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8;
- }
+ });
}
template <class BaseRenderer>
@@ -909,7 +930,7 @@
if (--num_spans == 0)
break;
- ++span;
+ UNSAFE_TODO(++span);
}
}
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index ff349e4..7620c7e 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -2,11 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2154): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
#include "core/fxge/skia/fx_skia_device.h"
#include <math.h>
@@ -349,25 +344,28 @@
float colors_min[3];
float colors_max[3];
- for (int i = 0; i < 3; ++i) {
- colors_min[i] = func->GetRange(i * 2);
- colors_max[i] = func->GetRange(i * 2 + 1);
- }
- pdfium::span<const uint8_t> sample_data = func->GetSampleStream()->GetSpan();
- CFX_BitStream bitstream(sample_data);
- for (uint32_t i = 0; i < sample_count; ++i) {
- float float_colors[3];
- for (uint32_t j = 0; j < 3; ++j) {
- float sample = static_cast<float>(bitstream.GetBits(sample_size));
- float interp = sample / (sample_count - 1);
- float_colors[j] =
- colors_min[j] + (colors_max[j] - colors_min[j]) * interp;
+ UNSAFE_TODO({
+ for (int i = 0; i < 3; ++i) {
+ colors_min[i] = func->GetRange(i * 2);
+ colors_max[i] = func->GetRange(i * 2 + 1);
}
- colors.push_back(SkPackARGB32NoCheck(0xFF, FloatToByte(float_colors[0]),
- FloatToByte(float_colors[1]),
- FloatToByte(float_colors[2])));
- pos.push_back(static_cast<float>(i) / (sample_count - 1));
- }
+ pdfium::span<const uint8_t> sample_data =
+ func->GetSampleStream()->GetSpan();
+ CFX_BitStream bitstream(sample_data);
+ for (uint32_t i = 0; i < sample_count; ++i) {
+ float float_colors[3];
+ for (uint32_t j = 0; j < 3; ++j) {
+ float sample = static_cast<float>(bitstream.GetBits(sample_size));
+ float interp = sample / (sample_count - 1);
+ float_colors[j] =
+ colors_min[j] + (colors_max[j] - colors_min[j]) * interp;
+ }
+ colors.push_back(SkPackARGB32NoCheck(0xFF, FloatToByte(float_colors[0]),
+ FloatToByte(float_colors[1]),
+ FloatToByte(float_colors[2])));
+ pos.push_back(static_cast<float>(i) / (sample_count - 1));
+ }
+ });
return true;
}
@@ -399,8 +397,9 @@
// see https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
SkScalar LineSide(const SkPoint line[2], const SkPoint& pt) {
- return (line[1].fY - line[0].fY) * pt.fX - (line[1].fX - line[0].fX) * pt.fY +
- line[1].fX * line[0].fY - line[1].fY * line[0].fX;
+ return UNSAFE_TODO((line[1].fY - line[0].fY) * pt.fX -
+ (line[1].fX - line[0].fX) * pt.fY +
+ line[1].fX * line[0].fY - line[1].fY * line[0].fX);
}
SkPoint IntersectSides(const SkPoint& parallelPt,
@@ -430,74 +429,83 @@
SkScalar maxPerpDist = SK_ScalarMin;
int minPerpPtIndex = -1;
int maxPerpPtIndex = -1;
- SkVector slope = pts[1] - pts[0];
- SkPoint startPerp[2] = {pts[0], {pts[0].fX + slope.fY, pts[0].fY - slope.fX}};
- SkPoint endPerp[2] = {pts[1], {pts[1].fX + slope.fY, pts[1].fY - slope.fX}};
- for (int i = 0; i < 4; ++i) {
- SkScalar sDist = LineSide(startPerp, rectPts[i]);
- SkScalar eDist = LineSide(endPerp, rectPts[i]);
- if (sDist * eDist <= 0) // if the signs are different,
- continue; // the point is inside the gradient
- if (sDist < 0) {
- SkScalar smaller = std::min(sDist, eDist);
- if (minPerpDist > smaller) {
- minPerpDist = smaller;
- minPerpPtIndex = i;
+ UNSAFE_TODO({
+ SkVector slope = pts[1] - pts[0];
+ SkPoint startPerp[2] = {pts[0],
+ {pts[0].fX + slope.fY, pts[0].fY - slope.fX}};
+ SkPoint endPerp[2] = {pts[1], {pts[1].fX + slope.fY, pts[1].fY - slope.fX}};
+ for (int i = 0; i < 4; ++i) {
+ SkScalar sDist = LineSide(startPerp, rectPts[i]);
+ SkScalar eDist = LineSide(endPerp, rectPts[i]);
+ if (sDist * eDist <= 0) { // if the signs are different,
+ continue; // the point is inside the gradient
}
- } else {
- SkScalar larger = std::max(sDist, eDist);
- if (maxPerpDist < larger) {
- maxPerpDist = larger;
- maxPerpPtIndex = i;
+ if (sDist < 0) {
+ SkScalar smaller = std::min(sDist, eDist);
+ if (minPerpDist > smaller) {
+ minPerpDist = smaller;
+ minPerpPtIndex = i;
+ }
+ } else {
+ SkScalar larger = std::max(sDist, eDist);
+ if (maxPerpDist < larger) {
+ maxPerpDist = larger;
+ maxPerpPtIndex = i;
+ }
}
}
- }
- if (minPerpPtIndex < 0 && maxPerpPtIndex < 0) // nothing's outside
- return;
-
- // determine if negative distances are before start or after end
- SkPoint beforeStart = {pts[0].fX * 2 - pts[1].fX, pts[0].fY * 2 - pts[1].fY};
- bool beforeNeg = LineSide(startPerp, beforeStart) < 0;
-
- int noClipStartIndex = maxPerpPtIndex;
- int noClipEndIndex = minPerpPtIndex;
- if (beforeNeg)
- std::swap(noClipStartIndex, noClipEndIndex);
- if ((!clipStart && noClipStartIndex < 0) ||
- (!clipEnd && noClipEndIndex < 0)) {
- return;
- }
-
- const SkPoint& startEdgePt = clipStart ? pts[0] : rectPts[noClipStartIndex];
- const SkPoint& endEdgePt = clipEnd ? pts[1] : rectPts[noClipEndIndex];
-
- // find the corners that bound the gradient
- SkScalar minDist = SK_ScalarMax;
- SkScalar maxDist = SK_ScalarMin;
- int minBounds = -1;
- int maxBounds = -1;
- for (int i = 0; i < 4; ++i) {
- SkScalar dist = LineSide(pts, rectPts[i]);
- if (minDist > dist) {
- minDist = dist;
- minBounds = i;
+ if (minPerpPtIndex < 0 && maxPerpPtIndex < 0) { // nothing's outside
+ return;
}
- if (maxDist < dist) {
- maxDist = dist;
- maxBounds = i;
+
+ // determine if negative distances are before start or after end
+ SkPoint beforeStart = {pts[0].fX * 2 - pts[1].fX,
+ pts[0].fY * 2 - pts[1].fY};
+ bool beforeNeg = LineSide(startPerp, beforeStart) < 0;
+
+ int noClipStartIndex = maxPerpPtIndex;
+ int noClipEndIndex = minPerpPtIndex;
+ if (beforeNeg) {
+ std::swap(noClipStartIndex, noClipEndIndex);
}
- }
- if (minBounds < 0 || maxBounds < 0)
- return;
- if (minBounds == maxBounds)
- return;
- // construct a clip parallel to the gradient that goes through
- // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the
- // gradient that goes through startEdgePt, endEdgePt.
- clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt));
- clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt));
- clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt));
- clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt));
+ if ((!clipStart && noClipStartIndex < 0) ||
+ (!clipEnd && noClipEndIndex < 0)) {
+ return;
+ }
+
+ const SkPoint& startEdgePt = clipStart ? pts[0] : rectPts[noClipStartIndex];
+ const SkPoint& endEdgePt = clipEnd ? pts[1] : rectPts[noClipEndIndex];
+
+ // find the corners that bound the gradient
+ SkScalar minDist = SK_ScalarMax;
+ SkScalar maxDist = SK_ScalarMin;
+ int minBounds = -1;
+ int maxBounds = -1;
+ for (int i = 0; i < 4; ++i) {
+ SkScalar dist = LineSide(pts, rectPts[i]);
+ if (minDist > dist) {
+ minDist = dist;
+ minBounds = i;
+ }
+ if (maxDist < dist) {
+ maxDist = dist;
+ maxBounds = i;
+ }
+ }
+ if (minBounds < 0 || maxBounds < 0) {
+ return;
+ }
+ if (minBounds == maxBounds) {
+ return;
+ }
+ // construct a clip parallel to the gradient that goes through
+ // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the
+ // gradient that goes through startEdgePt, endEdgePt.
+ clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt));
+ clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt));
+ clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt));
+ clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt));
+ });
}
// Converts a stroking path to scanlines
@@ -1313,35 +1321,37 @@
if (!skClip.isEmpty())
m_pCanvas->clipPath(skClip, SkClipOp::kIntersect, true);
m_pCanvas->concat(skMatrix);
- while (!stream.IsEOF()) {
- uint32_t flag = stream.ReadFlag();
- size_t start_point = flag ? 4 : 0;
- size_t start_color = flag ? 2 : 0;
- if (flag) {
- SkPoint temp_cubics[4];
- for (size_t i = 0; i < std::size(temp_cubics); ++i) {
- temp_cubics[i] = cubics[(flag * 3 + i) % 12];
+ UNSAFE_TODO({
+ while (!stream.IsEOF()) {
+ uint32_t flag = stream.ReadFlag();
+ size_t start_point = flag ? 4 : 0;
+ size_t start_color = flag ? 2 : 0;
+ if (flag) {
+ SkPoint temp_cubics[4];
+ for (size_t i = 0; i < std::size(temp_cubics); ++i) {
+ temp_cubics[i] = cubics[(flag * 3 + i) % 12];
+ }
+ std::copy(std::begin(temp_cubics), std::end(temp_cubics),
+ std::begin(cubics));
+ SkColor temp_colors[2] = {colors[flag % 4], colors[(flag + 1) % 4]};
+ std::copy(std::begin(temp_colors), std::end(temp_colors),
+ std::begin(colors));
}
- std::copy(std::begin(temp_cubics), std::end(temp_cubics),
- std::begin(cubics));
- SkColor temp_colors[2] = {colors[flag % 4], colors[(flag + 1) % 4]};
- std::copy(std::begin(temp_colors), std::end(temp_colors),
- std::begin(colors));
+ for (size_t i = start_point; i < std::size(cubics); ++i) {
+ CFX_PointF point = stream.ReadCoords();
+ cubics[i].fX = point.x;
+ cubics[i].fY = point.y;
+ }
+ for (size_t i = start_color; i < std::size(colors); ++i) {
+ FX_RGB_STRUCT<float> rgb = stream.ReadColor();
+ colors[i] =
+ SkColorSetARGB(0xFF, (U8CPU)(rgb.red * 255),
+ (U8CPU)(rgb.green * 255), (U8CPU)(rgb.blue * 255));
+ }
+ m_pCanvas->drawPatch(cubics, colors, /*texCoords=*/nullptr,
+ SkBlendMode::kDst, paint);
}
- for (size_t i = start_point; i < std::size(cubics); ++i) {
- CFX_PointF point = stream.ReadCoords();
- cubics[i].fX = point.x;
- cubics[i].fY = point.y;
- }
- for (size_t i = start_color; i < std::size(colors); ++i) {
- FX_RGB_STRUCT<float> rgb = stream.ReadColor();
- colors[i] =
- SkColorSetARGB(0xFF, (U8CPU)(rgb.red * 255),
- (U8CPU)(rgb.green * 255), (U8CPU)(rgb.blue * 255));
- }
- m_pCanvas->drawPatch(cubics, colors, /*texCoords=*/nullptr,
- SkBlendMode::kDst, paint);
- }
+ });
return true;
}
SkAutoCanvasRestore scoped_save_restore(m_pCanvas, /*doSave=*/true);