Issue 1462 attachment: cpdf_textpage_patch.cpp (3.0 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
void CPDF_TextPage::ProcessTextObject(
CPDF_TextObject* pTextObj,
const CFX_Matrix& formMatrix,
const CPDF_PageObjectHolder* pObjList,
CPDF_PageObjectHolder::const_iterator ObjPos) {
if (fabs(pTextObj->GetRect().Width()) < kSizeEpsilon)
return;

size_t count = m_LineObj.size();
PDFTEXT_Obj Obj;
Obj.m_pTextObj = pTextObj;
Obj.m_formMatrix = formMatrix;
if (count == 0) {
m_LineObj.push_back(Obj);
return;
}
if (IsSameAsPreTextObject(pTextObj, pObjList, ObjPos))
return;

CFX_Matrix this_matrix = pTextObj->GetTextMatrix() * formMatrix;

PDFTEXT_Obj prev_Obj = m_LineObj[count - 1];
CFX_Matrix prev_matrix =
prev_Obj.m_pTextObj->GetTextMatrix() * prev_Obj.m_formMatrix;

CFX_PointF this_pos =
m_DisplayMatrix.Transform(formMatrix.Transform(pTextObj->GetPos()));

int this_angle = ((int)(atan2(this_matrix.c, this_matrix.a) * 180 / FX_PI) + 360) % 360;
int prev_angle = ((int)(atan2(prev_matrix.c, prev_matrix.a) * 180 / FX_PI) + 360) % 360;
bool line_break = this_angle != prev_angle || (this_angle % 90) != 0;
if (!line_break) {
size_t nItem = prev_Obj.m_pTextObj->CountItems();
if (nItem == 0)
return;

CPDF_TextObjectItem item;
prev_Obj.m_pTextObj->GetItemInfo(nItem - 1, &item);
float prev_width =
GetCharWidth(item.m_CharCode, prev_Obj.m_pTextObj->GetFont().Get()) *
prev_Obj.m_pTextObj->GetFontSize() / 1000;
prev_width = prev_matrix.TransformDistance(fabs(prev_width));

pTextObj->GetItemInfo(0, &item);
float this_width = GetCharWidth(item.m_CharCode, pTextObj->GetFont().Get()) *
pTextObj->GetFontSize() / 1000;
this_width = fabs(this_width);
this_width = this_matrix.TransformDistance(fabs(this_width));

CFX_PointF prev_pos = m_DisplayMatrix.Transform(
prev_Obj.m_formMatrix.Transform(prev_Obj.m_pTextObj->GetPos()));

float threshold = std::max(prev_width, this_width) / 4;
if ((this_angle % 180) == 0)
line_break = fabs(this_pos.y - prev_pos.y) > threshold * 2;
else
line_break = fabs(this_pos.x - prev_pos.x) > threshold * 2;
}
if (line_break) {
for (size_t i = 0; i < count; ++i)
ProcessTextObject(m_LineObj[i]);
m_LineObj.clear();
m_LineObj.push_back(Obj);
return;
}

for (size_t i = 0; i < count; i++) {
PDFTEXT_Obj prev_obj = m_LineObj[i];
CFX_PointF prev_pos =
m_DisplayMatrix.Transform(prev_obj.m_formMatrix.Transform(
prev_obj.m_pTextObj->GetPos()));

bool can_insert = false;
switch (this_angle) {
case 0:
can_insert = this_pos.x <= prev_pos.x;
break;

case 90:
can_insert = this_pos.y <= prev_pos.y;
break;

case 180:
can_insert = this_pos.x >= prev_pos.x;
break;

case 270:
can_insert = this_pos.y >= prev_pos.y;
break;
}
if (can_insert) {
m_LineObj.insert(m_LineObj.begin() + i, Obj);
return;
}
}
m_LineObj.insert(m_LineObj.begin() + count, Obj);
}