summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_render
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-10-04 12:18:35 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-04 12:18:35 -0700
commit69d9c68e705afa7a4008feb9bbeb19cea887ed47 (patch)
treeb5509c51aeeb89c99c7a4e0a60f8e5f29af5245c /core/fpdfapi/fpdf_render
parent488b7ad845d6de212d89cd957303b294ecfa5922 (diff)
downloadpdfium-69d9c68e705afa7a4008feb9bbeb19cea887ed47.tar.xz
Move core/fpdfapi/fpdf_render to core/fpdfapi/render
BUG=pdfium:603 Review-Url: https://codereview.chromium.org/2393593002
Diffstat (limited to 'core/fpdfapi/fpdf_render')
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_pagerendercache.h71
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h62
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_rendercontext.h67
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_renderoptions.h54
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_textrenderer.h60
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_type3cache.cpp171
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_type3cache.h40
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_type3glyphs.cpp46
-rw-r--r--core/fpdfapi/fpdf_render/cpdf_type3glyphs.h35
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render.cpp1289
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_cache.cpp333
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_image.cpp1088
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp1559
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp39
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp1215
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp17
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_text.cpp652
-rw-r--r--core/fpdfapi/fpdf_render/render_int.h596
18 files changed, 0 insertions, 7394 deletions
diff --git a/core/fpdfapi/fpdf_render/cpdf_pagerendercache.h b/core/fpdfapi/fpdf_render/cpdf_pagerendercache.h
deleted file mode 100644
index fda448f7db..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_pagerendercache.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_PAGERENDERCACHE_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_PAGERENDERCACHE_H_
-
-#include <map>
-
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Stream;
-class CPDF_ImageCacheEntry;
-class CPDF_Page;
-class CPDF_RenderStatus;
-class CFX_DIBitmap;
-class CFX_DIBSource;
-class IFX_Pause;
-
-class CPDF_PageRenderCache {
- public:
- explicit CPDF_PageRenderCache(CPDF_Page* pPage);
- ~CPDF_PageRenderCache();
-
- uint32_t EstimateSize();
- void CacheOptimization(int32_t dwLimitCacheSize);
- uint32_t GetTimeCount() const { return m_nTimeCount; }
- void SetTimeCount(uint32_t dwTimeCount) { m_nTimeCount = dwTimeCount; }
-
- void GetCachedBitmap(CPDF_Stream* pStream,
- CFX_DIBSource*& pBitmap,
- CFX_DIBSource*& pMask,
- uint32_t& MatteColor,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t downsampleWidth = 0,
- int32_t downsampleHeight = 0);
-
- void ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap);
- void ClearImageCacheEntry(CPDF_Stream* pStream);
- CPDF_Page* GetPage() const { return m_pPage; }
- CPDF_ImageCacheEntry* GetCurImageCacheEntry() const {
- return m_pCurImageCacheEntry;
- }
-
- FX_BOOL StartGetCachedBitmap(CPDF_Stream* pStream,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t downsampleWidth = 0,
- int32_t downsampleHeight = 0);
-
- FX_BOOL Continue(IFX_Pause* pPause);
-
- protected:
- friend class CPDF_Page;
-
- CPDF_Page* const m_pPage;
- CPDF_ImageCacheEntry* m_pCurImageCacheEntry;
- std::map<CPDF_Stream*, CPDF_ImageCacheEntry*> m_ImageCache;
- uint32_t m_nTimeCount;
- uint32_t m_nCacheSize;
- FX_BOOL m_bCurFindCache;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_PAGERENDERCACHE_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h b/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h
deleted file mode 100644
index a488269d8d..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_PROGRESSIVERENDERER_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_PROGRESSIVERENDERER_H_
-
-#include <memory>
-
-#include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h"
-#include "core/fpdfapi/page/cpdf_pageobjectlist.h"
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_RenderOptions;
-class CPDF_RenderStatus;
-class CFX_RenderDevice;
-class IFX_Pause;
-
-class CPDF_ProgressiveRenderer {
- public:
- // Must match FDF_RENDER_* definitions in public/fpdf_progressive.h, but
- // cannot #include that header. fpdfsdk/fpdf_progressive.cpp has
- // static_asserts to make sure the two sets of values match.
- enum Status {
- Ready, // FPDF_RENDER_READER
- ToBeContinued, // FPDF_RENDER_TOBECOUNTINUED
- Done, // FPDF_RENDER_DONE
- Failed // FPDF_RENDER_FAILED
- };
-
- static int ToFPDFStatus(Status status) { return static_cast<int>(status); }
-
- CPDF_ProgressiveRenderer(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const CPDF_RenderOptions* pOptions);
- ~CPDF_ProgressiveRenderer();
-
- Status GetStatus() const { return m_Status; }
- void Start(IFX_Pause* pPause);
- void Continue(IFX_Pause* pPause);
-
- private:
- void RenderStep();
-
- // Maximum page objects to render before checking for pause.
- static const int kStepLimit = 100;
-
- Status m_Status;
- CPDF_RenderContext* const m_pContext;
- CFX_RenderDevice* const m_pDevice;
- const CPDF_RenderOptions* const m_pOptions;
- std::unique_ptr<CPDF_RenderStatus> m_pRenderStatus;
- CFX_FloatRect m_ClipRect;
- uint32_t m_LayerIndex;
- CPDF_RenderContext::Layer* m_pCurrentLayer;
- CPDF_PageObjectList::iterator m_LastObjectRendered;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_PROGRESSIVERENDERER_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_rendercontext.h b/core/fpdfapi/fpdf_render/cpdf_rendercontext.h
deleted file mode 100644
index 5d0845789f..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_rendercontext.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDERCONTEXT_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDERCONTEXT_H_
-
-#include "core/fxcrt/fx_basic.h"
-#include "core/fxcrt/fx_coordinates.h"
-
-class CPDF_Dictionary;
-class CPDF_Document;
-class CPDF_Page;
-class CPDF_PageObject;
-class CPDF_PageObjectHolder;
-class CPDF_PageRenderCache;
-class CPDF_RenderOptions;
-class CFX_DIBitmap;
-class CFX_Matrix;
-class CFX_RenderDevice;
-
-class CPDF_RenderContext {
- public:
- class Layer {
- public:
- CPDF_PageObjectHolder* m_pObjectHolder;
- CFX_Matrix m_Matrix;
- };
-
- explicit CPDF_RenderContext(CPDF_Page* pPage);
- CPDF_RenderContext(CPDF_Document* pDoc, CPDF_PageRenderCache* pPageCache);
- ~CPDF_RenderContext();
-
- void AppendLayer(CPDF_PageObjectHolder* pObjectHolder,
- const CFX_Matrix* pObject2Device);
-
- void Render(CFX_RenderDevice* pDevice,
- const CPDF_RenderOptions* pOptions,
- const CFX_Matrix* pFinalMatrix);
-
- void Render(CFX_RenderDevice* pDevice,
- const CPDF_PageObject* pStopObj,
- const CPDF_RenderOptions* pOptions,
- const CFX_Matrix* pFinalMatrix);
-
- void GetBackground(CFX_DIBitmap* pBuffer,
- const CPDF_PageObject* pObj,
- const CPDF_RenderOptions* pOptions,
- CFX_Matrix* pFinalMatrix);
-
- uint32_t CountLayers() const { return m_Layers.GetSize(); }
- Layer* GetLayer(uint32_t index) { return m_Layers.GetDataPtr(index); }
-
- CPDF_Document* GetDocument() const { return m_pDocument; }
- CPDF_Dictionary* GetPageResources() const { return m_pPageResources; }
- CPDF_PageRenderCache* GetPageCache() const { return m_pPageCache; }
-
- protected:
- CPDF_Document* const m_pDocument;
- CPDF_Dictionary* m_pPageResources;
- CPDF_PageRenderCache* m_pPageCache;
- CFX_ArrayTemplate<Layer> m_Layers;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDERCONTEXT_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_renderoptions.h b/core/fpdfapi/fpdf_render/cpdf_renderoptions.h
deleted file mode 100644
index bb0bcd3651..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_renderoptions.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDEROPTIONS_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDEROPTIONS_H_
-
-#include "core/fxcrt/fx_system.h"
-#include "core/fxge/fx_dib.h"
-
-class CPDF_OCContext;
-
-#define RENDER_COLOR_NORMAL 0
-#define RENDER_COLOR_GRAY 1
-#define RENDER_COLOR_TWOCOLOR 2
-#define RENDER_COLOR_ALPHA 3
-#define RENDER_CLEARTYPE 0x00000001
-#define RENDER_PRINTGRAPHICTEXT 0x00000002
-#define RENDER_FORCE_DOWNSAMPLE 0x00000004
-#define RENDER_PRINTPREVIEW 0x00000008
-#define RENDER_BGR_STRIPE 0x00000010
-#define RENDER_NO_NATIVETEXT 0x00000020
-#define RENDER_FORCE_HALFTONE 0x00000040
-#define RENDER_RECT_AA 0x00000080
-#define RENDER_FILL_FULLCOVER 0x00000100
-#define RENDER_PRINTIMAGETEXT 0x00000200
-#define RENDER_OVERPRINT 0x00000400
-#define RENDER_THINLINE 0x00000800
-#define RENDER_NOTEXTSMOOTH 0x10000000
-#define RENDER_NOPATHSMOOTH 0x20000000
-#define RENDER_NOIMAGESMOOTH 0x40000000
-#define RENDER_LIMITEDIMAGECACHE 0x80000000
-
-class CPDF_RenderOptions {
- public:
- CPDF_RenderOptions();
- CPDF_RenderOptions(const CPDF_RenderOptions& rhs);
- FX_ARGB TranslateColor(FX_ARGB argb) const;
-
- int m_ColorMode;
- FX_COLORREF m_BackColor;
- FX_COLORREF m_ForeColor;
- uint32_t m_Flags;
- int m_Interpolation;
- uint32_t m_AddFlags;
- CPDF_OCContext* m_pOCContext;
- uint32_t m_dwLimitCacheSize;
- int m_HalftoneLimit;
- bool m_bDrawAnnots;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_RENDEROPTIONS_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_textrenderer.h b/core/fpdfapi/fpdf_render/cpdf_textrenderer.h
deleted file mode 100644
index b758a01570..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_textrenderer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_TEXTRENDERER_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_TEXTRENDERER_H_
-
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "core/fxge/fx_dib.h"
-
-class CFX_RenderDevice;
-class CFX_GraphStateData;
-class CFX_PathData;
-class CPDF_RenderOptions;
-class CPDF_Font;
-
-class CPDF_TextRenderer {
- public:
- static void DrawTextString(CFX_RenderDevice* pDevice,
- FX_FLOAT origin_x,
- FX_FLOAT origin_y,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* matrix,
- const CFX_ByteString& str,
- FX_ARGB fill_argb,
- FX_ARGB stroke_argb,
- const CFX_GraphStateData* pGraphState,
- const CPDF_RenderOptions* pOptions);
-
- static FX_BOOL DrawTextPath(CFX_RenderDevice* pDevice,
- int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pText2User,
- const CFX_Matrix* pUser2Device,
- const CFX_GraphStateData* pGraphState,
- FX_ARGB fill_argb,
- FX_ARGB stroke_argb,
- CFX_PathData* pClippingPath,
- int nFlag);
-
- static FX_BOOL DrawNormalText(CFX_RenderDevice* pDevice,
- int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pText2Device,
- FX_ARGB fill_argb,
- const CPDF_RenderOptions* pOptions);
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_TEXTRENDERER_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp b/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp
deleted file mode 100644
index 1891a8d2d0..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/cpdf_type3cache.h"
-
-#include <map>
-#include <memory>
-
-#include "core/fpdfapi/font/cpdf_type3char.h"
-#include "core/fpdfapi/font/cpdf_type3font.h"
-#include "core/fpdfapi/fpdf_render/cpdf_type3glyphs.h"
-#include "core/fxge/fx_dib.h"
-#include "core/fxge/fx_font.h"
-
-namespace {
-
-struct CPDF_UniqueKeyGen {
- void Generate(int count, ...);
- FX_CHAR m_Key[128];
- int m_KeyLen;
-};
-
-void CPDF_UniqueKeyGen::Generate(int count, ...) {
- va_list argList;
- va_start(argList, count);
- for (int i = 0; i < count; i++) {
- int p = va_arg(argList, int);
- (reinterpret_cast<uint32_t*>(m_Key))[i] = p;
- }
- va_end(argList);
- m_KeyLen = count * sizeof(uint32_t);
-}
-
-FX_BOOL IsScanLine1bpp(uint8_t* pBuf, int width) {
- int size = width / 8;
- for (int i = 0; i < size; i++) {
- if (pBuf[i])
- return TRUE;
- }
- return (width % 8) && (pBuf[width / 8] & (0xff << (8 - width % 8)));
-}
-
-FX_BOOL IsScanLine8bpp(uint8_t* pBuf, int width) {
- for (int i = 0; i < width; i++) {
- if (pBuf[i] > 0x40)
- return TRUE;
- }
- return FALSE;
-}
-
-int DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst) {
- int height = pBitmap->GetHeight();
- int pitch = pBitmap->GetPitch();
- int width = pBitmap->GetWidth();
- int bpp = pBitmap->GetBPP();
- if (bpp > 8)
- width *= bpp / 8;
- uint8_t* pBuf = pBitmap->GetBuffer();
- int line = bFirst ? 0 : height - 1;
- int line_step = bFirst ? 1 : -1;
- int line_end = bFirst ? height : -1;
- while (line != line_end) {
- if (bpp == 1) {
- if (IsScanLine1bpp(pBuf + line * pitch, width))
- return line;
- } else {
- if (IsScanLine8bpp(pBuf + line * pitch, width))
- return line;
- }
- line += line_step;
- }
- return -1;
-}
-
-} // namespace
-
-CPDF_Type3Cache::CPDF_Type3Cache(CPDF_Type3Font* pFont) : m_pFont(pFont) {}
-
-CPDF_Type3Cache::~CPDF_Type3Cache() {
- for (const auto& pair : m_SizeMap)
- delete pair.second;
- m_SizeMap.clear();
-}
-
-CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(uint32_t charcode,
- const CFX_Matrix* pMatrix,
- FX_FLOAT retinaScaleX,
- FX_FLOAT retinaScaleY) {
- CPDF_UniqueKeyGen keygen;
- keygen.Generate(
- 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000),
- FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000));
- CFX_ByteString FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
- CPDF_Type3Glyphs* pSizeCache;
- auto it = m_SizeMap.find(FaceGlyphsKey);
- if (it == m_SizeMap.end()) {
- pSizeCache = new CPDF_Type3Glyphs;
- m_SizeMap[FaceGlyphsKey] = pSizeCache;
- } else {
- pSizeCache = it->second;
- }
- auto it2 = pSizeCache->m_GlyphMap.find(charcode);
- if (it2 != pSizeCache->m_GlyphMap.end())
- return it2->second;
-
- CFX_GlyphBitmap* pGlyphBitmap =
- RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY);
- pSizeCache->m_GlyphMap[charcode] = pGlyphBitmap;
- return pGlyphBitmap;
-}
-
-CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize,
- uint32_t charcode,
- const CFX_Matrix* pMatrix,
- FX_FLOAT retinaScaleX,
- FX_FLOAT retinaScaleY) {
- const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode);
- if (!pChar || !pChar->m_pBitmap)
- return nullptr;
-
- CFX_DIBitmap* pBitmap = pChar->m_pBitmap.get();
- CFX_Matrix image_matrix, text_matrix;
- image_matrix = pChar->m_ImageMatrix;
- text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0);
- image_matrix.Concat(text_matrix);
- std::unique_ptr<CFX_DIBitmap> pResBitmap;
- int left = 0;
- int top = 0;
- if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 &&
- FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) {
- int top_line = DetectFirstLastScan(pBitmap, TRUE);
- int bottom_line = DetectFirstLastScan(pBitmap, FALSE);
- if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) {
- FX_FLOAT top_y = image_matrix.d + image_matrix.f;
- FX_FLOAT bottom_y = image_matrix.f;
- FX_BOOL bFlipped = top_y > bottom_y;
- if (bFlipped) {
- FX_FLOAT temp = top_y;
- top_y = bottom_y;
- bottom_y = temp;
- }
- pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line);
- pResBitmap.reset(pBitmap->StretchTo(
- (int)(FXSYS_round(image_matrix.a) * retinaScaleX),
- (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) *
- retinaScaleY)));
- top = top_line;
- if (image_matrix.a < 0) {
- image_matrix.Scale(retinaScaleX, retinaScaleY);
- left = FXSYS_round(image_matrix.e + image_matrix.a);
- } else {
- left = FXSYS_round(image_matrix.e);
- }
- }
- }
- if (!pResBitmap) {
- image_matrix.Scale(retinaScaleX, retinaScaleY);
- pResBitmap.reset(pBitmap->TransformTo(&image_matrix, left, top));
- }
- if (!pResBitmap)
- return nullptr;
-
- CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap;
- pGlyph->m_Left = left;
- pGlyph->m_Top = -top;
- pGlyph->m_Bitmap.TakeOver(pResBitmap.get());
- return pGlyph;
-}
diff --git a/core/fpdfapi/fpdf_render/cpdf_type3cache.h b/core/fpdfapi/fpdf_render/cpdf_type3cache.h
deleted file mode 100644
index ea4b5a1408..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_type3cache.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3CACHE_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3CACHE_H_
-
-#include <map>
-
-#include "core/fpdfapi/font/cpdf_type3font.h"
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Type3Glyphs;
-
-class CPDF_Type3Cache {
- public:
- explicit CPDF_Type3Cache(CPDF_Type3Font* pFont);
- ~CPDF_Type3Cache();
-
- CFX_GlyphBitmap* LoadGlyph(uint32_t charcode,
- const CFX_Matrix* pMatrix,
- FX_FLOAT retinaScaleX,
- FX_FLOAT retinaScaleY);
-
- private:
- CFX_GlyphBitmap* RenderGlyph(CPDF_Type3Glyphs* pSize,
- uint32_t charcode,
- const CFX_Matrix* pMatrix,
- FX_FLOAT retinaScaleX,
- FX_FLOAT retinaScaleY);
-
- CPDF_Type3Font* const m_pFont;
- std::map<CFX_ByteString, CPDF_Type3Glyphs*> m_SizeMap;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3CACHE_H_
diff --git a/core/fpdfapi/fpdf_render/cpdf_type3glyphs.cpp b/core/fpdfapi/fpdf_render/cpdf_type3glyphs.cpp
deleted file mode 100644
index e811c2bd8c..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_type3glyphs.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/cpdf_type3glyphs.h"
-
-#include <map>
-
-#include "core/fxge/fx_font.h"
-
-CPDF_Type3Glyphs::CPDF_Type3Glyphs()
- : m_TopBlueCount(0), m_BottomBlueCount(0) {}
-
-CPDF_Type3Glyphs::~CPDF_Type3Glyphs() {
- for (const auto& pair : m_GlyphMap)
- delete pair.second;
-}
-
-static int _AdjustBlue(FX_FLOAT pos, int& count, int blues[]) {
- FX_FLOAT min_distance = 1000000.0f;
- int closest_pos = -1;
- for (int i = 0; i < count; i++) {
- FX_FLOAT distance = FXSYS_fabs(pos - static_cast<FX_FLOAT>(blues[i]));
- if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) {
- min_distance = distance;
- closest_pos = i;
- }
- }
- if (closest_pos >= 0)
- return blues[closest_pos];
- int new_pos = FXSYS_round(pos);
- if (count == TYPE3_MAX_BLUES)
- return new_pos;
- blues[count++] = new_pos;
- return new_pos;
-}
-
-void CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top,
- FX_FLOAT bottom,
- int& top_line,
- int& bottom_line) {
- top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue);
- bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue);
-}
diff --git a/core/fpdfapi/fpdf_render/cpdf_type3glyphs.h b/core/fpdfapi/fpdf_render/cpdf_type3glyphs.h
deleted file mode 100644
index c88d179b8b..0000000000
--- a/core/fpdfapi/fpdf_render/cpdf_type3glyphs.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3GLYPHS_H_
-#define CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3GLYPHS_H_
-
-#include <map>
-
-#include "core/fxcrt/fx_system.h"
-
-class CFX_GlyphBitmap;
-
-#define TYPE3_MAX_BLUES 16
-
-class CPDF_Type3Glyphs {
- public:
- CPDF_Type3Glyphs();
- ~CPDF_Type3Glyphs();
-
- void AdjustBlue(FX_FLOAT top,
- FX_FLOAT bottom,
- int& top_line,
- int& bottom_line);
-
- std::map<uint32_t, CFX_GlyphBitmap*> m_GlyphMap;
- int m_TopBlue[TYPE3_MAX_BLUES];
- int m_BottomBlue[TYPE3_MAX_BLUES];
- int m_TopBlueCount;
- int m_BottomBlueCount;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_CPDF_TYPE3GLYPHS_H_
diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp
deleted file mode 100644
index ff300f6090..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render.cpp
+++ /dev/null
@@ -1,1289 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-#include <memory>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/font/cpdf_type3char.h"
-#include "core/fpdfapi/font/cpdf_type3font.h"
-#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h"
-#include "core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h"
-#include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h"
-#include "core/fpdfapi/fpdf_render/cpdf_textrenderer.h"
-#include "core/fpdfapi/fpdf_render/cpdf_type3cache.h"
-#include "core/fpdfapi/page/cpdf_form.h"
-#include "core/fpdfapi/page/cpdf_formobject.h"
-#include "core/fpdfapi/page/cpdf_graphicstates.h"
-#include "core/fpdfapi/page/cpdf_image.h"
-#include "core/fpdfapi/page/cpdf_imageobject.h"
-#include "core/fpdfapi/page/cpdf_page.h"
-#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/cpdf_pathobject.h"
-#include "core/fpdfapi/page/cpdf_textobject.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfdoc/cpdf_occontext.h"
-#include "core/fxge/cfx_fxgedevice.h"
-#include "core/fxge/cfx_graphstatedata.h"
-#include "core/fxge/cfx_pathdata.h"
-#include "core/fxge/cfx_renderdevice.h"
-
-CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc)
- : m_pPDFDoc(pPDFDoc) {}
-
-CPDF_DocRenderData::~CPDF_DocRenderData() {
- Clear(TRUE);
-}
-
-void CPDF_DocRenderData::Clear(FX_BOOL bRelease) {
- for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) {
- auto curr_it = it++;
- CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second;
- if (bRelease || cache->use_count() < 2) {
- delete cache->get();
- delete cache;
- m_Type3FaceMap.erase(curr_it);
- }
- }
-
- for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) {
- auto curr_it = it++;
- CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second;
- if (bRelease || value->use_count() < 2) {
- delete value->get();
- delete value;
- m_TransferFuncMap.erase(curr_it);
- }
- }
-}
-
-CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) {
- CPDF_CountedObject<CPDF_Type3Cache>* pCache;
- auto it = m_Type3FaceMap.find(pFont);
- if (it == m_Type3FaceMap.end()) {
- CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont);
- pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3);
- m_Type3FaceMap[pFont] = pCache;
- } else {
- pCache = it->second;
- }
- return pCache->AddRef();
-}
-
-void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) {
- auto it = m_Type3FaceMap.find(pFont);
- if (it != m_Type3FaceMap.end())
- it->second->RemoveRef();
-}
-
-CPDF_RenderOptions::CPDF_RenderOptions()
- : m_ColorMode(RENDER_COLOR_NORMAL),
- m_Flags(RENDER_CLEARTYPE),
- m_Interpolation(0),
- m_AddFlags(0),
- m_pOCContext(nullptr),
- m_dwLimitCacheSize(1024 * 1024 * 100),
- m_HalftoneLimit(-1),
- m_bDrawAnnots(false) {}
-
-CPDF_RenderOptions::CPDF_RenderOptions(const CPDF_RenderOptions& rhs)
- : m_ColorMode(rhs.m_ColorMode),
- m_BackColor(rhs.m_BackColor),
- m_ForeColor(rhs.m_ForeColor),
- m_Flags(rhs.m_Flags),
- m_Interpolation(rhs.m_Interpolation),
- m_AddFlags(rhs.m_AddFlags),
- m_pOCContext(rhs.m_pOCContext),
- m_dwLimitCacheSize(rhs.m_dwLimitCacheSize),
- m_HalftoneLimit(rhs.m_HalftoneLimit),
- m_bDrawAnnots(rhs.m_bDrawAnnots) {}
-
-FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const {
- if (m_ColorMode == RENDER_COLOR_NORMAL) {
- return argb;
- }
- if (m_ColorMode == RENDER_COLOR_ALPHA) {
- return argb;
- }
- int a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- int gray = FXRGB2GRAY(r, g, b);
- if (m_ColorMode == RENDER_COLOR_TWOCOLOR) {
- int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) +
- (b - gray) * (b - gray);
- if (gray < 35 && color < 20) {
- return ArgbEncode(a, m_ForeColor);
- }
- if (gray > 221 && color < 20) {
- return ArgbEncode(a, m_BackColor);
- }
- return argb;
- }
- int fr = FXSYS_GetRValue(m_ForeColor);
- int fg = FXSYS_GetGValue(m_ForeColor);
- int fb = FXSYS_GetBValue(m_ForeColor);
- int br = FXSYS_GetRValue(m_BackColor);
- int bg = FXSYS_GetGValue(m_BackColor);
- int bb = FXSYS_GetBValue(m_BackColor);
- r = (br - fr) * gray / 255 + fr;
- g = (bg - fg) * gray / 255 + fg;
- b = (bb - fb) * gray / 255 + fb;
- return ArgbEncode(a, r, g, b);
-}
-
-// static
-int CPDF_RenderStatus::s_CurrentRecursionDepth = 0;
-
-CPDF_RenderStatus::CPDF_RenderStatus()
- : m_pFormResource(nullptr),
- m_pPageResource(nullptr),
- m_pContext(nullptr),
- m_bStopped(FALSE),
- m_pDevice(nullptr),
- m_pCurObj(nullptr),
- m_pStopObj(nullptr),
- m_HalftoneLimit(0),
- m_bPrint(FALSE),
- m_Transparency(0),
- m_bDropObjects(FALSE),
- m_bStdCS(FALSE),
- m_GroupFamily(0),
- m_bLoadMask(FALSE),
- m_pType3Char(nullptr),
- m_T3FillColor(0),
- m_curBlend(FXDIB_BLEND_NORMAL) {}
-
-CPDF_RenderStatus::~CPDF_RenderStatus() {}
-
-FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const CFX_Matrix* pDeviceMatrix,
- const CPDF_PageObject* pStopObj,
- const CPDF_RenderStatus* pParentState,
- const CPDF_GraphicStates* pInitialStates,
- const CPDF_RenderOptions* pOptions,
- int transparency,
- FX_BOOL bDropObjects,
- CPDF_Dictionary* pFormResource,
- FX_BOOL bStdCS,
- CPDF_Type3Char* pType3Char,
- FX_ARGB fill_color,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask) {
- m_pContext = pContext;
- m_pDevice = pDevice;
- m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
- if (pDeviceMatrix) {
- m_DeviceMatrix = *pDeviceMatrix;
- }
- m_pStopObj = pStopObj;
- if (pOptions) {
- m_Options = *pOptions;
- }
- m_bDropObjects = bDropObjects;
- m_bStdCS = bStdCS;
- m_T3FillColor = fill_color;
- m_pType3Char = pType3Char;
- m_GroupFamily = GroupFamily;
- m_bLoadMask = bLoadMask;
- m_pFormResource = pFormResource;
- m_pPageResource = m_pContext->GetPageResources();
- if (pInitialStates && !m_pType3Char) {
- m_InitialStates.CopyStates(*pInitialStates);
- if (pParentState) {
- if (!m_InitialStates.m_ColorState.HasFillColor()) {
- m_InitialStates.m_ColorState.SetFillRGB(
- pParentState->m_InitialStates.m_ColorState.GetFillRGB());
- m_InitialStates.m_ColorState.GetMutableFillColor()->Copy(
- pParentState->m_InitialStates.m_ColorState.GetFillColor());
- }
- if (!m_InitialStates.m_ColorState.HasStrokeColor()) {
- m_InitialStates.m_ColorState.SetStrokeRGB(
- pParentState->m_InitialStates.m_ColorState.GetFillRGB());
- m_InitialStates.m_ColorState.GetMutableStrokeColor()->Copy(
- pParentState->m_InitialStates.m_ColorState.GetStrokeColor());
- }
- }
- } else {
- m_InitialStates.DefaultStates();
- }
- m_pImageRenderer.reset();
- m_Transparency = transparency;
- return TRUE;
-}
-void CPDF_RenderStatus::RenderObjectList(
- const CPDF_PageObjectHolder* pObjectHolder,
- const CFX_Matrix* pObj2Device) {
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- CFX_FloatRect clip_rect(m_pDevice->GetClipBox());
- CFX_Matrix device2object;
- device2object.SetReverse(*pObj2Device);
- device2object.TransformRect(clip_rect);
-
- for (const auto& pCurObj : *pObjectHolder->GetPageObjectList()) {
- if (pCurObj.get() == m_pStopObj) {
- m_bStopped = TRUE;
- return;
- }
- if (!pCurObj)
- continue;
-
- if (pCurObj->m_Left > clip_rect.right ||
- pCurObj->m_Right < clip_rect.left ||
- pCurObj->m_Bottom > clip_rect.top ||
- pCurObj->m_Top < clip_rect.bottom) {
- continue;
- }
- RenderSingleObject(pCurObj.get(), pObj2Device);
- if (m_bStopped)
- return;
- }
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
-}
-
-void CPDF_RenderStatus::RenderSingleObject(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device) {
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
- if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) {
- return;
- }
- m_pCurObj = pObj;
- if (m_Options.m_pOCContext && pObj->m_ContentMark) {
- if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
- return;
- }
- }
- ProcessClipPath(pObj->m_ClipPath, pObj2Device);
- if (ProcessTransparency(pObj, pObj2Device)) {
- return;
- }
- ProcessObjectNoClip(pObj, pObj2Device);
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
-}
-
-FX_BOOL CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- IFX_Pause* pPause) {
- if (m_pImageRenderer) {
- if (m_pImageRenderer->Continue(pPause))
- return TRUE;
-
- if (!m_pImageRenderer->m_Result)
- DrawObjWithBackground(pObj, pObj2Device);
- m_pImageRenderer.reset();
- return FALSE;
- }
-
- m_pCurObj = pObj;
- if (m_Options.m_pOCContext && pObj->m_ContentMark &&
- !m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
- return FALSE;
- }
-
- ProcessClipPath(pObj->m_ClipPath, pObj2Device);
- if (ProcessTransparency(pObj, pObj2Device))
- return FALSE;
-
- if (pObj->IsImage()) {
- m_pImageRenderer.reset(new CPDF_ImageRenderer);
- if (!m_pImageRenderer->Start(this, pObj, pObj2Device, FALSE)) {
- if (!m_pImageRenderer->m_Result)
- DrawObjWithBackground(pObj, pObj2Device);
- m_pImageRenderer.reset();
- return FALSE;
- }
- return ContinueSingleObject(pObj, pObj2Device, pPause);
- }
-
- ProcessObjectNoClip(pObj, pObj2Device);
- return FALSE;
-}
-
-FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bLogical,
- FX_RECT& rect) const {
- rect = pObj->GetBBox(pObj2Device);
- FX_RECT rtClip = m_pDevice->GetClipBox();
- if (!bLogical) {
- CFX_Matrix dCTM = m_pDevice->GetCTM();
- FX_FLOAT a = FXSYS_fabs(dCTM.a);
- FX_FLOAT d = FXSYS_fabs(dCTM.d);
- if (a != 1.0f || d != 1.0f) {
- rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
- rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
- rtClip.right =
- rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a);
- rtClip.bottom =
- rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d);
- }
- }
- rect.Intersect(rtClip);
- return rect.IsEmpty();
-}
-
-void CPDF_RenderStatus::ProcessObjectNoClip(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device) {
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- FX_BOOL bRet = FALSE;
- switch (pObj->GetType()) {
- case CPDF_PageObject::TEXT:
- bRet = ProcessText(pObj->AsText(), pObj2Device, nullptr);
- break;
- case CPDF_PageObject::PATH:
- bRet = ProcessPath(pObj->AsPath(), pObj2Device);
- break;
- case CPDF_PageObject::IMAGE:
- bRet = ProcessImage(pObj->AsImage(), pObj2Device);
- break;
- case CPDF_PageObject::SHADING:
- ProcessShading(pObj->AsShading(), pObj2Device);
- return;
- case CPDF_PageObject::FORM:
- bRet = ProcessForm(pObj->AsForm(), pObj2Device);
- break;
- }
- if (!bRet)
- DrawObjWithBackground(pObj, pObj2Device);
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
-}
-
-FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device) {
- FX_BOOL bRet = FALSE;
- switch (pObj->GetType()) {
- case CPDF_PageObject::PATH:
- bRet = ProcessPath(pObj->AsPath(), pObj2Device);
- break;
- case CPDF_PageObject::IMAGE:
- bRet = ProcessImage(pObj->AsImage(), pObj2Device);
- break;
- case CPDF_PageObject::FORM:
- bRet = ProcessForm(pObj->AsForm(), pObj2Device);
- break;
- default:
- break;
- }
- return bRet;
-}
-void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix& matrix) const {
- CFX_Matrix dCTM = m_pDevice->GetCTM();
- matrix.a *= FXSYS_fabs(dCTM.a);
- matrix.d *= FXSYS_fabs(dCTM.d);
-}
-
-void CPDF_RenderStatus::DrawObjWithBackground(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device) {
- FX_RECT rect;
- if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
- return;
- }
- int res = 300;
- if (pObj->IsImage() &&
- m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
- res = 0;
- }
- CPDF_ScaledRenderBuffer buffer;
- if (!buffer.Initialize(m_pContext, m_pDevice, rect, pObj, &m_Options, res)) {
- return;
- }
- CFX_Matrix matrix = *pObj2Device;
- matrix.Concat(*buffer.GetMatrix());
- GetScaledMatrix(matrix);
- CPDF_Dictionary* pFormResource = nullptr;
- if (pObj->IsForm()) {
- const CPDF_FormObject* pFormObj = pObj->AsForm();
- if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
- pFormResource = pFormObj->m_pForm->m_pFormDict->GetDictFor("Resources");
- }
- }
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), nullptr,
- nullptr, nullptr, &m_Options, m_Transparency,
- m_bDropObjects, pFormResource);
- status.RenderSingleObject(pObj, &matrix);
- buffer.OutputToDevice();
-}
-
-FX_BOOL CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj,
- const CFX_Matrix* pObj2Device) {
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDictFor("OC");
- if (pOC && m_Options.m_pOCContext &&
- !m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
- return TRUE;
- }
- CFX_Matrix matrix = pFormObj->m_FormMatrix;
- matrix.Concat(*pObj2Device);
- CPDF_Dictionary* pResources = nullptr;
- if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
- pResources = pFormObj->m_pForm->m_pFormDict->GetDictFor("Resources");
- }
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, m_pDevice, nullptr, m_pStopObj, this, pFormObj,
- &m_Options, m_Transparency, m_bDropObjects, pResources,
- FALSE);
- status.m_curBlend = m_curBlend;
- m_pDevice->SaveState();
- status.RenderObjectList(pFormObj->m_pForm.get(), &matrix);
- m_bStopped = status.m_bStopped;
- m_pDevice->RestoreState(false);
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- return TRUE;
-}
-
-FX_BOOL IsAvailableMatrix(const CFX_Matrix& matrix) {
- if (matrix.a == 0 || matrix.d == 0) {
- return matrix.b != 0 && matrix.c != 0;
- }
- if (matrix.b == 0 || matrix.c == 0) {
- return matrix.a != 0 && matrix.d != 0;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device) {
- int FillType = pPathObj->m_FillType;
- FX_BOOL bStroke = pPathObj->m_bStroke;
- ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke);
- if (FillType == 0 && !bStroke)
- return TRUE;
-
- uint32_t fill_argb = FillType ? GetFillArgb(pPathObj) : 0;
- uint32_t stroke_argb = bStroke ? GetStrokeArgb(pPathObj) : 0;
- CFX_Matrix path_matrix = pPathObj->m_Matrix;
- path_matrix.Concat(*pObj2Device);
- if (!IsAvailableMatrix(path_matrix))
- return TRUE;
-
- if (FillType && (m_Options.m_Flags & RENDER_RECT_AA))
- FillType |= FXFILL_RECT_AA;
- if (m_Options.m_Flags & RENDER_FILL_FULLCOVER)
- FillType |= FXFILL_FULLCOVER;
- if (m_Options.m_Flags & RENDER_NOPATHSMOOTH)
- FillType |= FXFILL_NOPATHSMOOTH;
- if (bStroke)
- FillType |= FX_FILL_STROKE;
-
- const CPDF_PageObject* pPageObj =
- static_cast<const CPDF_PageObject*>(pPathObj);
- if (pPageObj->m_GeneralState.GetStrokeAdjust())
- FillType |= FX_STROKE_ADJUST;
- if (m_pType3Char)
- FillType |= FX_FILL_TEXT_MODE;
-
- CFX_GraphState graphState = pPathObj->m_GraphState;
- if (m_Options.m_Flags & RENDER_THINLINE)
- graphState.SetLineWidth(0);
- return m_pDevice->DrawPathWithBlend(
- pPathObj->m_Path.GetObject(), &path_matrix, graphState.GetObject(),
- fill_argb, stroke_argb, FillType, m_curBlend);
-}
-
-CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const {
- ASSERT(pObj);
- CPDF_DocRenderData* pDocCache = m_pContext->GetDocument()->GetRenderData();
- return pDocCache ? pDocCache->GetTransferFunc(pObj) : nullptr;
-}
-
-FX_ARGB CPDF_RenderStatus::GetFillArgb(CPDF_PageObject* pObj,
- FX_BOOL bType3) const {
- const CPDF_ColorState* pColorState = &pObj->m_ColorState;
- if (m_pType3Char && !bType3 &&
- (!m_pType3Char->m_bColored ||
- (m_pType3Char->m_bColored &&
- (!*pColorState || pColorState->GetFillColor()->IsNull())))) {
- return m_T3FillColor;
- }
- if (!*pColorState || pColorState->GetFillColor()->IsNull())
- pColorState = &m_InitialStates.m_ColorState;
-
- FX_COLORREF rgb = pColorState->GetFillRGB();
- if (rgb == (uint32_t)-1)
- return 0;
-
- int32_t alpha =
- static_cast<int32_t>((pObj->m_GeneralState.GetFillAlpha() * 255));
- if (pObj->m_GeneralState.GetTR()) {
- if (!pObj->m_GeneralState.GetTransferFunc()) {
- pObj->m_GeneralState.SetTransferFunc(
- GetTransferFunc(pObj->m_GeneralState.GetTR()));
- }
- if (pObj->m_GeneralState.GetTransferFunc())
- rgb = pObj->m_GeneralState.GetTransferFunc()->TranslateColor(rgb);
- }
- return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
-}
-
-FX_ARGB CPDF_RenderStatus::GetStrokeArgb(CPDF_PageObject* pObj) const {
- const CPDF_ColorState* pColorState = &pObj->m_ColorState;
- if (m_pType3Char &&
- (!m_pType3Char->m_bColored ||
- (m_pType3Char->m_bColored &&
- (!*pColorState || pColorState->GetStrokeColor()->IsNull())))) {
- return m_T3FillColor;
- }
- if (!*pColorState || pColorState->GetStrokeColor()->IsNull())
- pColorState = &m_InitialStates.m_ColorState;
-
- FX_COLORREF rgb = pColorState->GetStrokeRGB();
- if (rgb == (uint32_t)-1)
- return 0;
-
- int32_t alpha = static_cast<int32_t>(pObj->m_GeneralState.GetStrokeAlpha() *
- 255); // not rounded.
- if (pObj->m_GeneralState.GetTR()) {
- if (!pObj->m_GeneralState.GetTransferFunc()) {
- pObj->m_GeneralState.SetTransferFunc(
- GetTransferFunc(pObj->m_GeneralState.GetTR()));
- }
- if (pObj->m_GeneralState.GetTransferFunc())
- rgb = pObj->m_GeneralState.GetTransferFunc()->TranslateColor(rgb);
- }
- return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
-}
-void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath,
- const CFX_Matrix* pObj2Device) {
- if (!ClipPath) {
- if (m_LastClipPath) {
- m_pDevice->RestoreState(true);
- m_LastClipPath.SetNull();
- }
- return;
- }
- if (m_LastClipPath == ClipPath)
- return;
-
- m_LastClipPath = ClipPath;
- m_pDevice->RestoreState(true);
- int nClipPath = ClipPath.GetPathCount();
- for (int i = 0; i < nClipPath; ++i) {
- const CFX_PathData* pPathData = ClipPath.GetPath(i).GetObject();
- if (!pPathData)
- continue;
-
- if (pPathData->GetPointCount() == 0) {
- CFX_PathData EmptyPath;
- EmptyPath.AppendRect(-1, -1, 0, 0);
- int fill_mode = FXFILL_WINDING;
- m_pDevice->SetClip_PathFill(&EmptyPath, nullptr, fill_mode);
- } else {
- int ClipType = ClipPath.GetClipType(i);
- m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType);
- }
- }
- int textcount = ClipPath.GetTextCount();
- if (textcount == 0)
- return;
-
- if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
- !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
- return;
- }
-
- std::unique_ptr<CFX_PathData> pTextClippingPath;
- for (int i = 0; i < textcount; ++i) {
- CPDF_TextObject* pText = ClipPath.GetText(i);
- if (pText) {
- if (!pTextClippingPath)
- pTextClippingPath.reset(new CFX_PathData);
- ProcessText(pText, pObj2Device, pTextClippingPath.get());
- continue;
- }
-
- if (!pTextClippingPath)
- continue;
-
- int fill_mode = FXFILL_WINDING;
- if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH)
- fill_mode |= FXFILL_NOPATHSMOOTH;
- m_pDevice->SetClip_PathFill(pTextClippingPath.get(), nullptr, fill_mode);
- pTextClippingPath.reset();
- }
-}
-
-void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath,
- const CFX_Matrix* pObj2Device) {
- if (!ClipPath)
- return;
-
- int fill_mode = 0;
- if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
- fill_mode |= FXFILL_NOPATHSMOOTH;
- }
- int nClipPath = ClipPath.GetPathCount();
- int i;
- for (i = 0; i < nClipPath; i++) {
- const CFX_PathData* pPathData = ClipPath.GetPath(i).GetObject();
- if (!pPathData) {
- continue;
- }
- CFX_GraphStateData stroke_state;
- if (m_Options.m_Flags & RENDER_THINLINE) {
- stroke_state.m_LineWidth = 0;
- }
- m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000,
- fill_mode);
- }
-}
-FX_BOOL CPDF_RenderStatus::SelectClipPath(const CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke) {
- CFX_Matrix path_matrix = pPathObj->m_Matrix;
- path_matrix.Concat(*pObj2Device);
- if (bStroke) {
- CFX_GraphState graphState = pPathObj->m_GraphState;
- if (m_Options.m_Flags & RENDER_THINLINE)
- graphState.SetLineWidth(0);
- return m_pDevice->SetClip_PathStroke(pPathObj->m_Path.GetObject(),
- &path_matrix, graphState.GetObject());
- }
- int fill_mode = pPathObj->m_FillType;
- if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
- fill_mode |= FXFILL_NOPATHSMOOTH;
- }
- return m_pDevice->SetClip_PathFill(pPathObj->m_Path.GetObject(), &path_matrix,
- fill_mode);
-}
-FX_BOOL CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj,
- const CFX_Matrix* pObj2Device) {
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- int blend_type = pPageObj->m_GeneralState.GetBlendType();
- if (blend_type == FXDIB_BLEND_UNSUPPORTED)
- return TRUE;
-
- CPDF_Dictionary* pSMaskDict =
- ToDictionary(pPageObj->m_GeneralState.GetSoftMask());
- if (pSMaskDict) {
- if (pPageObj->IsImage() &&
- pPageObj->AsImage()->GetImage()->GetDict()->KeyExist("SMask")) {
- pSMaskDict = nullptr;
- }
- }
- CPDF_Dictionary* pFormResource = nullptr;
- FX_FLOAT group_alpha = 1.0f;
- int Transparency = m_Transparency;
- FX_BOOL bGroupTransparent = FALSE;
- if (pPageObj->IsForm()) {
- const CPDF_FormObject* pFormObj = pPageObj->AsForm();
- group_alpha = pFormObj->m_GeneralState.GetFillAlpha();
- Transparency = pFormObj->m_pForm->m_Transparency;
- bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED);
- if (pFormObj->m_pForm->m_pFormDict) {
- pFormResource = pFormObj->m_pForm->m_pFormDict->GetDictFor("Resources");
- }
- }
- bool bTextClip =
- (pPageObj->m_ClipPath && pPageObj->m_ClipPath.GetTextCount() &&
- m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
- !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP));
- if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->IsImage() &&
- pPageObj->m_GeneralState.GetFillOP() &&
- pPageObj->m_GeneralState.GetStrokeOP()) {
- CPDF_Document* pDocument = nullptr;
- CPDF_Page* pPage = nullptr;
- if (m_pContext->GetPageCache()) {
- pPage = m_pContext->GetPageCache()->GetPage();
- pDocument = pPage->m_pDocument;
- } else {
- pDocument = pPageObj->AsImage()->GetImage()->GetDocument();
- }
- CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
- CPDF_Object* pCSObj = pPageObj->AsImage()
- ->GetImage()
- ->GetStream()
- ->GetDict()
- ->GetDirectObjectFor("ColorSpace");
- CPDF_ColorSpace* pColorSpace =
- pDocument->LoadColorSpace(pCSObj, pPageResources);
- if (pColorSpace) {
- int format = pColorSpace->GetFamily();
- if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
- format == PDFCS_DEVICEN) {
- blend_type = FXDIB_BLEND_DARKEN;
- }
- pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
- }
- }
- if (!pSMaskDict && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL &&
- !bTextClip && !bGroupTransparent) {
- return FALSE;
- }
- bool isolated = !!(Transparency & PDFTRANS_ISOLATED);
- if (m_bPrint) {
- FX_BOOL bRet = FALSE;
- int rendCaps = m_pDevice->GetRenderCaps();
- if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
- (rendCaps & FXRC_BLEND_MODE)) {
- int oldBlend = m_curBlend;
- m_curBlend = blend_type;
- bRet = DrawObjWithBlend(pPageObj, pObj2Device);
- m_curBlend = oldBlend;
- }
- if (!bRet) {
- DrawObjWithBackground(pPageObj, pObj2Device);
- }
- return TRUE;
- }
- FX_RECT rect = pPageObj->GetBBox(pObj2Device);
- rect.Intersect(m_pDevice->GetClipBox());
- if (rect.IsEmpty()) {
- return TRUE;
- }
- CFX_Matrix deviceCTM = m_pDevice->GetCTM();
- FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
- FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
- int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
- int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
- CFX_FxgeDevice bitmap_device;
- std::unique_ptr<CFX_DIBitmap> oriDevice;
- if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
- oriDevice.reset(new CFX_DIBitmap);
- if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height))
- return TRUE;
- m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top);
- }
- if (!bitmap_device.Create(width, height, FXDIB_Argb, oriDevice.get()))
- return TRUE;
- CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
- bitmap->Clear(0);
- CFX_Matrix new_matrix = *pObj2Device;
- new_matrix.TranslateI(-rect.left, -rect.top);
- new_matrix.Scale(scaleX, scaleY);
- std::unique_ptr<CFX_DIBitmap> pTextMask;
- if (bTextClip) {
- pTextMask.reset(new CFX_DIBitmap);
- if (!pTextMask->Create(width, height, FXDIB_8bppMask))
- return TRUE;
-
- pTextMask->Clear(0);
- CFX_FxgeDevice text_device;
- text_device.Attach(pTextMask.get(), false, nullptr, false);
- for (uint32_t i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
- CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
- if (!textobj) {
- break;
- }
- CFX_Matrix text_matrix;
- textobj->GetTextMatrix(&text_matrix);
- CPDF_TextRenderer::DrawTextPath(
- &text_device, textobj->m_nChars, textobj->m_pCharCodes,
- textobj->m_pCharPos, textobj->m_TextState.GetFont(),
- textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
- textobj->m_GraphState.GetObject(), (FX_ARGB)-1, 0, nullptr, 0);
- }
- }
- CPDF_RenderStatus bitmap_render;
- bitmap_render.Initialize(m_pContext, &bitmap_device, nullptr, m_pStopObj,
- nullptr, nullptr, &m_Options, 0, m_bDropObjects,
- pFormResource, TRUE);
- bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
- m_bStopped = bitmap_render.m_bStopped;
- if (pSMaskDict) {
- CFX_Matrix smask_matrix = *pPageObj->m_GeneralState.GetSMaskMatrix();
- smask_matrix.Concat(*pObj2Device);
- std::unique_ptr<CFX_DIBSource> pSMaskSource(
- LoadSMask(pSMaskDict, &rect, &smask_matrix));
- if (pSMaskSource)
- bitmap->MultiplyAlpha(pSMaskSource.get());
- }
- if (pTextMask) {
- bitmap->MultiplyAlpha(pTextMask.get());
- pTextMask.reset();
- }
- int32_t blitAlpha = 255;
- if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
- blitAlpha = (int32_t)(group_alpha * 255);
-#ifndef _SKIA_SUPPORT_
- bitmap->MultiplyAlpha(blitAlpha);
- blitAlpha = 255;
-#endif
- }
- Transparency = m_Transparency;
- if (pPageObj->IsForm()) {
- Transparency |= PDFTRANS_GROUP;
- }
- CompositeDIBitmap(bitmap, rect.left, rect.top, 0, blitAlpha, blend_type,
- Transparency);
-#if defined _SKIA_SUPPORT_
- DebugVerifyDeviceIsPreMultiplied();
-#endif
- return TRUE;
-}
-
-CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj,
- const FX_RECT& rect,
- int& left,
- int& top,
- FX_BOOL bBackAlphaRequired) {
- FX_RECT bbox = rect;
- bbox.Intersect(m_pDevice->GetClipBox());
- left = bbox.left;
- top = bbox.top;
- CFX_Matrix deviceCTM = m_pDevice->GetCTM();
- FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
- FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
- int width = FXSYS_round(bbox.Width() * scaleX);
- int height = FXSYS_round(bbox.Height() * scaleY);
- std::unique_ptr<CFX_DIBitmap> pBackdrop(new CFX_DIBitmap);
- if (bBackAlphaRequired && !m_bDropObjects)
- pBackdrop->Create(width, height, FXDIB_Argb);
- else
- m_pDevice->CreateCompatibleBitmap(pBackdrop.get(), width, height);
-
- if (!pBackdrop->GetBuffer())
- return nullptr;
-
- FX_BOOL bNeedDraw;
- if (pBackdrop->HasAlpha())
- bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
- else
- bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);
-
- if (!bNeedDraw) {
- m_pDevice->GetDIBits(pBackdrop.get(), left, top);
- return pBackdrop.release();
- }
-
- CFX_Matrix FinalMatrix = m_DeviceMatrix;
- FinalMatrix.TranslateI(-left, -top);
- FinalMatrix.Scale(scaleX, scaleY);
- pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
- CFX_FxgeDevice device;
- device.Attach(pBackdrop.get(), false, nullptr, false);
- m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
- return pBackdrop.release();
-}
-
-void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer,
- const CPDF_PageObject* pObj,
- const CPDF_RenderOptions* pOptions,
- CFX_Matrix* pFinalMatrix) {
- CFX_FxgeDevice device;
- device.Attach(pBuffer, false, nullptr, false);
-
- FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight());
- device.FillRect(&rect, 0xffffffff);
- Render(&device, pObj, pOptions, pFinalMatrix);
-}
-CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(
- const CPDF_GraphicStates* pSrcStates,
- FX_BOOL bStroke) {
- if (!pSrcStates)
- return nullptr;
-
- CPDF_GraphicStates* pStates = new CPDF_GraphicStates;
- pStates->CopyStates(*pSrcStates);
- const CPDF_Color* pObjColor = bStroke
- ? pSrcStates->m_ColorState.GetStrokeColor()
- : pSrcStates->m_ColorState.GetFillColor();
- if (!pObjColor->IsNull()) {
- pStates->m_ColorState.SetFillRGB(
- bStroke ? pSrcStates->m_ColorState.GetStrokeRGB()
- : pSrcStates->m_ColorState.GetFillRGB());
- pStates->m_ColorState.SetStrokeRGB(pStates->m_ColorState.GetFillRGB());
- }
- return pStates;
-}
-
-CPDF_RenderContext::CPDF_RenderContext(CPDF_Page* pPage)
- : m_pDocument(pPage->m_pDocument),
- m_pPageResources(pPage->m_pPageResources),
- m_pPageCache(pPage->GetRenderCache()) {}
-
-CPDF_RenderContext::CPDF_RenderContext(CPDF_Document* pDoc,
- CPDF_PageRenderCache* pPageCache)
- : m_pDocument(pDoc), m_pPageResources(nullptr), m_pPageCache(pPageCache) {}
-
-CPDF_RenderContext::~CPDF_RenderContext() {}
-
-void CPDF_RenderContext::AppendLayer(CPDF_PageObjectHolder* pObjectHolder,
- const CFX_Matrix* pObject2Device) {
- Layer* pLayer = m_Layers.AddSpace();
- pLayer->m_pObjectHolder = pObjectHolder;
- if (pObject2Device) {
- pLayer->m_Matrix = *pObject2Device;
- } else {
- pLayer->m_Matrix.SetIdentity();
- }
-}
-void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice,
- const CPDF_RenderOptions* pOptions,
- const CFX_Matrix* pLastMatrix) {
- Render(pDevice, nullptr, pOptions, pLastMatrix);
-}
-void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice,
- const CPDF_PageObject* pStopObj,
- const CPDF_RenderOptions* pOptions,
- const CFX_Matrix* pLastMatrix) {
- int count = m_Layers.GetSize();
- for (int j = 0; j < count; j++) {
- pDevice->SaveState();
- Layer* pLayer = m_Layers.GetDataPtr(j);
- if (pLastMatrix) {
- CFX_Matrix FinalMatrix = pLayer->m_Matrix;
- FinalMatrix.Concat(*pLastMatrix);
- CPDF_RenderStatus status;
- status.Initialize(this, pDevice, pLastMatrix, pStopObj, nullptr, nullptr,
- pOptions, pLayer->m_pObjectHolder->m_Transparency,
- FALSE, nullptr);
- status.RenderObjectList(pLayer->m_pObjectHolder, &FinalMatrix);
- if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
- m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
- }
- if (status.m_bStopped) {
- pDevice->RestoreState(false);
- break;
- }
- } else {
- CPDF_RenderStatus status;
- status.Initialize(this, pDevice, nullptr, pStopObj, nullptr, nullptr,
- pOptions, pLayer->m_pObjectHolder->m_Transparency,
- FALSE, nullptr);
- status.RenderObjectList(pLayer->m_pObjectHolder, &pLayer->m_Matrix);
- if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
- m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
- }
- if (status.m_bStopped) {
- pDevice->RestoreState(false);
- break;
- }
- }
- pDevice->RestoreState(false);
- }
-}
-
-CPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer(
- CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const CPDF_RenderOptions* pOptions)
- : m_Status(Ready),
- m_pContext(pContext),
- m_pDevice(pDevice),
- m_pOptions(pOptions),
- m_LayerIndex(0),
- m_pCurrentLayer(nullptr) {}
-
-CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() {
- if (m_pRenderStatus)
- m_pDevice->RestoreState(false);
-}
-
-void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause) {
- if (!m_pContext || !m_pDevice || m_Status != Ready) {
- m_Status = Failed;
- return;
- }
- m_Status = ToBeContinued;
- Continue(pPause);
-}
-
-void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) {
- while (m_Status == ToBeContinued) {
- if (!m_pCurrentLayer) {
- if (m_LayerIndex >= m_pContext->CountLayers()) {
- m_Status = Done;
- return;
- }
- m_pCurrentLayer = m_pContext->GetLayer(m_LayerIndex);
- m_LastObjectRendered =
- m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->end();
- m_pRenderStatus.reset(new CPDF_RenderStatus());
- m_pRenderStatus->Initialize(
- m_pContext, m_pDevice, nullptr, nullptr, nullptr, nullptr, m_pOptions,
- m_pCurrentLayer->m_pObjectHolder->m_Transparency, FALSE, nullptr);
- m_pDevice->SaveState();
- m_ClipRect = CFX_FloatRect(m_pDevice->GetClipBox());
- CFX_Matrix device2object;
- device2object.SetReverse(m_pCurrentLayer->m_Matrix);
- device2object.TransformRect(m_ClipRect);
- }
- CPDF_PageObjectList::iterator iter;
- CPDF_PageObjectList::iterator iterEnd =
- m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->end();
- if (m_LastObjectRendered != iterEnd) {
- iter = m_LastObjectRendered;
- ++iter;
- } else {
- iter = m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->begin();
- }
- int nObjsToGo = kStepLimit;
- while (iter != iterEnd) {
- CPDF_PageObject* pCurObj = iter->get();
- if (pCurObj && pCurObj->m_Left <= m_ClipRect.right &&
- pCurObj->m_Right >= m_ClipRect.left &&
- pCurObj->m_Bottom <= m_ClipRect.top &&
- pCurObj->m_Top >= m_ClipRect.bottom) {
- if (m_pRenderStatus->ContinueSingleObject(
- pCurObj, &m_pCurrentLayer->m_Matrix, pPause)) {
- return;
- }
- if (pCurObj->IsImage() &&
- m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
- m_pContext->GetPageCache()->CacheOptimization(
- m_pRenderStatus->m_Options.m_dwLimitCacheSize);
- }
- if (pCurObj->IsForm() || pCurObj->IsShading()) {
- nObjsToGo = 0;
- } else {
- --nObjsToGo;
- }
- }
- m_LastObjectRendered = iter;
- if (nObjsToGo == 0) {
- if (pPause && pPause->NeedToPauseNow())
- return;
- nObjsToGo = kStepLimit;
- }
- ++iter;
- }
- if (m_pCurrentLayer->m_pObjectHolder->IsParsed()) {
- m_pRenderStatus.reset();
- m_pDevice->RestoreState(false);
- m_pCurrentLayer = nullptr;
- m_LayerIndex++;
- if (pPause && pPause->NeedToPauseNow()) {
- return;
- }
- } else {
- m_pCurrentLayer->m_pObjectHolder->ContinueParse(pPause);
- if (!m_pCurrentLayer->m_pObjectHolder->IsParsed())
- return;
- }
- }
-}
-
-CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) {
- if (!pObj)
- return nullptr;
-
- auto it = m_TransferFuncMap.find(pObj);
- if (it != m_TransferFuncMap.end()) {
- CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second;
- return pTransferCounter->AddRef();
- }
-
- std::unique_ptr<CPDF_Function> pFuncs[3];
- FX_BOOL bUniTransfer = TRUE;
- FX_BOOL bIdentity = TRUE;
- if (CPDF_Array* pArray = pObj->AsArray()) {
- bUniTransfer = FALSE;
- if (pArray->GetCount() < 3)
- return nullptr;
-
- for (uint32_t i = 0; i < 3; ++i) {
- pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i));
- if (!pFuncs[2 - i])
- return nullptr;
- }
- } else {
- pFuncs[0] = CPDF_Function::Load(pObj);
- if (!pFuncs[0])
- return nullptr;
- }
- CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc(m_pPDFDoc);
- CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter =
- new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer);
- m_TransferFuncMap[pObj] = pTransferCounter;
- static const int kMaxOutputs = 16;
- FX_FLOAT output[kMaxOutputs];
- FXSYS_memset(output, 0, sizeof(output));
- FX_FLOAT input;
- int noutput;
- for (int v = 0; v < 256; ++v) {
- input = (FX_FLOAT)v / 255.0f;
- if (bUniTransfer) {
- if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs)
- pFuncs[0]->Call(&input, 1, output, noutput);
- int o = FXSYS_round(output[0] * 255);
- if (o != v)
- bIdentity = FALSE;
- for (int i = 0; i < 3; ++i) {
- pTransfer->m_Samples[i * 256 + v] = o;
- }
- } else {
- for (int i = 0; i < 3; ++i) {
- if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) {
- pFuncs[i]->Call(&input, 1, output, noutput);
- int o = FXSYS_round(output[0] * 255);
- if (o != v)
- bIdentity = FALSE;
- pTransfer->m_Samples[i * 256 + v] = o;
- } else {
- pTransfer->m_Samples[i * 256 + v] = v;
- }
- }
- }
- }
-
- pTransfer->m_bIdentity = bIdentity;
- return pTransferCounter->AddRef();
-}
-
-void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) {
- auto it = m_TransferFuncMap.find(pObj);
- if (it != m_TransferFuncMap.end())
- it->second->RemoveRef();
-}
-
-CPDF_DeviceBuffer::CPDF_DeviceBuffer()
- : m_pDevice(nullptr), m_pContext(nullptr), m_pObject(nullptr) {}
-
-CPDF_DeviceBuffer::~CPDF_DeviceBuffer() {}
-
-FX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- FX_RECT* pRect,
- const CPDF_PageObject* pObj,
- int max_dpi) {
- m_pDevice = pDevice;
- m_pContext = pContext;
- m_Rect = *pRect;
- m_pObject = pObj;
- m_Matrix.TranslateI(-pRect->left, -pRect->top);
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
- int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
- int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
- if (horz_size && vert_size && max_dpi) {
- int dpih =
- pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
- int dpiv =
- pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
- if (dpih > max_dpi) {
- m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
- }
- if (dpiv > max_dpi) {
- m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
- }
- }
-#endif
- CFX_Matrix ctm = m_pDevice->GetCTM();
- FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
- FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
- m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
- CFX_FloatRect rect(*pRect);
- m_Matrix.TransformRect(rect);
- FX_RECT bitmap_rect = rect.GetOuterRect();
- m_pBitmap.reset(new CFX_DIBitmap);
- m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb);
- return TRUE;
-}
-void CPDF_DeviceBuffer::OutputToDevice() {
- if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
- if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) {
- m_pDevice->SetDIBits(m_pBitmap.get(), m_Rect.left, m_Rect.top);
- } else {
- m_pDevice->StretchDIBits(m_pBitmap.get(), m_Rect.left, m_Rect.top,
- m_Rect.Width(), m_Rect.Height());
- }
- } else {
- CFX_DIBitmap buffer;
- m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(),
- m_pBitmap->GetHeight());
- m_pContext->GetBackground(&buffer, m_pObject, nullptr, &m_Matrix);
- buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(),
- m_pBitmap.get(), 0, 0);
- m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
- m_Rect.Height());
- }
-}
-
-CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer() {}
-
-CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() {}
-
-#define _FPDFAPI_IMAGESIZE_LIMIT_ (30 * 1024 * 1024)
-FX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const FX_RECT& pRect,
- const CPDF_PageObject* pObj,
- const CPDF_RenderOptions* pOptions,
- int max_dpi) {
- m_pDevice = pDevice;
- if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
- return TRUE;
- }
- m_pContext = pContext;
- m_Rect = pRect;
- m_pObject = pObj;
- m_Matrix.TranslateI(-pRect.left, -pRect.top);
- int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
- int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
- if (horz_size && vert_size && max_dpi) {
- int dpih =
- pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
- int dpiv =
- pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
- if (dpih > max_dpi) {
- m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
- }
- if (dpiv > max_dpi) {
- m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
- }
- }
- m_pBitmapDevice.reset(new CFX_FxgeDevice);
- FXDIB_Format dibFormat = FXDIB_Rgb;
- int32_t bpp = 24;
- if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) {
- dibFormat = FXDIB_Argb;
- bpp = 32;
- }
- while (1) {
- CFX_FloatRect rect(pRect);
- m_Matrix.TransformRect(rect);
- FX_RECT bitmap_rect = rect.GetOuterRect();
- int32_t iWidth = bitmap_rect.Width();
- int32_t iHeight = bitmap_rect.Height();
- int32_t iPitch = (iWidth * bpp + 31) / 32 * 4;
- if (iWidth * iHeight < 1)
- return FALSE;
-
- if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ &&
- m_pBitmapDevice->Create(iWidth, iHeight, dibFormat, nullptr)) {
- break;
- }
- m_Matrix.Scale(0.5f, 0.5f);
- }
- m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions,
- &m_Matrix);
- return TRUE;
-}
-void CPDF_ScaledRenderBuffer::OutputToDevice() {
- if (m_pBitmapDevice) {
- m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left,
- m_Rect.top, m_Rect.Width(), m_Rect.Height());
- }
-}
-
-#if defined _SKIA_SUPPORT_
-void CPDF_RenderStatus::DebugVerifyDeviceIsPreMultiplied() const {
- m_pDevice->DebugVerifyBitmapIsPreMultiplied();
-}
-#endif
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp b/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp
deleted file mode 100644
index 08d749d5a2..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h"
-
-#include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h"
-#include "core/fpdfapi/fpdf_render/render_int.h"
-#include "core/fpdfapi/page/cpdf_page.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_document.h"
-
-struct CACHEINFO {
- uint32_t time;
- CPDF_Stream* pStream;
-};
-
-extern "C" {
-static int compare(const void* data1, const void* data2) {
- return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time;
-}
-} // extern "C"
-
-CPDF_PageRenderCache::CPDF_PageRenderCache(CPDF_Page* pPage)
- : m_pPage(pPage),
- m_pCurImageCacheEntry(nullptr),
- m_nTimeCount(0),
- m_nCacheSize(0),
- m_bCurFindCache(FALSE) {}
-
-CPDF_PageRenderCache::~CPDF_PageRenderCache() {
- for (const auto& it : m_ImageCache)
- delete it.second;
-}
-void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) {
- if (m_nCacheSize <= (uint32_t)dwLimitCacheSize)
- return;
-
- size_t nCount = m_ImageCache.size();
- CACHEINFO* pCACHEINFO = FX_Alloc(CACHEINFO, nCount);
- size_t i = 0;
- for (const auto& it : m_ImageCache) {
- pCACHEINFO[i].time = it.second->GetTimeCount();
- pCACHEINFO[i++].pStream = it.second->GetStream();
- }
- FXSYS_qsort(pCACHEINFO, nCount, sizeof(CACHEINFO), compare);
- uint32_t nTimeCount = m_nTimeCount;
-
- // Check if time value is about to roll over and reset all entries.
- // The comparision is legal because uint32_t is an unsigned type.
- if (nTimeCount + 1 < nTimeCount) {
- for (i = 0; i < nCount; i++)
- m_ImageCache[pCACHEINFO[i].pStream]->m_dwTimeCount = i;
- m_nTimeCount = nCount;
- }
-
- i = 0;
- while (i + 15 < nCount)
- ClearImageCacheEntry(pCACHEINFO[i++].pStream);
-
- while (i < nCount && m_nCacheSize > (uint32_t)dwLimitCacheSize)
- ClearImageCacheEntry(pCACHEINFO[i++].pStream);
-
- FX_Free(pCACHEINFO);
-}
-void CPDF_PageRenderCache::ClearImageCacheEntry(CPDF_Stream* pStream) {
- auto it = m_ImageCache.find(pStream);
- if (it == m_ImageCache.end())
- return;
-
- m_nCacheSize -= it->second->EstimateSize();
- delete it->second;
- m_ImageCache.erase(it);
-}
-uint32_t CPDF_PageRenderCache::EstimateSize() {
- uint32_t dwSize = 0;
- for (const auto& it : m_ImageCache)
- dwSize += it.second->EstimateSize();
-
- m_nCacheSize = dwSize;
- return dwSize;
-}
-void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream,
- CFX_DIBSource*& pBitmap,
- CFX_DIBSource*& pMask,
- uint32_t& MatteColor,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t downsampleWidth,
- int32_t downsampleHeight) {
- CPDF_ImageCacheEntry* pEntry;
- const auto it = m_ImageCache.find(pStream);
- FX_BOOL bFound = it != m_ImageCache.end();
- if (bFound)
- pEntry = it->second;
- else
- pEntry = new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
-
- m_nTimeCount++;
- FX_BOOL bAlreadyCached = pEntry->GetCachedBitmap(
- pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS,
- GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
-
- if (!bFound)
- m_ImageCache[pStream] = pEntry;
-
- if (!bAlreadyCached)
- m_nCacheSize += pEntry->EstimateSize();
-}
-FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap(
- CPDF_Stream* pStream,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t downsampleWidth,
- int32_t downsampleHeight) {
- const auto it = m_ImageCache.find(pStream);
- m_bCurFindCache = it != m_ImageCache.end();
- if (m_bCurFindCache) {
- m_pCurImageCacheEntry = it->second;
- } else {
- m_pCurImageCacheEntry =
- new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
- }
- int ret = m_pCurImageCacheEntry->StartGetCachedBitmap(
- pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS,
- GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
- if (ret == 2)
- return TRUE;
-
- m_nTimeCount++;
- if (!m_bCurFindCache)
- m_ImageCache[pStream] = m_pCurImageCacheEntry;
-
- if (!ret)
- m_nCacheSize += m_pCurImageCacheEntry->EstimateSize();
-
- return FALSE;
-}
-FX_BOOL CPDF_PageRenderCache::Continue(IFX_Pause* pPause) {
- int ret = m_pCurImageCacheEntry->Continue(pPause);
- if (ret == 2)
- return TRUE;
- m_nTimeCount++;
- if (!m_bCurFindCache)
- m_ImageCache[m_pCurImageCacheEntry->GetStream()] = m_pCurImageCacheEntry;
- if (!ret)
- m_nCacheSize += m_pCurImageCacheEntry->EstimateSize();
- return FALSE;
-}
-void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream,
- const CFX_DIBitmap* pBitmap) {
- CPDF_ImageCacheEntry* pEntry;
- const auto it = m_ImageCache.find(pStream);
- if (it == m_ImageCache.end()) {
- if (!pBitmap)
- return;
- pEntry = new CPDF_ImageCacheEntry(m_pPage->m_pDocument, pStream);
- m_ImageCache[pStream] = pEntry;
- } else {
- pEntry = it->second;
- }
- m_nCacheSize -= pEntry->EstimateSize();
- pEntry->Reset(pBitmap);
- m_nCacheSize += pEntry->EstimateSize();
-}
-CPDF_ImageCacheEntry::CPDF_ImageCacheEntry(CPDF_Document* pDoc,
- CPDF_Stream* pStream)
- : m_dwTimeCount(0),
- m_pCurBitmap(nullptr),
- m_pCurMask(nullptr),
- m_MatteColor(0),
- m_pRenderStatus(nullptr),
- m_pDocument(pDoc),
- m_pStream(pStream),
- m_pCachedBitmap(nullptr),
- m_pCachedMask(nullptr),
- m_dwCacheSize(0) {}
-CPDF_ImageCacheEntry::~CPDF_ImageCacheEntry() {
- delete m_pCachedBitmap;
- delete m_pCachedMask;
-}
-void CPDF_ImageCacheEntry::Reset(const CFX_DIBitmap* pBitmap) {
- delete m_pCachedBitmap;
- m_pCachedBitmap = nullptr;
- if (pBitmap) {
- m_pCachedBitmap = pBitmap->Clone();
- }
- CalcSize();
-}
-
-static uint32_t FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) {
- return pDIB && pDIB->GetBuffer()
- ? (uint32_t)pDIB->GetHeight() * pDIB->GetPitch() +
- (uint32_t)pDIB->GetPaletteSize() * 4
- : 0;
-}
-FX_BOOL CPDF_ImageCacheEntry::GetCachedBitmap(CFX_DIBSource*& pBitmap,
- CFX_DIBSource*& pMask,
- uint32_t& MatteColor,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t downsampleWidth,
- int32_t downsampleHeight) {
- if (m_pCachedBitmap) {
- pBitmap = m_pCachedBitmap;
- pMask = m_pCachedMask;
- MatteColor = m_MatteColor;
- return TRUE;
- }
- if (!pRenderStatus) {
- return FALSE;
- }
- CPDF_RenderContext* pContext = pRenderStatus->GetContext();
- CPDF_PageRenderCache* pPageRenderCache = pContext->GetPageCache();
- m_dwTimeCount = pPageRenderCache->GetTimeCount();
- CPDF_DIBSource* pSrc = new CPDF_DIBSource;
- CPDF_DIBSource* pMaskSrc = nullptr;
- if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor,
- pRenderStatus->m_pFormResource, pPageResources, bStdCS,
- GroupFamily, bLoadMask)) {
- delete pSrc;
- pBitmap = nullptr;
- return FALSE;
- }
- m_MatteColor = MatteColor;
- if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
- m_pCachedBitmap = pSrc->Clone();
- delete pSrc;
- } else {
- m_pCachedBitmap = pSrc;
- }
- if (pMaskSrc) {
- m_pCachedMask = pMaskSrc->Clone();
- delete pMaskSrc;
- }
-
- pBitmap = m_pCachedBitmap;
- pMask = m_pCachedMask;
- CalcSize();
- return FALSE;
-}
-CFX_DIBSource* CPDF_ImageCacheEntry::DetachBitmap() {
- CFX_DIBSource* pDIBSource = m_pCurBitmap;
- m_pCurBitmap = nullptr;
- return pDIBSource;
-}
-CFX_DIBSource* CPDF_ImageCacheEntry::DetachMask() {
- CFX_DIBSource* pDIBSource = m_pCurMask;
- m_pCurMask = nullptr;
- return pDIBSource;
-}
-int CPDF_ImageCacheEntry::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t downsampleWidth,
- int32_t downsampleHeight) {
- if (m_pCachedBitmap) {
- m_pCurBitmap = m_pCachedBitmap;
- m_pCurMask = m_pCachedMask;
- return 1;
- }
- if (!pRenderStatus) {
- return 0;
- }
- m_pRenderStatus = pRenderStatus;
- m_pCurBitmap = new CPDF_DIBSource;
- int ret =
- ((CPDF_DIBSource*)m_pCurBitmap)
- ->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources,
- pPageResources, bStdCS, GroupFamily, bLoadMask);
- if (ret == 2) {
- return ret;
- }
- if (!ret) {
- delete m_pCurBitmap;
- m_pCurBitmap = nullptr;
- return 0;
- }
- ContinueGetCachedBitmap();
- return 0;
-}
-void CPDF_ImageCacheEntry::ContinueGetCachedBitmap() {
- m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->GetMatteColor();
- m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
- CPDF_RenderContext* pContext = m_pRenderStatus->GetContext();
- CPDF_PageRenderCache* pPageRenderCache = pContext->GetPageCache();
- m_dwTimeCount = pPageRenderCache->GetTimeCount();
- if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() <
- FPDF_HUGE_IMAGE_SIZE) {
- m_pCachedBitmap = m_pCurBitmap->Clone();
- delete m_pCurBitmap;
- m_pCurBitmap = nullptr;
- } else {
- m_pCachedBitmap = m_pCurBitmap;
- }
- if (m_pCurMask) {
- m_pCachedMask = m_pCurMask->Clone();
- delete m_pCurMask;
- m_pCurMask = nullptr;
- }
- m_pCurBitmap = m_pCachedBitmap;
- m_pCurMask = m_pCachedMask;
- CalcSize();
-}
-int CPDF_ImageCacheEntry::Continue(IFX_Pause* pPause) {
- int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
- if (ret == 2) {
- return ret;
- }
- if (!ret) {
- delete m_pCurBitmap;
- m_pCurBitmap = nullptr;
- return 0;
- }
- ContinueGetCachedBitmap();
- return 0;
-}
-void CPDF_ImageCacheEntry::CalcSize() {
- m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) +
- FPDF_ImageCache_EstimateImageSize(m_pCachedMask);
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp
deleted file mode 100644
index d5a28a6019..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp
+++ /dev/null
@@ -1,1088 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h"
-#include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h"
-#include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h"
-#include "core/fpdfapi/page/cpdf_form.h"
-#include "core/fpdfapi/page/cpdf_image.h"
-#include "core/fpdfapi/page/cpdf_imageobject.h"
-#include "core/fpdfapi/page/cpdf_page.h"
-#include "core/fpdfapi/page/cpdf_shadingpattern.h"
-#include "core/fpdfapi/page/cpdf_tilingpattern.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfdoc/cpdf_occontext.h"
-#include "core/fxcodec/fx_codec.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "core/fxge/cfx_fxgedevice.h"
-#include "core/fxge/cfx_pathdata.h"
-
-#ifdef _SKIA_SUPPORT_
-#include "core/fxge/skia/fx_skia_device.h"
-#endif
-
-FX_BOOL CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj,
- const CFX_Matrix* pObj2Device) {
- CPDF_ImageRenderer render;
- if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) {
- render.Continue(nullptr);
- }
- return render.m_Result;
-}
-void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
- int left,
- int top,
- FX_ARGB mask_argb,
- int bitmap_alpha,
- int blend_mode,
- int Transparency) {
- if (!pDIBitmap) {
- return;
- }
- if (blend_mode == FXDIB_BLEND_NORMAL) {
- if (!pDIBitmap->IsAlphaMask()) {
- if (bitmap_alpha < 255) {
-#ifdef _SKIA_SUPPORT_
- void* dummy;
- CFX_Matrix m(pDIBitmap->GetWidth(), 0, 0, -pDIBitmap->GetHeight(), left,
- top + pDIBitmap->GetHeight());
- m_pDevice->StartDIBits(pDIBitmap, bitmap_alpha, 0, &m, 0, dummy);
- return;
-#else
- pDIBitmap->MultiplyAlpha(bitmap_alpha);
-#endif
- }
-#ifdef _SKIA_SUPPORT_
- CFX_SkiaDeviceDriver::PreMultiply(pDIBitmap);
-#endif
- if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
- return;
- }
- } else {
- uint32_t fill_argb = m_Options.TranslateColor(mask_argb);
- if (bitmap_alpha < 255) {
- ((uint8_t*)&fill_argb)[3] =
- ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
- }
- if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
- return;
- }
- }
- }
- bool bIsolated = !!(Transparency & PDFTRANS_ISOLATED);
- bool bGroup = !!(Transparency & PDFTRANS_GROUP);
- bool bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
- bool bGetBackGround =
- ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
- (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
- (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
- if (bGetBackGround) {
- if (bIsolated || !bGroup) {
- if (pDIBitmap->IsAlphaMask()) {
- return;
- }
- m_pDevice->SetDIBitsWithBlend(pDIBitmap, left, top, blend_mode);
- } else {
- FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
- top + pDIBitmap->GetHeight());
- rect.Intersect(m_pDevice->GetClipBox());
- CFX_DIBitmap* pClone = nullptr;
- FX_BOOL bClone = FALSE;
- if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
- bClone = TRUE;
- pClone = m_pDevice->GetBackDrop()->Clone(&rect);
- CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
- pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
- pForeBitmap, rect.left, rect.top);
- left = left >= 0 ? 0 : left;
- top = top >= 0 ? 0 : top;
- if (!pDIBitmap->IsAlphaMask())
- pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
- pDIBitmap, left, top, blend_mode);
- else
- pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
- pDIBitmap, mask_argb, left, top, blend_mode);
- } else {
- pClone = pDIBitmap;
- }
- if (m_pDevice->GetBackDrop()) {
- m_pDevice->SetDIBits(pClone, rect.left, rect.top);
- } else {
- if (pDIBitmap->IsAlphaMask()) {
- return;
- }
- m_pDevice->SetDIBitsWithBlend(pDIBitmap, rect.left, rect.top,
- blend_mode);
- }
- if (bClone) {
- delete pClone;
- }
- }
- return;
- }
- int back_left, back_top;
- FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
- top + pDIBitmap->GetHeight());
- std::unique_ptr<CFX_DIBitmap> pBackdrop(
- GetBackdrop(m_pCurObj, rect, back_left, back_top,
- blend_mode > FXDIB_BLEND_NORMAL && bIsolated));
- if (!pBackdrop)
- return;
-
- if (!pDIBitmap->IsAlphaMask()) {
- pBackdrop->CompositeBitmap(left - back_left, top - back_top,
- pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
- pDIBitmap, 0, 0, blend_mode);
- } else {
- pBackdrop->CompositeMask(left - back_left, top - back_top,
- pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
- pDIBitmap, mask_argb, 0, 0, blend_mode);
- }
-
- std::unique_ptr<CFX_DIBitmap> pBackdrop1(new CFX_DIBitmap);
- pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(),
- FXDIB_Rgb32);
- pBackdrop1->Clear((uint32_t)-1);
- pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(),
- pBackdrop->GetHeight(), pBackdrop.get(), 0, 0);
- pBackdrop = std::move(pBackdrop1);
- m_pDevice->SetDIBits(pBackdrop.get(), back_left, back_top);
-}
-
-CPDF_TransferFunc::CPDF_TransferFunc(CPDF_Document* pDoc) : m_pPDFDoc(pDoc) {}
-
-FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb) const {
- return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)],
- m_Samples[256 + FXSYS_GetGValue(rgb)],
- m_Samples[512 + FXSYS_GetBValue(rgb)]);
-}
-
-CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc,
- FX_BOOL bAutoDropSrc) {
- CPDF_DIBTransferFunc* pDest = new CPDF_DIBTransferFunc(this);
- pDest->LoadSrc(pSrc, bAutoDropSrc);
- return pDest;
-}
-
-CPDF_DIBTransferFunc::~CPDF_DIBTransferFunc() {}
-
-FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat() {
- if (m_pSrc->IsAlphaMask()) {
- return FXDIB_8bppMask;
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32;
-#else
- return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb;
-#endif
-}
-
-FX_ARGB* CPDF_DIBTransferFunc::GetDestPalette() {
- return nullptr;
-}
-
-CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(
- const CPDF_TransferFunc* pTransferFunc) {
- m_RampR = pTransferFunc->m_Samples;
- m_RampG = &pTransferFunc->m_Samples[256];
- m_RampB = &pTransferFunc->m_Samples[512];
-}
-
-void CPDF_DIBTransferFunc::TranslateScanline(
- const uint8_t* src_buf,
- std::vector<uint8_t>* dest_buf) const {
- FX_BOOL bSkip = FALSE;
- switch (m_pSrc->GetFormat()) {
- case FXDIB_1bppRgb: {
- int r0 = m_RampR[0];
- int g0 = m_RampG[0];
- int b0 = m_RampB[0];
- int r1 = m_RampR[255];
- int g1 = m_RampG[255];
- int b1 = m_RampB[255];
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- if (src_buf[i / 8] & (1 << (7 - i % 8))) {
- (*dest_buf)[index++] = b1;
- (*dest_buf)[index++] = g1;
- (*dest_buf)[index++] = r1;
- } else {
- (*dest_buf)[index++] = b0;
- (*dest_buf)[index++] = g0;
- (*dest_buf)[index++] = r0;
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- index++;
-#endif
- }
- break;
- }
- case FXDIB_1bppMask: {
- int m0 = m_RampR[0];
- int m1 = m_RampR[255];
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- if (src_buf[i / 8] & (1 << (7 - i % 8)))
- (*dest_buf)[index++] = m1;
- else
- (*dest_buf)[index++] = m0;
- }
- break;
- }
- case FXDIB_8bppRgb: {
- FX_ARGB* pPal = m_pSrc->GetPalette();
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- if (pPal) {
- FX_ARGB src_argb = pPal[*src_buf];
- (*dest_buf)[index++] = m_RampB[FXARGB_R(src_argb)];
- (*dest_buf)[index++] = m_RampG[FXARGB_G(src_argb)];
- (*dest_buf)[index++] = m_RampR[FXARGB_B(src_argb)];
- } else {
- uint32_t src_byte = *src_buf;
- (*dest_buf)[index++] = m_RampB[src_byte];
- (*dest_buf)[index++] = m_RampG[src_byte];
- (*dest_buf)[index++] = m_RampR[src_byte];
- }
- src_buf++;
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- index++;
-#endif
- }
- break;
- }
- case FXDIB_8bppMask: {
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- (*dest_buf)[index++] = m_RampR[*(src_buf++)];
- }
- break;
- }
- case FXDIB_Rgb: {
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- (*dest_buf)[index++] = m_RampB[*(src_buf++)];
- (*dest_buf)[index++] = m_RampG[*(src_buf++)];
- (*dest_buf)[index++] = m_RampR[*(src_buf++)];
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- index++;
-#endif
- }
- break;
- }
- case FXDIB_Rgb32:
- bSkip = TRUE;
- case FXDIB_Argb: {
- int index = 0;
- for (int i = 0; i < m_Width; i++) {
- (*dest_buf)[index++] = m_RampB[*(src_buf++)];
- (*dest_buf)[index++] = m_RampG[*(src_buf++)];
- (*dest_buf)[index++] = m_RampR[*(src_buf++)];
- if (!bSkip) {
- (*dest_buf)[index++] = *src_buf;
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- } else {
- index++;
-#endif
- }
- src_buf++;
- }
- break;
- }
- default:
- break;
- }
-}
-
-void CPDF_DIBTransferFunc::TranslateDownSamples(uint8_t* dest_buf,
- const uint8_t* src_buf,
- int pixels,
- int Bpp) const {
- if (Bpp == 8) {
- for (int i = 0; i < pixels; i++) {
- *dest_buf++ = m_RampR[*(src_buf++)];
- }
- } else if (Bpp == 24) {
- for (int i = 0; i < pixels; i++) {
- *dest_buf++ = m_RampB[*(src_buf++)];
- *dest_buf++ = m_RampG[*(src_buf++)];
- *dest_buf++ = m_RampR[*(src_buf++)];
- }
- } else {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!m_pSrc->HasAlpha()) {
- for (int i = 0; i < pixels; i++) {
- *dest_buf++ = m_RampB[*(src_buf++)];
- *dest_buf++ = m_RampG[*(src_buf++)];
- *dest_buf++ = m_RampR[*(src_buf++)];
- dest_buf++;
- src_buf++;
- }
- } else {
-#endif
- for (int i = 0; i < pixels; i++) {
- *dest_buf++ = m_RampB[*(src_buf++)];
- *dest_buf++ = m_RampG[*(src_buf++)];
- *dest_buf++ = m_RampR[*(src_buf++)];
- *dest_buf++ = *(src_buf++);
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- }
-#endif
- }
-}
-
-CPDF_ImageRenderer::CPDF_ImageRenderer() {
- m_pRenderStatus = nullptr;
- m_pImageObject = nullptr;
- m_Result = TRUE;
- m_Status = 0;
- m_DeviceHandle = nullptr;
- m_bStdCS = FALSE;
- m_bPatternColor = FALSE;
- m_BlendType = FXDIB_BLEND_NORMAL;
- m_pPattern = nullptr;
- m_pObj2Device = nullptr;
-}
-
-CPDF_ImageRenderer::~CPDF_ImageRenderer() {
- if (m_DeviceHandle) {
- m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle);
- }
-}
-
-FX_BOOL CPDF_ImageRenderer::StartLoadDIBSource() {
- CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
- FX_RECT image_rect = image_rect_f.GetOuterRect();
- if (!image_rect.Valid())
- return FALSE;
-
- int dest_width = image_rect.Width();
- int dest_height = image_rect.Height();
- if (m_ImageMatrix.a < 0) {
- dest_width = -dest_width;
- }
- if (m_ImageMatrix.d > 0) {
- dest_height = -dest_height;
- }
- if (m_Loader.Start(m_pImageObject,
- m_pRenderStatus->m_pContext->GetPageCache(), &m_LoadHandle,
- m_bStdCS, m_pRenderStatus->m_GroupFamily,
- m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width,
- dest_height)) {
- if (m_LoadHandle) {
- m_Status = 4;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource() {
- if (!m_Loader.m_pBitmap)
- return FALSE;
-
- m_BitmapAlpha =
- FXSYS_round(255 * m_pImageObject->m_GeneralState.GetFillAlpha());
- m_pDIBSource = m_Loader.m_pBitmap;
- if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA &&
- !m_Loader.m_pMask) {
- return StartBitmapAlpha();
- }
- if (m_pImageObject->m_GeneralState.GetTR()) {
- if (!m_pImageObject->m_GeneralState.GetTransferFunc()) {
- m_pImageObject->m_GeneralState.SetTransferFunc(
- m_pRenderStatus->GetTransferFunc(
- m_pImageObject->m_GeneralState.GetTR()));
- }
- if (m_pImageObject->m_GeneralState.GetTransferFunc() &&
- !m_pImageObject->m_GeneralState.GetTransferFunc()->m_bIdentity) {
- m_pDIBSource = m_Loader.m_pBitmap =
- m_pImageObject->m_GeneralState.GetTransferFunc()->TranslateImage(
- m_Loader.m_pBitmap, !m_Loader.m_bCached);
- if (m_Loader.m_bCached && m_Loader.m_pMask) {
- m_Loader.m_pMask = m_Loader.m_pMask->Clone();
- }
- m_Loader.m_bCached = FALSE;
- }
- }
- m_FillArgb = 0;
- m_bPatternColor = FALSE;
- m_pPattern = nullptr;
- if (m_pDIBSource->IsAlphaMask()) {
- const CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
- if (pColor && pColor->IsPattern()) {
- m_pPattern = pColor->GetPattern();
- if (m_pPattern) {
- m_bPatternColor = TRUE;
- }
- }
- m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
- } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
- m_pClone.reset(m_pDIBSource->Clone());
- m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor,
- m_pRenderStatus->m_Options.m_ForeColor);
- m_pDIBSource = m_pClone.get();
- }
- m_Flags = 0;
- if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) {
- m_Flags |= RENDER_FORCE_DOWNSAMPLE;
- } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) {
- m_Flags |= RENDER_FORCE_HALFTONE;
- }
- if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
- CPDF_Object* pFilters =
- m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
- "Filter");
- if (pFilters) {
- if (pFilters->IsName()) {
- CFX_ByteString bsDecodeType = pFilters->GetString();
- if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode") {
- m_Flags |= FXRENDER_IMAGE_LOSSY;
- }
- } else if (CPDF_Array* pArray = pFilters->AsArray()) {
- for (size_t i = 0; i < pArray->GetCount(); i++) {
- CFX_ByteString bsDecodeType = pArray->GetStringAt(i);
- if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode") {
- m_Flags |= FXRENDER_IMAGE_LOSSY;
- break;
- }
- }
- }
- }
- }
- if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) {
- m_Flags |= FXDIB_NOSMOOTH;
- } else if (m_pImageObject->GetImage()->IsInterpol()) {
- m_Flags |= FXDIB_INTERPOL;
- }
- if (m_Loader.m_pMask) {
- return DrawMaskedImage();
- }
- if (m_bPatternColor) {
- return DrawPatternImage(m_pObj2Device);
- }
- if (m_BitmapAlpha == 255 && m_pImageObject->m_GeneralState &&
- m_pImageObject->m_GeneralState.GetFillOP() &&
- m_pImageObject->m_GeneralState.GetOPMode() == 0 &&
- m_pImageObject->m_GeneralState.GetBlendType() == FXDIB_BLEND_NORMAL &&
- m_pImageObject->m_GeneralState.GetStrokeAlpha() == 1.0f &&
- m_pImageObject->m_GeneralState.GetFillAlpha() == 1.0f) {
- CPDF_Document* pDocument = nullptr;
- CPDF_Page* pPage = nullptr;
- if (m_pRenderStatus->m_pContext->GetPageCache()) {
- pPage = m_pRenderStatus->m_pContext->GetPageCache()->GetPage();
- pDocument = pPage->m_pDocument;
- } else {
- pDocument = m_pImageObject->GetImage()->GetDocument();
- }
- CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
- CPDF_Object* pCSObj =
- m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
- "ColorSpace");
- CPDF_ColorSpace* pColorSpace =
- pDocument->LoadColorSpace(pCSObj, pPageResources);
- if (pColorSpace) {
- int format = pColorSpace->GetFamily();
- if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
- format == PDFCS_DEVICEN) {
- m_BlendType = FXDIB_BLEND_DARKEN;
- }
- pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
- }
- }
- return StartDIBSource();
-}
-
-FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus,
- CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStdCS,
- int blendType) {
- m_pRenderStatus = pStatus;
- m_bStdCS = bStdCS;
- m_pImageObject = pObj->AsImage();
- m_BlendType = blendType;
- m_pObj2Device = pObj2Device;
- CPDF_Dictionary* pOC = m_pImageObject->GetImage()->GetOC();
- if (pOC && m_pRenderStatus->m_Options.m_pOCContext &&
- !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
- return FALSE;
- }
- m_ImageMatrix = m_pImageObject->m_Matrix;
- m_ImageMatrix.Concat(*pObj2Device);
- if (StartLoadDIBSource()) {
- return TRUE;
- }
- return StartRenderDIBSource();
-}
-
-FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus,
- const CFX_DIBSource* pDIBSource,
- FX_ARGB bitmap_argb,
- int bitmap_alpha,
- const CFX_Matrix* pImage2Device,
- uint32_t flags,
- FX_BOOL bStdCS,
- int blendType) {
- m_pRenderStatus = pStatus;
- m_pDIBSource = pDIBSource;
- m_FillArgb = bitmap_argb;
- m_BitmapAlpha = bitmap_alpha;
- m_ImageMatrix = *pImage2Device;
- m_Flags = flags;
- m_bStdCS = bStdCS;
- m_BlendType = blendType;
- return StartDIBSource();
-}
-
-FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) {
- if (m_pRenderStatus->m_bPrint &&
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
- m_Result = FALSE;
- return FALSE;
- }
- FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect();
- rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
- if (rect.IsEmpty()) {
- return FALSE;
- }
- CFX_Matrix new_matrix = m_ImageMatrix;
- new_matrix.TranslateI(-rect.left, -rect.top);
- int width = rect.Width();
- int height = rect.Height();
- CFX_FxgeDevice bitmap_device1;
- if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr))
- return TRUE;
-
- bitmap_device1.GetBitmap()->Clear(0xffffff);
- {
- CPDF_RenderStatus bitmap_render;
- bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1,
- nullptr, nullptr, nullptr, nullptr,
- &m_pRenderStatus->m_Options, 0,
- m_pRenderStatus->m_bDropObjects, nullptr, TRUE);
- CFX_Matrix patternDevice = *pObj2Device;
- patternDevice.Translate((FX_FLOAT)-rect.left, (FX_FLOAT)-rect.top);
- if (CPDF_TilingPattern* pTilingPattern = m_pPattern->AsTilingPattern()) {
- bitmap_render.DrawTilingPattern(pTilingPattern, m_pImageObject,
- &patternDevice, FALSE);
- } else if (CPDF_ShadingPattern* pShadingPattern =
- m_pPattern->AsShadingPattern()) {
- bitmap_render.DrawShadingPattern(pShadingPattern, m_pImageObject,
- &patternDevice, FALSE);
- }
- }
- {
- CFX_FxgeDevice bitmap_device2;
- if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb,
- nullptr)) {
- return TRUE;
- }
- bitmap_device2.GetBitmap()->Clear(0);
- CPDF_RenderStatus bitmap_render;
- bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2,
- nullptr, nullptr, nullptr, nullptr, nullptr, 0,
- m_pRenderStatus->m_bDropObjects, nullptr, TRUE);
- CPDF_ImageRenderer image_render;
- if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255,
- &new_matrix, m_Flags, TRUE)) {
- image_render.Continue(nullptr);
- }
- if (m_Loader.m_MatteColor != 0xffffffff) {
- int matte_r = FXARGB_R(m_Loader.m_MatteColor);
- int matte_g = FXARGB_G(m_Loader.m_MatteColor);
- int matte_b = FXARGB_B(m_Loader.m_MatteColor);
- for (int row = 0; row < height; row++) {
- uint8_t* dest_scan =
- (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
- const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
- for (int col = 0; col < width; col++) {
- int alpha = *mask_scan++;
- if (alpha) {
- int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- dest_scan++;
- } else {
- dest_scan += 4;
- }
- }
- }
- }
- bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
- bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
- bitmap_device1.GetBitmap()->MultiplyAlpha(255);
- }
- m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
- bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
- return FALSE;
-}
-
-FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() {
- if (m_pRenderStatus->m_bPrint &&
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
- m_Result = FALSE;
- return FALSE;
- }
- FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect();
- rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
- if (rect.IsEmpty()) {
- return FALSE;
- }
- CFX_Matrix new_matrix = m_ImageMatrix;
- new_matrix.TranslateI(-rect.left, -rect.top);
- int width = rect.Width();
- int height = rect.Height();
- CFX_FxgeDevice bitmap_device1;
- if (!bitmap_device1.Create(width, height, FXDIB_Rgb32, nullptr))
- return TRUE;
-
-#if defined _SKIA_SUPPORT_
- bitmap_device1.Clear(0xffffff);
-#else
- bitmap_device1.GetBitmap()->Clear(0xffffff);
-#endif
- {
- CPDF_RenderStatus bitmap_render;
- bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1,
- nullptr, nullptr, nullptr, nullptr, nullptr, 0,
- m_pRenderStatus->m_bDropObjects, nullptr, TRUE);
- CPDF_ImageRenderer image_render;
- if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix,
- m_Flags, TRUE)) {
- image_render.Continue(nullptr);
- }
- }
- {
- CFX_FxgeDevice bitmap_device2;
- if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb, nullptr))
- return TRUE;
-
-#if defined _SKIA_SUPPORT_
- bitmap_device2.Clear(0);
-#else
- bitmap_device2.GetBitmap()->Clear(0);
-#endif
- CPDF_RenderStatus bitmap_render;
- bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2,
- nullptr, nullptr, nullptr, nullptr, nullptr, 0,
- m_pRenderStatus->m_bDropObjects, nullptr, TRUE);
- CPDF_ImageRenderer image_render;
- if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255,
- &new_matrix, m_Flags, TRUE)) {
- image_render.Continue(nullptr);
- }
- if (m_Loader.m_MatteColor != 0xffffffff) {
- int matte_r = FXARGB_R(m_Loader.m_MatteColor);
- int matte_g = FXARGB_G(m_Loader.m_MatteColor);
- int matte_b = FXARGB_B(m_Loader.m_MatteColor);
- for (int row = 0; row < height; row++) {
- uint8_t* dest_scan =
- (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
- const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
- for (int col = 0; col < width; col++) {
- int alpha = *mask_scan++;
- if (alpha) {
- int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
- if (orig < 0) {
- orig = 0;
- } else if (orig > 255) {
- orig = 255;
- }
- *dest_scan++ = orig;
- dest_scan++;
- } else {
- dest_scan += 4;
- }
- }
- }
- }
-#ifdef _SKIA_SUPPORT_
- m_pRenderStatus->m_pDevice->SetBitsWithMask(
- bitmap_device1.GetBitmap(), bitmap_device2.GetBitmap(), rect.left,
- rect.top, m_BitmapAlpha, m_BlendType);
- }
-#else
- bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
- bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
- if (m_BitmapAlpha < 255) {
- bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha);
- }
- }
- m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
- bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
-#endif // _SKIA_SUPPORT_
- return FALSE;
-}
-
-FX_BOOL CPDF_ImageRenderer::StartDIBSource() {
- if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) {
- FX_SAFE_SIZE_T image_size = m_pDIBSource->GetBPP();
- image_size /= 8;
- image_size *= m_pDIBSource->GetWidth();
- image_size *= m_pDIBSource->GetHeight();
- if (!image_size.IsValid()) {
- return FALSE;
- }
-
- if (image_size.ValueOrDie() > FPDF_HUGE_IMAGE_SIZE &&
- !(m_Flags & RENDER_FORCE_HALFTONE)) {
- m_Flags |= RENDER_FORCE_DOWNSAMPLE;
- }
- }
-#ifdef _SKIA_SUPPORT_
- CFX_DIBitmap* premultiplied = m_pDIBSource->Clone();
- if (m_pDIBSource->HasAlpha())
- CFX_SkiaDeviceDriver::PreMultiply(premultiplied);
- if (m_pRenderStatus->m_pDevice->StartDIBitsWithBlend(
- premultiplied, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags,
- m_DeviceHandle, m_BlendType)) {
- if (m_DeviceHandle) {
- m_Status = 3;
- return TRUE;
- }
- return FALSE;
- }
-#else
- if (m_pRenderStatus->m_pDevice->StartDIBitsWithBlend(
- m_pDIBSource, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags,
- m_DeviceHandle, m_BlendType)) {
- if (m_DeviceHandle) {
- m_Status = 3;
- return TRUE;
- }
- return FALSE;
- }
-#endif
- CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
- FX_RECT image_rect = image_rect_f.GetOuterRect();
- int dest_width = image_rect.Width();
- int dest_height = image_rect.Height();
- if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
- (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
- if (m_pRenderStatus->m_bPrint &&
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
- m_Result = FALSE;
- return FALSE;
- }
- FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
- clip_box.Intersect(image_rect);
- m_Status = 2;
- m_pTransformer.reset(new CFX_ImageTransformer(m_pDIBSource, &m_ImageMatrix,
- m_Flags, &clip_box));
- m_pTransformer->Start();
- return TRUE;
- }
- if (m_ImageMatrix.a < 0)
- dest_width = -dest_width;
-
- if (m_ImageMatrix.d > 0)
- dest_height = -dest_height;
-
- int dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
- int dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
- if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
- if (m_pRenderStatus->m_pDevice->StretchDIBitsWithFlagsAndBlend(
- m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_Flags,
- m_BlendType)) {
- return FALSE;
- }
- }
- if (m_pDIBSource->IsAlphaMask()) {
- if (m_BitmapAlpha != 255)
- m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
- if (m_pRenderStatus->m_pDevice->StretchBitMaskWithFlags(
- m_pDIBSource, dest_left, dest_top, dest_width, dest_height,
- m_FillArgb, m_Flags)) {
- return FALSE;
- }
- }
- if (m_pRenderStatus->m_bPrint &&
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
- m_Result = FALSE;
- return TRUE;
- }
-
- FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox();
- FX_RECT dest_rect = clip_box;
- dest_rect.Intersect(image_rect);
- FX_RECT dest_clip(
- dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
- dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
- std::unique_ptr<CFX_DIBitmap> pStretched(
- m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip));
- if (pStretched) {
- m_pRenderStatus->CompositeDIBitmap(pStretched.get(), dest_rect.left,
- dest_rect.top, m_FillArgb, m_BitmapAlpha,
- m_BlendType, FALSE);
- }
- return FALSE;
-}
-
-FX_BOOL CPDF_ImageRenderer::StartBitmapAlpha() {
- if (m_pDIBSource->IsOpaqueImage()) {
- CFX_PathData path;
- path.AppendRect(0, 0, 1, 1);
- path.Transform(&m_ImageMatrix);
- uint32_t fill_color =
- ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha);
- m_pRenderStatus->m_pDevice->DrawPath(&path, nullptr, nullptr, fill_color, 0,
- FXFILL_WINDING);
- } else {
- const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask()
- ? m_pDIBSource
- : m_pDIBSource->GetAlphaMask();
- if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f ||
- FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) {
- int left, top;
- std::unique_ptr<CFX_DIBitmap> pTransformed(
- pAlphaMask->TransformTo(&m_ImageMatrix, left, top));
- if (!pTransformed)
- return TRUE;
-
- m_pRenderStatus->m_pDevice->SetBitMask(
- pTransformed.get(), left, top,
- ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
- } else {
- CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
- FX_RECT image_rect = image_rect_f.GetOuterRect();
- int dest_width =
- m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width();
- int dest_height =
- m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height();
- int left = dest_width > 0 ? image_rect.left : image_rect.right;
- int top = dest_height > 0 ? image_rect.top : image_rect.bottom;
- m_pRenderStatus->m_pDevice->StretchBitMask(
- pAlphaMask, left, top, dest_width, dest_height,
- ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha));
- }
- if (m_pDIBSource != pAlphaMask) {
- delete pAlphaMask;
- }
- }
- return FALSE;
-}
-
-FX_BOOL CPDF_ImageRenderer::Continue(IFX_Pause* pPause) {
- if (m_Status == 2) {
- if (m_pTransformer->Continue(pPause))
- return TRUE;
-
- std::unique_ptr<CFX_DIBitmap> pBitmap(m_pTransformer->DetachBitmap());
- if (!pBitmap)
- return FALSE;
-
- if (pBitmap->IsAlphaMask()) {
- if (m_BitmapAlpha != 255)
- m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
- m_Result = m_pRenderStatus->m_pDevice->SetBitMask(
- pBitmap.get(), m_pTransformer->result().left,
- m_pTransformer->result().top, m_FillArgb);
- } else {
- if (m_BitmapAlpha != 255)
- pBitmap->MultiplyAlpha(m_BitmapAlpha);
- m_Result = m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
- pBitmap.get(), m_pTransformer->result().left,
- m_pTransformer->result().top, m_BlendType);
- }
- return FALSE;
- }
- if (m_Status == 3)
- return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
-
- if (m_Status == 4) {
- if (m_Loader.Continue(m_LoadHandle.get(), pPause))
- return TRUE;
-
- if (StartRenderDIBSource())
- return Continue(pPause);
- }
- return FALSE;
-}
-
-CCodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(
- const uint8_t* src_buf,
- uint32_t src_size,
- int width,
- int height,
- int nComps,
- int bpc,
- const CPDF_Dictionary* pParams);
-
-CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict,
- FX_RECT* pClipRect,
- const CFX_Matrix* pMatrix) {
- if (!pSMaskDict)
- return nullptr;
-
- CPDF_Stream* pGroup = pSMaskDict->GetStreamFor("G");
- if (!pGroup)
- return nullptr;
-
- std::unique_ptr<CPDF_Function> pFunc;
- CPDF_Object* pFuncObj = pSMaskDict->GetDirectObjectFor("TR");
- if (pFuncObj && (pFuncObj->IsDictionary() || pFuncObj->IsStream()))
- pFunc = CPDF_Function::Load(pFuncObj);
-
- CFX_Matrix matrix = *pMatrix;
- matrix.TranslateI(-pClipRect->left, -pClipRect->top);
-
- CPDF_Form form(m_pContext->GetDocument(), m_pContext->GetPageResources(),
- pGroup);
- form.ParseContent(nullptr, nullptr, nullptr);
-
- CFX_FxgeDevice bitmap_device;
- FX_BOOL bLuminosity = pSMaskDict->GetStringFor("S") != "Alpha";
- int width = pClipRect->right - pClipRect->left;
- int height = pClipRect->bottom - pClipRect->top;
- FXDIB_Format format;
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || defined _SKIA_SUPPORT_
- format = bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask;
-#else
- format = bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask;
-#endif
- if (!bitmap_device.Create(width, height, format, nullptr))
- return nullptr;
-
- CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap();
- int color_space_family = 0;
- if (bLuminosity) {
- CPDF_Array* pBC = pSMaskDict->GetArrayFor("BC");
- FX_ARGB back_color = 0xff000000;
- if (pBC) {
- CPDF_Object* pCSObj = nullptr;
- CPDF_Dictionary* pDict = pGroup->GetDict();
- if (pDict && pDict->GetDictFor("Group")) {
- pCSObj = pDict->GetDictFor("Group")->GetDirectObjectFor("CS");
- }
- const CPDF_ColorSpace* pCS =
- m_pContext->GetDocument()->LoadColorSpace(pCSObj);
- if (pCS) {
- // Store Color Space Family to use in CPDF_RenderStatus::Initialize.
- color_space_family = pCS->GetFamily();
-
- FX_FLOAT R, G, B;
- uint32_t comps = 8;
- if (pCS->CountComponents() > comps) {
- comps = pCS->CountComponents();
- }
- CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps);
- FX_FLOAT* pFloats = float_array;
- FX_SAFE_UINT32 num_floats = comps;
- num_floats *= sizeof(FX_FLOAT);
- if (!num_floats.IsValid()) {
- return nullptr;
- }
- FXSYS_memset(pFloats, 0, num_floats.ValueOrDie());
- size_t count = pBC->GetCount() > 8 ? 8 : pBC->GetCount();
- for (size_t i = 0; i < count; i++) {
- pFloats[i] = pBC->GetNumberAt(i);
- }
- pCS->GetRGB(pFloats, R, G, B);
- back_color = 0xff000000 | ((int32_t)(R * 255) << 16) |
- ((int32_t)(G * 255) << 8) | (int32_t)(B * 255);
- m_pContext->GetDocument()->GetPageData()->ReleaseColorSpace(pCSObj);
- }
- }
- bitmap.Clear(back_color);
- } else {
- bitmap.Clear(0);
- }
- CPDF_Dictionary* pFormResource = nullptr;
- if (form.m_pFormDict) {
- pFormResource = form.m_pFormDict->GetDictFor("Resources");
- }
- CPDF_RenderOptions options;
- options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA;
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, &bitmap_device, nullptr, nullptr, nullptr,
- nullptr, &options, 0, m_bDropObjects, pFormResource, TRUE,
- nullptr, 0, color_space_family, bLuminosity);
- status.RenderObjectList(&form, &matrix);
- std::unique_ptr<CFX_DIBitmap> pMask(new CFX_DIBitmap);
- if (!pMask->Create(width, height, FXDIB_8bppMask))
- return nullptr;
-
- uint8_t* dest_buf = pMask->GetBuffer();
- int dest_pitch = pMask->GetPitch();
- uint8_t* src_buf = bitmap.GetBuffer();
- int src_pitch = bitmap.GetPitch();
- std::vector<uint8_t> transfers(256);
- if (pFunc) {
- CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs());
- for (int i = 0; i < 256; i++) {
- FX_FLOAT input = (FX_FLOAT)i / 255.0f;
- int nresult;
- pFunc->Call(&input, 1, results, nresult);
- transfers[i] = FXSYS_round(results[0] * 255);
- }
- } else {
- for (int i = 0; i < 256; i++) {
- transfers[i] = i;
- }
- }
- if (bLuminosity) {
- int Bpp = bitmap.GetBPP() / 8;
- for (int row = 0; row < height; row++) {
- uint8_t* dest_pos = dest_buf + row * dest_pitch;
- uint8_t* src_pos = src_buf + row * src_pitch;
- for (int col = 0; col < width; col++) {
- *dest_pos++ = transfers[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)];
- src_pos += Bpp;
- }
- }
- } else if (pFunc) {
- int size = dest_pitch * height;
- for (int i = 0; i < size; i++) {
- dest_buf[i] = transfers[src_buf[i]];
- }
- } else {
- FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height);
- }
- return pMask.release();
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
deleted file mode 100644
index ef4074ff15..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
+++ /dev/null
@@ -1,1559 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-#include <algorithm>
-#include <memory>
-#include <vector>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h"
-#include "core/fpdfapi/page/cpdf_image.h"
-#include "core/fpdfapi/page/cpdf_imageobject.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fxcodec/fx_codec.h"
-#include "core/fxcrt/fx_safe_types.h"
-
-namespace {
-
-unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) {
- ASSERT(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16);
- ASSERT((bitpos & (nbits - 1)) == 0);
- unsigned int byte = pData[bitpos / 8];
- if (nbits == 8)
- return byte;
-
- if (nbits == 16)
- return byte * 256 + pData[bitpos / 8 + 1];
-
- return (byte >> (8 - nbits - (bitpos % 8))) & ((1 << nbits) - 1);
-}
-
-FX_SAFE_UINT32 CalculatePitch8(uint32_t bpc, uint32_t components, int width) {
- FX_SAFE_UINT32 pitch = bpc;
- pitch *= components;
- pitch *= width;
- pitch += 7;
- pitch /= 8;
- return pitch;
-}
-
-FX_SAFE_UINT32 CalculatePitch32(int bpp, int width) {
- FX_SAFE_UINT32 pitch = bpp;
- pitch *= width;
- pitch += 31;
- pitch /= 32; // quantized to number of 32-bit words.
- pitch *= 4; // and then back to bytes, (not just /8 in one step).
- return pitch;
-}
-
-bool IsAllowedBPCValue(int bpc) {
- return bpc == 1 || bpc == 2 || bpc == 4 || bpc == 8 || bpc == 16;
-}
-
-template <typename T>
-T ClampValue(T value, T max_value) {
- value = std::min(value, max_value);
- value = std::max<T>(0, value);
- return value;
-}
-
-// Wrapper class to use with std::unique_ptr for CJPX_Decoder.
-class JpxBitMapContext {
- public:
- explicit JpxBitMapContext(CCodec_JpxModule* jpx_module)
- : jpx_module_(jpx_module), decoder_(nullptr) {}
-
- ~JpxBitMapContext() { jpx_module_->DestroyDecoder(decoder_); }
-
- // Takes ownership of |decoder|.
- void set_decoder(CJPX_Decoder* decoder) { decoder_ = decoder; }
-
- CJPX_Decoder* decoder() { return decoder_; }
-
- private:
- CCodec_JpxModule* const jpx_module_; // Weak pointer.
- CJPX_Decoder* decoder_; // Decoder, owned.
-
- // Disallow evil constructors
- JpxBitMapContext(const JpxBitMapContext&);
- void operator=(const JpxBitMapContext&);
-};
-
-const int kMaxImageDimension = 0x01FFFF;
-
-} // namespace
-
-CPDF_DIBSource::CPDF_DIBSource()
- : m_pDocument(nullptr),
- m_pStream(nullptr),
- m_pDict(nullptr),
- m_pColorSpace(nullptr),
- m_Family(0),
- m_bpc(0),
- m_bpc_orig(0),
- m_nComponents(0),
- m_GroupFamily(0),
- m_MatteColor(0),
- m_bLoadMask(FALSE),
- m_bDefaultDecode(TRUE),
- m_bImageMask(FALSE),
- m_bDoBpcCheck(TRUE),
- m_bColorKey(FALSE),
- m_bHasMask(FALSE),
- m_bStdCS(FALSE),
- m_pCompData(nullptr),
- m_pLineBuf(nullptr),
- m_pMaskedLine(nullptr),
- m_pMask(nullptr),
- m_pMaskStream(nullptr),
- m_Status(0) {}
-
-CPDF_DIBSource::~CPDF_DIBSource() {
- FX_Free(m_pMaskedLine);
- FX_Free(m_pLineBuf);
- m_pCachedBitmap.reset();
- FX_Free(m_pCompData);
- CPDF_ColorSpace* pCS = m_pColorSpace;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
-}
-
-CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const {
- return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone();
-}
-
-void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const {
- if (pBitmap && pBitmap != m_pCachedBitmap.get()) {
- delete pBitmap;
- }
-}
-
-FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc,
- const CPDF_Stream* pStream,
- CPDF_DIBSource** ppMask,
- uint32_t* pMatteColor,
- CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask) {
- if (!pStream) {
- return FALSE;
- }
- m_pDocument = pDoc;
- m_pDict = pStream->GetDict();
- if (!m_pDict) {
- return FALSE;
- }
- m_pStream = pStream;
- m_Width = m_pDict->GetIntegerFor("Width");
- m_Height = m_pDict->GetIntegerFor("Height");
- if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
- m_Height > kMaxImageDimension) {
- return FALSE;
- }
- m_GroupFamily = GroupFamily;
- m_bLoadMask = bLoadMask;
- if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? nullptr : pFormResources,
- pPageResources)) {
- return FALSE;
- }
- if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) {
- return FALSE;
- }
- FX_SAFE_UINT32 src_size =
- CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
- if (!src_size.IsValid()) {
- return FALSE;
- }
- m_pStreamAcc.reset(new CPDF_StreamAcc);
- m_pStreamAcc->LoadAllData(pStream, FALSE, src_size.ValueOrDie(), TRUE);
- if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData()) {
- return FALSE;
- }
- if (!CreateDecoder()) {
- return FALSE;
- }
- if (m_bImageMask) {
- m_bpp = 1;
- m_bpc = 1;
- m_nComponents = 1;
- m_AlphaFlag = 1;
- } else if (m_bpc * m_nComponents == 1) {
- m_bpp = 1;
- } else if (m_bpc * m_nComponents <= 8) {
- m_bpp = 8;
- } else {
- m_bpp = 24;
- }
- FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width);
- if (!pitch.IsValid()) {
- return FALSE;
- }
- m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie());
- if (m_pColorSpace && bStdCS) {
- m_pColorSpace->EnableStdConversion(TRUE);
- }
- LoadPalette();
- if (m_bColorKey) {
- m_bpp = 32;
- m_AlphaFlag = 2;
- pitch = CalculatePitch32(m_bpp, m_Width);
- if (!pitch.IsValid()) {
- return FALSE;
- }
- m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie());
- }
- m_Pitch = pitch.ValueOrDie();
- if (ppMask) {
- *ppMask = LoadMask(*pMatteColor);
- }
- if (m_pColorSpace && bStdCS) {
- m_pColorSpace->EnableStdConversion(FALSE);
- }
- return TRUE;
-}
-
-int CPDF_DIBSource::ContinueToLoadMask() {
- if (m_bImageMask) {
- m_bpp = 1;
- m_bpc = 1;
- m_nComponents = 1;
- m_AlphaFlag = 1;
- } else if (m_bpc * m_nComponents == 1) {
- m_bpp = 1;
- } else if (m_bpc * m_nComponents <= 8) {
- m_bpp = 8;
- } else {
- m_bpp = 24;
- }
- if (!m_bpc || !m_nComponents) {
- return 0;
- }
- FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width);
- if (!pitch.IsValid()) {
- return 0;
- }
- m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie());
- if (m_pColorSpace && m_bStdCS) {
- m_pColorSpace->EnableStdConversion(TRUE);
- }
- LoadPalette();
- if (m_bColorKey) {
- m_bpp = 32;
- m_AlphaFlag = 2;
- pitch = CalculatePitch32(m_bpp, m_Width);
- if (!pitch.IsValid()) {
- return 0;
- }
- m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie());
- }
- m_Pitch = pitch.ValueOrDie();
- return 1;
-}
-
-int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc,
- const CPDF_Stream* pStream,
- FX_BOOL bHasMask,
- CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask) {
- if (!pStream) {
- return 0;
- }
- m_pDocument = pDoc;
- m_pDict = pStream->GetDict();
- m_pStream = pStream;
- m_bStdCS = bStdCS;
- m_bHasMask = bHasMask;
- m_Width = m_pDict->GetIntegerFor("Width");
- m_Height = m_pDict->GetIntegerFor("Height");
- if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension ||
- m_Height > kMaxImageDimension) {
- return 0;
- }
- m_GroupFamily = GroupFamily;
- m_bLoadMask = bLoadMask;
- if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? nullptr : pFormResources,
- pPageResources)) {
- return 0;
- }
- if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) {
- return 0;
- }
- FX_SAFE_UINT32 src_size =
- CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height;
- if (!src_size.IsValid()) {
- return 0;
- }
- m_pStreamAcc.reset(new CPDF_StreamAcc);
- m_pStreamAcc->LoadAllData(pStream, FALSE, src_size.ValueOrDie(), TRUE);
- if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData()) {
- return 0;
- }
- int ret = CreateDecoder();
- if (!ret)
- return ret;
-
- if (ret != 1) {
- if (!ContinueToLoadMask()) {
- return 0;
- }
- if (m_bHasMask) {
- StratLoadMask();
- }
- return ret;
- }
- if (!ContinueToLoadMask()) {
- return 0;
- }
- if (m_bHasMask) {
- ret = StratLoadMask();
- }
- if (ret == 2) {
- return ret;
- }
- if (m_pColorSpace && m_bStdCS) {
- m_pColorSpace->EnableStdConversion(FALSE);
- }
- return ret;
-}
-
-int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) {
- FXCODEC_STATUS ret;
- if (m_Status == 1) {
- const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder();
- if (decoder == "JPXDecode") {
- return 0;
- }
- CCodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module();
- if (!m_pJbig2Context) {
- m_pJbig2Context.reset(new CCodec_Jbig2Context());
- if (m_pStreamAcc->GetImageParam()) {
- CPDF_Stream* pGlobals =
- m_pStreamAcc->GetImageParam()->GetStreamFor("JBIG2Globals");
- if (pGlobals) {
- m_pGlobalStream.reset(new CPDF_StreamAcc);
- m_pGlobalStream->LoadAllData(pGlobals, FALSE);
- }
- }
- ret = pJbig2Module->StartDecode(
- m_pJbig2Context.get(), m_pDocument->CodecContext(), m_Width, m_Height,
- m_pStreamAcc.get(), m_pGlobalStream.get(),
- m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), pPause);
- if (ret < 0) {
- m_pCachedBitmap.reset();
- m_pGlobalStream.reset();
- m_pJbig2Context.reset();
- return 0;
- }
- if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
- return 2;
- }
- int ret1 = 1;
- if (m_bHasMask) {
- ret1 = ContinueLoadMaskDIB(pPause);
- m_Status = 2;
- }
- if (ret1 == 2) {
- return ret1;
- }
- if (m_pColorSpace && m_bStdCS) {
- m_pColorSpace->EnableStdConversion(FALSE);
- }
- return ret1;
- }
- ret = pJbig2Module->ContinueDecode(m_pJbig2Context.get(), pPause);
- if (ret < 0) {
- m_pCachedBitmap.reset();
- m_pGlobalStream.reset();
- m_pJbig2Context.reset();
- return 0;
- }
- if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
- return 2;
- }
- int ret1 = 1;
- if (m_bHasMask) {
- ret1 = ContinueLoadMaskDIB(pPause);
- m_Status = 2;
- }
- if (ret1 == 2) {
- return ret1;
- }
- if (m_pColorSpace && m_bStdCS) {
- m_pColorSpace->EnableStdConversion(FALSE);
- }
- return ret1;
- }
- if (m_Status == 2) {
- return ContinueLoadMaskDIB(pPause);
- }
- return 0;
-}
-
-bool CPDF_DIBSource::LoadColorInfo(const CPDF_Dictionary* pFormResources,
- const CPDF_Dictionary* pPageResources) {
- m_bpc_orig = m_pDict->GetIntegerFor("BitsPerComponent");
- if (m_pDict->GetIntegerFor("ImageMask"))
- m_bImageMask = TRUE;
-
- if (m_bImageMask || !m_pDict->KeyExist("ColorSpace")) {
- if (!m_bImageMask) {
- CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
- if (pFilter) {
- CFX_ByteString filter;
- if (pFilter->IsName()) {
- filter = pFilter->GetString();
- } else if (CPDF_Array* pArray = pFilter->AsArray()) {
- filter = pArray->GetStringAt(pArray->GetCount() - 1);
- }
-
- if (filter == "JPXDecode") {
- m_bDoBpcCheck = FALSE;
- return true;
- }
- }
- }
- m_bImageMask = TRUE;
- m_bpc = m_nComponents = 1;
- CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
- m_bDefaultDecode = !pDecode || !pDecode->GetIntegerAt(0);
- return true;
- }
-
- CPDF_Object* pCSObj = m_pDict->GetDirectObjectFor("ColorSpace");
- if (!pCSObj)
- return false;
-
- CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
- if (pFormResources)
- m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources);
- if (!m_pColorSpace)
- m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources);
- if (!m_pColorSpace)
- return false;
-
- m_Family = m_pColorSpace->GetFamily();
- m_nComponents = m_pColorSpace->CountComponents();
- if (m_Family == PDFCS_ICCBASED && pCSObj->IsName()) {
- CFX_ByteString cs = pCSObj->GetString();
- if (cs == "DeviceGray") {
- m_nComponents = 1;
- } else if (cs == "DeviceRGB") {
- m_nComponents = 3;
- } else if (cs == "DeviceCMYK") {
- m_nComponents = 4;
- }
- }
- ValidateDictParam();
- m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey);
- return !!m_pCompData;
-}
-
-DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode,
- FX_BOOL& bColorKey) {
- if (!m_pColorSpace) {
- return nullptr;
- }
- DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents);
- int max_data = (1 << m_bpc) - 1;
- CPDF_Array* pDecode = m_pDict->GetArrayFor("Decode");
- if (pDecode) {
- for (uint32_t i = 0; i < m_nComponents; i++) {
- pCompData[i].m_DecodeMin = pDecode->GetNumberAt(i * 2);
- FX_FLOAT max = pDecode->GetNumberAt(i * 2 + 1);
- pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data;
- FX_FLOAT def_value;
- FX_FLOAT def_min;
- FX_FLOAT def_max;
- m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max);
- if (m_Family == PDFCS_INDEXED) {
- def_max = max_data;
- }
- if (def_min != pCompData[i].m_DecodeMin || def_max != max) {
- bDefaultDecode = FALSE;
- }
- }
- } else {
- for (uint32_t i = 0; i < m_nComponents; i++) {
- FX_FLOAT def_value;
- m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMin,
- pCompData[i].m_DecodeStep);
- if (m_Family == PDFCS_INDEXED) {
- pCompData[i].m_DecodeStep = max_data;
- }
- pCompData[i].m_DecodeStep =
- (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data;
- }
- }
- if (!m_pDict->KeyExist("SMask")) {
- CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
- if (!pMask) {
- return pCompData;
- }
- if (CPDF_Array* pArray = pMask->AsArray()) {
- if (pArray->GetCount() >= m_nComponents * 2) {
- for (uint32_t i = 0; i < m_nComponents; i++) {
- int min_num = pArray->GetIntegerAt(i * 2);
- int max_num = pArray->GetIntegerAt(i * 2 + 1);
- pCompData[i].m_ColorKeyMin = std::max(min_num, 0);
- pCompData[i].m_ColorKeyMax = std::min(max_num, max_data);
- }
- }
- bColorKey = TRUE;
- }
- }
- return pCompData;
-}
-
-CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(
- const uint8_t* src_buf,
- uint32_t src_size,
- int width,
- int height,
- const CPDF_Dictionary* pParams);
-
-CCodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(
- const uint8_t* src_buf,
- uint32_t src_size,
- int width,
- int height,
- int nComps,
- int bpc,
- const CPDF_Dictionary* pParams);
-
-int CPDF_DIBSource::CreateDecoder() {
- const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder();
- if (decoder.IsEmpty()) {
- return 1;
- }
- if (m_bDoBpcCheck && m_bpc == 0) {
- return 0;
- }
- const uint8_t* src_data = m_pStreamAcc->GetData();
- uint32_t src_size = m_pStreamAcc->GetSize();
- const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam();
- if (decoder == "CCITTFaxDecode") {
- m_pDecoder.reset(FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width,
- m_Height, pParams));
- } else if (decoder == "DCTDecode") {
- m_pDecoder.reset(CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
- src_data, src_size, m_Width, m_Height, m_nComponents,
- pParams ? pParams->GetIntegerFor("ColorTransform", 1) : 1));
- if (!m_pDecoder) {
- bool bTransform = false;
- int comps;
- int bpc;
- CCodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule();
- if (pJpegModule->LoadInfo(src_data, src_size, &m_Width, &m_Height, &comps,
- &bpc, &bTransform)) {
- if (m_nComponents != static_cast<uint32_t>(comps)) {
- FX_Free(m_pCompData);
- m_pCompData = nullptr;
- m_nComponents = static_cast<uint32_t>(comps);
- if (m_pColorSpace &&
- m_pColorSpace->CountComponents() != m_nComponents) {
- return 0;
- }
- if (m_Family == PDFCS_LAB && m_nComponents != 3)
- return 0;
- m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey);
- if (!m_pCompData)
- return 0;
- }
- m_bpc = bpc;
- m_pDecoder.reset(CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
- src_data, src_size, m_Width, m_Height, m_nComponents, bTransform));
- }
- }
- } else if (decoder == "FlateDecode") {
- m_pDecoder.reset(FPDFAPI_CreateFlateDecoder(
- src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams));
- } else if (decoder == "JPXDecode") {
- LoadJpxBitmap();
- return m_pCachedBitmap ? 1 : 0;
- } else if (decoder == "JBIG2Decode") {
- m_pCachedBitmap.reset(new CFX_DIBitmap);
- if (!m_pCachedBitmap->Create(
- m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) {
- m_pCachedBitmap.reset();
- return 0;
- }
- m_Status = 1;
- return 2;
- } else if (decoder == "RunLengthDecode") {
- m_pDecoder.reset(CPDF_ModuleMgr::Get()
- ->GetCodecModule()
- ->GetBasicModule()
- ->CreateRunLengthDecoder(src_data, src_size, m_Width,
- m_Height, m_nComponents,
- m_bpc));
- }
- if (!m_pDecoder)
- return 0;
-
- FX_SAFE_UINT32 requested_pitch =
- CalculatePitch8(m_bpc, m_nComponents, m_Width);
- if (!requested_pitch.IsValid())
- return 0;
- FX_SAFE_UINT32 provided_pitch = CalculatePitch8(
- m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
- if (!provided_pitch.IsValid())
- return 0;
- if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie())
- return 0;
- return 1;
-}
-
-void CPDF_DIBSource::LoadJpxBitmap() {
- CCodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule();
- if (!pJpxModule)
- return;
-
- std::unique_ptr<JpxBitMapContext> context(new JpxBitMapContext(pJpxModule));
- context->set_decoder(pJpxModule->CreateDecoder(
- m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), m_pColorSpace));
- if (!context->decoder())
- return;
-
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t components = 0;
- pJpxModule->GetImageInfo(context->decoder(), &width, &height, &components);
- if (static_cast<int>(width) < m_Width || static_cast<int>(height) < m_Height)
- return;
-
- FX_BOOL bSwapRGB = FALSE;
- if (m_pColorSpace) {
- if (components != m_pColorSpace->CountComponents())
- return;
-
- if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) {
- bSwapRGB = TRUE;
- m_pColorSpace = nullptr;
- }
- } else {
- if (components == 3) {
- bSwapRGB = TRUE;
- } else if (components == 4) {
- m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- }
- m_nComponents = components;
- }
-
- FXDIB_Format format;
- if (components == 1) {
- format = FXDIB_8bppRgb;
- } else if (components <= 3) {
- format = FXDIB_Rgb;
- } else if (components == 4) {
- format = FXDIB_Rgb32;
- } else {
- width = (width * components + 2) / 3;
- format = FXDIB_Rgb;
- }
-
- m_pCachedBitmap.reset(new CFX_DIBitmap);
- if (!m_pCachedBitmap->Create(width, height, format)) {
- m_pCachedBitmap.reset();
- return;
- }
- m_pCachedBitmap->Clear(0xFFFFFFFF);
- std::vector<uint8_t> output_offsets(components);
- for (uint32_t i = 0; i < components; ++i)
- output_offsets[i] = i;
- if (bSwapRGB) {
- output_offsets[0] = 2;
- output_offsets[2] = 0;
- }
- if (!pJpxModule->Decode(context->decoder(), m_pCachedBitmap->GetBuffer(),
- m_pCachedBitmap->GetPitch(), output_offsets)) {
- m_pCachedBitmap.reset();
- return;
- }
- if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED &&
- m_bpc < 8) {
- int scale = 8 - m_bpc;
- for (uint32_t row = 0; row < height; ++row) {
- uint8_t* scanline =
- const_cast<uint8_t*>(m_pCachedBitmap->GetScanline(row));
- for (uint32_t col = 0; col < width; ++col) {
- *scanline = (*scanline) >> scale;
- ++scanline;
- }
- }
- }
- m_bpc = 8;
-}
-
-CPDF_DIBSource* CPDF_DIBSource::LoadMask(uint32_t& MatteColor) {
- MatteColor = 0xFFFFFFFF;
- CPDF_Stream* pSoftMask = m_pDict->GetStreamFor("SMask");
- if (pSoftMask) {
- CPDF_Array* pMatte = pSoftMask->GetDict()->GetArrayFor("Matte");
- if (pMatte && m_pColorSpace &&
- m_pColorSpace->CountComponents() <= m_nComponents) {
- std::vector<FX_FLOAT> colors(m_nComponents);
- for (uint32_t i = 0; i < m_nComponents; i++) {
- colors[i] = pMatte->GetFloatAt(i);
- }
- FX_FLOAT R, G, B;
- m_pColorSpace->GetRGB(colors.data(), R, G, B);
- MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255),
- FXSYS_round(B * 255));
- }
- return LoadMaskDIB(pSoftMask);
- }
-
- if (CPDF_Stream* pStream = ToStream(m_pDict->GetDirectObjectFor("Mask")))
- return LoadMaskDIB(pStream);
-
- return nullptr;
-}
-
-int CPDF_DIBSource::StratLoadMask() {
- m_MatteColor = 0XFFFFFFFF;
- m_pMaskStream = m_pDict->GetStreamFor("SMask");
- if (m_pMaskStream) {
- CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArrayFor("Matte");
- if (pMatte && m_pColorSpace &&
- m_pColorSpace->CountComponents() <= m_nComponents) {
- FX_FLOAT R, G, B;
- std::vector<FX_FLOAT> colors(m_nComponents);
- for (uint32_t i = 0; i < m_nComponents; i++) {
- colors[i] = pMatte->GetFloatAt(i);
- }
- m_pColorSpace->GetRGB(colors.data(), R, G, B);
- m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255),
- FXSYS_round(B * 255));
- }
- return StartLoadMaskDIB();
- }
-
- m_pMaskStream = ToStream(m_pDict->GetDirectObjectFor("Mask"));
- return m_pMaskStream ? StartLoadMaskDIB() : 1;
-}
-
-int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) {
- if (!m_pMask) {
- return 1;
- }
- int ret = m_pMask->ContinueLoadDIBSource(pPause);
- if (ret == 2) {
- return ret;
- }
- if (m_pColorSpace && m_bStdCS) {
- m_pColorSpace->EnableStdConversion(FALSE);
- }
- if (!ret) {
- delete m_pMask;
- m_pMask = nullptr;
- return ret;
- }
- return 1;
-}
-
-CPDF_DIBSource* CPDF_DIBSource::DetachMask() {
- CPDF_DIBSource* pDIBSource = m_pMask;
- m_pMask = nullptr;
- return pDIBSource;
-}
-
-CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) {
- CPDF_DIBSource* pMaskSource = new CPDF_DIBSource;
- if (!pMaskSource->Load(m_pDocument, pMask, nullptr, nullptr, nullptr, nullptr,
- TRUE)) {
- delete pMaskSource;
- return nullptr;
- }
- return pMaskSource;
-}
-
-int CPDF_DIBSource::StartLoadMaskDIB() {
- m_pMask = new CPDF_DIBSource;
- int ret = m_pMask->StartLoadDIBSource(m_pDocument, m_pMaskStream, FALSE,
- nullptr, nullptr, TRUE);
- if (ret == 2) {
- if (m_Status == 0)
- m_Status = 2;
- return 2;
- }
- if (!ret) {
- delete m_pMask;
- m_pMask = nullptr;
- return 1;
- }
- return 1;
-}
-
-void CPDF_DIBSource::LoadPalette() {
- if (m_bpc == 0) {
- return;
- }
- if (m_bpc * m_nComponents > 8) {
- return;
- }
- if (!m_pColorSpace) {
- return;
- }
- if (m_bpc * m_nComponents == 1) {
- if (m_bDefaultDecode &&
- (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) {
- return;
- }
- if (m_pColorSpace->CountComponents() > 3) {
- return;
- }
- FX_FLOAT color_values[3];
- color_values[0] = m_pCompData[0].m_DecodeMin;
- color_values[1] = color_values[2] = color_values[0];
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- m_pColorSpace->GetRGB(color_values, R, G, B);
- FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255),
- FXSYS_round(B * 255));
- color_values[0] += m_pCompData[0].m_DecodeStep;
- color_values[1] += m_pCompData[0].m_DecodeStep;
- color_values[2] += m_pCompData[0].m_DecodeStep;
- m_pColorSpace->GetRGB(color_values, R, G, B);
- FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255),
- FXSYS_round(B * 255));
- if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) {
- SetPaletteArgb(0, argb0);
- SetPaletteArgb(1, argb1);
- }
- return;
- }
- if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) &&
- m_bpc == 8 && m_bDefaultDecode) {
- } else {
- int palette_count = 1 << (m_bpc * m_nComponents);
- CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents);
- FX_FLOAT* color_value = color_values;
- for (int i = 0; i < palette_count; i++) {
- int color_data = i;
- for (uint32_t j = 0; j < m_nComponents; j++) {
- int encoded_component = color_data % (1 << m_bpc);
- color_data /= 1 << m_bpc;
- color_value[j] = m_pCompData[j].m_DecodeMin +
- m_pCompData[j].m_DecodeStep * encoded_component;
- }
- FX_FLOAT R = 0, G = 0, B = 0;
- if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED &&
- m_pColorSpace->CountComponents() > 1) {
- int nComponents = m_pColorSpace->CountComponents();
- std::vector<FX_FLOAT> temp_buf(nComponents);
- for (int k = 0; k < nComponents; k++) {
- temp_buf[k] = *color_value;
- }
- m_pColorSpace->GetRGB(temp_buf.data(), R, G, B);
- } else {
- m_pColorSpace->GetRGB(color_value, R, G, B);
- }
- SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255),
- FXSYS_round(G * 255), FXSYS_round(B * 255)));
- }
- }
-}
-
-void CPDF_DIBSource::ValidateDictParam() {
- m_bpc = m_bpc_orig;
- CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
- if (pFilter) {
- if (pFilter->IsName()) {
- CFX_ByteString filter = pFilter->GetString();
- if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
- m_bpc = 1;
- m_nComponents = 1;
- } else if (filter == "RunLengthDecode") {
- if (m_bpc != 1) {
- m_bpc = 8;
- }
- } else if (filter == "DCTDecode") {
- m_bpc = 8;
- }
- } else if (CPDF_Array* pArray = pFilter->AsArray()) {
- CFX_ByteString filter = pArray->GetStringAt(pArray->GetCount() - 1);
- if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
- m_bpc = 1;
- m_nComponents = 1;
- } else if (filter == "DCTDecode") {
- // Previously, filter == "RunLengthDecode" was checked in the "if"
- // statement as well, but too many documents don't conform to it.
- m_bpc = 8;
- }
- }
- }
-
- if (!IsAllowedBPCValue(m_bpc))
- m_bpc = 0;
-}
-
-void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan,
- const uint8_t* src_scan) const {
- if (m_bpc == 0) {
- return;
- }
- unsigned int max_data = (1 << m_bpc) - 1;
- if (m_bDefaultDecode) {
- if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) {
- if (m_nComponents != 3)
- return;
-
- const uint8_t* src_pos = src_scan;
- switch (m_bpc) {
- case 16:
- for (int col = 0; col < m_Width; col++) {
- *dest_scan++ = src_pos[4];
- *dest_scan++ = src_pos[2];
- *dest_scan++ = *src_pos;
- src_pos += 6;
- }
- break;
- case 8:
- for (int column = 0; column < m_Width; column++) {
- *dest_scan++ = src_pos[2];
- *dest_scan++ = src_pos[1];
- *dest_scan++ = *src_pos;
- src_pos += 3;
- }
- break;
- default:
- uint64_t src_bit_pos = 0;
- size_t dest_byte_pos = 0;
- for (int column = 0; column < m_Width; column++) {
- unsigned int R = GetBits8(src_scan, src_bit_pos, m_bpc);
- src_bit_pos += m_bpc;
- unsigned int G = GetBits8(src_scan, src_bit_pos, m_bpc);
- src_bit_pos += m_bpc;
- unsigned int B = GetBits8(src_scan, src_bit_pos, m_bpc);
- src_bit_pos += m_bpc;
- R = std::min(R, max_data);
- G = std::min(G, max_data);
- B = std::min(B, max_data);
- dest_scan[dest_byte_pos] = B * 255 / max_data;
- dest_scan[dest_byte_pos + 1] = G * 255 / max_data;
- dest_scan[dest_byte_pos + 2] = R * 255 / max_data;
- dest_byte_pos += 3;
- }
- break;
- }
- return;
- }
- if (m_bpc == 8) {
- if (m_nComponents == m_pColorSpace->CountComponents())
- m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width, m_Width,
- m_Height, TransMask());
- return;
- }
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents);
- FX_FLOAT* color_values = color_values1;
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- if (m_bpc == 8) {
- uint64_t src_byte_pos = 0;
- size_t dest_byte_pos = 0;
- for (int column = 0; column < m_Width; column++) {
- for (uint32_t color = 0; color < m_nComponents; color++) {
- uint8_t data = src_scan[src_byte_pos++];
- color_values[color] = m_pCompData[color].m_DecodeMin +
- m_pCompData[color].m_DecodeStep * data;
- }
- if (TransMask()) {
- FX_FLOAT k = 1.0f - color_values[3];
- R = (1.0f - color_values[0]) * k;
- G = (1.0f - color_values[1]) * k;
- B = (1.0f - color_values[2]) * k;
- } else {
- m_pColorSpace->GetRGB(color_values, R, G, B);
- }
- R = ClampValue(R, 1.0f);
- G = ClampValue(G, 1.0f);
- B = ClampValue(B, 1.0f);
- dest_scan[dest_byte_pos] = static_cast<uint8_t>(B * 255);
- dest_scan[dest_byte_pos + 1] = static_cast<uint8_t>(G * 255);
- dest_scan[dest_byte_pos + 2] = static_cast<uint8_t>(R * 255);
- dest_byte_pos += 3;
- }
- } else {
- uint64_t src_bit_pos = 0;
- size_t dest_byte_pos = 0;
- for (int column = 0; column < m_Width; column++) {
- for (uint32_t color = 0; color < m_nComponents; color++) {
- unsigned int data = GetBits8(src_scan, src_bit_pos, m_bpc);
- color_values[color] = m_pCompData[color].m_DecodeMin +
- m_pCompData[color].m_DecodeStep * data;
- src_bit_pos += m_bpc;
- }
- if (TransMask()) {
- FX_FLOAT k = 1.0f - color_values[3];
- R = (1.0f - color_values[0]) * k;
- G = (1.0f - color_values[1]) * k;
- B = (1.0f - color_values[2]) * k;
- } else {
- m_pColorSpace->GetRGB(color_values, R, G, B);
- }
- R = ClampValue(R, 1.0f);
- G = ClampValue(G, 1.0f);
- B = ClampValue(B, 1.0f);
- dest_scan[dest_byte_pos] = static_cast<uint8_t>(B * 255);
- dest_scan[dest_byte_pos + 1] = static_cast<uint8_t>(G * 255);
- dest_scan[dest_byte_pos + 2] = static_cast<uint8_t>(R * 255);
- dest_byte_pos += 3;
- }
- }
-}
-
-uint8_t* CPDF_DIBSource::GetBuffer() const {
- return m_pCachedBitmap ? m_pCachedBitmap->GetBuffer() : nullptr;
-}
-
-const uint8_t* CPDF_DIBSource::GetScanline(int line) const {
- if (m_bpc == 0) {
- return nullptr;
- }
- FX_SAFE_UINT32 src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width);
- if (!src_pitch.IsValid())
- return nullptr;
- uint32_t src_pitch_value = src_pitch.ValueOrDie();
- const uint8_t* pSrcLine = nullptr;
- if (m_pCachedBitmap && src_pitch_value <= m_pCachedBitmap->GetPitch()) {
- if (line >= m_pCachedBitmap->GetHeight()) {
- line = m_pCachedBitmap->GetHeight() - 1;
- }
- pSrcLine = m_pCachedBitmap->GetScanline(line);
- } else if (m_pDecoder) {
- pSrcLine = m_pDecoder->GetScanline(line);
- } else {
- if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) {
- pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value;
- }
- }
- if (!pSrcLine) {
- uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf;
- FXSYS_memset(pLineBuf, 0xFF, m_Pitch);
- return pLineBuf;
- }
- if (m_bpc * m_nComponents == 1) {
- if (m_bImageMask && m_bDefaultDecode) {
- for (uint32_t i = 0; i < src_pitch_value; i++) {
- m_pLineBuf[i] = ~pSrcLine[i];
- }
- } else if (m_bColorKey) {
- uint32_t reset_argb, set_argb;
- reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
- set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
- if (m_pCompData[0].m_ColorKeyMin == 0) {
- reset_argb = 0;
- }
- if (m_pCompData[0].m_ColorKeyMax == 1) {
- set_argb = 0;
- }
- set_argb = FXARGB_TODIB(set_argb);
- reset_argb = FXARGB_TODIB(reset_argb);
- uint32_t* dest_scan = reinterpret_cast<uint32_t*>(m_pMaskedLine);
- for (int col = 0; col < m_Width; col++) {
- if (pSrcLine[col / 8] & (1 << (7 - col % 8))) {
- *dest_scan = set_argb;
- } else {
- *dest_scan = reset_argb;
- }
- dest_scan++;
- }
- return m_pMaskedLine;
- } else {
- FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value);
- }
- return m_pLineBuf;
- }
- if (m_bpc * m_nComponents <= 8) {
- if (m_bpc == 8) {
- FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value);
- } else {
- uint64_t src_bit_pos = 0;
- for (int col = 0; col < m_Width; col++) {
- unsigned int color_index = 0;
- for (uint32_t color = 0; color < m_nComponents; color++) {
- unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
- color_index |= data << (color * m_bpc);
- src_bit_pos += m_bpc;
- }
- m_pLineBuf[col] = color_index;
- }
- }
- if (m_bColorKey) {
- uint8_t* pDestPixel = m_pMaskedLine;
- const uint8_t* pSrcPixel = m_pLineBuf;
- for (int col = 0; col < m_Width; col++) {
- uint8_t index = *pSrcPixel++;
- if (m_pPalette) {
- *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
- *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
- *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
- } else {
- *pDestPixel++ = index;
- *pDestPixel++ = index;
- *pDestPixel++ = index;
- }
- *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin ||
- index > m_pCompData[0].m_ColorKeyMax)
- ? 0xFF
- : 0;
- pDestPixel++;
- }
- return m_pMaskedLine;
- }
- return m_pLineBuf;
- }
- if (m_bColorKey) {
- if (m_nComponents == 3 && m_bpc == 8) {
- uint8_t* alpha_channel = m_pMaskedLine + 3;
- for (int col = 0; col < m_Width; col++) {
- const uint8_t* pPixel = pSrcLine + col * 3;
- alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin ||
- pPixel[0] > m_pCompData[0].m_ColorKeyMax ||
- pPixel[1] < m_pCompData[1].m_ColorKeyMin ||
- pPixel[1] > m_pCompData[1].m_ColorKeyMax ||
- pPixel[2] < m_pCompData[2].m_ColorKeyMin ||
- pPixel[2] > m_pCompData[2].m_ColorKeyMax)
- ? 0xFF
- : 0;
- }
- } else {
- FXSYS_memset(m_pMaskedLine, 0xFF, m_Pitch);
- }
- }
- if (m_pColorSpace) {
- TranslateScanline24bpp(m_pLineBuf, pSrcLine);
- pSrcLine = m_pLineBuf;
- }
- if (m_bColorKey) {
- const uint8_t* pSrcPixel = pSrcLine;
- uint8_t* pDestPixel = m_pMaskedLine;
- for (int col = 0; col < m_Width; col++) {
- *pDestPixel++ = *pSrcPixel++;
- *pDestPixel++ = *pSrcPixel++;
- *pDestPixel++ = *pSrcPixel++;
- pDestPixel++;
- }
- return m_pMaskedLine;
- }
- return pSrcLine;
-}
-
-FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const {
- return m_pDecoder && m_pDecoder->SkipToScanline(line, pPause);
-}
-
-void CPDF_DIBSource::DownSampleScanline(int line,
- uint8_t* dest_scan,
- int dest_bpp,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const {
- if (line < 0 || !dest_scan || dest_bpp <= 0 || dest_width <= 0 ||
- clip_left < 0 || clip_width <= 0) {
- return;
- }
-
- uint32_t src_width = m_Width;
- FX_SAFE_UINT32 pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width);
- if (!pitch.IsValid())
- return;
-
- const uint8_t* pSrcLine = nullptr;
- if (m_pCachedBitmap) {
- pSrcLine = m_pCachedBitmap->GetScanline(line);
- } else if (m_pDecoder) {
- pSrcLine = m_pDecoder->GetScanline(line);
- } else {
- uint32_t src_pitch = pitch.ValueOrDie();
- pitch *= (line + 1);
- if (!pitch.IsValid()) {
- return;
- }
-
- if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) {
- pSrcLine = m_pStreamAcc->GetData() + line * src_pitch;
- }
- }
- int orig_Bpp = m_bpc * m_nComponents / 8;
- int dest_Bpp = dest_bpp / 8;
- if (!pSrcLine) {
- FXSYS_memset(dest_scan, 0xFF, dest_Bpp * clip_width);
- return;
- }
-
- FX_SAFE_INT32 max_src_x = clip_left;
- max_src_x += clip_width - 1;
- max_src_x *= src_width;
- max_src_x /= dest_width;
- if (!max_src_x.IsValid())
- return;
-
- if (m_bpc * m_nComponents == 1) {
- DownSampleScanline1Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
- dest_width, bFlipX, clip_left, clip_width);
- } else if (m_bpc * m_nComponents <= 8) {
- DownSampleScanline8Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
- dest_width, bFlipX, clip_left, clip_width);
- } else {
- DownSampleScanline32Bit(orig_Bpp, dest_Bpp, src_width, pSrcLine, dest_scan,
- dest_width, bFlipX, clip_left, clip_width);
- }
-}
-
-void CPDF_DIBSource::DownSampleScanline1Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const {
- uint32_t set_argb = (uint32_t)-1;
- uint32_t reset_argb = 0;
- if (m_bImageMask) {
- if (m_bDefaultDecode) {
- set_argb = 0;
- reset_argb = (uint32_t)-1;
- }
- } else if (m_bColorKey) {
- reset_argb = m_pPalette ? m_pPalette.get()[0] : 0xFF000000;
- set_argb = m_pPalette ? m_pPalette.get()[1] : 0xFFFFFFFF;
- if (m_pCompData[0].m_ColorKeyMin == 0) {
- reset_argb = 0;
- }
- if (m_pCompData[0].m_ColorKeyMax == 1) {
- set_argb = 0;
- }
- set_argb = FXARGB_TODIB(set_argb);
- reset_argb = FXARGB_TODIB(reset_argb);
- uint32_t* dest_scan_dword = reinterpret_cast<uint32_t*>(dest_scan);
- for (int i = 0; i < clip_width; i++) {
- uint32_t src_x = (clip_left + i) * src_width / dest_width;
- if (bFlipX) {
- src_x = src_width - src_x - 1;
- }
- src_x %= src_width;
- if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) {
- dest_scan_dword[i] = set_argb;
- } else {
- dest_scan_dword[i] = reset_argb;
- }
- }
- return;
- } else {
- if (dest_Bpp == 1) {
- } else if (m_pPalette) {
- reset_argb = m_pPalette.get()[0];
- set_argb = m_pPalette.get()[1];
- }
- }
- for (int i = 0; i < clip_width; i++) {
- uint32_t src_x = (clip_left + i) * src_width / dest_width;
- if (bFlipX) {
- src_x = src_width - src_x - 1;
- }
- src_x %= src_width;
- int dest_pos = i * dest_Bpp;
- if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) {
- if (dest_Bpp == 1) {
- dest_scan[dest_pos] = static_cast<uint8_t>(set_argb);
- } else if (dest_Bpp == 3) {
- dest_scan[dest_pos] = FXARGB_B(set_argb);
- dest_scan[dest_pos + 1] = FXARGB_G(set_argb);
- dest_scan[dest_pos + 2] = FXARGB_R(set_argb);
- } else {
- *reinterpret_cast<uint32_t*>(dest_scan + dest_pos) = set_argb;
- }
- } else {
- if (dest_Bpp == 1) {
- dest_scan[dest_pos] = static_cast<uint8_t>(reset_argb);
- } else if (dest_Bpp == 3) {
- dest_scan[dest_pos] = FXARGB_B(reset_argb);
- dest_scan[dest_pos + 1] = FXARGB_G(reset_argb);
- dest_scan[dest_pos + 2] = FXARGB_R(reset_argb);
- } else {
- *reinterpret_cast<uint32_t*>(dest_scan + dest_pos) = reset_argb;
- }
- }
- }
-}
-
-void CPDF_DIBSource::DownSampleScanline8Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const {
- if (m_bpc < 8) {
- uint64_t src_bit_pos = 0;
- for (uint32_t col = 0; col < src_width; col++) {
- unsigned int color_index = 0;
- for (uint32_t color = 0; color < m_nComponents; color++) {
- unsigned int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
- color_index |= data << (color * m_bpc);
- src_bit_pos += m_bpc;
- }
- m_pLineBuf[col] = color_index;
- }
- pSrcLine = m_pLineBuf;
- }
- if (m_bColorKey) {
- for (int i = 0; i < clip_width; i++) {
- uint32_t src_x = (clip_left + i) * src_width / dest_width;
- if (bFlipX) {
- src_x = src_width - src_x - 1;
- }
- src_x %= src_width;
- uint8_t* pDestPixel = dest_scan + i * 4;
- uint8_t index = pSrcLine[src_x];
- if (m_pPalette) {
- *pDestPixel++ = FXARGB_B(m_pPalette.get()[index]);
- *pDestPixel++ = FXARGB_G(m_pPalette.get()[index]);
- *pDestPixel++ = FXARGB_R(m_pPalette.get()[index]);
- } else {
- *pDestPixel++ = index;
- *pDestPixel++ = index;
- *pDestPixel++ = index;
- }
- *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin ||
- index > m_pCompData[0].m_ColorKeyMax)
- ? 0xFF
- : 0;
- }
- return;
- }
- for (int i = 0; i < clip_width; i++) {
- uint32_t src_x = (clip_left + i) * src_width / dest_width;
- if (bFlipX) {
- src_x = src_width - src_x - 1;
- }
- src_x %= src_width;
- uint8_t index = pSrcLine[src_x];
- if (dest_Bpp == 1) {
- dest_scan[i] = index;
- } else {
- int dest_pos = i * dest_Bpp;
- FX_ARGB argb = m_pPalette.get()[index];
- dest_scan[dest_pos] = FXARGB_B(argb);
- dest_scan[dest_pos + 1] = FXARGB_G(argb);
- dest_scan[dest_pos + 2] = FXARGB_R(argb);
- }
- }
-}
-
-void CPDF_DIBSource::DownSampleScanline32Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const {
- // last_src_x used to store the last seen src_x position which should be
- // in [0, src_width). Set the initial value to be an invalid src_x value.
- uint32_t last_src_x = src_width;
- FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF);
- FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1);
- for (int i = 0; i < clip_width; i++) {
- int dest_x = clip_left + i;
- uint32_t src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) *
- (int64_t)src_width / dest_width;
- src_x %= src_width;
-
- uint8_t* pDestPixel = dest_scan + i * dest_Bpp;
- FX_ARGB argb;
- if (src_x == last_src_x) {
- argb = last_argb;
- } else {
- CFX_FixedBufGrow<uint8_t, 128> extracted_components(m_nComponents);
- const uint8_t* pSrcPixel = nullptr;
- if (m_bpc % 8 != 0) {
- // No need to check for 32-bit overflow, as |src_x| is bounded by
- // |src_width| and DownSampleScanline() already checked for overflow
- // with the pitch calculation.
- size_t num_bits = src_x * m_bpc * m_nComponents;
- uint64_t src_bit_pos = num_bits % 8;
- pSrcPixel = pSrcLine + num_bits / 8;
- for (uint32_t j = 0; j < m_nComponents; ++j) {
- extracted_components[j] = static_cast<uint8_t>(
- GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc);
- src_bit_pos += m_bpc;
- }
- pSrcPixel = extracted_components;
- } else {
- pSrcPixel = pSrcLine + src_x * orig_Bpp;
- if (m_bpc == 16) {
- for (uint32_t j = 0; j < m_nComponents; ++j)
- extracted_components[j] = pSrcPixel[j * 2];
- pSrcPixel = extracted_components;
- }
- }
-
- if (m_pColorSpace) {
- uint8_t color[4];
- const FX_BOOL bTransMask = TransMask();
- if (m_bDefaultDecode) {
- m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0,
- bTransMask);
- } else {
- for (uint32_t j = 0; j < m_nComponents; ++j) {
- FX_FLOAT component_value =
- static_cast<FX_FLOAT>(extracted_components[j]);
- int color_value = static_cast<int>(
- (m_pCompData[j].m_DecodeMin +
- m_pCompData[j].m_DecodeStep * component_value) *
- 255.0f +
- 0.5f);
- extracted_components[j] =
- color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value);
- }
- m_pColorSpace->TranslateImageLine(color, extracted_components, 1, 0,
- 0, bTransMask);
- }
- argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]);
- } else {
- argb = FXARGB_MAKE(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]);
- }
- if (m_bColorKey) {
- int alpha = 0xFF;
- if (m_nComponents == 3 && m_bpc == 8) {
- alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin ||
- pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax ||
- pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin ||
- pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax ||
- pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin ||
- pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax)
- ? 0xFF
- : 0;
- }
- argb &= 0xFFFFFF;
- argb |= alpha << 24;
- }
- last_src_x = src_x;
- last_argb = argb;
- }
- if (dest_Bpp == 4) {
- *reinterpret_cast<uint32_t*>(pDestPixel) = FXARGB_TODIB(argb);
- } else {
- *pDestPixel++ = FXARGB_B(argb);
- *pDestPixel++ = FXARGB_G(argb);
- *pDestPixel = FXARGB_R(argb);
- }
- }
-}
-
-FX_BOOL CPDF_DIBSource::TransMask() const {
- return m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK &&
- m_Family == PDFCS_DEVICECMYK;
-}
-
-CPDF_ImageLoaderHandle::CPDF_ImageLoaderHandle() {
- m_pImageLoader = nullptr;
- m_pCache = nullptr;
- m_pImage = nullptr;
-}
-
-CPDF_ImageLoaderHandle::~CPDF_ImageLoaderHandle() {}
-
-FX_BOOL CPDF_ImageLoaderHandle::Start(CPDF_ImageLoader* pImageLoader,
- const CPDF_ImageObject* pImage,
- CPDF_PageRenderCache* pCache,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t nDownsampleWidth,
- int32_t nDownsampleHeight) {
- m_pImageLoader = pImageLoader;
- m_pCache = pCache;
- m_pImage = const_cast<CPDF_ImageObject*>(pImage);
- m_nDownsampleWidth = nDownsampleWidth;
- m_nDownsampleHeight = nDownsampleHeight;
- FX_BOOL ret;
- if (pCache) {
- ret = pCache->StartGetCachedBitmap(
- m_pImage->GetImage()->GetStream(), bStdCS, GroupFamily, bLoadMask,
- pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight);
- } else {
- ret = m_pImage->GetImage()->StartLoadDIBSource(
- pRenderStatus->m_pFormResource, pRenderStatus->m_pPageResource, bStdCS,
- GroupFamily, bLoadMask);
- }
- if (!ret)
- HandleFailure();
- return ret;
-}
-
-FX_BOOL CPDF_ImageLoaderHandle::Continue(IFX_Pause* pPause) {
- FX_BOOL ret = m_pCache ? m_pCache->Continue(pPause)
- : m_pImage->GetImage()->Continue(pPause);
- if (!ret)
- HandleFailure();
- return ret;
-}
-
-void CPDF_ImageLoaderHandle::HandleFailure() {
- if (m_pCache) {
- CPDF_ImageCacheEntry* entry = m_pCache->GetCurImageCacheEntry();
- m_pImageLoader->m_bCached = TRUE;
- m_pImageLoader->m_pBitmap = entry->DetachBitmap();
- m_pImageLoader->m_pMask = entry->DetachMask();
- m_pImageLoader->m_MatteColor = entry->m_MatteColor;
- } else {
- CPDF_Image* pImage = m_pImage->GetImage();
- m_pImageLoader->m_bCached = FALSE;
- m_pImageLoader->m_pBitmap = pImage->DetachBitmap();
- m_pImageLoader->m_pMask = pImage->DetachMask();
- m_pImageLoader->m_MatteColor = pImage->m_MatteColor;
- }
-}
-
-FX_BOOL CPDF_ImageLoader::Start(
- const CPDF_ImageObject* pImage,
- CPDF_PageRenderCache* pCache,
- std::unique_ptr<CPDF_ImageLoaderHandle>* pLoadHandle,
- FX_BOOL bStdCS,
- uint32_t GroupFamily,
- FX_BOOL bLoadMask,
- CPDF_RenderStatus* pRenderStatus,
- int32_t nDownsampleWidth,
- int32_t nDownsampleHeight) {
- m_nDownsampleWidth = nDownsampleWidth;
- m_nDownsampleHeight = nDownsampleHeight;
- pLoadHandle->reset(new CPDF_ImageLoaderHandle);
- return (*pLoadHandle)
- ->Start(this, pImage, pCache, bStdCS, GroupFamily, bLoadMask,
- pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight);
-}
-
-FX_BOOL CPDF_ImageLoader::Continue(CPDF_ImageLoaderHandle* LoadHandle,
- IFX_Pause* pPause) {
- return LoadHandle->Continue(pPause);
-}
-
-CPDF_ImageLoader::~CPDF_ImageLoader() {
- if (!m_bCached) {
- delete m_pBitmap;
- delete m_pMask;
- }
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp b/core/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp
deleted file mode 100644
index 5c6a8c513f..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_loadimage_embeddertest.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class FPDFRenderLoadImageEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFRenderLoadImageEmbeddertest, Bug_554151) {
- // Test scanline downsampling with a BitsPerComponent of 4.
- // Should not crash.
- EXPECT_TRUE(OpenDocument("bug_554151.pdf"));
- FPDF_PAGE page = LoadPage(0);
- EXPECT_NE(nullptr, page);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
-
-TEST_F(FPDFRenderLoadImageEmbeddertest, Bug_557223) {
- // Should not crash
- EXPECT_TRUE(OpenDocument("bug_557223.pdf"));
- FPDF_PAGE page = LoadPage(0);
- EXPECT_NE(nullptr, page);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
-
-TEST_F(FPDFRenderLoadImageEmbeddertest, Bug_603518) {
- // Should not crash
- EXPECT_TRUE(OpenDocument("bug_603518.pdf"));
- FPDF_PAGE page = LoadPage(0);
- EXPECT_NE(nullptr, page);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
deleted file mode 100644
index 4bd712e7eb..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
+++ /dev/null
@@ -1,1215 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-#include <algorithm>
-
-#include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h"
-#include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h"
-#include "core/fpdfapi/page/cpdf_form.h"
-#include "core/fpdfapi/page/cpdf_graphicstates.h"
-#include "core/fpdfapi/page/cpdf_meshstream.h"
-#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/cpdf_pathobject.h"
-#include "core/fpdfapi/page/cpdf_shadingobject.h"
-#include "core/fpdfapi/page/cpdf_shadingpattern.h"
-#include "core/fpdfapi/page/cpdf_tilingpattern.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fxge/cfx_fxgedevice.h"
-#include "core/fxge/cfx_pathdata.h"
-#include "core/fxge/cfx_renderdevice.h"
-#include "core/fxge/ifx_renderdevicedriver.h"
-
-namespace {
-
-uint32_t CountOutputs(
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs) {
- uint32_t total = 0;
- for (const auto& func : funcs) {
- if (func)
- total += func->CountOutputs();
- }
- return total;
-}
-
-#define SHADING_STEPS 256
-void DrawAxialShading(CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Dictionary* pDict,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
- CPDF_Array* pCoords = pDict->GetArrayFor("Coords");
- if (!pCoords) {
- return;
- }
- FX_FLOAT start_x = pCoords->GetNumberAt(0);
- FX_FLOAT start_y = pCoords->GetNumberAt(1);
- FX_FLOAT end_x = pCoords->GetNumberAt(2);
- FX_FLOAT end_y = pCoords->GetNumberAt(3);
- FX_FLOAT t_min = 0, t_max = 1.0f;
- CPDF_Array* pArray = pDict->GetArrayFor("Domain");
- if (pArray) {
- t_min = pArray->GetNumberAt(0);
- t_max = pArray->GetNumberAt(1);
- }
- FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
- pArray = pDict->GetArrayFor("Extend");
- if (pArray) {
- bStartExtend = pArray->GetIntegerAt(0);
- bEndExtend = pArray->GetIntegerAt(1);
- }
- int width = pBitmap->GetWidth();
- int height = pBitmap->GetHeight();
- FX_FLOAT x_span = end_x - start_x;
- FX_FLOAT y_span = end_y - start_y;
- FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span);
- CFX_Matrix matrix;
- matrix.SetReverse(*pObject2Bitmap);
- uint32_t total_results =
- std::max(CountOutputs(funcs), pCS->CountComponents());
- CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
- FX_FLOAT* pResults = result_array;
- FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
- uint32_t rgb_array[SHADING_STEPS];
- for (int i = 0; i < SHADING_STEPS; i++) {
- FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
- int offset = 0;
- for (const auto& func : funcs) {
- if (func) {
- int nresults = 0;
- if (func->Call(&input, 1, pResults + offset, nresults))
- offset += nresults;
- }
- }
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- pCS->GetRGB(pResults, R, G, B);
- rgb_array[i] =
- FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
- FXSYS_round(G * 255), FXSYS_round(B * 255)));
- }
- int pitch = pBitmap->GetPitch();
- for (int row = 0; row < height; row++) {
- uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch);
- for (int column = 0; column < width; column++) {
- FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
- matrix.Transform(x, y);
- FX_FLOAT scale = (((x - start_x) * x_span) + ((y - start_y) * y_span)) /
- axis_len_square;
- int index = (int32_t)(scale * (SHADING_STEPS - 1));
- if (index < 0) {
- if (!bStartExtend) {
- continue;
- }
- index = 0;
- } else if (index >= SHADING_STEPS) {
- if (!bEndExtend) {
- continue;
- }
- index = SHADING_STEPS - 1;
- }
- dib_buf[column] = rgb_array[index];
- }
- }
-}
-
-void DrawRadialShading(CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Dictionary* pDict,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
- CPDF_Array* pCoords = pDict->GetArrayFor("Coords");
- if (!pCoords) {
- return;
- }
- FX_FLOAT start_x = pCoords->GetNumberAt(0);
- FX_FLOAT start_y = pCoords->GetNumberAt(1);
- FX_FLOAT start_r = pCoords->GetNumberAt(2);
- FX_FLOAT end_x = pCoords->GetNumberAt(3);
- FX_FLOAT end_y = pCoords->GetNumberAt(4);
- FX_FLOAT end_r = pCoords->GetNumberAt(5);
- CFX_Matrix matrix;
- matrix.SetReverse(*pObject2Bitmap);
- FX_FLOAT t_min = 0, t_max = 1.0f;
- CPDF_Array* pArray = pDict->GetArrayFor("Domain");
- if (pArray) {
- t_min = pArray->GetNumberAt(0);
- t_max = pArray->GetNumberAt(1);
- }
- FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE;
- pArray = pDict->GetArrayFor("Extend");
- if (pArray) {
- bStartExtend = pArray->GetIntegerAt(0);
- bEndExtend = pArray->GetIntegerAt(1);
- }
- uint32_t total_results =
- std::max(CountOutputs(funcs), pCS->CountComponents());
- CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
- FX_FLOAT* pResults = result_array;
- FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
- uint32_t rgb_array[SHADING_STEPS];
- for (int i = 0; i < SHADING_STEPS; i++) {
- FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min;
- int offset = 0;
- for (const auto& func : funcs) {
- if (func) {
- int nresults;
- if (func->Call(&input, 1, pResults + offset, nresults))
- offset += nresults;
- }
- }
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- pCS->GetRGB(pResults, R, G, B);
- rgb_array[i] =
- FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255),
- FXSYS_round(G * 255), FXSYS_round(B * 255)));
- }
- FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) +
- ((start_y - end_y) * (start_y - end_y)) -
- ((start_r - end_r) * (start_r - end_r));
- int width = pBitmap->GetWidth();
- int height = pBitmap->GetHeight();
- int pitch = pBitmap->GetPitch();
- FX_BOOL bDecreasing = FALSE;
- if (start_r > end_r) {
- int length = (int)FXSYS_sqrt((((start_x - end_x) * (start_x - end_x)) +
- ((start_y - end_y) * (start_y - end_y))));
- if (length < start_r - end_r) {
- bDecreasing = TRUE;
- }
- }
- for (int row = 0; row < height; row++) {
- uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch);
- for (int column = 0; column < width; column++) {
- FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
- matrix.Transform(x, y);
- FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) +
- ((y - start_y) * (end_y - start_y)) +
- (start_r * (end_r - start_r)));
- FX_FLOAT c = ((x - start_x) * (x - start_x)) +
- ((y - start_y) * (y - start_y)) - (start_r * start_r);
- FX_FLOAT s;
- if (a == 0) {
- s = -c / b;
- } else {
- FX_FLOAT b2_4ac = (b * b) - 4 * (a * c);
- if (b2_4ac < 0) {
- continue;
- }
- FX_FLOAT root = FXSYS_sqrt(b2_4ac);
- FX_FLOAT s1, s2;
- if (a > 0) {
- s1 = (-b - root) / (2 * a);
- s2 = (-b + root) / (2 * a);
- } else {
- s2 = (-b - root) / (2 * a);
- s1 = (-b + root) / (2 * a);
- }
- if (bDecreasing) {
- if (s1 >= 0 || bStartExtend) {
- s = s1;
- } else {
- s = s2;
- }
- } else {
- if (s2 <= 1.0f || bEndExtend) {
- s = s2;
- } else {
- s = s1;
- }
- }
- if ((start_r + s * (end_r - start_r)) < 0) {
- continue;
- }
- }
- int index = (int32_t)(s * (SHADING_STEPS - 1));
- if (index < 0) {
- if (!bStartExtend) {
- continue;
- }
- index = 0;
- }
- if (index >= SHADING_STEPS) {
- if (!bEndExtend) {
- continue;
- }
- index = SHADING_STEPS - 1;
- }
- dib_buf[column] = rgb_array[index];
- }
- }
-}
-
-void DrawFuncShading(CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Dictionary* pDict,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
- CPDF_Array* pDomain = pDict->GetArrayFor("Domain");
- FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f;
- if (pDomain) {
- xmin = pDomain->GetNumberAt(0);
- xmax = pDomain->GetNumberAt(1);
- ymin = pDomain->GetNumberAt(2);
- ymax = pDomain->GetNumberAt(3);
- }
- CFX_Matrix mtDomain2Target = pDict->GetMatrixFor("Matrix");
- CFX_Matrix matrix, reverse_matrix;
- matrix.SetReverse(*pObject2Bitmap);
- reverse_matrix.SetReverse(mtDomain2Target);
- matrix.Concat(reverse_matrix);
- int width = pBitmap->GetWidth();
- int height = pBitmap->GetHeight();
- int pitch = pBitmap->GetPitch();
- uint32_t total_results =
- std::max(CountOutputs(funcs), pCS->CountComponents());
- CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results);
- FX_FLOAT* pResults = result_array;
- FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT));
- for (int row = 0; row < height; row++) {
- uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch);
- for (int column = 0; column < width; column++) {
- FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row;
- matrix.Transform(x, y);
- if (x < xmin || x > xmax || y < ymin || y > ymax) {
- continue;
- }
- FX_FLOAT input[2];
- int offset = 0;
- input[0] = x;
- input[1] = y;
- for (const auto& func : funcs) {
- if (func) {
- int nresults;
- if (func->Call(input, 2, pResults + offset, nresults))
- offset += nresults;
- }
- }
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- pCS->GetRGB(pResults, R, G, B);
- dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(
- alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)));
- }
- }
-}
-
-bool GetScanlineIntersect(int y,
- FX_FLOAT x1,
- FX_FLOAT y1,
- FX_FLOAT x2,
- FX_FLOAT y2,
- FX_FLOAT* x) {
- if (y1 == y2)
- return FALSE;
-
- if (y1 < y2) {
- if (y < y1 || y > y2)
- return FALSE;
- } else {
- if (y < y2 || y > y1)
- return FALSE;
- }
- *x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1));
- 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;
- 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;
- }
- }
- 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()) {
- 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];
- 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]);
- if (!bIntersect)
- continue;
-
- FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.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) {
- 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]);
- max_x = (int)FXSYS_ceil(inter_x[1]);
- start_index = 0;
- end_index = 1;
- } else {
- min_x = (int)FXSYS_floor(inter_x[1]);
- max_x = (int)FXSYS_ceil(inter_x[0]);
- 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()) {
- 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);
- FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x);
- FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x);
- FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit;
- FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit;
- FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit;
- for (int x = start_x; x < end_x; x++) {
- R += r_unit;
- G += g_unit;
- B += b_unit;
- FXARGB_SETDIB(dib_buf,
- FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255),
- (int32_t)(B * 255)));
- dib_buf += 4;
- }
- }
-}
-
-void DrawFreeGouraudShading(
- CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Stream* pShadingStream,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
-
- CPDF_MeshStream stream(kFreeFormGouraudTriangleMeshShading, funcs,
- pShadingStream, pCS);
- if (!stream.Load())
- return;
-
- CPDF_MeshVertex triangle[3];
- FXSYS_memset(triangle, 0, sizeof(triangle));
-
- while (!stream.BitStream()->IsEOF()) {
- CPDF_MeshVertex vertex;
- uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap);
- if (flag == 0) {
- triangle[0] = vertex;
- for (int j = 1; j < 3; j++) {
- stream.GetVertex(triangle[j], pObject2Bitmap);
- }
- } else {
- if (flag == 1) {
- triangle[0] = triangle[1];
- }
- triangle[1] = triangle[2];
- triangle[2] = vertex;
- }
- DrawGouraud(pBitmap, alpha, triangle);
- }
-}
-
-void DrawLatticeGouraudShading(
- CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Stream* pShadingStream,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
-
- int row_verts = pShadingStream->GetDict()->GetIntegerFor("VerticesPerRow");
- if (row_verts < 2)
- return;
-
- CPDF_MeshStream stream(kLatticeFormGouraudTriangleMeshShading, funcs,
- pShadingStream, pCS);
- if (!stream.Load())
- return;
-
- std::unique_ptr<CPDF_MeshVertex, FxFreeDeleter> vertex(
- FX_Alloc2D(CPDF_MeshVertex, row_verts, 2));
- if (!stream.GetVertexRow(vertex.get(), row_verts, pObject2Bitmap))
- 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))
- return;
-
- CPDF_MeshVertex triangle[3];
- for (int i = 1; i < row_verts; i++) {
- triangle[0] = last_row[i];
- triangle[1] = this_row[i - 1];
- triangle[2] = last_row[i - 1];
- DrawGouraud(pBitmap, alpha, triangle);
- triangle[2] = this_row[i];
- DrawGouraud(pBitmap, alpha, triangle);
- }
- last_index = 1 - last_index;
- }
-}
-
-struct Coon_BezierCoeff {
- float a, b, c, d;
- void FromPoints(float p0, float p1, float p2, float p3) {
- a = -p0 + 3 * p1 - 3 * p2 + p3;
- b = 3 * p0 - 6 * p1 + 3 * p2;
- c = -3 * p0 + 3 * p1;
- d = p0;
- }
- Coon_BezierCoeff first_half() {
- Coon_BezierCoeff result;
- result.a = a / 8;
- result.b = b / 4;
- result.c = c / 2;
- result.d = d;
- return result;
- }
- Coon_BezierCoeff second_half() {
- Coon_BezierCoeff result;
- result.a = a / 8;
- result.b = 3 * a / 8 + b / 4;
- result.c = 3 * a / 8 + b / 2 + c / 2;
- result.d = a / 8 + b / 4 + c / 2 + d;
- return result;
- }
- void GetPoints(float p[4]) {
- p[0] = d;
- p[1] = c / 3 + p[0];
- p[2] = b / 3 - p[0] + 2 * p[1];
- p[3] = a + p[0] - 3 * p[1] + 3 * p[2];
- }
- void GetPointsReverse(float p[4]) {
- p[3] = d;
- p[2] = c / 3 + p[3];
- p[1] = b / 3 - p[3] + 2 * p[2];
- p[0] = a + p[3] - 3 * p[2] + 3 * p[1];
- }
- void BezierInterpol(Coon_BezierCoeff& C1,
- Coon_BezierCoeff& C2,
- Coon_BezierCoeff& D1,
- Coon_BezierCoeff& D2) {
- a = (D1.a + D2.a) / 2;
- b = (D1.b + D2.b) / 2;
- c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) +
- (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2;
- d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d;
- }
- float Distance() {
- float dis = a + b + c;
- return dis < 0 ? -dis : dis;
- }
-};
-
-struct Coon_Bezier {
- Coon_BezierCoeff x, y;
- void FromPoints(float x0,
- float y0,
- float x1,
- float y1,
- float x2,
- float y2,
- float x3,
- float y3) {
- x.FromPoints(x0, x1, x2, x3);
- y.FromPoints(y0, y1, y2, y3);
- }
- Coon_Bezier first_half() {
- Coon_Bezier result;
- result.x = x.first_half();
- result.y = y.first_half();
- return result;
- }
- Coon_Bezier second_half() {
- Coon_Bezier result;
- result.x = x.second_half();
- result.y = y.second_half();
- return result;
- }
- void BezierInterpol(Coon_Bezier& C1,
- Coon_Bezier& C2,
- Coon_Bezier& D1,
- Coon_Bezier& D2) {
- x.BezierInterpol(C1.x, C2.x, D1.x, D2.x);
- y.BezierInterpol(C1.y, C2.y, D1.y, D2.y);
- }
- void GetPoints(FX_PATHPOINT* pPoints) {
- float p[4];
- int i;
- x.GetPoints(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointX = p[i];
- }
- y.GetPoints(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointY = p[i];
- }
- }
- void GetPointsReverse(FX_PATHPOINT* pPoints) {
- float p[4];
- int i;
- x.GetPointsReverse(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointX = p[i];
- }
- y.GetPointsReverse(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointY = p[i];
- }
- }
- float Distance() { return x.Distance() + y.Distance(); }
-};
-
-int BiInterpolImpl(int c0,
- int c1,
- int c2,
- int c3,
- int x,
- int y,
- int x_scale,
- int y_scale) {
- int x1 = c0 + (c3 - c0) * x / x_scale;
- int x2 = c1 + (c2 - c1) * x / x_scale;
- return x1 + (x2 - x1) * y / y_scale;
-}
-
-struct Coon_Color {
- Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); }
- int comp[3];
-
- void BiInterpol(Coon_Color colors[4],
- int x,
- int y,
- int x_scale,
- int y_scale) {
- for (int i = 0; i < 3; i++) {
- comp[i] = BiInterpolImpl(colors[0].comp[i], colors[1].comp[i],
- colors[2].comp[i], colors[3].comp[i], x, y,
- x_scale, y_scale);
- }
- }
-
- int Distance(Coon_Color& o) {
- return std::max({FXSYS_abs(comp[0] - o.comp[0]),
- FXSYS_abs(comp[1] - o.comp[1]),
- FXSYS_abs(comp[2] - o.comp[2])});
- }
-};
-
-struct CPDF_PatchDrawer {
- Coon_Color patch_colors[4];
- int max_delta;
- CFX_PathData path;
- CFX_RenderDevice* pDevice;
- int fill_mode;
- int alpha;
- void Draw(int x_scale,
- int y_scale,
- int left,
- int bottom,
- Coon_Bezier C1,
- Coon_Bezier C2,
- Coon_Bezier D1,
- Coon_Bezier D2) {
- FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 &&
- D1.Distance() < 2 && D2.Distance() < 2;
- Coon_Color div_colors[4];
- int d_bottom = 0;
- int d_left = 0;
- int d_top = 0;
- int d_right = 0;
- div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale);
- if (!bSmall) {
- div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale,
- y_scale);
- div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale,
- y_scale);
- div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale,
- y_scale);
- d_bottom = div_colors[3].Distance(div_colors[0]);
- d_left = div_colors[1].Distance(div_colors[0]);
- d_top = div_colors[1].Distance(div_colors[2]);
- d_right = div_colors[2].Distance(div_colors[3]);
- }
-#define COONCOLOR_THRESHOLD 4
- if (bSmall ||
- (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD &&
- d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) {
- FX_PATHPOINT* pPoints = path.GetPoints();
- C1.GetPoints(pPoints);
- D2.GetPoints(pPoints + 3);
- C2.GetPointsReverse(pPoints + 6);
- D1.GetPointsReverse(pPoints + 9);
- int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER;
- if (fill_mode & RENDER_NOPATHSMOOTH) {
- fillFlags |= FXFILL_NOPATHSMOOTH;
- }
- pDevice->DrawPath(
- &path, nullptr, nullptr,
- FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1],
- div_colors[0].comp[2]),
- 0, fillFlags);
- } else {
- if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) {
- Coon_Bezier m1;
- m1.BezierInterpol(D1, D2, C1, C2);
- y_scale *= 2;
- bottom *= 2;
- Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(),
- D2.first_half());
- Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(),
- D2.second_half());
- } else if (d_left < COONCOLOR_THRESHOLD &&
- d_right < COONCOLOR_THRESHOLD) {
- Coon_Bezier m2;
- m2.BezierInterpol(C1, C2, D1, D2);
- x_scale *= 2;
- left *= 2;
- Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(),
- D1, m2);
- Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(),
- C2.second_half(), m2, D2);
- } else {
- Coon_Bezier m1, m2;
- m1.BezierInterpol(D1, D2, C1, C2);
- m2.BezierInterpol(C1, C2, D1, D2);
- Coon_Bezier m1f = m1.first_half();
- Coon_Bezier m1s = m1.second_half();
- Coon_Bezier m2f = m2.first_half();
- Coon_Bezier m2s = m2.second_half();
- x_scale *= 2;
- y_scale *= 2;
- left *= 2;
- bottom *= 2;
- Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f,
- D1.first_half(), m2f);
- Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(),
- D1.second_half(), m2s);
- Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f,
- D2.first_half());
- Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s,
- D2.second_half());
- }
- }
- }
-};
-
-void DrawCoonPatchMeshes(
- ShadingType type,
- CFX_DIBitmap* pBitmap,
- CFX_Matrix* pObject2Bitmap,
- CPDF_Stream* pShadingStream,
- const std::vector<std::unique_ptr<CPDF_Function>>& funcs,
- CPDF_ColorSpace* pCS,
- int fill_mode,
- int alpha) {
- ASSERT(pBitmap->GetFormat() == FXDIB_Argb);
- ASSERT(type == kCoonsPatchMeshShading ||
- type == kTensorProductPatchMeshShading);
-
- CFX_FxgeDevice device;
- device.Attach(pBitmap, false, nullptr, false);
- CPDF_MeshStream stream(type, funcs, pShadingStream, pCS);
- if (!stream.Load())
- return;
-
- CPDF_PatchDrawer patch;
- patch.alpha = alpha;
- patch.pDevice = &device;
- patch.fill_mode = fill_mode;
- patch.path.SetPointCount(13);
- FX_PATHPOINT* pPoints = patch.path.GetPoints();
- pPoints[0].m_Flag = FXPT_MOVETO;
- for (int i = 1; i < 13; i++)
- pPoints[i].m_Flag = FXPT_BEZIERTO;
- CFX_PointF coords[16];
- int point_count = type == kTensorProductPatchMeshShading ? 16 : 12;
- while (!stream.BitStream()->IsEOF()) {
- uint32_t flag = stream.GetFlag();
- int iStartPoint = 0, iStartColor = 0, i = 0;
- if (flag) {
- iStartPoint = 4;
- iStartColor = 2;
- CFX_PointF tempCoords[4];
- for (i = 0; i < 4; i++) {
- tempCoords[i] = coords[(flag * 3 + i) % 12];
- }
- FXSYS_memcpy(coords, tempCoords, sizeof(tempCoords));
- Coon_Color tempColors[2];
- tempColors[0] = patch.patch_colors[flag];
- tempColors[1] = patch.patch_colors[(flag + 1) % 4];
- 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);
- pObject2Bitmap->Transform(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);
- 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);
- }
- CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count);
- if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() ||
- bbox.top <= 0 || bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) {
- continue;
- }
- Coon_Bezier C1, C2, D1, D2;
- C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y,
- coords[10].x, coords[10].y, coords[9].x, coords[9].y);
- C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y,
- coords[5].x, coords[5].y, coords[6].x, coords[6].y);
- D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y,
- coords[2].x, coords[2].y, coords[3].x, coords[3].y);
- D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y,
- coords[7].x, coords[7].y, coords[6].x, coords[6].y);
- patch.Draw(1, 1, 0, 0, C1, C2, D1, D2);
- }
-}
-
-std::unique_ptr<CFX_DIBitmap> DrawPatternBitmap(
- CPDF_Document* pDoc,
- CPDF_PageRenderCache* pCache,
- CPDF_TilingPattern* pPattern,
- const CFX_Matrix* pObject2Device,
- int width,
- int height,
- int flags) {
- std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap);
- if (!pBitmap->Create(width, height,
- pPattern->colored() ? FXDIB_Argb : FXDIB_8bppMask)) {
- return std::unique_ptr<CFX_DIBitmap>();
- }
- CFX_FxgeDevice bitmap_device;
- bitmap_device.Attach(pBitmap.get(), false, nullptr, false);
- pBitmap->Clear(0);
- CFX_FloatRect cell_bbox = pPattern->bbox();
- pPattern->pattern_to_form()->TransformRect(cell_bbox);
- pObject2Device->TransformRect(cell_bbox);
- CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height);
- CFX_Matrix mtAdjust;
- mtAdjust.MatchRect(bitmap_rect, cell_bbox);
- CFX_Matrix mtPattern2Bitmap = *pObject2Device;
- mtPattern2Bitmap.Concat(mtAdjust);
- CPDF_RenderOptions options;
- if (!pPattern->colored())
- options.m_ColorMode = RENDER_COLOR_ALPHA;
-
- flags |= RENDER_FORCE_HALFTONE;
- options.m_Flags = flags;
- CPDF_RenderContext context(pDoc, pCache);
- context.AppendLayer(pPattern->form(), &mtPattern2Bitmap);
- context.Render(&bitmap_device, &options, nullptr);
- return pBitmap;
-}
-
-} // namespace
-
-void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
- CFX_Matrix* pMatrix,
- FX_RECT& clip_rect,
- int alpha,
- FX_BOOL bAlphaMode) {
- const auto& funcs = pPattern->GetFuncs();
- CPDF_Dictionary* pDict = pPattern->GetShadingObject()->GetDict();
- CPDF_ColorSpace* pColorSpace = pPattern->GetCS();
- if (!pColorSpace)
- return;
-
- FX_ARGB background = 0;
- if (!pPattern->IsShadingObject() && pDict->KeyExist("Background")) {
- CPDF_Array* pBackColor = pDict->GetArrayFor("Background");
- if (pBackColor &&
- pBackColor->GetCount() >= pColorSpace->CountComponents()) {
- CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
- for (uint32_t i = 0; i < pColorSpace->CountComponents(); i++)
- comps[i] = pBackColor->GetNumberAt(i);
- FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
- pColorSpace->GetRGB(comps, R, G, B);
- background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
- (int32_t)(B * 255));
- }
- }
- if (pDict->KeyExist("BBox")) {
- CFX_FloatRect rect = pDict->GetRectFor("BBox");
- rect.Transform(pMatrix);
- clip_rect.Intersect(rect.GetOuterRect());
- }
- if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING &&
- m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, clip_rect,
- alpha, bAlphaMode)) {
- return;
- }
- CPDF_DeviceBuffer buffer;
- buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
- CFX_Matrix FinalMatrix = *pMatrix;
- FinalMatrix.Concat(*buffer.GetMatrix());
- CFX_DIBitmap* pBitmap = buffer.GetBitmap();
- if (!pBitmap->GetBuffer())
- return;
-
- pBitmap->Clear(background);
- int fill_mode = m_Options.m_Flags;
- switch (pPattern->GetShadingType()) {
- case kInvalidShading:
- case kMaxShading:
- return;
- case kFunctionBasedShading:
- DrawFuncShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha);
- break;
- case kAxialShading:
- DrawAxialShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace, alpha);
- break;
- case kRadialShading:
- DrawRadialShading(pBitmap, &FinalMatrix, pDict, funcs, pColorSpace,
- alpha);
- break;
- case kFreeFormGouraudTriangleMeshShading: {
- // The shading object can be a stream or a dictionary. We do not handle
- // the case of dictionary at the moment.
- if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
- DrawFreeGouraudShading(pBitmap, &FinalMatrix, pStream, funcs,
- pColorSpace, alpha);
- }
- } break;
- case kLatticeFormGouraudTriangleMeshShading: {
- // The shading object can be a stream or a dictionary. We do not handle
- // the case of dictionary at the moment.
- if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
- DrawLatticeGouraudShading(pBitmap, &FinalMatrix, pStream, funcs,
- pColorSpace, alpha);
- }
- } break;
- case kCoonsPatchMeshShading:
- case kTensorProductPatchMeshShading: {
- // The shading object can be a stream or a dictionary. We do not handle
- // the case of dictionary at the moment.
- if (CPDF_Stream* pStream = ToStream(pPattern->GetShadingObject())) {
- DrawCoonPatchMeshes(pPattern->GetShadingType(), pBitmap, &FinalMatrix,
- pStream, funcs, pColorSpace, fill_mode, alpha);
- }
- } break;
- }
- if (bAlphaMode)
- pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
-
- if (m_Options.m_ColorMode == RENDER_COLOR_GRAY)
- pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
- buffer.OutputToDevice();
-}
-
-void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern,
- const CPDF_PageObject* pPageObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke) {
- if (!pattern->Load())
- return;
-
- m_pDevice->SaveState();
- if (pPageObj->IsPath()) {
- if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) {
- m_pDevice->RestoreState(false);
- return;
- }
- } else if (pPageObj->IsImage()) {
- m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device));
- } else {
- return;
- }
- FX_RECT rect;
- if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) {
- m_pDevice->RestoreState(false);
- return;
- }
- CFX_Matrix matrix = *pattern->pattern_to_form();
- matrix.Concat(*pObj2Device);
- GetScaledMatrix(matrix);
- int alpha =
- FXSYS_round(255 * (bStroke ? pPageObj->m_GeneralState.GetStrokeAlpha()
- : pPageObj->m_GeneralState.GetFillAlpha()));
- DrawShading(pattern, &matrix, rect, alpha,
- m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
- m_pDevice->RestoreState(false);
-}
-
-void CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj,
- const CFX_Matrix* pObj2Device) {
- FX_RECT rect = pShadingObj->GetBBox(pObj2Device);
- FX_RECT clip_box = m_pDevice->GetClipBox();
- rect.Intersect(clip_box);
- if (rect.IsEmpty())
- return;
-
- CFX_Matrix matrix = pShadingObj->m_Matrix;
- matrix.Concat(*pObj2Device);
- DrawShading(pShadingObj->m_pShading, &matrix, rect,
- FXSYS_round(255 * pShadingObj->m_GeneralState.GetFillAlpha()),
- m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
-}
-
-void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
- CPDF_PageObject* pPageObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke) {
- if (!pPattern->Load()) {
- return;
- }
- m_pDevice->SaveState();
- if (pPageObj->IsPath()) {
- if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) {
- m_pDevice->RestoreState(false);
- return;
- }
- } else if (pPageObj->IsImage()) {
- m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device));
- } else {
- return;
- }
- FX_RECT clip_box = m_pDevice->GetClipBox();
- if (clip_box.IsEmpty()) {
- m_pDevice->RestoreState(false);
- return;
- }
- CFX_Matrix dCTM = m_pDevice->GetCTM();
- FX_FLOAT sa = FXSYS_fabs(dCTM.a);
- FX_FLOAT sd = FXSYS_fabs(dCTM.d);
- clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
- clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd);
- CFX_Matrix mtPattern2Device = *pPattern->pattern_to_form();
- mtPattern2Device.Concat(*pObj2Device);
- GetScaledMatrix(mtPattern2Device);
- FX_BOOL bAligned = FALSE;
- if (pPattern->bbox().left == 0 && pPattern->bbox().bottom == 0 &&
- pPattern->bbox().right == pPattern->x_step() &&
- pPattern->bbox().top == pPattern->y_step() &&
- (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
- bAligned = TRUE;
- }
- CFX_FloatRect cell_bbox = pPattern->bbox();
- mtPattern2Device.TransformRect(cell_bbox);
- int width = (int)FXSYS_ceil(cell_bbox.Width());
- int height = (int)FXSYS_ceil(cell_bbox.Height());
- if (width == 0) {
- width = 1;
- }
- if (height == 0) {
- height = 1;
- }
- int min_col, max_col, min_row, max_row;
- CFX_Matrix mtDevice2Pattern;
- mtDevice2Pattern.SetReverse(mtPattern2Device);
- CFX_FloatRect clip_box_p(clip_box);
- clip_box_p.Transform(&mtDevice2Pattern);
-
- min_col = (int)FXSYS_ceil((clip_box_p.left - pPattern->bbox().right) /
- pPattern->x_step());
- max_col = (int)FXSYS_floor((clip_box_p.right - pPattern->bbox().left) /
- pPattern->x_step());
- min_row = (int)FXSYS_ceil((clip_box_p.bottom - pPattern->bbox().top) /
- pPattern->y_step());
- max_row = (int)FXSYS_floor((clip_box_p.top - pPattern->bbox().bottom) /
- pPattern->y_step());
-
- if (width > clip_box.Width() || height > clip_box.Height() ||
- width * height > clip_box.Width() * clip_box.Height()) {
- CPDF_GraphicStates* pStates = nullptr;
- if (!pPattern->colored())
- pStates = CloneObjStates(pPageObj, bStroke);
-
- CPDF_Dictionary* pFormResource = nullptr;
- if (pPattern->form()->m_pFormDict)
- pFormResource = pPattern->form()->m_pFormDict->GetDictFor("Resources");
-
- for (int col = min_col; col <= max_col; col++)
- for (int row = min_row; row <= max_row; row++) {
- FX_FLOAT orig_x, orig_y;
- orig_x = col * pPattern->x_step();
- orig_y = row * pPattern->y_step();
- mtPattern2Device.Transform(orig_x, orig_y);
- CFX_Matrix matrix = *pObj2Device;
- matrix.Translate(orig_x - mtPattern2Device.e,
- orig_y - mtPattern2Device.f);
- m_pDevice->SaveState();
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this,
- pStates, &m_Options, pPattern->form()->m_Transparency,
- m_bDropObjects, pFormResource);
- status.RenderObjectList(pPattern->form(), &matrix);
- m_pDevice->RestoreState(false);
- }
- m_pDevice->RestoreState(false);
- delete pStates;
- return;
- }
- if (bAligned) {
- int orig_x = FXSYS_round(mtPattern2Device.e);
- int orig_y = FXSYS_round(mtPattern2Device.f);
- min_col = (clip_box.left - orig_x) / width;
- if (clip_box.left < orig_x) {
- min_col--;
- }
- max_col = (clip_box.right - orig_x) / width;
- if (clip_box.right <= orig_x) {
- max_col--;
- }
- min_row = (clip_box.top - orig_y) / height;
- if (clip_box.top < orig_y) {
- min_row--;
- }
- max_row = (clip_box.bottom - orig_y) / height;
- if (clip_box.bottom <= orig_y) {
- max_row--;
- }
- }
- FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
- FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
- std::unique_ptr<CFX_DIBitmap> pPatternBitmap;
- if (width * height < 16) {
- std::unique_ptr<CFX_DIBitmap> pEnlargedBitmap =
- DrawPatternBitmap(m_pContext->GetDocument(), m_pContext->GetPageCache(),
- pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
- pPatternBitmap.reset(pEnlargedBitmap->StretchTo(width, height));
- } else {
- pPatternBitmap = DrawPatternBitmap(
- m_pContext->GetDocument(), m_pContext->GetPageCache(), pPattern,
- pObj2Device, width, height, m_Options.m_Flags);
- }
- if (!pPatternBitmap) {
- m_pDevice->RestoreState(false);
- return;
- }
- if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
- pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor,
- m_Options.m_BackColor);
- }
- FX_ARGB fill_argb = GetFillArgb(pPageObj);
- int clip_width = clip_box.right - clip_box.left;
- int clip_height = clip_box.bottom - clip_box.top;
- CFX_DIBitmap screen;
- if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
- return;
- }
- screen.Clear(0);
- uint32_t* src_buf = (uint32_t*)pPatternBitmap->GetBuffer();
- for (int col = min_col; col <= max_col; col++) {
- for (int row = min_row; row <= max_row; row++) {
- int start_x, start_y;
- if (bAligned) {
- start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left;
- start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top;
- } else {
- FX_FLOAT orig_x = col * pPattern->x_step();
- FX_FLOAT orig_y = row * pPattern->y_step();
- mtPattern2Device.Transform(orig_x, orig_y);
-
- pdfium::base::CheckedNumeric<int> safeStartX =
- FXSYS_round(orig_x + left_offset);
- pdfium::base::CheckedNumeric<int> safeStartY =
- FXSYS_round(orig_y + top_offset);
-
- safeStartX -= clip_box.left;
- safeStartY -= clip_box.top;
- if (!safeStartX.IsValid() || !safeStartY.IsValid())
- return;
-
- start_x = safeStartX.ValueOrDie();
- start_y = safeStartY.ValueOrDie();
- }
- if (width == 1 && height == 1) {
- if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 ||
- start_y >= clip_box.Height()) {
- continue;
- }
- uint32_t* dest_buf =
- (uint32_t*)(screen.GetBuffer() + screen.GetPitch() * start_y +
- start_x * 4);
- if (pPattern->colored())
- *dest_buf = *src_buf;
- else
- *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
- } else {
- if (pPattern->colored()) {
- screen.CompositeBitmap(start_x, start_y, width, height,
- pPatternBitmap.get(), 0, 0);
- } else {
- screen.CompositeMask(start_x, start_y, width, height,
- pPatternBitmap.get(), fill_argb, 0, 0);
- }
- }
- }
- }
- CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
- FXDIB_BLEND_NORMAL, FALSE);
- m_pDevice->RestoreState(false);
-}
-
-void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- const CPDF_Color* pColor,
- FX_BOOL bStroke) {
- CPDF_Pattern* pattern = pColor->GetPattern();
- if (!pattern)
- return;
-
- if (CPDF_TilingPattern* pTilingPattern = pattern->AsTilingPattern())
- DrawTilingPattern(pTilingPattern, pPathObj, pObj2Device, bStroke);
- else if (CPDF_ShadingPattern* pShadingPattern = pattern->AsShadingPattern())
- DrawShadingPattern(pShadingPattern, pPathObj, pObj2Device, bStroke);
-}
-
-void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- int& filltype,
- FX_BOOL& bStroke) {
- if (filltype) {
- const CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor();
- if (FillColor.IsPattern()) {
- DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE);
- filltype = 0;
- }
- }
- if (bStroke) {
- const CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor();
- if (StrokeColor.IsPattern()) {
- DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE);
- bStroke = FALSE;
- }
- }
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp
deleted file mode 100644
index 176c923372..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_pattern_embeddertest.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class FPDFRenderPatternEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFRenderPatternEmbeddertest, LoadError_547706) {
- // Test shading where object is a dictionary instead of a stream.
- EXPECT_TRUE(OpenDocument("bug_547706.pdf"));
- FPDF_PAGE page = LoadPage(0);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
deleted file mode 100644
index 316cbff3a6..0000000000
--- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-#include <vector>
-
-#include "core/fpdfapi/font/cpdf_cidfont.h"
-#include "core/fpdfapi/font/cpdf_font.h"
-#include "core/fpdfapi/font/cpdf_type3char.h"
-#include "core/fpdfapi/font/cpdf_type3font.h"
-#include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h"
-#include "core/fpdfapi/fpdf_render/cpdf_textrenderer.h"
-#include "core/fpdfapi/fpdf_render/cpdf_type3cache.h"
-#include "core/fpdfapi/page/cpdf_form.h"
-#include "core/fpdfapi/page/cpdf_imageobject.h"
-#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/cpdf_pathobject.h"
-#include "core/fpdfapi/page/cpdf_textobject.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fxge/cfx_facecache.h"
-#include "core/fxge/cfx_fxgedevice.h"
-#include "core/fxge/cfx_gemodule.h"
-#include "core/fxge/cfx_graphstatedata.h"
-#include "core/fxge/cfx_pathdata.h"
-#include "core/fxge/cfx_renderdevice.h"
-
-FX_BOOL CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device,
- CFX_PathData* pClippingPath) {
- if (textobj->m_nChars == 0)
- return TRUE;
-
- const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode();
- if (text_render_mode == TextRenderingMode::MODE_INVISIBLE)
- return TRUE;
-
- CPDF_Font* pFont = textobj->m_TextState.GetFont();
- if (pFont->IsType3Font())
- return ProcessType3Text(textobj, pObj2Device);
-
- bool bFill = false;
- bool bStroke = false;
- bool bClip = false;
- if (pClippingPath) {
- bClip = true;
- } else {
- switch (text_render_mode) {
- case TextRenderingMode::MODE_FILL:
- case TextRenderingMode::MODE_FILL_CLIP:
- bFill = true;
- break;
- case TextRenderingMode::MODE_STROKE:
- case TextRenderingMode::MODE_STROKE_CLIP:
- if (pFont->GetFace() ||
- (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
- bStroke = true;
- } else {
- bFill = true;
- }
- break;
- case TextRenderingMode::MODE_FILL_STROKE:
- case TextRenderingMode::MODE_FILL_STROKE_CLIP:
- bFill = true;
- if (pFont->GetFace() ||
- (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
- bStroke = true;
- }
- break;
- case TextRenderingMode::MODE_INVISIBLE:
- // Already handled above, but the compiler is not smart enough to
- // realize it. Fall through.
- ASSERT(false);
- case TextRenderingMode::MODE_CLIP:
- return TRUE;
- }
- }
- FX_ARGB stroke_argb = 0;
- FX_ARGB fill_argb = 0;
- bool bPattern = false;
- if (bStroke) {
- if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) {
- bPattern = true;
- } else {
- stroke_argb = GetStrokeArgb(textobj);
- }
- }
- if (bFill) {
- if (textobj->m_ColorState.GetFillColor()->IsPattern()) {
- bPattern = true;
- } else {
- fill_argb = GetFillArgb(textobj);
- }
- }
- CFX_Matrix text_matrix;
- textobj->GetTextMatrix(&text_matrix);
- if (!IsAvailableMatrix(text_matrix))
- return TRUE;
-
- FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
- if (bPattern) {
- DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size,
- &text_matrix, bFill, bStroke);
- return TRUE;
- }
- if (bClip || bStroke) {
- const CFX_Matrix* pDeviceMatrix = pObj2Device;
- CFX_Matrix device_matrix;
- if (bStroke) {
- const FX_FLOAT* pCTM = textobj->m_TextState.GetCTM();
- if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) {
- CFX_Matrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0);
- text_matrix.ConcatInverse(ctm);
- device_matrix = ctm;
- device_matrix.Concat(*pObj2Device);
- pDeviceMatrix = &device_matrix;
- }
- }
- int flag = 0;
- if (bStroke && bFill) {
- flag |= FX_FILL_STROKE;
- flag |= FX_STROKE_TEXT_MODE;
- }
- if (textobj->m_GeneralState.GetStrokeAdjust())
- flag |= FX_STROKE_ADJUST;
- if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH)
- flag |= FXFILL_NOPATHSMOOTH;
- return CPDF_TextRenderer::DrawTextPath(
- m_pDevice, textobj->m_nChars, textobj->m_pCharCodes,
- textobj->m_pCharPos, pFont, font_size, &text_matrix, pDeviceMatrix,
- textobj->m_GraphState.GetObject(), fill_argb, stroke_argb,
- pClippingPath, flag);
- }
- text_matrix.Concat(*pObj2Device);
- return CPDF_TextRenderer::DrawNormalText(
- m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos,
- pFont, font_size, &text_matrix, fill_argb, &m_Options);
-}
-
-CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) {
- if (!pFont->m_pDocument) {
- return nullptr;
- }
- pFont->m_pDocument->GetPageData()->GetFont(pFont->GetFontDict(), FALSE);
- return pFont->m_pDocument->GetRenderData()->GetCachedType3(pFont);
-}
-static void ReleaseCachedType3(CPDF_Type3Font* pFont) {
- if (!pFont->m_pDocument) {
- return;
- }
- pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont);
- pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict());
-}
-
-class CPDF_RefType3Cache {
- public:
- explicit CPDF_RefType3Cache(CPDF_Type3Font* pType3Font)
- : m_dwCount(0), m_pType3Font(pType3Font) {}
- ~CPDF_RefType3Cache() {
- while (m_dwCount--) {
- ReleaseCachedType3(m_pType3Font);
- }
- }
- uint32_t m_dwCount;
- CPDF_Type3Font* const m_pType3Font;
-};
-
-// TODO(npm): Font fallback for type 3 fonts? (Completely separate code!!)
-FX_BOOL CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device) {
- CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font();
- for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) {
- if (m_Type3FontCache.GetAt(i) == pType3Font)
- return TRUE;
- }
-
- CFX_Matrix dCTM = m_pDevice->GetCTM();
- FX_FLOAT sa = FXSYS_fabs(dCTM.a);
- FX_FLOAT sd = FXSYS_fabs(dCTM.d);
- CFX_Matrix text_matrix;
- textobj->GetTextMatrix(&text_matrix);
- CFX_Matrix char_matrix = pType3Font->GetFontMatrix();
- FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
- char_matrix.Scale(font_size, font_size);
- FX_ARGB fill_argb = GetFillArgb(textobj, TRUE);
- int fill_alpha = FXARGB_A(fill_argb);
- int device_class = m_pDevice->GetDeviceClass();
- std::vector<FXTEXT_GLYPHPOS> glyphs;
- if (device_class == FXDC_DISPLAY)
- glyphs.resize(textobj->m_nChars);
- else if (fill_alpha < 255)
- return FALSE;
-
- CPDF_RefType3Cache refTypeCache(pType3Font);
- uint32_t* pChars = textobj->m_pCharCodes;
- if (textobj->m_nChars == 1)
- pChars = (uint32_t*)(&textobj->m_pCharCodes);
-
- for (int iChar = 0; iChar < textobj->m_nChars; iChar++) {
- uint32_t charcode = pChars[iChar];
- if (charcode == (uint32_t)-1)
- continue;
-
- CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode);
- if (!pType3Char)
- continue;
-
- CFX_Matrix matrix = char_matrix;
- matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0;
- matrix.Concat(text_matrix);
- matrix.Concat(*pObj2Device);
- if (!pType3Char->LoadBitmap(m_pContext)) {
- if (!glyphs.empty()) {
- for (int i = 0; i < iChar; i++) {
- const FXTEXT_GLYPHPOS& glyph = glyphs[i];
- if (!glyph.m_pGlyph)
- continue;
-
- m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap,
- glyph.m_OriginX + glyph.m_pGlyph->m_Left,
- glyph.m_OriginY - glyph.m_pGlyph->m_Top,
- fill_argb);
- }
- glyphs.clear();
- }
- CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE);
- CPDF_RenderOptions Options = m_Options;
- Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA;
- Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE;
- CPDF_Dictionary* pFormResource = nullptr;
- if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) {
- pFormResource =
- pType3Char->m_pForm->m_pFormDict->GetDictFor("Resources");
- }
- if (fill_alpha == 255) {
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this,
- pStates, &Options,
- pType3Char->m_pForm->m_Transparency, m_bDropObjects,
- pFormResource, FALSE, pType3Char, fill_argb);
- status.m_Type3FontCache.Append(m_Type3FontCache);
- status.m_Type3FontCache.Add(pType3Font);
- m_pDevice->SaveState();
- status.RenderObjectList(pType3Char->m_pForm.get(), &matrix);
- m_pDevice->RestoreState(false);
- } else {
- CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox();
- rect_f.Transform(&matrix);
- FX_RECT rect = rect_f.GetOuterRect();
- CFX_FxgeDevice bitmap_device;
- if (!bitmap_device.Create((int)(rect.Width() * sa),
- (int)(rect.Height() * sd), FXDIB_Argb,
- nullptr)) {
- return TRUE;
- }
- bitmap_device.GetBitmap()->Clear(0);
- CPDF_RenderStatus status;
- status.Initialize(m_pContext, &bitmap_device, nullptr, nullptr, this,
- pStates, &Options,
- pType3Char->m_pForm->m_Transparency, m_bDropObjects,
- pFormResource, FALSE, pType3Char, fill_argb);
- status.m_Type3FontCache.Append(m_Type3FontCache);
- status.m_Type3FontCache.Add(pType3Font);
- matrix.TranslateI(-rect.left, -rect.top);
- matrix.Scale(sa, sd);
- status.RenderObjectList(pType3Char->m_pForm.get(), &matrix);
- m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top);
- }
- delete pStates;
- } else if (pType3Char->m_pBitmap) {
- if (device_class == FXDC_DISPLAY) {
- CPDF_Type3Cache* pCache = GetCachedType3(pType3Font);
- refTypeCache.m_dwCount++;
- CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd);
- if (!pBitmap)
- continue;
-
- int origin_x = FXSYS_round(matrix.e);
- int origin_y = FXSYS_round(matrix.f);
- if (glyphs.empty()) {
- m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left,
- origin_y - pBitmap->m_Top, fill_argb);
- } else {
- glyphs[iChar].m_pGlyph = pBitmap;
- glyphs[iChar].m_OriginX = origin_x;
- glyphs[iChar].m_OriginY = origin_y;
- }
- } else {
- CFX_Matrix image_matrix = pType3Char->m_ImageMatrix;
- image_matrix.Concat(matrix);
- CPDF_ImageRenderer renderer;
- if (renderer.Start(this, pType3Char->m_pBitmap.get(), fill_argb, 255,
- &image_matrix, 0, FALSE)) {
- renderer.Continue(nullptr);
- }
- if (!renderer.m_Result)
- return FALSE;
- }
- }
- }
-
- if (glyphs.empty())
- return TRUE;
-
- FX_RECT rect = FXGE_GetGlyphsBBox(glyphs, 0, sa, sd);
- CFX_DIBitmap bitmap;
- if (!bitmap.Create(static_cast<int>(rect.Width() * sa),
- static_cast<int>(rect.Height() * sd), FXDIB_8bppMask)) {
- return TRUE;
- }
- bitmap.Clear(0);
- for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
- 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);
- }
- m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
- return TRUE;
-}
-
-class CPDF_CharPosList {
- public:
- CPDF_CharPosList();
- ~CPDF_CharPosList();
- void Load(int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT font_size);
- FXTEXT_CHARPOS* m_pCharPos;
- uint32_t m_nChars;
-};
-
-CPDF_CharPosList::CPDF_CharPosList() {
- m_pCharPos = nullptr;
-}
-
-CPDF_CharPosList::~CPDF_CharPosList() {
- FX_Free(m_pCharPos);
-}
-
-void CPDF_CharPosList::Load(int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT FontSize) {
- m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars);
- m_nChars = 0;
- CPDF_CIDFont* pCIDFont = pFont->AsCIDFont();
- FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting();
- for (int iChar = 0; iChar < nChars; iChar++) {
- uint32_t CharCode =
- nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar];
- if (CharCode == (uint32_t)-1) {
- continue;
- }
- bool bVert = false;
- FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++];
- if (pCIDFont) {
- charpos.m_bFontStyle = true;
- }
- charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert);
- if (charpos.m_GlyphIndex != static_cast<uint32_t>(-1)) {
- charpos.m_FallbackFontPosition = -1;
- } else {
- charpos.m_FallbackFontPosition =
- pFont->FallbackFontFromCharcode(CharCode);
- charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode(
- charpos.m_FallbackFontPosition, CharCode);
- }
-// TODO(npm): Figure out how this affects m_ExtGID
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode);
-#endif
- if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) {
- charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode);
- } else {
- charpos.m_FontCharWidth = 0;
- }
- charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0;
- charpos.m_OriginY = 0;
- charpos.m_bGlyphAdjust = FALSE;
- if (!pCIDFont) {
- continue;
- }
- uint16_t CID = pCIDFont->CIDFromCharCode(CharCode);
- if (bVertWriting) {
- charpos.m_OriginY = charpos.m_OriginX;
- charpos.m_OriginX = 0;
- short vx, vy;
- pCIDFont->GetVertOrigin(CID, vx, vy);
- charpos.m_OriginX -= FontSize * vx / 1000;
- charpos.m_OriginY -= FontSize * vy / 1000;
- }
- const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID);
- if (pTransform && !bVert) {
- charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]);
- charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]);
- charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]);
- charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]);
- charpos.m_OriginX +=
- pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize;
- charpos.m_OriginY +=
- pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize;
- charpos.m_bGlyphAdjust = TRUE;
- }
- }
-}
-
-// static
-FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice,
- int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pText2User,
- const CFX_Matrix* pUser2Device,
- const CFX_GraphStateData* pGraphState,
- FX_ARGB fill_argb,
- FX_ARGB stroke_argb,
- CFX_PathData* pClippingPath,
- int nFlag) {
- CPDF_CharPosList CharPosList;
- CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
- if (CharPosList.m_nChars == 0)
- return TRUE;
- bool bDraw = true;
- int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
- uint32_t startIndex = 0;
- for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
- int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
- if (fontPosition == curFontPosition)
- continue;
- auto* font = fontPosition == -1
- ? &pFont->m_Font
- : pFont->m_FontFallbacks[fontPosition].get();
- if (!pDevice->DrawTextPath(i - startIndex,
- CharPosList.m_pCharPos + startIndex, font,
- font_size, pText2User, pUser2Device, pGraphState,
- fill_argb, stroke_argb, pClippingPath, nFlag)) {
- bDraw = false;
- }
- fontPosition = curFontPosition;
- startIndex = i;
- }
- auto* font = fontPosition == -1 ? &pFont->m_Font
- : pFont->m_FontFallbacks[fontPosition].get();
- if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex,
- CharPosList.m_pCharPos + startIndex, font,
- font_size, pText2User, pUser2Device, pGraphState,
- fill_argb, stroke_argb, pClippingPath, nFlag)) {
- bDraw = false;
- }
- return bDraw;
-}
-
-// static
-void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice,
- FX_FLOAT origin_x,
- FX_FLOAT origin_y,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pMatrix,
- const CFX_ByteString& str,
- FX_ARGB fill_argb,
- FX_ARGB stroke_argb,
- const CFX_GraphStateData* pGraphState,
- const CPDF_RenderOptions* pOptions) {
- if (pFont->IsType3Font())
- return;
-
- int nChars = pFont->CountChar(str.c_str(), str.GetLength());
- if (nChars <= 0)
- return;
-
- int offset = 0;
- uint32_t* pCharCodes;
- FX_FLOAT* pCharPos;
- std::vector<uint32_t> codes;
- std::vector<FX_FLOAT> positions;
- if (nChars == 1) {
- pCharCodes = reinterpret_cast<uint32_t*>(
- pFont->GetNextChar(str.c_str(), str.GetLength(), offset));
- pCharPos = nullptr;
- } else {
- codes.resize(nChars);
- positions.resize(nChars - 1);
- FX_FLOAT cur_pos = 0;
- for (int i = 0; i < nChars; i++) {
- codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset);
- if (i)
- positions[i - 1] = cur_pos;
- cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000;
- }
- pCharCodes = codes.data();
- pCharPos = positions.data();
- }
- CFX_Matrix matrix;
- if (pMatrix)
- matrix = *pMatrix;
-
- matrix.e = origin_x;
- matrix.f = origin_y;
-
- if (stroke_argb == 0) {
- DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size,
- &matrix, fill_argb, pOptions);
- } else {
- DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size,
- &matrix, nullptr, pGraphState, fill_argb, stroke_argb, nullptr,
- 0);
- }
-}
-
-// static
-FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice,
- int nChars,
- uint32_t* pCharCodes,
- FX_FLOAT* pCharPos,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pText2Device,
- FX_ARGB fill_argb,
- const CPDF_RenderOptions* pOptions) {
- CPDF_CharPosList CharPosList;
- CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
- if (CharPosList.m_nChars == 0)
- return TRUE;
- int FXGE_flags = 0;
- if (pOptions) {
- uint32_t dwFlags = pOptions->m_Flags;
- if (dwFlags & RENDER_CLEARTYPE) {
- FXGE_flags |= FXTEXT_CLEARTYPE;
- if (dwFlags & RENDER_BGR_STRIPE) {
- FXGE_flags |= FXTEXT_BGR_STRIPE;
- }
- }
- if (dwFlags & RENDER_NOTEXTSMOOTH) {
- FXGE_flags |= FXTEXT_NOSMOOTH;
- }
- if (dwFlags & RENDER_PRINTGRAPHICTEXT) {
- FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT;
- }
- if (dwFlags & RENDER_NO_NATIVETEXT) {
- FXGE_flags |= FXTEXT_NO_NATIVETEXT;
- }
- if (dwFlags & RENDER_PRINTIMAGETEXT) {
- FXGE_flags |= FXTEXT_PRINTIMAGETEXT;
- }
- } else {
- FXGE_flags = FXTEXT_CLEARTYPE;
- }
- if (pFont->IsCIDFont()) {
- FXGE_flags |= FXFONT_CIDFONT;
- }
- bool bDraw = true;
- int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
- uint32_t startIndex = 0;
- for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
- int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
- if (fontPosition == curFontPosition)
- continue;
- auto* font = fontPosition == -1
- ? &pFont->m_Font
- : pFont->m_FontFallbacks[fontPosition].get();
- if (!pDevice->DrawNormalText(
- i - startIndex, CharPosList.m_pCharPos + startIndex, font,
- font_size, pText2Device, fill_argb, FXGE_flags)) {
- bDraw = false;
- }
- fontPosition = curFontPosition;
- startIndex = i;
- }
- auto* font = fontPosition == -1 ? &pFont->m_Font
- : pFont->m_FontFallbacks[fontPosition].get();
- if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex,
- CharPosList.m_pCharPos + startIndex, font,
- font_size, pText2Device, fill_argb,
- FXGE_flags)) {
- bDraw = false;
- }
- return bDraw;
-}
-
-void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pTextMatrix,
- FX_BOOL bFill,
- FX_BOOL bStroke) {
- if (!bStroke) {
- CPDF_PathObject path;
- std::vector<std::unique_ptr<CPDF_TextObject>> pCopy;
- pCopy.push_back(std::unique_ptr<CPDF_TextObject>(textobj->Clone()));
- path.m_bStroke = FALSE;
- path.m_FillType = FXFILL_WINDING;
- path.m_ClipPath.AppendTexts(&pCopy);
- path.m_ColorState = textobj->m_ColorState;
- path.m_Path.AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right,
- textobj->m_Top);
- path.m_Left = textobj->m_Left;
- path.m_Bottom = textobj->m_Bottom;
- path.m_Right = textobj->m_Right;
- path.m_Top = textobj->m_Top;
- RenderSingleObject(&path, pObj2Device);
- return;
- }
- CPDF_CharPosList CharPosList;
- CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes,
- textobj->m_pCharPos, pFont, font_size);
- for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
- FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i];
- auto font =
- charpos.m_FallbackFontPosition == -1
- ? &pFont->m_Font
- : pFont->m_FontFallbacks[charpos.m_FallbackFontPosition].get();
- const CFX_PathData* pPath =
- font->LoadGlyphPath(charpos.m_GlyphIndex, charpos.m_FontCharWidth);
- if (!pPath) {
- continue;
- }
- CPDF_PathObject path;
- path.m_GraphState = textobj->m_GraphState;
- path.m_ColorState = textobj->m_ColorState;
- CFX_Matrix matrix;
- if (charpos.m_bGlyphAdjust)
- matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
- charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
- matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX,
- charpos.m_OriginY);
- path.m_Path.Append(pPath, &matrix);
- path.m_Matrix = *pTextMatrix;
- path.m_bStroke = bStroke;
- path.m_FillType = bFill ? FXFILL_WINDING : 0;
- path.CalcBoundingBox();
- ProcessPath(&path, pObj2Device);
- }
-}
diff --git a/core/fpdfapi/fpdf_render/render_int.h b/core/fpdfapi/fpdf_render/render_int.h
deleted file mode 100644
index aa82a9f53c..0000000000
--- a/core/fpdfapi/fpdf_render/render_int.h
+++ /dev/null
@@ -1,596 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_RENDER_RENDER_INT_H_
-#define CORE_FPDFAPI_FPDF_RENDER_RENDER_INT_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h"
-#include "core/fpdfapi/page/cpdf_clippath.h"
-#include "core/fpdfapi/page/cpdf_countedobject.h"
-#include "core/fpdfapi/page/cpdf_graphicstates.h"
-#include "core/fpdfapi/parser/cpdf_stream_acc.h"
-#include "core/fxge/cfx_fxgedevice.h"
-#include "core/fxge/cfx_renderdevice.h"
-
-class CCodec_Jbig2Context;
-class CCodec_ScanlineDecoder;
-class CFX_GlyphBitmap;
-class CFX_ImageTransformer;
-class CFX_PathData;
-class CPDF_Color;
-class CPDF_Dictionary;
-class CPDF_Document;
-class CPDF_Font;
-class CPDF_FormObject;
-class CPDF_ImageCacheEntry;
-class CPDF_ImageLoaderHandle;
-class CPDF_ImageObject;
-class CPDF_ImageRenderer;
-class CPDF_Object;
-class CPDF_PageObject;
-class CPDF_PageObjectHolder;
-class CPDF_PageRenderCache;
-class CPDF_PathObject;
-class CPDF_RenderStatus;
-class CPDF_ShadingObject;
-class CPDF_ShadingPattern;
-class CPDF_Stream;
-class CPDF_TilingPattern;
-class CPDF_TransferFunc;
-class CPDF_Type3Cache;
-class CPDF_Type3Glyphs;
-class CPDF_Type3Char;
-class CPDF_Type3Font;
-
-FX_BOOL IsAvailableMatrix(const CFX_Matrix& matrix);
-
-class CPDF_TransferFunc {
- public:
- explicit CPDF_TransferFunc(CPDF_Document* pDoc);
-
- FX_COLORREF TranslateColor(FX_COLORREF src) const;
- CFX_DIBSource* TranslateImage(const CFX_DIBSource* pSrc,
- FX_BOOL bAutoDropSrc);
-
- CPDF_Document* const m_pPDFDoc;
- FX_BOOL m_bIdentity;
- uint8_t m_Samples[256 * 3];
-};
-
-class CPDF_DocRenderData {
- public:
- explicit CPDF_DocRenderData(CPDF_Document* pPDFDoc);
- ~CPDF_DocRenderData();
- CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont);
- CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObj);
- void Clear(FX_BOOL bRelease = FALSE);
- void ReleaseCachedType3(CPDF_Type3Font* pFont);
- void ReleaseTransferFunc(CPDF_Object* pObj);
-
- private:
- using CPDF_Type3CacheMap =
- std::map<CPDF_Font*, CPDF_CountedObject<CPDF_Type3Cache>*>;
- using CPDF_TransferFuncMap =
- std::map<CPDF_Object*, CPDF_CountedObject<CPDF_TransferFunc>*>;
-
- CPDF_Document* m_pPDFDoc;
- CPDF_Type3CacheMap m_Type3FaceMap;
- CPDF_TransferFuncMap m_TransferFuncMap;
-};
-
-class CPDF_RenderStatus {
- public:
- CPDF_RenderStatus();
- ~CPDF_RenderStatus();
-
- FX_BOOL Initialize(class CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const CFX_Matrix* pDeviceMatrix,
- const CPDF_PageObject* pStopObj,
- const CPDF_RenderStatus* pParentStatus,
- const CPDF_GraphicStates* pInitialStates,
- const CPDF_RenderOptions* pOptions,
- int transparency,
- FX_BOOL bDropObjects,
- CPDF_Dictionary* pFormResource = nullptr,
- FX_BOOL bStdCS = FALSE,
- CPDF_Type3Char* pType3Char = nullptr,
- FX_ARGB fill_color = 0,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE);
- void RenderObjectList(const CPDF_PageObjectHolder* pObjectHolder,
- const CFX_Matrix* pObj2Device);
- void RenderSingleObject(CPDF_PageObject* pObj, const CFX_Matrix* pObj2Device);
- FX_BOOL ContinueSingleObject(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- IFX_Pause* pPause);
- CPDF_RenderContext* GetContext() { return m_pContext; }
-
-#if defined _SKIA_SUPPORT_
- void DebugVerifyDeviceIsPreMultiplied() const;
-#endif
-
- CPDF_RenderOptions m_Options;
- CPDF_Dictionary* m_pFormResource;
- CPDF_Dictionary* m_pPageResource;
- CFX_ArrayTemplate<CPDF_Type3Font*> m_Type3FontCache;
-
- protected:
- friend class CPDF_ImageRenderer;
- friend class CPDF_RenderContext;
-
- void ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_Matrix* pObj2Device);
- void DrawClipPath(CPDF_ClipPath ClipPath, const CFX_Matrix* pObj2Device);
- FX_BOOL ProcessTransparency(CPDF_PageObject* PageObj,
- const CFX_Matrix* pObj2Device);
- void ProcessObjectNoClip(CPDF_PageObject* PageObj,
- const CFX_Matrix* pObj2Device);
- void DrawObjWithBackground(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device);
- FX_BOOL DrawObjWithBlend(CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device);
- FX_BOOL ProcessPath(CPDF_PathObject* pPathObj, const CFX_Matrix* pObj2Device);
- void ProcessPathPattern(CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- int& filltype,
- FX_BOOL& bStroke);
- void DrawPathWithPattern(CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- const CPDF_Color* pColor,
- FX_BOOL bStroke);
- void DrawTilingPattern(CPDF_TilingPattern* pPattern,
- CPDF_PageObject* pPageObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke);
- void DrawShadingPattern(CPDF_ShadingPattern* pPattern,
- const CPDF_PageObject* pPageObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke);
- FX_BOOL SelectClipPath(const CPDF_PathObject* pPathObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStroke);
- FX_BOOL ProcessImage(CPDF_ImageObject* pImageObj,
- const CFX_Matrix* pObj2Device);
- FX_BOOL OutputBitmapAlpha(CPDF_ImageObject* pImageObj,
- const CFX_Matrix* pImage2Device);
- FX_BOOL OutputImage(CPDF_ImageObject* pImageObj,
- const CFX_Matrix* pImage2Device);
- FX_BOOL OutputDIBSource(const CFX_DIBSource* pOutputBitmap,
- FX_ARGB fill_argb,
- int bitmap_alpha,
- const CFX_Matrix* pImage2Device,
- CPDF_ImageCacheEntry* pImageCache,
- uint32_t flags);
- void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
- int left,
- int top,
- FX_ARGB mask_argb,
- int bitmap_alpha,
- int blend_mode,
- int bIsolated);
- void ProcessShading(const CPDF_ShadingObject* pShadingObj,
- const CFX_Matrix* pObj2Device);
- void DrawShading(CPDF_ShadingPattern* pPattern,
- CFX_Matrix* pMatrix,
- FX_RECT& clip_rect,
- int alpha,
- FX_BOOL bAlphaMode);
- FX_BOOL ProcessType3Text(CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device);
- FX_BOOL ProcessText(CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device,
- CFX_PathData* pClippingPath);
- void DrawTextPathWithPattern(const CPDF_TextObject* textobj,
- const CFX_Matrix* pObj2Device,
- CPDF_Font* pFont,
- FX_FLOAT font_size,
- const CFX_Matrix* pTextMatrix,
- FX_BOOL bFill,
- FX_BOOL bStroke);
- FX_BOOL ProcessForm(const CPDF_FormObject* pFormObj,
- const CFX_Matrix* pObj2Device);
- CFX_DIBitmap* GetBackdrop(const CPDF_PageObject* pObj,
- const FX_RECT& rect,
- int& left,
- int& top,
- FX_BOOL bBackAlphaRequired);
- CFX_DIBitmap* LoadSMask(CPDF_Dictionary* pSMaskDict,
- FX_RECT* pClipRect,
- const CFX_Matrix* pMatrix);
- void Init(CPDF_RenderContext* pParent);
- static class CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont);
- static CPDF_GraphicStates* CloneObjStates(const CPDF_GraphicStates* pPathObj,
- FX_BOOL bStroke);
- CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObject) const;
- FX_ARGB GetFillArgb(CPDF_PageObject* pObj, FX_BOOL bType3 = FALSE) const;
- FX_ARGB GetStrokeArgb(CPDF_PageObject* pObj) const;
- FX_BOOL GetObjectClippedRect(const CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bLogical,
- FX_RECT& rect) const;
- void GetScaledMatrix(CFX_Matrix& matrix) const;
-
- static const int kRenderMaxRecursionDepth = 64;
- static int s_CurrentRecursionDepth;
-
- CPDF_RenderContext* m_pContext;
- FX_BOOL m_bStopped;
- CFX_RenderDevice* m_pDevice;
- CFX_Matrix m_DeviceMatrix;
- CPDF_ClipPath m_LastClipPath;
- const CPDF_PageObject* m_pCurObj;
- const CPDF_PageObject* m_pStopObj;
- CPDF_GraphicStates m_InitialStates;
- int m_HalftoneLimit;
- std::unique_ptr<CPDF_ImageRenderer> m_pImageRenderer;
- FX_BOOL m_bPrint;
- int m_Transparency;
- FX_BOOL m_bDropObjects;
- FX_BOOL m_bStdCS;
- uint32_t m_GroupFamily;
- FX_BOOL m_bLoadMask;
- CPDF_Type3Char* m_pType3Char;
- FX_ARGB m_T3FillColor;
- int m_curBlend;
-};
-
-class CPDF_ImageLoader {
- public:
- CPDF_ImageLoader()
- : m_pBitmap(nullptr),
- m_pMask(nullptr),
- m_MatteColor(0),
- m_bCached(FALSE),
- m_nDownsampleWidth(0),
- m_nDownsampleHeight(0) {}
- ~CPDF_ImageLoader();
-
- FX_BOOL Start(const CPDF_ImageObject* pImage,
- CPDF_PageRenderCache* pCache,
- std::unique_ptr<CPDF_ImageLoaderHandle>* pLoadHandle,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t nDownsampleWidth = 0,
- int32_t nDownsampleHeight = 0);
- FX_BOOL Continue(CPDF_ImageLoaderHandle* LoadHandle, IFX_Pause* pPause);
-
- CFX_DIBSource* m_pBitmap;
- CFX_DIBSource* m_pMask;
- uint32_t m_MatteColor;
- FX_BOOL m_bCached;
-
- protected:
- int32_t m_nDownsampleWidth;
- int32_t m_nDownsampleHeight;
-};
-
-class CPDF_ImageLoaderHandle {
- public:
- CPDF_ImageLoaderHandle();
- ~CPDF_ImageLoaderHandle();
-
- FX_BOOL Start(CPDF_ImageLoader* pImageLoader,
- const CPDF_ImageObject* pImage,
- CPDF_PageRenderCache* pCache,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t nDownsampleWidth = 0,
- int32_t nDownsampleHeight = 0);
- FX_BOOL Continue(IFX_Pause* pPause);
-
- protected:
- void HandleFailure();
-
- CPDF_ImageLoader* m_pImageLoader;
- CPDF_PageRenderCache* m_pCache;
- CPDF_ImageObject* m_pImage;
- int32_t m_nDownsampleWidth;
- int32_t m_nDownsampleHeight;
-};
-
-class CPDF_ImageRenderer {
- public:
- CPDF_ImageRenderer();
- ~CPDF_ImageRenderer();
-
- FX_BOOL Start(CPDF_RenderStatus* pStatus,
- CPDF_PageObject* pObj,
- const CFX_Matrix* pObj2Device,
- FX_BOOL bStdCS,
- int blendType = FXDIB_BLEND_NORMAL);
- FX_BOOL Continue(IFX_Pause* pPause);
-
- FX_BOOL Start(CPDF_RenderStatus* pStatus,
- const CFX_DIBSource* pDIBSource,
- FX_ARGB bitmap_argb,
- int bitmap_alpha,
- const CFX_Matrix* pImage2Device,
- uint32_t flags,
- FX_BOOL bStdCS,
- int blendType = FXDIB_BLEND_NORMAL);
-
- FX_BOOL m_Result;
-
- protected:
- FX_BOOL StartBitmapAlpha();
- FX_BOOL StartDIBSource();
- FX_BOOL StartRenderDIBSource();
- FX_BOOL StartLoadDIBSource();
- FX_BOOL DrawMaskedImage();
- FX_BOOL DrawPatternImage(const CFX_Matrix* pObj2Device);
-
- CPDF_RenderStatus* m_pRenderStatus;
- CPDF_ImageObject* m_pImageObject;
- int m_Status;
- const CFX_Matrix* m_pObj2Device;
- CFX_Matrix m_ImageMatrix;
- CPDF_ImageLoader m_Loader;
- const CFX_DIBSource* m_pDIBSource;
- std::unique_ptr<CFX_DIBitmap> m_pClone;
- int m_BitmapAlpha;
- FX_BOOL m_bPatternColor;
- CPDF_Pattern* m_pPattern;
- FX_ARGB m_FillArgb;
- uint32_t m_Flags;
- std::unique_ptr<CFX_ImageTransformer> m_pTransformer;
- void* m_DeviceHandle;
- std::unique_ptr<CPDF_ImageLoaderHandle> m_LoadHandle;
- FX_BOOL m_bStdCS;
- int m_BlendType;
-};
-
-class CPDF_ScaledRenderBuffer {
- public:
- CPDF_ScaledRenderBuffer();
- ~CPDF_ScaledRenderBuffer();
-
- FX_BOOL Initialize(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- const FX_RECT& pRect,
- const CPDF_PageObject* pObj,
- const CPDF_RenderOptions* pOptions = nullptr,
- int max_dpi = 0);
- CFX_RenderDevice* GetDevice() {
- return m_pBitmapDevice ? m_pBitmapDevice.get() : m_pDevice;
- }
- CFX_Matrix* GetMatrix() { return &m_Matrix; }
- void OutputToDevice();
-
- private:
- CFX_RenderDevice* m_pDevice;
- CPDF_RenderContext* m_pContext;
- FX_RECT m_Rect;
- const CPDF_PageObject* m_pObject;
- std::unique_ptr<CFX_FxgeDevice> m_pBitmapDevice;
- CFX_Matrix m_Matrix;
-};
-
-class CPDF_DeviceBuffer {
- public:
- CPDF_DeviceBuffer();
- ~CPDF_DeviceBuffer();
- FX_BOOL Initialize(CPDF_RenderContext* pContext,
- CFX_RenderDevice* pDevice,
- FX_RECT* pRect,
- const CPDF_PageObject* pObj,
- int max_dpi = 0);
- void OutputToDevice();
- CFX_DIBitmap* GetBitmap() const { return m_pBitmap.get(); }
- const CFX_Matrix* GetMatrix() const { return &m_Matrix; }
-
- private:
- CFX_RenderDevice* m_pDevice;
- CPDF_RenderContext* m_pContext;
- FX_RECT m_Rect;
- const CPDF_PageObject* m_pObject;
- std::unique_ptr<CFX_DIBitmap> m_pBitmap;
- CFX_Matrix m_Matrix;
-};
-
-class CPDF_ImageCacheEntry {
- public:
- CPDF_ImageCacheEntry(CPDF_Document* pDoc, CPDF_Stream* pStream);
- ~CPDF_ImageCacheEntry();
-
- void Reset(const CFX_DIBitmap* pBitmap);
- FX_BOOL GetCachedBitmap(CFX_DIBSource*& pBitmap,
- CFX_DIBSource*& pMask,
- uint32_t& MatteColor,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t downsampleWidth = 0,
- int32_t downsampleHeight = 0);
- uint32_t EstimateSize() const { return m_dwCacheSize; }
- uint32_t GetTimeCount() const { return m_dwTimeCount; }
- CPDF_Stream* GetStream() const { return m_pStream; }
- void SetTimeCount(uint32_t dwTimeCount) { m_dwTimeCount = dwTimeCount; }
- int m_dwTimeCount;
-
- public:
- int StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE,
- CPDF_RenderStatus* pRenderStatus = nullptr,
- int32_t downsampleWidth = 0,
- int32_t downsampleHeight = 0);
- int Continue(IFX_Pause* pPause);
- CFX_DIBSource* DetachBitmap();
- CFX_DIBSource* DetachMask();
- CFX_DIBSource* m_pCurBitmap;
- CFX_DIBSource* m_pCurMask;
- uint32_t m_MatteColor;
- CPDF_RenderStatus* m_pRenderStatus;
-
- protected:
- void ContinueGetCachedBitmap();
-
- CPDF_Document* m_pDocument;
- CPDF_Stream* m_pStream;
- CFX_DIBSource* m_pCachedBitmap;
- CFX_DIBSource* m_pCachedMask;
- uint32_t m_dwCacheSize;
- void CalcSize();
-};
-typedef struct {
- FX_FLOAT m_DecodeMin;
- FX_FLOAT m_DecodeStep;
- int m_ColorKeyMin;
- int m_ColorKeyMax;
-} DIB_COMP_DATA;
-
-class CPDF_DIBSource : public CFX_DIBSource {
- public:
- CPDF_DIBSource();
- ~CPDF_DIBSource() override;
-
- FX_BOOL Load(CPDF_Document* pDoc,
- const CPDF_Stream* pStream,
- CPDF_DIBSource** ppMask,
- uint32_t* pMatteColor,
- CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE);
-
- // CFX_DIBSource
- FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) const override;
- uint8_t* GetBuffer() const override;
- const uint8_t* GetScanline(int line) const override;
- void DownSampleScanline(int line,
- uint8_t* dest_scan,
- int dest_bpp,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const override;
-
- CFX_DIBitmap* GetBitmap() const;
- void ReleaseBitmap(CFX_DIBitmap* pBitmap) const;
- uint32_t GetMatteColor() const { return m_MatteColor; }
-
- int StartLoadDIBSource(CPDF_Document* pDoc,
- const CPDF_Stream* pStream,
- FX_BOOL bHasMask,
- CPDF_Dictionary* pFormResources,
- CPDF_Dictionary* pPageResources,
- FX_BOOL bStdCS = FALSE,
- uint32_t GroupFamily = 0,
- FX_BOOL bLoadMask = FALSE);
- int ContinueLoadDIBSource(IFX_Pause* pPause);
- int StratLoadMask();
- int StartLoadMaskDIB();
- int ContinueLoadMaskDIB(IFX_Pause* pPause);
- int ContinueToLoadMask();
- CPDF_DIBSource* DetachMask();
-
- private:
- bool LoadColorInfo(const CPDF_Dictionary* pFormResources,
- const CPDF_Dictionary* pPageResources);
- DIB_COMP_DATA* GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode,
- FX_BOOL& bColorKey);
- CPDF_DIBSource* LoadMask(uint32_t& MatteColor);
- CPDF_DIBSource* LoadMaskDIB(CPDF_Stream* pMask);
- void LoadJpxBitmap();
- void LoadPalette();
- int CreateDecoder();
- void TranslateScanline24bpp(uint8_t* dest_scan,
- const uint8_t* src_scan) const;
- void ValidateDictParam();
- void DownSampleScanline1Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const;
- void DownSampleScanline8Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const;
- void DownSampleScanline32Bit(int orig_Bpp,
- int dest_Bpp,
- uint32_t src_width,
- const uint8_t* pSrcLine,
- uint8_t* dest_scan,
- int dest_width,
- FX_BOOL bFlipX,
- int clip_left,
- int clip_width) const;
- FX_BOOL TransMask() const;
-
- CPDF_Document* m_pDocument;
- const CPDF_Stream* m_pStream;
- std::unique_ptr<CPDF_StreamAcc> m_pStreamAcc;
- const CPDF_Dictionary* m_pDict;
- CPDF_ColorSpace* m_pColorSpace;
- uint32_t m_Family;
- uint32_t m_bpc;
- uint32_t m_bpc_orig;
- uint32_t m_nComponents;
- uint32_t m_GroupFamily;
- uint32_t m_MatteColor;
- FX_BOOL m_bLoadMask;
- FX_BOOL m_bDefaultDecode;
- FX_BOOL m_bImageMask;
- FX_BOOL m_bDoBpcCheck;
- FX_BOOL m_bColorKey;
- FX_BOOL m_bHasMask;
- FX_BOOL m_bStdCS;
- DIB_COMP_DATA* m_pCompData;
- uint8_t* m_pLineBuf;
- uint8_t* m_pMaskedLine;
- std::unique_ptr<CFX_DIBitmap> m_pCachedBitmap;
- std::unique_ptr<CCodec_ScanlineDecoder> m_pDecoder;
- CPDF_DIBSource* m_pMask;
- std::unique_ptr<CPDF_StreamAcc> m_pGlobalStream;
- std::unique_ptr<CCodec_Jbig2Context> m_pJbig2Context;
- CPDF_Stream* m_pMaskStream;
- int m_Status;
-};
-
-#define FPDF_HUGE_IMAGE_SIZE 60000000
-class CPDF_DIBTransferFunc : public CFX_FilteredDIB {
- public:
- explicit CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc);
- ~CPDF_DIBTransferFunc() override;
-
- // CFX_FilteredDIB
- FXDIB_Format GetDestFormat() override;
- FX_ARGB* GetDestPalette() override;
- void TranslateScanline(const uint8_t* src_buf,
- std::vector<uint8_t>* dest_buf) const override;
- void TranslateDownSamples(uint8_t* dest_buf,
- const uint8_t* src_buf,
- int pixels,
- int Bpp) const override;
-
- const uint8_t* m_RampR;
- const uint8_t* m_RampG;
- const uint8_t* m_RampB;
-};
-
-#endif // CORE_FPDFAPI_FPDF_RENDER_RENDER_INT_H_