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