Use CPDF_DictionaryLocker in CPDF_GenerateAP
Reduce ref churn.
Change-Id: Ie11cd4983d939426a7605619c4ac1004659d9954
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97670
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index 62440a7..d24aac8 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -319,41 +319,35 @@
return GenerateColorAP(crDefaultColor, nOperation);
}
-float GetBorderWidth(const CPDF_Dictionary& pAnnotDict) {
- if (const CPDF_Dictionary* pBorderStyleDict = pAnnotDict.GetDictFor("BS")) {
- if (pBorderStyleDict->KeyExist("W"))
- return pBorderStyleDict->GetNumberFor("W");
- }
+float GetBorderWidth(const CPDF_DictionaryLocker& locked_dict) {
+ const CPDF_Dictionary* pBorderStyleDict = locked_dict.GetDictFor("BS");
+ if (pBorderStyleDict && pBorderStyleDict->KeyExist("W"))
+ return pBorderStyleDict->GetNumberFor("W");
- if (const CPDF_Array* pBorderArray =
- pAnnotDict.GetArrayFor(pdfium::annotation::kBorder)) {
- if (pBorderArray->size() > 2)
- return pBorderArray->GetNumberAt(2);
- }
+ const CPDF_Array* pBorderArray =
+ locked_dict.GetArrayFor(pdfium::annotation::kBorder);
+ if (pBorderArray && pBorderArray->size() > 2)
+ return pBorderArray->GetNumberAt(2);
return 1;
}
-const CPDF_Array* GetDashArray(const CPDF_Dictionary& pAnnotDict) {
- if (const CPDF_Dictionary* pBorderStyleDict = pAnnotDict.GetDictFor("BS")) {
- if (pBorderStyleDict->GetStringFor("S") == "D")
- return pBorderStyleDict->GetArrayFor("D");
- }
+RetainPtr<const CPDF_Array> GetDashArray(
+ const CPDF_DictionaryLocker& locked_dict) {
+ const CPDF_Dictionary* pBorderStyleDict = locked_dict.GetDictFor("BS");
+ if (pBorderStyleDict && pBorderStyleDict->GetStringFor("S") == "D")
+ return pdfium::WrapRetain(pBorderStyleDict->GetArrayFor("D"));
- if (const CPDF_Array* pBorderArray =
- pAnnotDict.GetArrayFor(pdfium::annotation::kBorder)) {
- if (pBorderArray->size() == 4) {
- // TODO(tsepez): Convert to retained as part of future CPDF_Dictionary
- // CLs.
- return pBorderArray->GetArrayAt(3).Get();
- }
- }
+ const CPDF_Array* pBorderArray =
+ locked_dict.GetArrayFor(pdfium::annotation::kBorder);
+ if (pBorderArray && pBorderArray->size() == 4)
+ return pBorderArray->GetArrayAt(3);
return nullptr;
}
-ByteString GetDashPatternString(const CPDF_Dictionary& pAnnotDict) {
- const CPDF_Array* pDashArray = GetDashArray(pAnnotDict);
+ByteString GetDashPatternString(const CPDF_DictionaryLocker& locked_dict) {
+ RetainPtr<const CPDF_Array> pDashArray = GetDashArray(locked_dict);
if (!pDashArray || pDashArray->IsEmpty())
return ByteString();
@@ -536,66 +530,69 @@
fxcrt::ostringstream sAppStream;
ByteString sExtGSDictName = "GS";
sAppStream << "/" << sExtGSDictName << " gs ";
+ {
+ CPDF_DictionaryLocker locked_dict(pAnnotDict);
+ const CPDF_Array* pInteriorColor = locked_dict.GetArrayFor("IC");
+ sAppStream << GetColorStringWithDefault(
+ pInteriorColor, CFX_Color(CFX_Color::Type::kTransparent),
+ PaintOperation::kFill);
- const CPDF_Array* pInteriorColor = pAnnotDict->GetArrayFor("IC");
- sAppStream << GetColorStringWithDefault(
- pInteriorColor, CFX_Color(CFX_Color::Type::kTransparent),
- PaintOperation::kFill);
+ sAppStream << GetColorStringWithDefault(
+ locked_dict.GetArrayFor(pdfium::annotation::kC),
+ CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
- sAppStream << GetColorStringWithDefault(
- pAnnotDict->GetArrayFor(pdfium::annotation::kC),
- CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
+ float fBorderWidth = GetBorderWidth(locked_dict);
+ bool bIsStrokeRect = fBorderWidth > 0;
- float fBorderWidth = GetBorderWidth(*pAnnotDict);
- bool bIsStrokeRect = fBorderWidth > 0;
+ if (bIsStrokeRect) {
+ sAppStream << fBorderWidth << " w ";
+ sAppStream << GetDashPatternString(locked_dict);
+ }
- if (bIsStrokeRect) {
- sAppStream << fBorderWidth << " w ";
- sAppStream << GetDashPatternString(*pAnnotDict);
+ CFX_FloatRect rect =
+ locked_dict.GetUnderlying()->GetRectFor(pdfium::annotation::kRect);
+ rect.Normalize();
+
+ if (bIsStrokeRect) {
+ // Deflating rect because stroking a path entails painting all points
+ // whose perpendicular distance from the path in user space is less than
+ // or equal to half the line width.
+ rect.Deflate(fBorderWidth / 2, fBorderWidth / 2);
+ }
+
+ const float fMiddleX = (rect.left + rect.right) / 2;
+ const float fMiddleY = (rect.top + rect.bottom) / 2;
+
+ // |fL| is precalculated approximate value of 4 * tan((3.14 / 2) / 4) / 3,
+ // where |fL| * radius is a good approximation of control points for
+ // arc with 90 degrees.
+ const float fL = 0.5523f;
+ const float fDeltaX = fL * rect.Width() / 2.0;
+ const float fDeltaY = fL * rect.Height() / 2.0;
+
+ // Starting point
+ sAppStream << fMiddleX << " " << rect.top << " m\n";
+ // First Bezier Curve
+ sAppStream << fMiddleX + fDeltaX << " " << rect.top << " " << rect.right
+ << " " << fMiddleY + fDeltaY << " " << rect.right << " "
+ << fMiddleY << " c\n";
+ // Second Bezier Curve
+ sAppStream << rect.right << " " << fMiddleY - fDeltaY << " "
+ << fMiddleX + fDeltaX << " " << rect.bottom << " " << fMiddleX
+ << " " << rect.bottom << " c\n";
+ // Third Bezier Curve
+ sAppStream << fMiddleX - fDeltaX << " " << rect.bottom << " " << rect.left
+ << " " << fMiddleY - fDeltaY << " " << rect.left << " "
+ << fMiddleY << " c\n";
+ // Fourth Bezier Curve
+ sAppStream << rect.left << " " << fMiddleY + fDeltaY << " "
+ << fMiddleX - fDeltaX << " " << rect.top << " " << fMiddleX
+ << " " << rect.top << " c\n";
+
+ bool bIsFillRect = pInteriorColor && !pInteriorColor->IsEmpty();
+ sAppStream << GetPaintOperatorString(bIsStrokeRect, bIsFillRect) << "\n";
}
- CFX_FloatRect rect = pAnnotDict->GetRectFor(pdfium::annotation::kRect);
- rect.Normalize();
-
- if (bIsStrokeRect) {
- // Deflating rect because stroking a path entails painting all points whose
- // perpendicular distance from the path in user space is less than or equal
- // to half the line width.
- rect.Deflate(fBorderWidth / 2, fBorderWidth / 2);
- }
-
- const float fMiddleX = (rect.left + rect.right) / 2;
- const float fMiddleY = (rect.top + rect.bottom) / 2;
-
- // |fL| is precalculated approximate value of 4 * tan((3.14 / 2) / 4) / 3,
- // where |fL| * radius is a good approximation of control points for
- // arc with 90 degrees.
- const float fL = 0.5523f;
- const float fDeltaX = fL * rect.Width() / 2.0;
- const float fDeltaY = fL * rect.Height() / 2.0;
-
- // Starting point
- sAppStream << fMiddleX << " " << rect.top << " m\n";
- // First Bezier Curve
- sAppStream << fMiddleX + fDeltaX << " " << rect.top << " " << rect.right
- << " " << fMiddleY + fDeltaY << " " << rect.right << " "
- << fMiddleY << " c\n";
- // Second Bezier Curve
- sAppStream << rect.right << " " << fMiddleY - fDeltaY << " "
- << fMiddleX + fDeltaX << " " << rect.bottom << " " << fMiddleX
- << " " << rect.bottom << " c\n";
- // Third Bezier Curve
- sAppStream << fMiddleX - fDeltaX << " " << rect.bottom << " " << rect.left
- << " " << fMiddleY - fDeltaY << " " << rect.left << " " << fMiddleY
- << " c\n";
- // Fourth Bezier Curve
- sAppStream << rect.left << " " << fMiddleY + fDeltaY << " "
- << fMiddleX - fDeltaX << " " << rect.top << " " << fMiddleX << " "
- << rect.top << " c\n";
-
- bool bIsFillRect = pInteriorColor && !pInteriorColor->IsEmpty();
- sAppStream << GetPaintOperatorString(bIsStrokeRect, bIsFillRect) << "\n";
-
auto pExtGStateDict =
GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal");
auto pResourceDict =
@@ -638,26 +635,28 @@
}
bool GenerateInkAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) {
- float fBorderWidth = GetBorderWidth(*pAnnotDict);
- bool bIsStroke = fBorderWidth > 0;
-
- if (!bIsStroke)
- return false;
-
const CPDF_Array* pInkList = pAnnotDict->GetArrayFor("InkList");
if (!pInkList || pInkList->IsEmpty())
return false;
- fxcrt::ostringstream sAppStream;
+ float fBorderWidth;
ByteString sExtGSDictName = "GS";
- sAppStream << "/" << sExtGSDictName << " gs ";
+ fxcrt::ostringstream sAppStream;
+ {
+ CPDF_DictionaryLocker locked_dict(pAnnotDict);
+ fBorderWidth = GetBorderWidth(locked_dict);
+ const bool bIsStroke = fBorderWidth > 0;
+ if (!bIsStroke)
+ return false;
- sAppStream << GetColorStringWithDefault(
- pAnnotDict->GetArrayFor(pdfium::annotation::kC),
- CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
+ sAppStream << "/" << sExtGSDictName << " gs ";
+ sAppStream << GetColorStringWithDefault(
+ locked_dict.GetArrayFor(pdfium::annotation::kC),
+ CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
- sAppStream << fBorderWidth << " w ";
- sAppStream << GetDashPatternString(*pAnnotDict);
+ sAppStream << fBorderWidth << " w ";
+ sAppStream << GetDashPatternString(locked_dict);
+ }
// Set inflated rect as a new rect because paths near the border with large
// width should not be clipped to the original rect.
@@ -785,43 +784,42 @@
}
bool GenerateSquareAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) {
+ const ByteString sExtGSDictName = "GS";
fxcrt::ostringstream sAppStream;
- ByteString sExtGSDictName = "GS";
sAppStream << "/" << sExtGSDictName << " gs ";
+ {
+ CPDF_DictionaryLocker locked_dict(pAnnotDict);
+ const CPDF_Array* pInteriorColor = locked_dict.GetArrayFor("IC");
+ sAppStream << GetColorStringWithDefault(
+ pInteriorColor, CFX_Color(CFX_Color::Type::kTransparent),
+ PaintOperation::kFill);
- const CPDF_Array* pInteriorColor = pAnnotDict->GetArrayFor("IC");
- sAppStream << GetColorStringWithDefault(
- pInteriorColor, CFX_Color(CFX_Color::Type::kTransparent),
- PaintOperation::kFill);
+ sAppStream << GetColorStringWithDefault(
+ locked_dict.GetArrayFor(pdfium::annotation::kC),
+ CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
- sAppStream << GetColorStringWithDefault(
- pAnnotDict->GetArrayFor(pdfium::annotation::kC),
- CFX_Color(CFX_Color::Type::kRGB, 0, 0, 0), PaintOperation::kStroke);
+ float fBorderWidth = GetBorderWidth(locked_dict);
+ const bool bIsStrokeRect = fBorderWidth > 0;
+ if (bIsStrokeRect) {
+ sAppStream << fBorderWidth << " w ";
+ sAppStream << GetDashPatternString(locked_dict);
+ }
- float fBorderWidth = GetBorderWidth(*pAnnotDict);
- bool bIsStrokeRect = fBorderWidth > 0;
+ CFX_FloatRect rect = pAnnotDict->GetRectFor(pdfium::annotation::kRect);
+ rect.Normalize();
- if (bIsStrokeRect) {
- sAppStream << fBorderWidth << " w ";
- sAppStream << GetDashPatternString(*pAnnotDict);
+ if (bIsStrokeRect) {
+ // Deflating rect because stroking a path entails painting all points
+ // whose perpendicular distance from the path in user space is less than
+ // or equal to half the line width.
+ rect.Deflate(fBorderWidth / 2, fBorderWidth / 2);
+ }
+
+ const bool bIsFillRect = pInteriorColor && (pInteriorColor->size() > 0);
+ sAppStream << rect.left << " " << rect.bottom << " " << rect.Width() << " "
+ << rect.Height() << " re "
+ << GetPaintOperatorString(bIsStrokeRect, bIsFillRect) << "\n";
}
-
- CFX_FloatRect rect = pAnnotDict->GetRectFor(pdfium::annotation::kRect);
- rect.Normalize();
-
- if (bIsStrokeRect) {
- // Deflating rect because stroking a path entails painting all points whose
- // perpendicular distance from the path in user space is less than or equal
- // to half the line width.
- rect.Deflate(fBorderWidth / 2, fBorderWidth / 2);
- }
-
- bool bIsFillRect = pInteriorColor && (pInteriorColor->size() > 0);
-
- sAppStream << rect.left << " " << rect.bottom << " " << rect.Width() << " "
- << rect.Height() << " re "
- << GetPaintOperatorString(bIsStrokeRect, bIsFillRect) << "\n";
-
auto pExtGStateDict =
GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal");
auto pResourceDict =