merge conflict solve
This commit is contained in:
@@ -168,8 +168,29 @@ class PageReorderOperation(BaseModel):
|
||||
data: PageReorderData
|
||||
|
||||
|
||||
class EditTextData(BaseModel):
|
||||
# Target line/run bbox in PDF bottom-left page space (frontend does the Y-flip).
|
||||
x: float
|
||||
y: float
|
||||
width: float = Field(..., gt=0)
|
||||
height: float = Field(..., gt=0)
|
||||
newText: str
|
||||
originalText: str | None = None
|
||||
fontSize: float | None = Field(default=None, gt=0)
|
||||
color: str | None = None
|
||||
fallbackFont: str = "Helvetica"
|
||||
|
||||
|
||||
class EditTextOperation(BaseModel):
|
||||
id: str
|
||||
type: Literal["edit_text"]
|
||||
pageIndex: int = Field(..., ge=0)
|
||||
data: EditTextData
|
||||
|
||||
|
||||
class UpdateFieldData(BaseModel):
|
||||
value: str | bool
|
||||
annotationId: str | None = None
|
||||
|
||||
|
||||
class UpdateFieldOperation(BaseModel):
|
||||
@@ -261,6 +282,7 @@ EditOperation = Annotated[
|
||||
| UpdateFieldOperation
|
||||
| DeleteAnnotationOperation
|
||||
| UpdateAnnotationOperation
|
||||
| EditTextOperation
|
||||
| ReplaceTextOperation
|
||||
| UnderlineOperation
|
||||
| StrikeoutOperation
|
||||
@@ -290,7 +312,7 @@ def apply_edits_impl(document_id: str, request: EditsRequest):
|
||||
pdfengine = engine.require()
|
||||
doc = doc_info["doc_instance"]
|
||||
|
||||
req_dict = request.model_dump()
|
||||
req_dict = request.model_dump(exclude_none=True)
|
||||
for op in req_dict.get("operations", []):
|
||||
if op.get("type") == "image_overlay":
|
||||
img_data_str = op["data"].get("imageData", "")
|
||||
@@ -338,8 +360,11 @@ def apply_edits_impl(document_id: str, request: EditsRequest):
|
||||
edits_json = json.dumps(req_dict)
|
||||
doc.apply_edits(edits_json)
|
||||
|
||||
has_redaction = any(op.get("type") == "redaction" for op in req_dict.get("operations", []))
|
||||
new_bytes = doc.save_full() if has_redaction else doc.save_incremental()
|
||||
# Redaction and in-place text rewrites mutate existing objects, which do
|
||||
# not round-trip cleanly through an incremental save — force a full save.
|
||||
full_save_types = {"redaction", "edit_text"}
|
||||
needs_full = any(op.get("type") in full_save_types for op in req_dict.get("operations", []))
|
||||
new_bytes = doc.save_full() if needs_full else doc.save_incremental()
|
||||
|
||||
new_doc = pdfengine.PdfDocument.load_from_memory(new_bytes)
|
||||
|
||||
|
||||
@@ -56,7 +56,14 @@ def extract_page_text(document_id: str, page_index: Annotated[int, Path(ge=0)]):
|
||||
annots = page.extract_annotations_text()
|
||||
if annots:
|
||||
text += "\n" + "\n".join(annots)
|
||||
# The engine emits glyph bounds in PDFium-native BOTTOM-LEFT space (y = bbox
|
||||
# bottom). The frontend renders pages top-down, so flip to TOP-LEFT here —
|
||||
# the same convention /search and the annotation/highlight paths already use.
|
||||
# Without this, text selection is vertically mirrored.
|
||||
page_height = page.height
|
||||
glyphs = page.extract_text_with_bounds()
|
||||
for g in glyphs:
|
||||
g["y"] = page_height - (g["y"] + g["h"])
|
||||
return {"text": text, "glyphs": glyphs}
|
||||
except IndexError:
|
||||
raise HTTPException(
|
||||
|
||||
Reference in New Issue
Block a user