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))