Skip to content

段落编辑 (Paragraph Editing)

福昕 PDF SDK 为开发人员提供了一套多功能工具,用于微调和自定义 PDF 文档中的文本。段落编辑模块提供了复杂的调整、合并和拆分功能,让用户能够对文档内容进行精确控制。这些功能通过直观的 UI 界面实现,便于高效编辑,确保了在管理文本段落时的无缝和定制化体验。

段落编辑功能主要围绕两个核心模块,即 ParagraphEditing 模块和 JoinSplit 模块。

ParagraphEditing 模块旨在提供各种文本编辑操作,使用户能够根据具体要求轻松执行以下操作:

  • 插入文本 (Insert Text):在特定位置插入新内容,允许定制文档的精确布局。
  • 删除文本 (Delete Text):精细删除段落或字符,实现高度定制的内容修剪。
  • 修改文本 (Modify Text):调整现有文本,包括其内容和格式,以适应不同的编辑风格。
  • 格式调整 (Format Adjustment):支持对段落格式和文本样式进行细微调整,以便更准确的排版。

JoinSplit 模块包含四种重要的操作类型,以支持更复杂的文本处理需求:

  • 拼接 (Join):整合多个文本块,增强内容布局和整体文档的一致性。
  • 拆分 (Split):精细地将文本块拆分,为管理文档的各个部分提供了灵活性。
  • 链接 (Link):在文本块之间建立连接,确保相关内容的一致性。
  • 取消链接 (Unlink):断开文本块之间的链接,提供更多的编辑控制权。

系统要求

平台: Windows, Linux, Mac

开发语言: C, C++, Java, C#, Python, Objective-C

授权许可: 包含 AdvEdit 模块的授权码

SDK 版本: 福昕 PDF SDK 10.0 或更高版本

使用段落编辑功能

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/fs_pdfpage.h"
#include "include/addon/pageeditor/fs_paragraphediting.h"

using namespace foxit;
using namespace foxit::common;
using namespace pdf;
using namespace foxit::addon::pageeditor;

...
class FxParagraphEditingProviderCallback : public foxit::addon::pageeditor::ParagraphEditingProviderCallback {
public:

    FxParagraphEditingProviderCallback(int page_index) {
        this->current_page_index_ = page_index;
    }
    virtual ~FxParagraphEditingProviderCallback() {}

    virtual void Release() { delete this; }

    virtual foxit::Matrix GetRenderMatrix(const pdf::PDFDoc& document, int page_index) {
        PDFPage page = (PDFDoc(document)).GetPage(page_index);
        int width = static_cast<int>(page.GetWidth());
        int height = static_cast<int>(page.GetHeight());
        Matrix matrix = page.GetDisplayMatrix(0, 0, width, height, e_Rotation0);
        return matrix;
    }
    virtual void* GetPageViewHandle(const pdf::PDFDoc& document, int page_index) {
        return NULL;
    }
    virtual foxit::RectF GetClientRect(const pdf::PDFDoc& document) {
        return foxit::RectF();
    }
    virtual float GetScale(const pdf::PDFDoc& document, int page_index) {
        return 1.0f;
    }
    virtual bool GotoPageView(const pdf::PDFDoc& document, int page_index, float left, float top) {
        return true;
    }
    virtual Int32Array GetVisiblePageIndexArray(const pdf::PDFDoc& document) {
        Int32Array page_array;
        int pageindex = this->current_page_index_;
        page_array.Add(pageindex);
        return page_array;
    }
    virtual RectF GetPageVisibleRect(const pdf::PDFDoc& document, int page_index) {
        return foxit::RectF();
    }
    virtual foxit::RectF GetPageRect(const pdf::PDFDoc& document, int page_index) {
        PDFDoc doc = document;
        PDFPage page = doc.GetPage(page_index);
        float width = page.GetWidth();
        float height = page.GetHeight();
        RectF rect;
        rect.left = 0;
        rect.bottom = height;
        rect.right = width;
        rect.top = 0;
        return rect;
    }
    virtual int GetCurrentPageIndex(const pdf::PDFDoc& document) {
        return this->current_page_index_;
    }
    virtual common::Rotation GetRotation(const pdf::PDFDoc& document, int page_index) {
        PDFPage page = (PDFDoc(document)).GetPage(page_index);
        Rotation rotation = page.GetRotation();
        return rotation;
    }
    virtual void InvalidateRect(const pdf::PDFDoc& document, int page_index, const RectFArray& invalid_rects) {

    }
    virtual void AddUndoItem(const ParagraphEditingUndoItem& undo_item) {
    }
    virtual void SetDocChangeMark(const pdf::PDFDoc& document) {
    }
    virtual void NotifyTextInputReachLimit(const pdf::PDFDoc& document, int page_index) {
    }

private:
    int current_page_index_;
};

...

PDFPage page = doc.GetPage(0);
page.StartParse();
float height = page.GetHeight();

FxParagraphEditingProviderCallback* callback = new FxParagraphEditingProviderCallback(page.GetIndex());
ParagraphEditingMgr touchup_mgr = ParagraphEditingMgr(callback, doc);

// Paragraph_editing
{
    ParagraphEditing paragraphEditing = touchup_mgr.GetParagraphEditing();
    paragraphEditing.Activate();
    paragraphEditing.StartEditing(0, PointF(95, height - 728), PointF(95, height - 728));
    paragraphEditing.SetFontSize(24);
    paragraphEditing.SetUnderline(true);
    paragraphEditing.InsertText(L"InsertText_Paragraph_editing");
    paragraphEditing.Deactivate();
    WString save_pdf_path = output_directory + L"Paragraph_editing.pdf";
    doc.SaveAs(save_pdf_path, PDFDoc::e_SaveFlagNoOriginal);
}

// Join&split
{
    JoinSplit joinSplit = touchup_mgr.GetJoinSplit();
    joinSplit.Activate();
    joinSplit.OnLButtonDown(0, PointF(289, 659));
    joinSplit.OnLButtonUp(0, PointF(289, 659));
    joinSplit.SplitBoxes();
    joinSplit.Deactivate();
    WString save_pdf_path = output_directory + L"Split_Boxes.pdf";
    doc.SaveAs(save_pdf_path, PDFDoc::e_SaveFlagNoOriginal);

    joinSplit.Activate();
    joinSplit.OnLButtonDown(0, PointF(307, height - 637));
    joinSplit.OnLButtonUp(0, PointF(307, height - 637));
    joinSplit.OnLButtonDown(0, PointF(307, height - 453));
    joinSplit.OnLButtonUp(0, PointF(307, height - 453));
    joinSplit.JoinBoxes();
    joinSplit.Deactivate();
    save_pdf_path = output_directory + L"Join_Boxes.pdf";
    doc.SaveAs(save_pdf_path, PDFDoc::e_SaveFlagNoOriginal);
}
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfpage_c.h"
#include "include/fs_paragraphediting_c.h"
...

FSParagraphEditingProviderCallback* provider_callback;

FSDK_PDFPage_StartParse(page, e_FSParseFlagsParsePageNormal, NULL, FALSE, &return_value);
FSDK_PDFPage_GetHeight(page, &floatheight);
FSDK_PDFPage_GetIndex(page, &page_index_);

provider_callback = (FSParagraphEditingProviderCallback*)malloc(sizeof(FSParagraphEditingProviderCallback));
provider_callback->user_data = (void*)provider_callback;
provider_callback->Release = gRelease;
provider_callback->GetRenderMatrix = gGetRenderMatrix;
provider_callback->GetPageViewHandle = gGetPageViewHandle;
provider_callback->GetClientRect = gGetClientRect;
provider_callback->GetScale = gGetScale;
provider_callback->GotoPageView = gGotoPageView;
provider_callback->GetVisiblePageIndexArray = gGetVisiblePageIndexArray;
provider_callback->GetPageVisibleRect = gGetPageVisibleRect;
provider_callback->GetPageRect = gGetPageRect;
provider_callback->GetCurrentPageIndex = gGetCurrentPageIndex;
provider_callback->GetRotation = gGetRotation;
provider_callback->InvalidateRect = gInvalidateRect;
provider_callback->AddUndoItem = gAddUndoItem;
provider_callback->SetDocChangeMark = gSetDocChangeMark;
provider_callback->NotifyTextInputReachLimit = gNotifyTextInputReachLimit;
FSDK_ParagraphEditingMgr_Create(provider_callback, doc, &provider_mgr);

// Paragraph_editing
{
    FSDK_ParagraphEditingMgr_GetParagraphEditing(provider_mgr, &provider_editting);
    FSDK_ParagraphEditing_Activate(provider_editting, &return_value);
    point.x = 95;
    point.y = floatheight - 728;
    FSDK_ParagraphEditing_StartEditing(provider_editting, 0, point, point);
    FSDK_ParagraphEditing_SetFontSize(provider_editting, 24);
    FSDK_ParagraphEditing_SetUnderline(provider_editting, TRUE);
    FSDK_ParagraphEditing_InsertText(provider_editting, L"InsertText_Paragraph_editing", &return_value);
    FSDK_ParagraphEditing_Deactivate(provider_editting, &return_value);
    swprintf_s(output_file, MAX_FILE_PATH, L"%lsParagraph_editing.pdf", output_directory);
    error_code = FSDK_PDFDoc_SaveAs(doc, output_file, e_FSSaveFlagNoOriginal, &return_result);
    if (error_code != e_FSErrSuccess) {
        printf("Save doc error!\n");
        FSDK_PDFDoc_Release(doc);
        return 1;
    }
}

// Join&split
{
    point.x = 289;
    point.y = 659;
    FSDK_ParagraphEditingMgr_GetJoinSplit(provider_mgr, &join_split);
    FSDK_ParagraphEditing_Activate(join_split, &return_value);
    FSDK_JoinSplit_OnLButtonDown(join_split, 0, point, &return_value);
    FSDK_JoinSplit_OnLButtonUp(join_split, 0, point, &return_value);
    FSDK_JoinSplit_SplitBoxes(join_split);
    FSDK_JoinSplit_Deactivate(join_split, &return_value);
    swprintf_s(output_file, MAX_FILE_PATH, L"%lsSplit_Boxes.pdf", output_directory);
    error_code = FSDK_PDFDoc_SaveAs(doc, output_file, e_FSSaveFlagNoOriginal, &return_result);
    if (error_code != e_FSErrSuccess) {
        printf("Save doc error!\n");
        FSDK_PDFDoc_Release(doc);
        return 1;
    }

    FSDK_ParagraphEditing_Activate(join_split, &return_value);
    point.x = 307;
    point.y = floatheight - 637;
    FSDK_JoinSplit_OnLButtonDown(join_split, 0, point, &return_value);
    FSDK_JoinSplit_OnLButtonUp(join_split, 0, point, &return_value);
    point.x = 307;
    point.y = floatheight - 453;
    FSDK_JoinSplit_OnLButtonDown(join_split, 0, point, &return_value);
    FSDK_JoinSplit_OnLButtonUp(join_split, 0, point, &return_value);
    FSDK_JoinSplit_JoinBoxes(join_split);
    FSDK_JoinSplit_Deactivate(join_split, &return_value);
    swprintf_s(output_file, MAX_FILE_PATH, L"%lsJoin_Boxes.pdf", output_directory);
    error_code = FSDK_PDFDoc_SaveAs(doc, output_file, e_FSSaveFlagNoOriginal, &return_result);
}
java
import com.foxit.sdk.addon.pageeditor.*;
import com.foxit.sdk.common.Library;
import com.foxit.sdk.common.fxcrt.*;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.PDFPage;
import com.foxit.sdk.common.fxcrt.RectF;
import com.foxit.sdk.common.fxcrt.RectFArray;
import com.foxit.sdk.common.fxcrt.Matrix2D;
import java.io.File;

...

class IParagraphEditingProviderCallback extends ParagraphEditingProviderCallback
{
    private  int current_page_index = 0;

    @Override
    public void release() {

    }

    @Override
    public Matrix2D getRenderMatrix(PDFDoc document,int page_index) {

    try {
        PDFPage currentpage = document.getPage(page_index);
        int width = (int) currentpage.getWidth();
        int height = (int) currentpage.getHeight();
        Matrix2D matrix = new Matrix2D();
        matrix = currentpage.getDisplayMatrix(0, 0, width, height, currentpage.getRotation());
        return matrix;
        } catch (PDFException e) {

        e.printStackTrace();
        return null; 
        }
    }

    @Override
    public Object getPageViewHandle(PDFDoc document,int page_index) {

        return null;
    }

    @Override
    public RectF getClientRect(PDFDoc document) {
        return new RectF();
    }

    @Override
    public float getScale(PDFDoc document,int page_index) {
        return 1;
    }

    @Override
    public boolean gotoPageView(PDFDoc document,int page_index, float left, float top) {
        return true;
    }

    @Override
    public Int32Array getVisiblePageIndexArray(PDFDoc document) {
        Int32Array page_array = new Int32Array();
        page_array.add(0);
       return page_array;
    }

    @Override
    public RectF getPageVisibleRect(PDFDoc document,int page_index) {
        return new RectF();
    }

    @Override
    public RectF getPageRect(PDFDoc document,int page_index) {
    try {
         PDFPage currentpage = document.getPage(page_index);
         int width = (int) currentpage.getWidth();
         int height = (int) currentpage.getHeight();
         RectF rect = new RectF(0,height,width,0); ;
         return rect;
        } catch (PDFException e) {

        e.printStackTrace();
        return null; 
        }  

    }

    @Override
    public int getCurrentPageIndex(PDFDoc document) {
        return current_page_index;
    }

    @Override
    public int getRotation(PDFDoc document,int page_index) {
        return 0;
    }

    @Override
    public void invalidateRect(PDFDoc doc,int page_index, RectFArray rectFArray) {
    }

    @Override
    public void addUndoItem(ParagraphEditingUndoItem paragraphEditingUndoItem) {
    }

    @Override
    public void setDocChangeMark(PDFDoc pdfDoc) {
    }

    @Override
    public void notifyTextInputReachLimit(PDFDoc doc,int page_index) {
    }

    public IParagraphEditingProviderCallback(int page_index)
    {
        current_page_index = page_index;
    }
}

...

page.startParse(0, null, false);
float height = page.getHeight();
if (error_code != e_ErrSuccess)
{
	System.out.println(String.format("The Doc [%s] Error: %d\n", input_file, error_code));
	return;
}
 int page_index = page.getIndex();
IParagraphEditingProviderCallback callback = new IParagraphEditingProviderCallback(page_index);
ParagraphEditingMgr editingMgr = new ParagraphEditingMgr(callback, doc);
ParagraphEditing editing = editingMgr.getParagraphEditing();
if (editing.isEmpty() == true)
	return;
editing.activate();

editing.startEditing(0, new PointF(95, height - 728), new PointF(95, height - 728));
editing.setFontSize(24);
editing.setUnderline(true);
editing.insertText("InsertText_Paragraph_editing");
editing.deactivate();
doc.saveAs(output_file, PDFDoc.e_SaveFlagNoOriginal);

// Join&split
JoinSplit joinSplit = editingMgr.getJoinSplit();
joinSplit.activate();
joinSplit.onLButtonDown(0, new PointF(289, 659));
joinSplit.onLButtonUp(0, new PointF(289, 659));
joinSplit.splitBoxes();
joinSplit.deactivate();
String output_path_split = output_path + "Split_Boxes.pdf";
doc.saveAs(output_path_split, PDFDoc.e_SaveFlagNoOriginal);

joinSplit.activate();
joinSplit.onLButtonDown(0, new PointF(307, height - 637));
joinSplit.onLButtonUp(0, new PointF(307, height - 637));
joinSplit.onLButtonDown(0, new PointF(307, height - 453));
joinSplit.onLButtonUp(0, new PointF(307, height - 453));
joinSplit.joinBoxes();
joinSplit.deactivate();
String output_path_join = output_path + "Join_Boxes.pdf";
doc.saveAs(output_path_join, PDFDoc.e_SaveFlagNoOriginal);
py
import os
import sys

...

class FxParagraphEditingProviderCallback(ParagraphEditingProviderCallback):
    def __init__(self, * args):
        super(FxParagraphEditingProviderCallback, self).__init__()
        self.page = args[0]
    def __del__(self):
        super(FxParagraphEditingProviderCallback, self).__disown__()

    def Release(self):
        pass

    def GetRenderMatrix(self, *args):
        width = int(self.page.GetWidth());
        height = int(self.page.GetHeight());
        matrix = self.page.GetDisplayMatrix(0, 0, width, height, self.page.GetRotation());
        return matrix;
    def GetPageViewHandle(self, * args):
        pass
    def GetClientRect(self, *args):
        return RectF(0, 0, 0, 0)
    def GetScale(self, * args):
        return 1
    def GotoPageView(self, * args):
        return True
    def GetVisiblePageIndexArray(self, * args):
        page_array = Int32Array();
        pageindex = self.page.GetIndex();
        page_array.Add(pageindex);
        return page_array;
    def GetPageVisibleRect(self, * args):
        return RectF(0, 0, 0, 0)
    def GetPageRect(self, * args):
        width = int(self.page.GetWidth());
        height = int(self.page.GetHeight());
        rect = RectF(0, height, width, 0)
        return rect
    def GetCurrentPageIndex(self, * args):
        return self.page.GetIndex()
    def GetRotation(self, * args):
        return e_Rotation0
    def InvalidateRect(self, * args):
        pass
    def AddUndoItem(self, *args):
        pass
    def SetDocChangeMark(self, *args):
        pass
    def NotifyTextInputReachLimit(self, *args):
        pass
...

page = doc.GetPage(0)
page.StartParse(0, None, False)
height = page.GetHeight()
callback = FxParagraphEditingProviderCallback(page)
editingMgr = ParagraphEditingMgr(callback, doc)

# Paragraph_editing
editing = editingMgr.GetParagraphEditing()
editing.Activate();
ponit_insert = PointF(95, height - 728)
editing.StartEditing(0, ponit_insert, ponit_insert)
editing.SetFontSize(24)
editing.SetUnderline(True)
editing.InsertText("InsertText_Paragraph_editing")
editing.Deactivate()
output_path = output_directory + "Paragraph_editing.pdf"
doc.SaveAs(output_path, PDFDoc.e_SaveFlagNoOriginal)

# Join&split
jionsplit = editingMgr.GetJoinSplit()
jionsplit.Activate()
ponit = PointF(289, 659)
jionsplit.OnLButtonDown(0, ponit)
jionsplit.OnLButtonUp(0, ponit)
jionsplit.SplitBoxes()
jionsplit.Deactivate()
output_path = output_directory + "Split_Boxes.pdf"
doc.SaveAs(output_path, PDFDoc.e_SaveFlagNoOriginal)

jionsplit.Activate()
ponit = PointF(307, height - 637)
jionsplit.OnLButtonDown(0, ponit)
jionsplit.OnLButtonUp(0, ponit)
ponit = PointF(307, height - 453)
jionsplit.OnLButtonDown(0, ponit)
jionsplit.OnLButtonUp(0, ponit)
jionsplit.JoinBoxes()
jionsplit.Deactivate()
objc
#include "FSPDFObjC.h"

...

@interface FxParagraphEditingProviderCallbackOC : NSObject <FSParagraphEditingProviderCallback>
{
    @private
    FSPDFPage* page;
}
-(id)init;
-(id)initWithPage:(FSPDFPage*)page_;
@end

@implementation FxParagraphEditingProviderCallbackOC
-(id)init {
    page = nil;
    return self;
}

-(id)initWithPage:(FSPDFPage*)page_{
    page = page_;
    return self;
}

- (FSMatrix2D *)getRenderMatrix:(FSPDFDoc *)document page_index:(int)pageIndex {
    int width = (int)[self->page getWidth];
    int height = (int)[self->page getHeight];
    FSMatrix2D *matrix = [self->page getDisplayMatrix:0 top:0 width:width height:height rotate:FSRotation0];
    return matrix;
}

- (void*)getPageViewHandle:(FSPDFDoc *)document page_index:(int)pageIndex {
    return nil;
}

- (FSRectF *)getClientRect:(FSPDFDoc *)document {
    return [[FSRectF alloc] init];
}

- (float)getScale:(FSPDFDoc *)document page_index:(int)pageIndex {
    return 1.0f;
}

- (BOOL)gotoPageView:(FSPDFDoc *)document page_index:(int)pageIndex left:(float)left top:(float)top {
    return YES;
}


- (NSArray<NSNumber *> *)getVisiblePageIndexArray:(FSPDFDoc *)document {
    NSMutableArray<NSNumber *> *pageArray = [NSMutableArray array];
    int pageIndex = (int)[self->page getIndex];
    [pageArray addObject:@(pageIndex)];
    return [pageArray copy];
}

- (FSRectF *)getPageVisibleRect:(FSPDFDoc *)document page_index:(int)pageIndex {
    return [[FSRectF alloc] init];
}

- (FSRectF *)getPageRect:(FSPDFDoc *)document page_index:(int)pageIndex {
    int width = (int)[self->page getWidth];
    int height = (int)[self->page getHeight];
    FSRectF* rect = [[FSRectF alloc] initWithLeft1:0 bottom1:height right1:width top1:0];
    return rect;
}

- (int)getCurrentPageIndex:(FSPDFDoc *)document {
    return (int)[self->page getIndex];
}

- (FSRotation)getRotation:(FSPDFDoc *)document page_index:(int)pageIndex {
    return [self->page getRotation];
}
    

- (void)invalidateRect:(FSPDFDoc *)document page_index:(int)pageIndex invalid_rects:(FSRectFArray*)invalid_rects {

}

- (void)addUndoItem:(FSParagraphEditingUndoItem *)undoItem {
}

- (void)setDocChangeMark:(FSPDFDoc *)document {
}

- (void)notifyTextInputReachLimit:(FSPDFDoc *)document page_index:(int)pageIndex {
}

@end

...

FSPDFPage *page = [doc getPage:0];
[page startParse:FSPDFPageParsePageNormal pause:nil is_reparse:NO];
int height = static_cast<int>([page getHeight]);
height = height ;
FxParagraphEditingProviderCallbackOC *callback = [[FxParagraphEditingProviderCallbackOC alloc] initWithPage:page];
FSParagraphEditingMgr *touchup_mgr = [[FSParagraphEditingMgr alloc] initWithCallback:callback document:doc];

// Paragraph_editing
FSParagraphEditing* paragraphEditing = [touchup_mgr getParagraphEditing];
[paragraphEditing activate];
FSPointF* point = [FSPointF new];
[point set:95 y:height- 728];
[paragraphEditing startEditing:0 start_point:point end_point:point];
[paragraphEditing setFontSize:24];
[paragraphEditing setUnderline:YES];
NSString* insert_text = @"InsertText_Paragraph_editing";
[paragraphEditing insertText:insert_text];
[paragraphEditing deactivate];
NSString* save_pdf_path = [NSString  stringWithFormat:@"%@%@", output_directory, @"Paragraph_editing.pdf"];
[doc saveAs:save_pdf_path save_flags:FSPDFDocSaveFlagNoOriginal];
 
// Join&split
FSJoinSplit* joinSplit = [touchup_mgr getJoinSplit];
[point set:289 y:height- 659];
[joinSplit activate];
[joinSplit onLButtonDown:0 point:point];
[joinSplit onLButtonUp:0 point:point];
[joinSplit splitBoxes];
[joinSplit deactivate];
save_pdf_path = [NSString  stringWithFormat:@"%@%@", output_directory, @"Split_Boxes.pdf"];
[doc saveAs:save_pdf_path save_flags:FSPDFDocSaveFlagNoOriginal];
 
[point set:307 y:height - 637];
[joinSplit activate];
[joinSplit onLButtonDown:0 point:point];
[joinSplit onLButtonUp:0 point:point];
[point set:307 y:height - 453];
[joinSplit onLButtonDown:0 point:point];
[joinSplit onLButtonUp:0 point:point];
[joinSplit joinBoxes];
[joinSplit deactivate];
save_pdf_path = [NSString  stringWithFormat:@"%@%@", output_directory, @"Join_Boxes.pdf"];
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.addon.pageeditor

...

class FxParagraphEditingProviderCallback : ParagraphEditingProviderCallback
{
    private int page_index = 0;

    public FxParagraphEditingProviderCallback(int index)
    {
        page_index = index;
    }

    public override void Release()
    {
    }

    public override void AddUndoItem(ParagraphEditingUndoItem undo_item)
    {

    }
    public override RectF GetClientRect(PDFDoc document)
    {
        return new RectF();
    }
    public override int GetCurrentPageIndex(PDFDoc document)
    {
        return 0;
    }
    public override RectF GetPageRect(PDFDoc document, int page_index)
    {
        PDFPage page = document.GetPage(page_index);
        int width = (int)(page.GetWidth());
        int height = (int)(page.GetHeight());
        RectF rect = new RectF(); ;
        rect.left = 0;
        rect.bottom = height;
        rect.right = width;
        rect.top = 0;
        page.Dispose();
        return rect;
    }
    public override IntPtr GetPageViewHandle(PDFDoc document, int page_index)
    {
        return IntPtr.Zero; ;
    }
    public override RectF GetPageVisibleRect(PDFDoc document, int page_index)
    {
        return new RectF();
    }
    public override Matrix2D GetRenderMatrix(PDFDoc document, int page_index)
    {
        PDFPage page = document.GetPage(page_index);
        int width = (int)page.GetWidth();
        int height = (int)page.GetHeight();
        Matrix2D matrix = page.GetDisplayMatrix(0, 0, width, height, page.GetRotation());
        page.Dispose();
        return matrix;
    }
    public override Rotation GetRotation(PDFDoc document, int page_index)
    {
        return Rotation.e_Rotation0;

    }
    public override float GetScale(PDFDoc document, int page_index)
    {
        return 1;
    }
    public override Int32Array GetVisiblePageIndexArray(PDFDoc document)
    {
        Int32Array page_array = new Int32Array();
        page_array.Add(0);
        return page_array;
    }
    public override bool GotoPageView(PDFDoc document, int page_index, float left, float top)
    {
        return true;
    }
    public override void InvalidateRect(PDFDoc document, int page_index, RectFArray invalid_rects)
    {
    }
    public override void NotifyTextInputReachLimit(PDFDoc document, int page_index)
    {
    }
    public override void SetDocChangeMark(PDFDoc document)
    {
    }
};

...

using (PDFPage page = doc.GetPage(0))
{

    page.StartParse(0, null, false);
    float height = page.GetHeight();
    string output_dir = output_path;
    int index = page.GetIndex();
    using (FxParagraphEditingProviderCallback callback = new FxParagraphEditingProviderCallback(index))
    {
        using (ParagraphEditingMgr editingMgr = new ParagraphEditingMgr(callback, doc))
        {
            //Paragraph_editing
            ParagraphEditing editing = editingMgr.GetParagraphEditing();
            if (editing.IsEmpty() == true)
                return;
            editing.Activate();
            editing.StartEditing(0, new PointF(95, height - 728), new PointF(95, height - 728));
            editing.SetFontSize(24);
            editing.SetUnderline(true);
            editing.InsertText("InsertText_Paragraph_editing");
            editing.Deactivate();
            output_path = output_dir + "Paragraph_editing.pdf";
            doc.SaveAs(output_path, (int)PDFDoc.SaveFlags.e_SaveFlagNoOriginal);

            //Join&split
            JoinSplit joinSplit = editingMgr.GetJoinSplit();
            joinSplit.Activate();
            joinSplit.OnLButtonDown(0, new PointF(289, 659));
            joinSplit.OnLButtonUp(0, new PointF(289, 659));
            joinSplit.SplitBoxes();
            joinSplit.Deactivate();
            output_path = output_dir + "Split_Boxes.pdf";
            doc.SaveAs(output_path, (int)PDFDoc.SaveFlags.e_SaveFlagNoOriginal);

            joinSplit.Activate();
            joinSplit.OnLButtonDown(0, new PointF(307, height - 637));
            joinSplit.OnLButtonUp(0, new PointF(307, height - 637));
            joinSplit.OnLButtonDown(0, new PointF(307, height - 453));
            joinSplit.OnLButtonUp(0, new PointF(307, height - 453));
            joinSplit.JoinBoxes();
            joinSplit.Deactivate();
            output_path = output_dir + "Join_Boxes.pdf";
            doc.SaveAs(output_path, (int)PDFDoc.SaveFlags.e_SaveFlagNoOriginal);
        }
    }
}