Skip to content

Paragraph Editing

Foxit PDF SDK provides developers with a versatile set of tools for fine-tuning and customizing text in PDF documents. The paragraph editing module provides sophisticated adjustment, merging and splitting functions, giving users precise control over document content. These features are implemented through an intuitive UI interface for efficient editing, ensuring a seamless and customized experience when managing text paragraphs.

The paragraph editing function mainly revolves around two core modules, namely the ParagraphEditing module and the JoinSplit module.

The ParagraphEditing module is designed to provide a variety of text editing operations, allowing users to easily perform the following operations based on specific requirements:

  • Insert Text: Inserts new content at a specific location, allowing you to customize the precise layout of your document.
  • Delete Text: Finely delete paragraphs or characters to achieve highly customized content trimming.
  • Modify Text: Adjust existing text, including its content and format, to suit different editing styles.
  • Format Adjustment: Supports subtle adjustments to paragraph format and text style for more accurate layout.

The JoinSplit module contains four important operation types to support more complex text processing needs:

  • Join: Integrate multiple text blocks to enhance content layout and overall document consistency.
  • Split: Finely split blocks of text, providing flexibility in managing individual parts of the document.
  • Link: Establish connections between blocks of text to ensure consistency of related content.
  • Unlink: Breaks links between blocks of text, providing more editing control.

System requirements

Platform: Windows, Linux, Mac

Development language: C, C++, Java, C#, Python, Objective-C, Go

License: Requires the AdvEdit module to authorize.

SDK version: Foxit PDF SDK 10.0+

Use paragraph editing function

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);
        }
    }
}
go
import (
. "foxit.com/fsdk"
)  

...

type FxParagraphEditingProviderCallback struct {
    page PDFPage
}

# Release releases resources
func (callback FxParagraphEditingProviderCallback) Release() {
}

# GetRenderMatrix returns the render matrix
func (callback FxParagraphEditingProviderCallback) GetRenderMatrix(arg2 PDFDoc, arg3 int) Matrix2D {
    width := int(callback.page.GetWidth())
    height := int(callback.page.GetHeight())
    matrix := callback.page.GetDisplayMatrix(0, 0, width, height, callback.page.GetRotation())
    return matrix
}

# GetPageViewHandle returns the page view handle
func (callback FxParagraphEditingProviderCallback) GetPageViewHandle(arg2 PDFDoc, arg3 int) uintptr {
    return uintptr(0)
}

# GetClientRect returns the client rectangle
func (callback FxParagraphEditingProviderCallback) GetClientRect(arg2 PDFDoc) RectF {
    rect := NewRectF(float32(0), float32(0), float32(0), float32(0))
    return rect
}

# GetScale returns the scale
func (callback FxParagraphEditingProviderCallback) GetScale(arg2 PDFDoc, arg3 int) float32 {
    return 1.0
}

# GotoPageView navigates to the page view
func (callback FxParagraphEditingProviderCallback) GotoPageView(arg2 PDFDoc, arg3 int, arg4 float32, arg5 float32) bool {
    return true
}

# GetVisiblePageIndexArray returns an array of visible page indices
func (callback FxParagraphEditingProviderCallback) GetVisiblePageIndexArray(arg2 PDFDoc) Int32Array {
    pageArray := NewInt32Array()
    pageIndex := callback.page.GetIndex()
    pageArray.Add(pageIndex)
    return pageArray
}

# GetPageVisibleRect returns the visible rectangle of the page
func (callback FxParagraphEditingProviderCallback) GetPageVisibleRect(arg2 PDFDoc, arg3 int) RectF {
    rect := NewRectF(float32(0), float32(0), float32(0), float32(0))
    return rect
}

# GetPageRect returns the page rectangle
func (callback FxParagraphEditingProviderCallback) GetPageRect(arg2 PDFDoc, arg3 int) RectF {
    width := int(callback.page.GetWidth())
    height := int(callback.page.GetHeight())
    rect := NewRectF(float32(0), float32(height), float32(width), float32(0))
    return rect
}

# GetCurrentPageIndex returns the current page index
func (callback FxParagraphEditingProviderCallback) GetCurrentPageIndex(arg2 PDFDoc) int {
    return callback.page.GetIndex()
}

# GetRotation returns the rotation
func (callback FxParagraphEditingProviderCallback) GetRotation(arg2 PDFDoc, arg3 int) FoxitCommon_Rotation {
    return E_Rotation0
}

# InvalidateRect invalidates the specified rectangle
func (callback FxParagraphEditingProviderCallback) InvalidateRect(arg2 PDFDoc, arg3 int, arg4 RectFArray) {
    / Not implemented for this example
}

# AddUndoItem adds an undo item
func (callback FxParagraphEditingProviderCallback) AddUndoItem(arg2 ParagraphEditingUndoItem) {
    # Not implemented for this example
}

# SetDocChangeMark sets the document change mark
func (callback FxParagraphEditingProviderCallback) SetDocChangeMark(arg2 PDFDoc) {
    # Not implemented for this example
}

# NotifyTextInputReachLimit notifies when text input reaches the limit
func (callback FxParagraphEditingProviderCallback) NotifyTextInputReachLimit(arg2 PDFDoc, arg3 int) {
    # Not implemented for this example
}
...

page := doc.GetPage(0)
page.StartParse(0)
height := page.GetHeight()
callback := FxParagraphEditingProviderCallback{ page: page:}
callback_ := NewDirectorParagraphEditingProviderCallback(callback)
editingMgr := NewParagraphEditingMgr(callback_, doc)

# Paragraph_editing
editing := editingMgr.GetParagraphEditing()
editing.Activate()
point_insert := NewPointF(95, height - 728)
editing.StartEditing(0, point_insert, point_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, PDFDocE_SaveFlagNoOriginal)

# Join&split
jionsplit := editingMgr.GetJoinSplit()
jionsplit.Activate()
point := NewPointF(289, 659)
jionsplit.OnLButtonDown(0, point)
jionsplit.OnLButtonUp(0, point)
jionsplit.SplitBoxes()
jionsplit.Deactivate()
output_path := output_directory + "Split_Boxes.pdf"
doc.SaveAs(output_path, PDFDocE_SaveFlagNoOriginal)

jionsplit.Activate()
point = NewPointF(307, height - 637)
jionsplit.OnLButtonDown(0, point)
jionsplit.OnLButtonUp(0, point)
point = NewPointF(307, height - 453)
jionsplit.OnLButtonDown(0, point)
jionsplit.OnLButtonUp(0, point)
jionsplit.JoinBoxes()
jionsplit.Deactivate()