diff options
author | npm <npm@chromium.org> | 2016-10-28 12:47:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-28 12:47:48 -0700 |
commit | b849e816eee20c256cf1da94f4ba9e233b13ac23 (patch) | |
tree | 1baee6ae466153c703cf7ebd82b089e688d22935 | |
parent | 5bca5ca83624d2ba8df064cb888c2f27ab248097 (diff) | |
download | pdfium-b849e816eee20c256cf1da94f4ba9e233b13ac23.tar.xz |
Use CompositeMask instead of TransferBitmap when drawing type 3 text
TransferBitmap seems to work improperly when the glyph boxes overlap.
In particular, after drawing a glyph, the next glyph's blanks will
override what the previous glyph drew, and this is not the correct
behavior. While on it, use CheckedNumeric to do operations safely.
For reference of somewhere where something similar is done, see:
https://cs.chromium.org/chromium/src/third_party/pdfium/core/fxge/ge/cfx_renderdevice.cpp?sq=package:chromium&rcl=1477581616&l=988
BUG=513954
Review-Url: https://codereview.chromium.org/2461743002
-rw-r--r-- | core/fpdfapi/render/fpdf_render_text.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/core/fpdfapi/render/fpdf_render_text.cpp b/core/fpdfapi/render/fpdf_render_text.cpp index b8f44f8bd9..7d29f5c87f 100644 --- a/core/fpdfapi/render/fpdf_render_text.cpp +++ b/core/fpdfapi/render/fpdf_render_text.cpp @@ -29,6 +29,7 @@ #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" +#include "third_party/base/numerics/safe_math.h" FX_BOOL CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, const CFX_Matrix* pObj2Device, @@ -314,13 +315,25 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, if (!glyph.m_pGlyph) continue; - bitmap.TransferBitmap( - static_cast<int>( - (glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa), - static_cast<int>((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * - sd), - glyph.m_pGlyph->m_Bitmap.GetWidth(), - glyph.m_pGlyph->m_Bitmap.GetHeight(), &glyph.m_pGlyph->m_Bitmap, 0, 0); + pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX; + left += glyph.m_pGlyph->m_Left; + left -= rect.left; + left *= sa; + if (!left.IsValid()) + continue; + + pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY; + top -= glyph.m_pGlyph->m_Top; + top -= rect.top; + top *= sd; + if (!top.IsValid()) + continue; + + bitmap.CompositeMask(left.ValueOrDie(), top.ValueOrDie(), + glyph.m_pGlyph->m_Bitmap.GetWidth(), + glyph.m_pGlyph->m_Bitmap.GetHeight(), + &glyph.m_pGlyph->m_Bitmap, fill_argb, 0, 0, + FXDIB_BLEND_NORMAL, nullptr, FALSE, 0, nullptr); } m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); return TRUE; |