doc-ai-api / Libraries /Common_PdfProcess.py
LongK171's picture
Add all
dbe2c62
from . import Common_MyUtils as MyUtils
# ===============================
# 1. General
# ===============================
def fontFlags(span):
"""Trả về tuple booleans (bold, italic, underline) từ span.flags"""
flags = span.get("flags", 0)
b = bool(flags & 16)
i = bool(flags & 2)
u = bool(flags & 8)
return b, i, u
def setAlign(position, regionWidth):
mid = abs(position["Mid"])
left = position["Left"]
if mid <= 0.01 * regionWidth:
if left > 0.01 * regionWidth:
return "Center"
else:
return "Justify"
elif position["Mid"] > 0.01 * regionWidth:
return "Right"
else:
return "Left"
def setPosition(line, prev_line, next_line, xStart, xEnd, xMid):
left = round(line["Coords"]["X0"] - xStart, 1)
right = round(xEnd - line["Coords"]["X1"], 1)
mid = round(line["Coords"]["XM"] - xMid, 1)
top = round(line["Coords"]["Y1"] - prev_line["Coords"]["Y1"], 1) if prev_line else 0
bot = round(next_line["Coords"]["Y1"] - line["Coords"]["Y1"], 1) if next_line else 0
return (left, right, mid, top, bot)
# ===============================
# 2. Words
# ===============================
def extractWords(line):
"""Trả về list [(word, span)] theo thứ tự trong line; giữ nguyên dấu câu."""
spans = line.get("spans", [])
full_text = line.get("text", "")
if not spans or not full_text.strip():
return []
# chỉ giữ spans có chữ thật
valid_spans = [s for s in spans if s.get("text", "").strip()]
if not valid_spans:
valid_spans = spans
words = []
for s in valid_spans:
for raw in s.get("text", "").split():
words.append((raw, s))
return words
def getWordText(line, index: int):
"""Lấy Text của từ tại vị trí index (hỗ trợ index âm)."""
words = extractWords(line)
if -len(words) <= index < len(words):
return words[index][0]
return ""
def getWordFontSize(line, index: int):
"""Lấy FontSize của từ tại vị trí index."""
words = extractWords(line)
if -len(words) <= index < len(words):
_, span = words[index]
return round(span.get("size", 12.0), 1)
return 0.0
def getWordCoord(line, index: int):
"""Lấy tọa độ (x0, x1, xm, y0, y1) của từ tại vị trí index (dựa bbox của span chứa từ)."""
words = extractWords(line)
if -len(words) <= index < len(words):
_, span = words[index]
x0, y0, x1, y1 = span["bbox"]
x0, y0, x1, y1 = round(x0, 1), round(y0, 1), round(x1, 1), round(y1, 1)
return (x0, x1, y0, y1)
return (0, 0, 0, 0)
# ===============================
# 3. Lines
# ===============================
def getLineFontSize(line):
"""FontSize của line = mean FontSize các từ (làm tròn 0.5)."""
words = extractWords(line)
if not words:
return 12.0
sizes = [span.get("size", 12.0) for _, span in words]
avg = sum(sizes) / len(sizes)
return round(avg * 2) / 2
def getLineCoord(line):
"""
Coord của line:
- x0 = x0 của từ đầu tiên
- x1 = x1 của từ cuối cùng
- y0 = min(y0) các từ
- y1 = max(y1) các từ
- xm = (x0 + x1) / 2
"""
words = extractWords(line)
if not words:
return (0, 0, 0, 0, 0)
coords = []
for _, span in words:
x0, y0, x1, y1 = span["bbox"]
coords.append((round(x0, 1), round(y0, 1), round(x1, 1), round(y1, 1)))
x0 = coords[0][0]
x1 = coords[-1][2]
y0 = min(c[1] for c in coords)
y1 = max(c[3] for c in coords)
xm = round((x0 + x1) / 2, 1)
return (x0, x1, xm, y0, y1)
def setLineSize(line):
x0, x1, y0, y1 = line["Coords"]["X0"], line["Coords"]["X1"], line["Coords"]["Y0"], line["Coords"]["Y1"]
return (round(x1 - x0, 1), round(y1 - y0, 1))
# ===============================
# 4. Page
# ===============================
def setPageCoords(lines, pageGeneralSize):
x0s = [round(l["Coords"]["X0"], 1) for l in lines]
x1s = [round(l["Coords"]["X1"], 1) for l in lines]
y0s = [round(l["Coords"]["Y0"], 1) for l in lines]
y1s = [round(l["Coords"]["Y1"], 1) for l in lines]
xStart = MyUtils.most_common(x0s)
page_width = pageGeneralSize[1]
threshold = page_width * 0.75
x1_candidates = [x for x in x1s if x >= threshold]
xEnd = MyUtils.most_common(x1_candidates) if x1_candidates else max(x1s)
yStart = min(y0s)
yEnd = max(y1s)
xMid = round((xStart + xEnd) / 2, 1)
yMid = round((yStart + yEnd) / 2, 1)
return (xStart, yStart, xEnd, yEnd, xMid, yMid)
def setPageRegionSize(xStart, yStart, xEnd, yEnd):
return (round(xEnd - xStart, 1), round(yEnd - yStart, 1))