Index: core/fpdfdoc/cpvt_generateap.cpp |
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp |
index da3c052b85809ea938baad35b5ef3b38e07f2f46..12ba4ef29519e28f47546e285e845481b029733a 100644 |
--- a/core/fpdfdoc/cpvt_generateap.cpp |
+++ b/core/fpdfdoc/cpvt_generateap.cpp |
@@ -563,6 +563,56 @@ CFX_ByteString GetPaintOperatorString(bool bIsStrokeRect, bool bIsFillRect) { |
return bIsFillRect ? "f" : "n"; |
} |
+CFX_ByteString GenerateTextSymbolAP(const CFX_FloatRect& rect) { |
+ CFX_ByteTextBuf sAppStream; |
+ sAppStream << CPVT_GenerateAP::GenerateColorAP( |
+ CPVT_Color(CPVT_Color::kRGB, 1, 1, 0), PaintOperation::FILL); |
+ sAppStream << CPVT_GenerateAP::GenerateColorAP( |
+ CPVT_Color(CPVT_Color::kRGB, 0, 0, 0), PaintOperation::STROKE); |
+ |
+ const FX_FLOAT fBorderWidth = 1; |
+ sAppStream << fBorderWidth << " w\n"; |
+ |
+ const FX_FLOAT fHalfWidth = fBorderWidth / 2; |
+ const FX_FLOAT fTipDelta = 4; |
+ |
+ CFX_FloatRect outerRect1 = rect; |
+ outerRect1.Deflate(fHalfWidth, fHalfWidth); |
+ outerRect1.bottom += fTipDelta; |
+ |
+ CFX_FloatRect outerRect2 = outerRect1; |
+ outerRect2.left += fTipDelta; |
+ outerRect2.right = outerRect2.left + fTipDelta; |
+ outerRect2.top = outerRect2.bottom - fTipDelta; |
+ FX_FLOAT outerRect2Middle = (outerRect2.left + outerRect2.right) / 2; |
+ |
+ // Draw outer boxes. |
+ sAppStream << outerRect1.left << " " << outerRect1.bottom << " m\n" |
+ << outerRect1.left << " " << outerRect1.top << " l\n" |
+ << outerRect1.right << " " << outerRect1.top << " l\n" |
+ << outerRect1.right << " " << outerRect1.bottom << " l\n" |
+ << outerRect2.right << " " << outerRect2.bottom << " l\n" |
+ << outerRect2Middle << " " << outerRect2.top << " l\n" |
+ << outerRect2.left << " " << outerRect2.bottom << " l\n" |
+ << outerRect1.left << " " << outerRect1.bottom << " l\n"; |
+ |
+ // Draw inner lines. |
+ CFX_FloatRect lineRect = outerRect1; |
+ const FX_FLOAT fXDelta = 2; |
+ const FX_FLOAT fYDelta = (lineRect.top - lineRect.bottom) / 4; |
+ |
+ lineRect.left += fXDelta; |
+ lineRect.right -= fXDelta; |
+ for (int i = 0; i < 3; ++i) { |
+ lineRect.top -= fYDelta; |
+ sAppStream << lineRect.left << " " << lineRect.top << " m\n" |
+ << lineRect.right << " " << lineRect.top << " l\n"; |
+ } |
+ sAppStream << "B*\n"; |
+ |
+ return sAppStream.MakeString(); |
+} |
+ |
bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) { |
// If AP dictionary exists, we use the appearance defined in the |
// existing AP dictionary. |
@@ -778,6 +828,30 @@ bool CPVT_GenerateAP::GenerateInkAP(CPDF_Document* pDoc, |
return true; |
} |
+bool CPVT_GenerateAP::GenerateTextAP(CPDF_Document* pDoc, |
+ CPDF_Dictionary* pAnnotDict) { |
+ if (!ShouldGenerateAPForAnnotation(pAnnotDict)) |
+ return false; |
+ |
+ CFX_ByteTextBuf sAppStream; |
+ CFX_ByteString sExtGSDictName = "GS"; |
+ sAppStream << "/" << sExtGSDictName << " gs "; |
+ |
+ CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); |
+ const FX_FLOAT fNoteLength = 20; |
+ CFX_FloatRect noteRect(rect.left, rect.bottom, rect.left + fNoteLength, |
+ rect.bottom + fNoteLength); |
+ pAnnotDict->SetAtRect("Rect", noteRect); |
+ |
+ sAppStream << GenerateTextSymbolAP(noteRect); |
+ |
+ CPDF_Dictionary* pExtGStateDict = |
+ GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); |
+ GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict); |
+ |
+ return true; |
+} |
+ |
bool CPVT_GenerateAP::GenerateUnderlineAP(CPDF_Document* pDoc, |
CPDF_Dictionary* pAnnotDict) { |
if (!ShouldGenerateAPForAnnotation(pAnnotDict)) |