/**
 * Copyright (C) 2003-2026, Foxit Software Inc..
 * All Rights Reserved.
 *
 * http://www.foxitsoftware.com
 *
 * The following code is copyrighted and is the proprietary of Foxit Software Inc.. It is not allowed to
 * distribute any parts of Foxit PDF SDK to third party or public without permission unless an agreement
 * is signed between Foxit Software Inc. and customers to explicitly grant customers permissions.
 *
 * @file fs_render.h
 * @brief Header file for rendering related definitions and classes.
 */

#ifndef FS_RENDER_H_
#define FS_RENDER_H_

#include "common/fs_common.h"
#include "common/fs_image.h"
#include "pdf/annots/fs_annot.h"
#include "pdf/fs_pdflayer.h"
#include "pdf/fs_reflowpage.h"
#ifndef _FX_NO_XFA_
#include "addon/xfa/fs_xfa.h"
#endif  // #ifndef _FX_NO_XFA_

#ifdef __APPLE__
#include <CoreGraphics/CoreGraphics.h>
#endif
/**
 * @brief Foxit namespace.
 *
 * @details All the definitions and classes of Foxit PDF SDK are defined within this namespace.
 */
namespace foxit {
namespace pdf {
class PDFPage;
}
namespace ofd {
class OFDPage;
};
namespace fld {
class FLDPage;
};
/**
 * @brief Common namespace.
 */
namespace common {
/**
 * This class represents setting data for print device. This would be used in class @link Renderer @endlink.
 *
 * @see @link Renderer @endlink
 */
class PrintDeviceSettingData FS_FINAL : public Object{
 public:
 /**
  * @brief Enumeration for specifying the orientation of the printer.
  *
  * @details Values of this enumeration should be used alone.
  */
 typedef enum _OrientationFlag {
   /** @brief Portrait orientation for printing. */
   e_Portrait  = 0,
   /** @brief Landscape orientation for printing */
   e_Landscape = 1
 } OrientationFlag;
 
  /**
   * @brief Constructor, with parameters.
   *
   * @param[in] device_width   The width of the device in pixels.
   * @param[in] device_height  The height of the device in pixels.
   * @param[in] device_margin  The page margins of the device. it does not represent a rectangle. It just defines the left margin, bottom margin,
   *                           right margin and top margin of the device.
   * @param[in] orientation    Orientation flag. Please refer to values starting from @link OrientationFlag::e_Portrait @endlink
   *                           and this should be one of these values.
   * @param[in] resolution     The resolution of the device in pixels per inch.
   * @param[in] copies         The number of copies to be printed. This parameter only has an effect on PostScrip files.
   */
  explicit PrintDeviceSettingData(int device_width, int device_height, RectF device_margin, OrientationFlag orientation , int resolution, uint32 copies)
    : device_width(device_width)
    , device_height(device_height)
    , device_margin(device_margin)
    , orientation(orientation)
    , resolution(resolution)
    , copies(copies){}

  /**
   * @brief Constructor and set the default value.
   *
   * @details By default, the pixel value of an A4 paper is set to 300 dpi (dots per inch).
   *
   */
  PrintDeviceSettingData()
    : device_width(2479)
    , device_height(3508)
    , orientation(e_Portrait)
    , resolution(300)
    , copies(1) {}

  /**
   * @brief Constructor, with another print device setting data object.
   *
   * @param[in] settings  Another print device settings object.
   */
  PrintDeviceSettingData(const PrintDeviceSettingData& settings)
      : device_width(settings.device_width)
      , device_height(settings.device_height)
      , device_margin(settings.device_margin)
      , orientation(settings.orientation)
      , resolution(settings.resolution)
      , copies(settings.copies) {}

  /**
   * @brief Assign operator.
   *
   * @param[in] settings  Another print device setting data object, whose value would be assigned to current object.
   *
   * @return Reference to current object itself.
   */
  PrintDeviceSettingData& operator = (const PrintDeviceSettingData& settings) {
    device_width = settings.device_width;
    device_height = settings.device_height;
    device_margin = settings.device_margin;
    orientation = settings.orientation;
    resolution = settings.resolution;
    copies = settings.copies;
    return *this;
  }

  /**
   * @brief Set value.
   *
   * @param[in] device_width   The width of the device in pixels.
   * @param[in] device_height  The height of the device in pixels.
   * @param[in] device_margin  The page margins of the device. it does not represent a rectangle. It just defines the left margin, bottom margin,
   *                           right margin and top margin of the device.
   * @param[in] orientation    Orientation flag. Please refer to values starting from @link OrientationFlag::e_Portrait @endlink
   *                           and this should be one of these values.
   * @param[in] resolution     The resolution of the device in pixels per inch.
   * @param[in] copies         The number of copies to be printed. This parameter only has an effect on PostScrip files.
   *
   * @return None.
   */
   void Set(int device_width, int device_height, RectF device_margin, OrientationFlag orientation, int resolution, uint32 copies ) {
     this->device_width = device_width;
     this->device_height = device_height;
     this->device_margin = device_margin;
     this->orientation = orientation;
     this->resolution = resolution;
     this->copies = copies;
   }
  /** @brief The width of the device in pixels.*/
    int device_width;
  /** @brief The height of the device in pixels.*/
    int device_height;
  /**
   * @brief The page margins of the device.
   *
   * @note This value does not represent a rectangle. It just defines the left margin, bottom margin,
   *       right margin and top margin of the device. The value should not be negative.
   */
    RectF device_margin;
  /**
   * @brief Orientation flag. Please refer to values starting from @link OrientationFlag::e_Portrait @endlink
   *        and this should be one of these values.
   */
    OrientationFlag orientation;
  /** @brief The resolution of the device in pixels per inch. */
    int resolution;
  /** @brief The number of copies to be printed. This parameter only has an effect on PostScrip files.*/
    uint32 copies;
};

/**
 * PDF renderer is a graphics engine and is used to render page to a bitmap or a platform device context.
 * This class can be constructed with a bitmap, or a device object. It offers functions to set rendering options/flags,
 * and do rendering. In this class, there are several ways to do rendering:
 * <ul>
 * <li>To render page and annotations, first use function @link Renderer::SetRenderContentFlags @endlink to
 *     decide whether to render page and annotation both or not, and then use functions
 *     @link Renderer::StartRender @endlink to do the rendering.
 *     Function @link Renderer::StartQuickRender @endlink can also be used to render page but only for thumbnail purpose.
 * </li>
 * <li>To render a single annotation, use function @link Renderer::RenderAnnot @endlink.</li>
 * <li>To render a bitmap, use function @link Renderer::StartRenderBitmap @endlink.</li>
 * <li>To render a reflow page, use function @link Renderer::StartRenderReflowPage @endlink.</li>
 * </ul>
 * Widget annotation is always associated with form field and form control in Foxit PDF SDK. For how to render
 * widget annotations, here is a recommended flow:
 * <ul>
 * <li>After loading a PDF page, first render the page and all annotations in this page (including widget annotations).</li>
 * <li>Then, if user uses @link pdf::interform::Filler @endlink object to fill the form, user should use function
 *     @link pdf::interform::Filler::Render @endlink to render the focused form control instead of using function
 *     @link Renderer::RenderAnnot @endlink.</li>
 * </ul>
 *
 * @see @link pdf::interform::Filler @endlink
 */

class Renderer FS_FINAL : public Base {
 public:
  /**
   * @brief Enumeration for rendering color mode.
   *
   * @details Values of this enumeration should be used alone.
   */
  typedef enum _ColorMode {
    /** @brief Normal color mode. */
    e_ColorModeNormal = 0,
    /** @brief Map gray/white/black color value to background/foreground; for other colors, no change. */
    e_ColorModeMappingGray = 1,
    /** @brief Map a color value to the color range defined by a background color and a foreground color. */
    e_ColorModeMapping = 2,
    /** @brief Output alpha only, ignore color. */
    e_ColorModeAlpha = 3,
    /** @brief Custom color mode. map colors to foreground. */
    e_ColorModeForeground = 4
  } ColorMode;
  
  /**
   * @brief Enumeration for rendering content flags.
   *
   * @details Values of this enumeration can be used alone or in combination.
   */
  typedef enum _ContentFlag {
    /** @brief If set, page content will be rendered. */
    e_RenderPage = 0x01,
    /** @brief If set, annotations will be rendered. */
    e_RenderAnnot = 0x02,
    /** @brief If set, only highlight annotations will be rendered. */
    e_RenderHighlight = 0x04,
    /** @brief If set, all annotations expect highlight will be rendered. */
    e_RenderExceptHighlight = 0x08,
    /** @brief If set, only screen annotations will be rendered. */
    e_RenderScreen = 0x10
  } ContentFlag;
  
  /**
   * @brief Enumeration for rendering foreground color mode.
   *
   * @details Values of this enumeration can be used alone or in combination.
   */
  typedef enum _ColorModeForeground {
    /** @brief If set, the color of text need to be replaced. */
    e_ColorModeForegroundText = 0x01,
    /** @brief If set, the color of path need to be replaced. */
    e_ColorModeForegroundPath = 0x02,
    /** @brief If set, only the black color of text need to be replaced. */
    e_ColorModeForegroundBlackText = 0x04,
    /** @brief If set, only the black color of path need to be replaced. */
    e_ColorModeForegroundBlackPath = 0x08
  } ColorModeForeground;
  
  #ifdef __APPLE__
  /**
   * @brief Enumeration for rendering device type.
   *
   * @details Values of this enumeration should be used alone.
   */
  typedef enum _DeviceType {
  /** @brief Device type: display device. */
    e_DeviceDisplay = 1,
    /** @brief Device type: printer. */
    e_DevicePrinter = 2
  }DeviceType;
  #endif
  /**
   * @brief Constructor, with bitmap.
   *
   * @details The input bitmap is treated as an independent device and all the content rendered by the renderer
   *          would appear in the bitmap.
   *
   * @param[in] bitmap        A bitmap used for rendering. User should ensure the bitmap to keep valid until
   *                          the end of life cycle of current renderer object.
   * @param[in] is_rgb_order  <b>true</b> means Foxit PDF SDK needs to use RGB byte-order
   *                          (Red is in the lowest order) when rendering. <br>
   *                          <b>false</b> means Foxit PDF SDK needs to use BGR byte-order
   *                          (Blue is in the lowest order) when rendering.
   */
  Renderer(const Bitmap& bitmap, bool is_rgb_order);

  /**
   * @brief Constructor for printing, with specified print device setting data.
   *
   * @details All the content rendered by the renderer would appear in the PDF file or PostScrip file.
   *          Generating PS files is only supported on Linux systems.
   *
   * @param[in] print_param     Setting data used to print device.
   * @param[in] dest_file_path  The path to generate the printed PDF file or PostScrip file. If this path
   *                            is a PDF file path, please ensure Foxit PDF SDK has been initialized successfully
   *                            by function @link common::Library::Initialize @endlink with a key including
   *                            "Print2PDF" module.
   */
  Renderer(const PrintDeviceSettingData& print_param, const wchar_t* dest_file_path);

#if (defined(_WIN32) || defined(_WIN64)) && (!defined(SWIG) || defined(_SWIG_DOTNET_) || defined(_SWIG_PYTHON_))
  /**
   * @brief Constructor, with specified device object.
   *
   * @details All the content rendered by the renderer would appear in the input device object.
   *
   * @param[in] dc  A handle of DC.
   */
  explicit Renderer(HDC dc);

  /**
   * @brief Constructor for printing, with specified printer device object and printer driver name.
   *
   * @details All the content rendered by the renderer would appear in the input device object.
   *
   * @param[in] dc                   A handle of DC which is used for printing.
   * @param[in] printer_driver_name  Printer driver name. This should represent a valid printer driver and
   *                                 should not be an empty string.
   */
  Renderer(HDC dc, const wchar_t* printer_driver_name);
#endif

#ifdef __APPLE__
  /**
   * @brief Constructor, with device context.
   *
   * @details All the content rendered by the renderer would appear in CGContextRef object.
   *
   * @param[in] context      A CGContextRef object. User should ensure the device to keep valid until the end of
   *                         life cycle of current renderer object.
   * @param[in] device_type  The device type of parameter <i>context</i>. Please refer to values starting from
   *                         @link Renderer::e_DeviceDisplay @endlink and this should be one of these values.
   */
  Renderer(const CGContextRef& context, DeviceType device_type);
#endif

  /**
   * @brief Constructor, with another renderer object.
   *
   * @param[in] other  Another renderer object.
   */
  Renderer(const Renderer& other);
  /** @brief Destructor. */
  ~Renderer();

  /**
   * @brief Assign operator.
   *
   * @param[in] other  Another renderer object, whose value would be assigned to current object.
   *
   * @return Reference to current object itself.
   */
  Renderer& operator = (const Renderer& other);
  /**
   * @brief Equal operator.
   *
   * @param[in] other  Another renderer object. This function will check if current object is equal to this one.
   *
   * @return <b>true</b> means equal, while <b>false</b> means not equal.
   */
  bool operator == (const Renderer& other) const;
  /**
   * @brief Not equal operator.
   *
   * @param[in] other  Another renderer object. This function will check if current object is not equal to this one.
   *
   * @return <b>true</b> means not equal, while <b>false</b> means equal.
   */
  bool operator != (const Renderer& other) const;

  /**
   * @brief Check whether current object is empty or not.
   *
   * @details When the current object is empty, that means current object is useless.
   *
   * @return <b>true</b> means current object is empty, while <b>false</b> means not.
   */
  bool IsEmpty() const;

  /**
   * @brief Start to quickly render a PDF page, mainly for thumbnail purpose.
   *
   * @details This function is mainly used for render a page for thumbnail purpose.
   *          The rendered content will not be completed: all the annotations will be ignored, event if
   *          flag @link Renderer::e_RenderAnnot @endlink is set by function
   *          @link Renderer::SetRenderContentFlags @endlink; text content will become blurred and
   *          will be replace by pixel point.<br>
   *          It may still take a long time to do this quick rendering when page has complex or large contents,
   *          so Foxit PDF SDK uses a progressive process to do this.
   *
   * @param[in] page    A valid PDF page. It should have been parsed.
   * @param[in] matrix  The transformation matrix used for rendering, which is usually returned by function
   *                    @link pdf::PDFPage::GetDisplayMatrix @endlink.
   * @param[in] pause   Pause callback object which decides if the rendering process needs to be paused.
   *                    This can be <b>NULL</b> which means not to pause during the rendering process.
   *                    If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *                    Default value: <b>NULL</b>.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartQuickRender(const pdf::PDFPage& page, const Matrix& matrix, PauseCallback* pause = NULL);

 /**
   * @brief Start to render a PDF page.
   *
   * @details It may take a long time to render a PDF page with complex or large contents, so Foxit PDF SDK uses
   *          a progressive process to do this.<br>
   *          Widget annotation is always associated with form field and form control in Foxit PDF SDK. For how to
   *          render widget annotations, here is a recommended flow:
   *          <ul>
   *          <li>After loading a PDF page, first render the page and all annotations in this page
   *              (including widget annotations).</li>
   *          <li>Then, if user uses @link pdf::interform::Filler @endlink object to fill the form, user should use function
   *              @link pdf::interform::Filler::Render @endlink to render the focused form control instead of using
   *              function @link Renderer::RenderAnnot @endlink.</li>
   *          </ul>
   *
   * @param[in] page    A valid PDF page. If only to render annotations (that means only
   *                    @link Renderer::e_RenderAnnot @endlink is set by function
   *                    @link Renderer::SetRenderContentFlags @endlink), there is no need to parse the input page;
   *                    otherwise the input page should have been parsed.
   * @param[in] matrix  The transformation matrix used for rendering, which is usually returned by function
   *                    @link pdf::PDFPage::GetDisplayMatrix @endlink.
   * @param[in] pause   Pause callback object which decides if the rendering process needs to be paused.
   *                    This can be <b>NULL</b> which means not to pause during the rendering process.
   *                    If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *                    Default value: <b>NULL</b>.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartRender(const pdf::PDFPage& page, const Matrix& matrix, PauseCallback* pause = NULL);

  /**
   * @brief Start to render a reflow page.
   *
   * @details It may take a long time to render a reflow page with complex or large contents, so Foxit PDF SDK uses
   *          a progressive process to do this.
   *
   * @param[in] reflow_page  A valid reflow page. It should have been parsed.
   * @param[in] matrix       The transformation matrix used for rendering, which is usually returned by function
   *                         @link pdf::ReflowPage::GetDisplayMatrix @endlink.
   * @param[in] pause        Pause callback object which decides if the rendering process needs to be paused.
   *                         This can be <b>NULL</b> which means not to pause during the rendering process.
   *                         If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *                         Default value:<b>NULL</b>.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartRenderReflowPage(const pdf::ReflowPage& reflow_page, const Matrix& matrix,
                                    PauseCallback* pause = NULL);

#ifndef _FX_NO_XFA_
  /**
   * @brief Start to render an XFA page.
   *
   * @details It will take a long time to render an XFA page with complex or large contents, so Foxit PDF SDK uses
   *          a progressive process to do this.
   *
   * @param[in] xfa_page_view  A valid XFA page.
   * @param[in] matrix         The transformation matrix used for rendering, which is usually returned by function
   *                           @link addon::xfa::XFAPage::GetDisplayMatrix @endlink.
   * @param[in] is_highlight   <b>true</b> means to highlight XFA widgets, and <b>false</b> means not to highlight
   *                           XFA widgets.
   * @param[in] pause          Pause callback object which decides if the rendering process needs to be paused.
   *                           This can be <b>NULL</b> which means not to pause during the rendering process.
   *                           If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *                           Default value: <b>NULL</b>.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartRenderXFAPage(const addon::xfa::XFAPage& xfa_page_view, const Matrix& matrix, bool is_highlight,
                                 PauseCallback* pause = NULL);
#endif  // #ifndef _FX_NO_XFA_

  /**
   * @brief Start to render a bitmap.
   *
   * @details It may take a long time to render a bitmap with complex or large contents, so Foxit PDF SDK uses
   *          a progressive process to do this.
   *
   * @param[in] bitmap         A valid bitmap. User should ensure the bitmap to keep valid until
   *                           current rendering process is finished.
   * @param[in] matrix         The transformation matrix used for rendering. This matrix is used as image matrix:<br>
   *                           assume that <i>h</i> is image height, <i>w</i> is image width, and then matrix
   *                           [w 0 0 h 0 0] will produce an identical image.
   * @param[in] clip_rect      Clip rectangle for the rendering device. This can be <b>NULL</b>.
   *                           Default value: <b>NULL</b>.
   * @param[in] interpolation  Bitmap interpolation flags. Please refer to values starting from
   *                           @link Bitmap::e_Downsample @endlink and this can be one or a combination of these values.
   *                           If not specify any flag, please use 0. Default value: 0.
   * @param[in] pause          Pause callback object which decides if the rendering process needs to be paused.
   *                           This can be <b>NULL</b> which means not to pause during the rendering process.
   *                           If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *                           Default value: <b>NULL</b>.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartRenderBitmap(const Bitmap& bitmap, const Matrix& matrix,
                                const RectI* clip_rect = NULL, uint32 interpolation = 0,
                                PauseCallback* pause = NULL);

  /**
   * @brief Start to render a bitmap.
   *
   * @details It may take a long time to render a bitmap with complex or large contents, so Foxit PDF SDK uses
   *          a progressive process to do this.
   *
   * @param[in] bitmap         A valid bitmap. User should ensure the bitmap to keep valid until
   *                           current rendering process is finished.
   * @param[in] matrix         The transformation matrix used for rendering. This matrix is used as image matrix:<br>
   *                           assume that <i>h</i> is image height, <i>w</i> is image width, and then matrix
   *                           [w 0 0 h 0 0] will produce an identical image.
   * @param[in] clip_rect      Clip rectangle for the rendering device. This can be <b>NULL</b>.
   * @param[in] interpolation  Bitmap interpolation flags. Please refer to values starting from
   *                           @link Bitmap::e_Downsample @endlink and this can be one or a combination of these values.
   *                           If not specify any flag, please use 0.
   * @param[in] alpha          Bitmap alpha represents transparency (0 = fully transparent, 255 = fully opaque).
   *                           Valid range: from 0 to 255.
   * @param[in] pause          Pause callback object which decides if the rendering process needs to be paused.
   *                           This can be <b>NULL</b> which means not to pause during the rendering process.
   *                           If this is not <b>NULL</b>, it should be a valid pause object implemented by user.
   *
   * @return A progressive object. Please check the rate of current progress by function
   *         @link Progressive::GetRateOfProgress @endlink. If the rate is not 100 yet, call function
   *         @link Progressive::Continue @endlink to continue the progress until the progress is finished.
   */
  Progressive StartRenderBitmap(const Bitmap& bitmap, const Matrix& matrix,
                                const RectI* clip_rect, uint32 interpolation,
                                uint32 alpha, PauseCallback* pause);

  /**
   * @brief Set the annotation's appearance type for rendering.
   *
   * @param[in] ap_type  Type of annotation's appearance. Please refer to values starting from
   *                     @link pdf::annots::Annot::e_AppearanceTypeNormal @endlink and this should be one of these values.
   *
   * @return None.
   */
  void SetRenderAnnotAppearanceType(foxit::pdf::annots::Annot::AppearanceType ap_type);

  /**
   * @brief Render a specified annotation.
   *
   * @details When this function is called, rendering flag (set by function @link Renderer::SetRenderContentFlags @endlink or
   *          by default) will be ignored.
   *
   * @param[in] annot   An annotation object to be rendered. If input annot is a pop-up annotation, this function will
   *                    not render it and will return <b>false</b>.
   * @param[in] matrix  The transformation matrix used for rendering, which is usually returned by function
   *                    @link pdf::PDFPage::GetDisplayMatrix @endlink.
   *
   * @return <b>true</b> means success, while <b>false</b> means failure.
   */
  bool RenderAnnot(const pdf::annots::Annot& annot, const Matrix& matrix);

  /**
   * @brief Render form controls.
   *
   * @details When this function is called, rendering flag (set by function @link Renderer::SetRenderContentFlags @endlink
   *          or by default) will be ignored.
   *
   * @param[in] page    A valid PDF page. If input page is invalid, this function do nothing and return <b>false</b> directly.
   * @param[in] matrix  The transformation matrix used for rendering, which is usually returned by function
   *                    @link pdf::PDFPage::GetDisplayMatrix @endlink.
   *
   * @return <b>true</b> means success, while <b>false</b> means failure.
   */
  bool RenderFormControls(const pdf::PDFPage& page, const Matrix& matrix);

  /**
   * @brief Render a graphics object.
   *
   * @details When this function is called, rendering flag (set by function @link Renderer::SetRenderContentFlags @endlink or
   *          by default) will be ignored.
   *
   * @param[in] graphics_object  A valid PDF graphics object to be rendered.
   * @param[in] page             A valid PDF page. Parameter <i>graphics_object</i> belongs to this PDF page.
   * @param[in] matrix           The transformation matrix used for rendering, which is usually returned by function
   *                             @link pdf::PDFPage::GetDisplayMatrix @endlink.
   *
   * @return <b>true</b> means success, while <b>false</b> means failure.
   */
  bool RenderGraphicsObject(const pdf::graphics::GraphicsObject* graphics_object, const pdf::PDFPage& page, const Matrix& matrix);

  /**
   * @brief Set the clipping rectangle which will be used in subsequent rendering progress
   *
   * @param[in] clip_rect  A clipping rectangle. If it is <b>NULL</b>, that means not to use clipping rectangle in
   *                       subsequent rendering progress.
   *
   * @return None.
   */
  void SetClipRect(const RectI* clip_rect);

  /**
 * @brief Clear the clipping rectangle set by function @link Renderer::SetClipRect @endlink
 *
 * @return None.
 */
  void ClearClips();

  /**
   * @brief Set clipping path using filled region.
   *
   * @param[in] clip_path  A clipping path.
   * @param[in] matrix     The transformation matrix used for clipping.
   * @param[in] fill_mode  Fill mode. It should be value @link e_FillModeAlternate @endlink or
   *                       @link e_FillModeWinding @endlink.
   *
   * @return None.
   */
  void SetClipPathFill(const Path& clip_path, const Matrix& matrix, foxit::common::FillMode fill_mode);

  /**
   * @brief Set clipping path using stroked region.
   *
   * @param[in] clip_path    A clipping path.
   * @param[in] matrix       The transformation matrix used for clipping.
   * @param[in] graph_state  A valid graph state, for pen attributes. If this is <b>NULL</b>, Foxit PDF SDK will
   *                         use a graph state object with default constructor. Default value: <b>NULL</b>.
   *
   * @return None.
   */
  void SetClipPathStroke(const Path& clip_path, const Matrix& matrix, const GraphState* graph_state = NULL);

  /**
   * @brief Set rendering flag to decide what content will be rendered.
   *
   * @details If this function is not called, default value
   *          (@link Renderer::e_RenderPage @endlink | @link Renderer::e_RenderAnnot @endlink) will be used.
   *
   * @param[in] render_content_flags  Rendering content flags. Please refer to values starting from
   *                                  @link Renderer::e_RenderPage @endlink and this should be one or a combination of
   *                                  these values. The @link Renderer::e_RenderHighlight @endlink can not be combined with
   *                                  @link Renderer::e_RenderExceptHighlight @endlink.
   *
   * @return None.
   */
  void SetRenderContentFlags(uint32 render_content_flags);

  /**
   * @brief Set rendering flag to decide whether to render annotations in thumbnail mode or not.
   *
   * @details In thumbnail mode, the flags of annotations, "NoZoom" and "NoRotate", will be ignored.
   *          This rendering flag is available only when flag @link Renderer::e_RenderAnnot @endlink is used for rendering or
   *          function @link Renderer::RenderAnnot @endlink is called. Please refer to function @link Renderer::SetRenderContentFlags @endlink
   *          about setting flag @link Renderer::e_RenderAnnot @endlink.<br>
   *          If this function is not called, default value <b>false</b> will be used when this rendering flag is available.
   *
   * @param[in] is_render_annots_for_thumbnail  <b>true</b> means to render annotations in thumbnail mode.
   *                                            <b>false</b> means not to render annotations in thumbnail mode.
   *
   * @return None.
   */
  void SetRenderAnnotsForThumbnail(bool is_render_annots_for_thumbnail);

  /**
   * @brief Set the flag to decide whether to render form fields (except signature fields).
   *
   * @details If this function is not called, default value <b>true</b> will be used when this flag is available.
   *
   * @param[in] is_render_formfield  <b>true</b> means to render form fields (except signature fields).
   *                                 <b>false</b> means not to render form fields (except signature fields).
   *
   * @return None.
   */
  void SetRenderFormField(bool is_render_formfield);

  /**
   * @brief Set the flag to decide whether to render signatures or not.
   *
   * @details If this function is not called, default value <b>true</b> will be used when this flag is available.
   *
   * @param[in] is_render_signature  <b>true</b> means to render signatures.
   *                                 <b>false</b> means not to render signatures.
   *
   * @return None.
   */
  void SetRenderSignature(bool is_render_signature);

  /**
   * @brief Set layer context to render context handle.
   *
   * @details In order to render one layer when PDF page's contents is rendered on a rendering context,
   *          user should call this function to set the layer context to render context.
   *
   * @param[in] layer_context  A layer context object.
   *
   * @return None.
   */
  void SetLayerContext(const pdf::LayerContext& layer_context);

  /**
   * @brief Set the flag to decide whether to render one layer or all available layers.
   *
   * @details If this function is not called, default value <b>true</b> will be used when this flag is available.
   *
   * @param[in] is_render_one_layer  <b>true</b> means to render one layer.
   *                                 <b>false</b> means to render all available layers.
   *
   * @return None.
   */
  void SetRenderLayer(bool is_render_one_layer);

  /**
   * @brief Set color mode.
   *
   * @details If this function is not called, default value
   *          @link Renderer::e_ColorModeNormal @endlink will be used.
   *
   * @param[in] color_mode  Color mode value. It should be one of following values:
   *                        <ul>
   *                        <li>@link Renderer::e_ColorModeNormal @endlink means normal color mode.</li>
   *                        <li>@link Renderer::e_ColorModeMappingGray @endlink means to
   *                            map white/black color value to background/foreground; for other colors, no change.
   *                            If this mode is used, please call function
   *                            @link Renderer::SetMappingModeColors @endlink to set "background color" and
   *                            "foreground color".</li>
   *                        <li>@link Renderer::e_ColorModeMapping @endlink means to
   *                            map a color value to the color range defined by a background color and
   *                            a foreground color. If this mode is used, please call function
   *                            @link Renderer::SetMappingModeColors @endlink to set "background color" and
   *                            "foreground color".</li>
   *                        </ul>
   *
   * @return None.
   */
  void SetColorMode(ColorMode color_mode);
  /**
   * @brief Set background color and foreground color when color mode is @link Renderer::e_ColorModeMappingGray @endlink
   *        or @link Renderer::e_ColorModeMapping @endlink.
   *
   * @param[in] background_color  The background color. Format: 0xAARRGGBB.
   * @param[in] foreground_color  The foreground color. Format: 0xAARRGGBB.
   *
   * @return None.
   */
  void SetMappingModeColors(ARGB background_color, ARGB foreground_color);

  /**
   * @brief Set rendering foreground color mode when color mode is @link Renderer::e_ColorModeForeground @endlink.
   *
   * @details If this function is not called, default value
   *          (@link Renderer::e_ColorModeForegroundText @endlink | @link Renderer::e_ColorModeForegroundPath @endlink |
   *           @link Renderer::e_ColorModeForegroundBlackText @endlink | @link Renderer::e_ColorModeForegroundBlackPath @endlink) will be used.
   *
   * @param[in] foreground_color_mode  Rendering foreground color mode. Please refer to values starting from
   *                                   @link Renderer::e_ColorModeForegroundText @endlink and this should be one or a
   *                                   combination of these values.
   *
   * @return None.
   */
  void SetForegroundColorMode(uint32 foreground_color_mode);

  /**
   * @brief Set foreground color for text, path or both when color mode is @link Renderer::e_ColorModeForeground @endlink.
   *
   * @details The foreground color for text, path, or both is determined by the foreground color mode set by the
   *          function @link Renderer::SetForegroundColorMode @endlink.
   *
   * @param[in] foreground_color  The foreground color for text, path, or both. Format: 0xAARRGGBB.
   *
   * @return None.
   */
  void SetForegroundColor(ARGB foreground_color);

  /**
   * @brief Set the flag to decide whether to use ClearType-like anti-aliasing to render text objects.
   *
   * @details If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_clear_type  <b>true</b> means to use ClearType-like anti-aliasing to render text objects.
   *                           <b>false</b> means not to use ClearType-like anti-aliasing to render text objects.
   *
   * @return None.
   */
  void SetClearType(bool is_clear_type);
  /**
   * @brief Set the flag to decide whether to print text as path or bitmap.
   *
   * @details When this flag is <b>true</b>, Foxit PDF SDK will render text in different way:
   *          if font size is greater than 50, print text as path; otherwise, print text as bitmap.<br>
   *          If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_to_print_text_graphic  <b>true</b> means to print text as path or bitmap.
   *                                      <b>false</b> means not to print text as path or bitmap.
   *
   * @return None.
   */
  void SetPrintTextAsGraphic(bool is_to_print_text_graphic);

  /**
   * @brief Set the flag to decide whether to print text as image.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_to_print_text_image  <b>true</b> means to print text as image.
   *                                    <b>false</b> means not to print text as image.
   *
   * @return None.
   */
  void SetPrintTextAsImage(bool is_to_print_text_image);

  /**
   * @brief Set the flag to decide whether to use down-sampling for image stretching.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_to_force_down_sample  <b>true</b> means to use down-sampling for image stretching.
   *                                     <b>false</b> means not to use down-sampling for image stretching.
   *
   * @return None.
   */
  void SetForceDownSample(bool is_to_force_down_sample);

  /**
   * @brief Set the flag to decide whether to enable overprint.
   *
   * @param[in] is_to_enable_overprint  <b>true</b> means to enable overprint.
   *                                    <b>false</b> means not to enable overprint.
   *                                    Default: <b>false</b>.
   *
   * @return None.
   */
  void SetOverprint(bool is_to_enable_overprint);

  /**
   * @brief Set the flag to decide whether to use down-sampling for jpeg image.
   *
   * @details Whether to use down-sampling for jpeg image or not will affect rendering result for a PDF page.
   *          When current function is called successfully, user should called function @link pdf::PDFPage::ClearRenderCache @endlink
   *          for a PDF page (which has been rendered at least once) before rendering the PDF page again.<br>
   *          If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_jepg_down_sample  <b>true</b> means to use down-sampling for jpeg image.
   *                                 <b>false</b> means not to use down-sampling for jpeg image.
   *
   * @return None.
   */
  void SetJPEGDownSample(bool is_jepg_down_sample);

  /**
   * @brief Set the flag to decide whether to use down-sampling for jpx image.
   *
   * @details Whether to use down-sampling for jpx image or not will affect rendering result for a PDF page.
   *          When current function is called successfully, user should called function @link pdf::PDFPage::ClearRenderCache @endlink
   *          for a PDF page (which has been rendered at least once) before rendering the PDF page again.<br>
   *          If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_jpx_down_sample  <b>true</b> means to use down-sampling for jpx image.
   *                                <b>false</b> means not to use down-sampling for jpx image.
   *
   * @return None.
   */
  void SetJPXDownSample(bool is_jpx_down_sample);

  /**
   * @brief Set the flag to decide whether to do rendering in print mode.
   *
   * @details Please ensure this rendering flag is set as expected when current renderer is to used for printing.
   *          For rendering annotations, if this flag is set to be <b>true</b>, Foxit PDF SDK will only render annotations
   *          which have annotation flag @link pdf::annots::Annot::e_FlagPrint @endlink.<br>
   *          If this function is not called for current renderer object yet, default value <b>false</b> will be used.
   *
   * @param[in] is_render_for_print  <b>true</b> means to render in print mode, while <b>false</b> means to render not in print mode.
   *
   * @return None.
   */
  void EnableForPrint(bool is_render_for_print);

  /**
   * @brief Set the flag to decide whether to use halftone for image stretching.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_to_force_halftone  <b>true</b> means to use halftone for image stretching.
   *                                  <b>false</b> means not to use halftone for image stretching.
   *
   * @return None.
   */
  void SetForceHalftone(bool is_to_force_halftone);

  /**
   * @brief Set the flag to decide whether to draw path as thin line.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_render_path_thin_line  <b>true</b> means to draw path as thin line.
   *                                      <b>false</b> means not to draw path as thin line.
   *
   * @return None.
   */
  void SetRenderPathThinLine(bool is_render_path_thin_line);

  /**
   * @brief Set the flag to decide whether to draw text anti-aliasing.
   *
   * @details If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_render_text_antialiasing  <b>true</b> means to draw text anti-aliasing.
   *                                         <b>false</b> means to draw text aliasing.
   *
   * @return None.
   */
  void SetRenderTextAntiAliasing(bool is_render_text_antialiasing);

  /**
   * @brief Set the flag to decide whether to draw path anti-aliasing.
   *
   * @details If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_render_path_antialiasing  <b>true</b> means to draw path anti-aliasing.
   *                                         <b>false</b> means to draw path aliasing.
   *
   * @return None.
   */
  void SetRenderPathAntiAliasing(bool is_render_path_antialiasing);

  /**
   * @brief A special flag that can be applied to fill mode.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_render_path_full_covered  <b>true</b> means that all pixels partially covered by the path will be fully painted, while <b>false</b> means not.
   *
   * @return None.
   */
  void SetRenderPathFullCovered(bool is_render_path_full_covered);

  /**
   * @brief Set the flag to decide whether to draw image anti-aliasing.
   *
   * @details If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_render_image_antialiasing  <b>true</b> means to draw image anti-aliasing, and the effect would be
   *                                          similar to values defined in enum class InterpolationFlag.
   *                                          <b>false</b> means to draw image aliasing.
   *
   * @return None.
   */
  void SetRenderImageAntiAliasing(bool is_render_image_antialiasing);

  /**
   * @brief Set the flag to decide whether to enhance thin lines.
   *
   * @details If this function is not called, default value <b>false</b> will be used.
   *
   * @param[in] is_render_enhance_thin_lines  <b>true</b> means to draw zero width lines with a thicker path
   *                                          so they are more visible than the default single pixel.<br>
   *                                          <b>false</b> means to draw zero width lines with a single pixel width.
   *
   * @return None.
   */
  void SetRenderEnhanceThinLines(bool is_render_enhance_thin_lines);

  /**
   * @brief Set the flag to decide whether to draw the signature state on the signature.
   *
   * @details If this function is not called, default value <b>true</b> will be used.
   *
   * @param[in] is_render_signature_state  <b>true</b> means to draw the signature state on the signature,
   *                                             while <b>false</b> means not.
   */
  void SetRenderSignatureState(bool is_render_signature_state);

  // User is strongly recommended NOT to use this method; otherwise unknown situation may occur.
  explicit Renderer(FS_HANDLE handle =  NULL);

  /**
   * @brief Set the screen DPI scaling factor for rendering.
   *
   * @details Set the screen DPI scaling scale to adapt to different DPI conditions.
   *          This value should typically match the system-reported scaling factor
   *          (e.g., 1.25f for 125% scaling in display settings) to ensure proper
   *          rendering alignment with the physical display characteristics.
   *
   * @param[in] scale  The scale of curren screen DPI(1.0f = 100% native DPI, 2.0f = 200%, etc.).
   *                   Must be greater than 0 and should generally correspond to the system's recommended scaling factor.
   *                   Default value: 1.0f for non-Android platforms; 2.5f for Android platform.
   *
   * @note Currently, this screen DPI scaling factor only affects the annotations.
   *
   * @return None.
   */
  void SetScreenDPIScale(float scale);

};

/** 此类表示和OFD渲染选项相关的方法。*/
class OFDRenderOption FS_FINAL : public Object {
 public:
  /**
   * @brief OFD渲染颜色模式枚举类型.
   *
   * @details 该枚举值应单独使用.
   */
  typedef enum _ColorMode {
    /** @brief 正常颜色模式. */
    e_ColorModeNormal = 0,
    /** @brief 灰度颜色模式:将颜色映射到背景色/前景色. */
    e_ColorModeMappingGray = 1,
    /** @brief 映射颜色模式:将颜色映射到由背景色和前景色定义的颜色范围. */
    e_ColorModeMapping = 2,
    /** @brief 任意颜色模式:不对颜色进行任何映射. */
    e_ColorModeAnyColor = 3,
    /** 将用户选中的区域中的红色文字或者路径渲染成黑色 */
    e_ColorModeRedHead = 4
  } ColorMode;
  
  /**
    * @brief OFD渲染标识枚举类型.
    *
    * @details 该枚举值应单独使用.
    */
  typedef enum _RenderFlag {
    /** @brief 不渲染作为背景层的模板页. */
    e_RenderFlagNoDisplayBackgroundTemplatePage = 0x10,
    /** @brief 资源不使用缓存. */
    e_RenderFlagResourceNoCache = 0x20,
    /** @brief 打印时总是输出图像替代. */
    e_RenderFlagPrintSubImage = 0x40,
    /** @brief 总是显示缩略图. */
    e_RenderFlagDisplayThumbnail = 0x80,
    /** @brief 渲染时使用渐进式显示. */
    e_RenderFlagProgressiveRending = 0x100,
    /** @brief 不使用ClearType类的文本抗锯齿技术. */
    e_RenderFlagNoUseFxTextClearType = 0x200,
    /** @brief 注释不使用边界. */
    e_RenderFlagAnnotNoUseBound = 0x400,
    /** @brief 页面不使用裁剪框. */
    e_RenderFlagPageNoUseCropBox = 0x800,
    /** @brief 页面不使用页面区域. */
    e_RenderFlagPageNoUsePageArea = 0x1000,
    /** @brief 渲染手写笔迹. */
    e_RenderFlagRenHanWriting = 0x2000,
    /** @brief 页面不使用字体粗细设置. */
    e_RenderFlagPageNoUseFontWeight = 0x4000,
    /** @brief 打印为PDF格式. */
    e_RenderFlagPrintPDF = 0x8000,
    /** @brief 页面不使用裁剪路径. */
    e_RenderFlagPageNoUseClip = 0x10000,
    /** @brief 页面使用缓存图像. */
    e_RenderFlagPageUseCacheImage = 0x20000,
    /** @brief 水印默认作为背景. */
    e_WaterMarkDefaultIsBackground = 0x40000,
    /** @brief 水印不打印. */
    e_RenderFlagWaterMarkNotPrint = 0x80000,
    /** @brief CG变换有优先级. */
    e_RenderFlagCGTransformHasPriority = 0x100000,
    /** @brief 嵌入字体文件损坏时不渲染文本对象. */
    e_RenderFlagBadEmbedFontNoRender = 0x200000
  } RenderFlag;
  

  /**
    * @brief 构造函数。
   */
  OFDRenderOption() :
    is_print(false),
    color_mode(OFDRenderOption::e_ColorModeNormal),
    back_color(0xFFFFFFFF),
    fore_color(0xFF000000),
    x_dpi(96),
    y_dpi(96),
    render_flags(0) {};
  /**
   * @brief 带参数的构造函数。
     *
     * @param[in] is_print       是否为打印模式。
     * @param[in] color_mode     颜色模式。请参考从 @link foxit::common::OFDRenderOption::e_ColorModeNormal @endlink 开始的值，
     *                           应该是这些值中的一个。
     * @param[in] back_color     背景颜色。
     * @param[in] fore_color     前景颜色。
     * @param[in] x_dpi          水平DPI值。
     * @param[in] y_dpi          垂直DPI值。
     * @param[in] render_flags   渲染标识。请参考从 @link foxit::common::OFDRenderOption::e_RenderFlagNoDisplayBackgroundTemplatePage @endlink 开始的值，
     *                           应该是这些值的组合。
   */
  explicit OFDRenderOption(bool is_print, ColorMode color_mode, foxit::RGB back_color, foxit::RGB fore_color, int x_dpi, int y_dpi, int render_flags) :
    is_print(is_print),
    color_mode(color_mode),
    back_color(back_color),
    fore_color(fore_color),
    x_dpi(x_dpi),
    y_dpi(y_dpi),
    render_flags(render_flags) {};

  /** @brief 析构函数。*/
  ~OFDRenderOption() {};

  /**
   * @brief 构造函数，通过另一个OFDRenderOption对象。
   *
   * @param[in] other  另一个OFDRenderOption对象。
   */
  OFDRenderOption(const OFDRenderOption& other) :
    is_print(other.is_print),
    color_mode(other.color_mode),
    back_color(other.back_color),
    fore_color(other.fore_color),
    x_dpi(other.x_dpi),
    y_dpi(other.y_dpi),
    render_flags(other.render_flags) {
  };

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other  另一个OFDRenderOption对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  OFDRenderOption& operator = (const OFDRenderOption& other) {
    this->is_print = other.is_print;
    this->color_mode = other.color_mode;
    this->back_color = other.back_color;
    this->fore_color = other.fore_color;
    this->x_dpi = other.x_dpi;
    this->y_dpi = other.y_dpi;
    this->render_flags = other.render_flags;
    return *this;
  }

  /**
   * @brief 设置值。
   *
   * @param[in] is_print       是否为打印模式。
    * @param[in] color_mode     颜色模式。请参考从 @link foxit::common::OFDRenderOption::e_ColorModeNormal @endlink 开始的值，
    *                           应该是这些值中的一个。
   * @param[in] back_color     背景颜色。
   * @param[in] fore_color     前景颜色。
   * @param[in] x_dpi          水平DPI值。
   * @param[in] y_dpi          垂直DPI值。
   * @param[in] render_flags   渲染标识。请参考从 @link foxit::common::OFDRenderOption::e_RenderFlagNoDisplayBackgroundTemplatePage @endlink 开始的值，
   *                           应该是这些值的组合。
   *
   * @return 无。
   */
  void Set(bool is_print, ColorMode color_mode, foxit::RGB back_color, foxit::RGB fore_color, int x_dpi, int y_dpi, int render_flags) {
    this->is_print = is_print;
    this->color_mode = color_mode;
    this->back_color = back_color;
    this->fore_color = fore_color;
    this->x_dpi = x_dpi;
    this->y_dpi = y_dpi;
    this->render_flags = render_flags;
  }

  /**
   * @brief 是否为打印模式。
   */
  bool is_print;

  /**
   * @brief 颜色模式。请参考从 @link foxit::common::OFDRenderOption::e_ColorModeNormal @endlink 开始的值，
   *        应该是这些值中的一个。
   */
  ColorMode color_mode;

  /**
   * @brief 背景颜色。
   */
  foxit::RGB back_color;

  /**
   * @brief 前景颜色。
   */
  foxit::RGB fore_color;

  /**
   * @brief 水平DPI值。
   */
  int x_dpi;

  /**
   * @brief 垂直DPI值。
   */
  int y_dpi;

  /**
   * @brief 渲染标识。请参考从 @link foxit::common::OFDRenderOption::e_RenderFlagNoDisplayBackgroundTemplatePage @endlink 开始的值，
   *        应该是这些值的组合。
   */
  int render_flags;
};

/** 此类表示和OFD渲染相关的方法。*/
class OFDRender FS_FINAL : public Base {
 public:
  /**
   * @brief OFD渲染内容标识枚举类型.
   *
   * @details 该枚举值应单独使用或组合使用.
   */
  typedef enum _ContentFlag {
    /** @brief 只渲染页面内容，不渲染标注. */
    e_RenderPage = 0x01,
    /** @brief 渲染Stamp类型的标注（不是Seal）. */
    e_RenderStampAnnot = 0x02,
    /** @brief 渲染高亮类型的标注(与e_RenderExceptHighlightAnnot互斥）. */
    e_RenderHighlightAnnot = 0x04,
    /** @brief 渲染非高亮类型的标注(与e_RenderHighlightAnnot互斥）. */
    e_RenderExceptHighlightAnnot = 0x08,
    /** @brief 渲染Seal类型的标注(与e_RenderSealAnnotGray互斥). */
    e_RenderSealAnnot = 0x10,
    /** @brief 以灰度模式渲染Seal类型的标注(与e_RenderSealAnnot互斥). */
    e_RenderSealAnnotGray = 0x20
  } ContentFlag;
  

  /**
   * @brief 构造函数。
   *
   * @param[in] bitmap  用于渲染的位图。用户应确保该位图在当前渲染对象的整个生命周期内保持有效。
   */
  explicit OFDRender(const Bitmap& bitmap);

  /** @brief 析构函数。*/
  ~OFDRender();

  /**
   * @brief 构造函数，通过另一个OFDRender对象。
   *
   * @param[in] other  另一个OFDRender对象。
   */
  OFDRender(const OFDRender& other);

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other  另一个OFDRender对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  OFDRender& operator = (const OFDRender& other);

  /**
   * @brief 相等操作符
   *
   * @param[in] other 另一个OFDRender对象。此函数将检查当前对象是否等于这个对象。
   *
   * @return <b>true</b> 表示相等，<b>false</b> 表示不相等
   */
  bool operator == (const OFDRender& other) const;

  /**
   * @brief 不相等操作符
   *
   * @param[in] other 另一个OFDRender对象。此函数将检查当前对象是否不等于这个对象。
   *
   * @return <b>true</b> 表示不相等，<b>false</b> 表示相等
   */
  bool operator != (const OFDRender& other) const;

  /**
   * @brief 检查当前对象是否为空。
   *
   * @details 当前对象为空时，表示当前对象是无用的。
   *
   * @return <b>true</b> 表示当前对象为空，<b>false</b> 表示不为空。
   */
  bool IsEmpty() const;

  /**
   * @brief 渲染OFD页面。
   *
   * @param[in] page    需要渲染的OFD页面。
   * @param[in] matrix  用于渲染的矩阵。
   * @param[in] pause   渲染过程中用于暂停的回调函数指针。用户可以通过实现该回调函数来控制渲染过程中的暂停和继续。
   *
   * @return Progressive对象，用户可以通过该对象来检查渲染的进度，并在需要时暂停或继续渲染。
   */
  Progressive StartRender(const foxit::ofd::OFDPage& page, const Matrix& matrix, PauseCallback* pause = NULL);

  /**
   * @brief 设置渲染选项。
   *
   * @param[in] render_option 渲染选项对象。
   *
   * @return 无。
   */
  void SetRenderOption(const OFDRenderOption& render_option);

  /**
   * @brief 设置渲染内容标识。
   *
   * @details 渲染内容标识用于指定在渲染过程中需要渲染的内容类型。用户可以通过设置不同的标识来控制渲染的内容，例如只渲染页面内容、只渲染特定类型的标注等。
   *
   * @param[in] render_content_flags 渲染内容标识，默认为0。请参考从 @link foxit::common::OFDRender::e_RenderPage @endlink 开始的值，
   *                                 应该是这些值的组合。
   *
   * @return 无。
   */
  void SetRenderContentFlags(uint32 render_content_flags);

  // User is strongly recommended NOT to use this method; otherwise unknown situation may occur.
  explicit OFDRender(FS_HANDLE handle);
};

/** 此类表示和FLD渲染相关的选项。*/
class FLDRenderOption FS_FINAL : public Object {
 public:
  /**
   * @brief OFD渲染颜色模式枚举类型.
   *
   * @details 该枚举值应单独使用.
   */
  typedef enum _ColorMode {
    /** @brief 正常颜色模式. */
    e_ColorModeNormal = 0,
    /** @brief 灰度颜色模式:将颜色映射到背景色/前景色. */
    e_ColorModeMappingGray = 1,
    /** @brief 映射颜色模式:将颜色映射到由背景色和前景色定义的颜色范围. */
    e_ColorModeMapping = 2,
    /** @brief 任意颜色模式:不对颜色进行任何映射. */
    e_ColorModeAnyColor = 3,
    /** 将用户选中的区域中的红色文字或者路径渲染成黑色 */
    e_ColorModeRedHead = 4
  } ColorMode;
  

  /** @brief 构造函数。*/
  FLDRenderOption() :
    is_print(false),
    color_mode(FLDRenderOption::e_ColorModeNormal),
    back_color(0xFFFFFFFF),
    fore_color(0xFF000000),
    x_dpi(96),
    y_dpi(96) {};

  /**
   * @brief 带参数的构造函数。
   *
   * @param[in] is_print       是否为打印模式。
   * @param[in] color_mode     颜色模式。请参考从 @link foxit::common::FLDRenderOption::e_ColorModeNormal @endlink 开始的值，
   *                           应该是这些值中的一个。
   * @param[in] back_color     背景颜色。
   * @param[in] fore_color     前景颜色。
   * @param[in] x_dpi          水平DPI值。
   * @param[in] y_dpi          垂直DPI值。
   */
  explicit FLDRenderOption(bool is_print, ColorMode color_mode, foxit::RGB back_color, foxit::RGB fore_color, int x_dpi, int y_dpi) :
    is_print(is_print),
    color_mode(color_mode),
    back_color(back_color),
    fore_color(fore_color),
    x_dpi(x_dpi),
    y_dpi(y_dpi) {};

  /** @brief 析构函数。*/
  ~FLDRenderOption() {};

  /**
   * @brief 构造函数，通过另一个FLDRenderOption对象。
   *
   * @param[in] other 另一个FLDRenderOption对象。
   */
  FLDRenderOption(const FLDRenderOption& other) :
    is_print(other.is_print),
    color_mode(other.color_mode),
    back_color(other.back_color),
    fore_color(other.fore_color),
    x_dpi(other.x_dpi),
    y_dpi(other.y_dpi) {
  };

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other 另一个FLDRenderOption对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  FLDRenderOption& operator = (const FLDRenderOption& other) {
    this->is_print = other.is_print;
    this->color_mode = other.color_mode;
    this->back_color = other.back_color;
    this->fore_color = other.fore_color;
    this->x_dpi = other.x_dpi;
    this->y_dpi = other.y_dpi;
    return *this;
  }

  /**
   * @brief 设置值。
   *
   * @param[in] is_print    是否为打印模式。
   * @param[in] color_mode  颜色模式。请参考从 @link foxit::common::FLDRenderOption::e_ColorModeNormal @endlink 开始的值，
   *                        应该是这些值中的一个。
   * @param[in] back_color  背景颜色。
   * @param[in] fore_color  前景颜色。
   * @param[in] x_dpi       水平DPI值。
   * @param[in] y_dpi       垂直DPI值。
   *
   * @return 无。
   */
  void Set(bool is_print, ColorMode color_mode, foxit::RGB back_color, foxit::RGB fore_color, int x_dpi, int y_dpi) {
    this->is_print = is_print;
    this->color_mode = color_mode;
    this->back_color = back_color;
    this->fore_color = fore_color;
    this->x_dpi = x_dpi;
    this->y_dpi = y_dpi;
  }

  /**
   * @brief 是否为打印模式。
   */
  bool is_print;

  /**
   * @brief 颜色模式。请参考从 @link foxit::common::FLDRenderOption::e_ColorModeNormal @endlink 开始的值，
   *        应该是这些值中的一个。
   */
  ColorMode color_mode;

  /**
   * @brief 背景颜色。
   */
  foxit::RGB back_color;

  /**
   * @brief 前景颜色。
   */
  foxit::RGB fore_color;

  /**
   * @brief 水平DPI值。
   */
  int x_dpi;

  /**
   * @brief 垂直DPI值。
   */
  int y_dpi;
};

/** 此类表示和FLD渲染相关的方法。*/
class FLDRender FS_FINAL : public Base {
 public:
  /**
   * @brief 构造函数。
   *
   * @param[in] bitmap 用于渲染的位图。用户应确保该位图在当前渲染对象的整个生命周期内保持有效。
   */
  explicit FLDRender(const Bitmap& bitmap);

  /** @brief 析构函数。*/
  ~FLDRender();

  /**
   * @brief 构造函数，通过另一个FLDRender对象。
   *
   * @param[in] other 另一个FLDRender对象。
   */
  FLDRender(const FLDRender& other);

  /**
   * @brief 赋值操作符。
   *
   * @param[in] other 另一个FLDRender对象，其值将被赋给当前对象。
   *
   * @return 当前对象自身的引用。
   */
  FLDRender& operator = (const FLDRender& other);

  /**
   * @brief 相等操作符
   *
   * @param[in] other 另一个FLDRender对象。此函数将检查当前对象是否等于这个对象。
   *
   * @return <b>true</b> 表示相等，<b>false</b> 表示不相等
   */
  bool operator == (const FLDRender& other) const;

  /**
   * @brief 不相等操作符
   *
   * @param[in] other 另一个FLDRender对象。此函数将检查当前对象是否不等于这个对象。
   *
   * @return <b>true</b> 表示不相等，<b>false</b> 表示相等
   */
  bool operator != (const FLDRender& other) const;

  /**
   * @brief 检查当前对象是否为空。
   *
   * @details 当前对象为空时，表示当前对象是无用的。
   *
   * @return <b>true</b> 表示当前对象为空，<b>false</b> 表示不为空。
   */
  bool IsEmpty() const;

  /**
   * @brief 渲染FLD页面。
   *
   * @param[in] page    需要渲染的FLD页面。
   * @param[in] matrix  用于渲染的矩阵。
   *
   * @return <b>true</b> 表示渲染成功，<b>false</b> 表示渲染失败。
   */
  bool Render(const foxit::fld::FLDPage& page, const Matrix& matrix);

  /**
   * @brief 设置渲染选项。
   *
   * @param[in] render_option 渲染选项。
   */
  void SetRenderOption(const FLDRenderOption& render_option);

  // User is strongly recommended NOT to use this method; otherwise unknown situation may occur.
  explicit FLDRender(FS_HANDLE handle);
};
}  // namespace common
}  // namespace foxit
#endif  // FS_RENDER_H_

