summaryrefslogtreecommitdiff
path: root/core/src/reflow/reflowedtextpage.cpp
diff options
context:
space:
mode:
authorJohn Abd-El-Malek <jabdelmalek@google.com>2014-05-17 22:33:34 -0700
committerJohn Abd-El-Malek <jabdelmalek@google.com>2014-05-17 22:33:34 -0700
commit5110c4743751145c4ae1934cd1d83bc6c55bb43f (patch)
treeb141608096b73163182764c25b895d3df4b2c182 /core/src/reflow/reflowedtextpage.cpp
parent76b563d2feed92ed328afb1f15e3466a9536b11b (diff)
downloadpdfium-5110c4743751145c4ae1934cd1d83bc6c55bb43f.tar.xz
Initial commit.
Diffstat (limited to 'core/src/reflow/reflowedtextpage.cpp')
-rw-r--r--core/src/reflow/reflowedtextpage.cpp402
1 files changed, 402 insertions, 0 deletions
diff --git a/core/src/reflow/reflowedtextpage.cpp b/core/src/reflow/reflowedtextpage.cpp
new file mode 100644
index 0000000000..a5ad0be948
--- /dev/null
+++ b/core/src/reflow/reflowedtextpage.cpp
@@ -0,0 +1,402 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "reflowedtextpage.h"
+IPDF_TextPage* IPDF_TextPage::CreateReflowTextPage(IPDF_ReflowedPage* pRefPage)
+{
+ return FX_NEW CRF_TextPage(pRefPage);
+}
+CRF_TextPage::CRF_TextPage(IPDF_ReflowedPage* pRefPage)
+{
+ m_pRefPage = (CPDF_ReflowedPage*)(pRefPage);
+ m_pDataList = NULL;
+ m_CountBSArray = NULL;
+}
+CRF_TextPage::~CRF_TextPage()
+{
+ if(m_pDataList) {
+ delete m_pDataList;
+ m_pDataList = NULL;
+ }
+ if(m_CountBSArray) {
+ delete m_CountBSArray;
+ m_CountBSArray = NULL;
+ }
+}
+FX_BOOL CRF_TextPage::ParseTextPage()
+{
+ if(!m_pRefPage) {
+ return FALSE;
+ }
+ int count = m_pRefPage->m_pReflowed->GetSize();
+ if(count < 500) {
+ m_pDataList = FX_NEW CRF_CharDataPtrArray(count);
+ } else {
+ m_pDataList = FX_NEW CRF_CharDataPtrArray(500);
+ }
+ if (NULL == m_pDataList) {
+ return FALSE;
+ }
+ for(int i = 0; i < count; i++) {
+ CRF_Data* pData = (*(m_pRefPage->m_pReflowed))[i];
+ if(pData->GetType() == CRF_Data::Text) {
+ m_pDataList->Add((CRF_CharData*)pData);
+ }
+ }
+ m_CountBSArray = FX_NEW CFX_CountBSINT32Array(20);
+ if(NULL == m_CountBSArray) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CRF_TextPage::IsParsered() const
+{
+ if(m_pDataList) {
+ return TRUE;
+ }
+ return FALSE;
+}
+int CRF_TextPage::CharIndexFromTextIndex(int TextIndex) const
+{
+ return TextIndex;
+}
+int CRF_TextPage::TextIndexFromCharIndex(int CharIndex) const
+{
+ return CharIndex;
+}
+
+int CRF_TextPage::CountChars() const
+{
+ if (NULL == m_pDataList) {
+ return -1;
+ }
+ return m_pDataList->GetSize();
+}
+void CRF_TextPage::GetCharInfo(int index, FPDF_CHAR_INFO & info) const
+{
+ if(index >= CountChars() || index < 0 || !m_pDataList) {
+ return;
+ }
+ CRF_CharData* pData = (*m_pDataList)[index];
+ FX_FLOAT ReltiveCorddDs = pData->m_pCharState->m_fDescent;
+ FX_FLOAT ReltiveCorddAs = pData->m_pCharState->m_fAscent;
+ info.m_Flag = CHAR_NORMAL;
+ info.m_pTextObj = pData->m_pCharState->m_pTextObj;
+ info.m_OriginX = pData->m_PosX;
+ info.m_OriginY = pData->m_PosY - ReltiveCorddDs;
+ info.m_FontSize = pData->m_pCharState->m_fFontSize;
+ CFX_FloatRect FloatRectTmp(pData->m_PosX, pData->m_PosY, pData->m_PosX + pData->m_Width, pData->m_PosY + ReltiveCorddAs - ReltiveCorddDs);
+ info.m_CharBox = FloatRectTmp;
+ CFX_WideString str = pData->m_pCharState->m_pFont->UnicodeFromCharCode(pData->m_CharCode);
+ if(!str.IsEmpty()) {
+ info.m_Unicode = str.GetAt(0);
+ } else {
+ info.m_Unicode = -1;
+ }
+ info.m_Charcode = (FX_WCHAR)pData->m_CharCode;
+ info.m_Matrix = CFX_Matrix(1, 0, 0, 1, 0, 0);
+}
+extern FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_FLOAT high2, FX_FLOAT& interlow, FX_FLOAT& interhigh);
+inline FX_BOOL _IsInsameline(const CFX_FloatRect& rectA, const CFX_FloatRect& rectB)
+{
+ if((rectA.top >= rectB.bottom && rectB.top >= rectA.bottom)) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+inline FX_BOOL _IsIntersect(const CFX_FloatRect& rectA, const CFX_FloatRect& rectB)
+{
+ FX_FLOAT interlow = .0f, interhigh = .0f;
+ if(GetIntersection(rectA.bottom, rectA.top, rectB.bottom, rectB.top, interlow, interhigh)) {
+ if(GetIntersection(rectA.left, rectA.right, rectB.left, rectB.right, interlow, interhigh)) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+void CRF_TextPage::GetRectArray(int start, int nCount, CFX_RectArray& rectArray) const
+{
+ int indexlen = start + nCount;
+ FPDF_CHAR_INFO info;
+ FX_BOOL bstart = TRUE;
+ CFX_FloatRect recttmp;
+ int i;
+ for(i = start; i < indexlen; i++) {
+ GetCharInfo(i, info);
+ if(bstart) {
+ recttmp = info.m_CharBox;
+ bstart = FALSE;
+ } else if(_IsInsameline(recttmp, info.m_CharBox)) {
+ recttmp.right = info.m_CharBox.right;
+ if(info.m_CharBox.top > recttmp.top) {
+ recttmp.top = info.m_CharBox.top;
+ }
+ if(info.m_CharBox.bottom < recttmp.bottom) {
+ recttmp.bottom = info.m_CharBox.bottom;
+ }
+ } else {
+ rectArray.Add(recttmp);
+ recttmp = info.m_CharBox;
+ }
+ }
+ rectArray.Add(recttmp);
+}
+inline FX_FLOAT _GetDistance(CFX_FloatRect floatRect, CPDF_Point point)
+{
+ if(floatRect.right < point.x && floatRect.bottom > point.y) {
+ return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(floatRect.bottom - point.y, 2));
+ }
+ if (floatRect.right < point.x && floatRect.top < point.y) {
+ return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(point.y - floatRect.top, 2));
+ }
+ if(floatRect.left > point.x && floatRect.bottom > point.y) {
+ return FXSYS_sqrt(FXSYS_pow(floatRect.bottom - point.y, 2) + FXSYS_pow(floatRect.left - point.x, 2));
+ }
+ if((floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) &&
+ (floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) && floatRect.bottom > point.y) {
+ return FXSYS_fabs(floatRect.bottom - point.y);
+ }
+ if(floatRect.left > point.x && (floatRect.bottom < point.y || FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f) &&
+ (floatRect.top > point.y || FXSYS_fabs(floatRect.top - point.y) <= 0.0001f)) {
+ return FXSYS_fabs(floatRect.left - point.x);
+ }
+ if(floatRect.left > point.x && floatRect.top < point.y) {
+ return FXSYS_sqrt(FXSYS_pow(floatRect.left - point.x, 2) + FXSYS_pow(point.y - floatRect.top, 2));
+ }
+ if ((floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) &&
+ (floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) && floatRect.top < point.y) {
+ return FXSYS_fabs(point.y - floatRect.top);
+ }
+ if(floatRect.right < point.x && (floatRect.top > point.y || FXSYS_fabs(floatRect.top - point.y) <= 0.0001f) &&
+ (floatRect.bottom < point.y || FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f)) {
+ return point.x - floatRect.right;
+ }
+ return .0f;
+}
+int CRF_TextPage::GetIndexAtPos(CPDF_Point point, FX_FLOAT xTorelance, FX_FLOAT yTorelance) const
+{
+ int index = -1, i = 0, j = 0;
+ FPDF_CHAR_INFO info;
+ CFX_FloatRect rectTmp;
+ FX_FLOAT MinDistance = 1000, DistanceTmp = 0;
+ FX_FLOAT rect_bottom = point.x - xTorelance;
+ CFX_FloatRect TorelanceRect(rect_bottom <= 0 ? 0 : rect_bottom, point.y - yTorelance, point.x + xTorelance, point.y + yTorelance);
+ int count = CountChars();
+ for(i = 0; i < count; i++) {
+ GetCharInfo(i, info);
+ rectTmp = info.m_CharBox;
+ if(rectTmp.Contains(point.x, point.y)) {
+ index = i;
+ break;
+ } else if(_IsIntersect(rectTmp, TorelanceRect)) {
+ DistanceTmp = _GetDistance(rectTmp, point);
+ if(DistanceTmp < MinDistance) {
+ MinDistance = DistanceTmp;
+ index = i;
+ }
+ }
+ }
+ return index;
+}
+int CRF_TextPage::GetIndexAtPos(FX_FLOAT x, FX_FLOAT y, FX_FLOAT xTorelance, FX_FLOAT yTorelance) const
+{
+ int index = 0;
+ CPDF_Point point(x, y);
+ if((index = GetIndexAtPos(point, xTorelance, yTorelance)) < 0) {
+ return -1;
+ } else {
+ return index;
+ }
+}
+int CRF_TextPage::GetOrderByDirection(int index, int direction) const
+{
+ return -1;
+}
+CFX_WideString CRF_TextPage::GetTextByRect(CFX_FloatRect rect) const
+{
+ int count;
+ FPDF_CHAR_INFO info;
+ CFX_WideString str;
+ CFX_FloatRect Recttmp;
+ FX_BOOL bstart = TRUE;
+ count = CountChars();
+ if(rect.IsEmpty()) {
+ return L"";
+ }
+ for(int i = 0; i < count; i++) {
+ GetCharInfo(i, info);
+ if(_IsIntersect(rect, info.m_CharBox)) {
+ if(bstart) {
+ Recttmp = info.m_CharBox;
+ str += info.m_Unicode;
+ bstart = FALSE;
+ } else if(_IsInsameline(Recttmp, info.m_CharBox)) {
+ str += info.m_Unicode;
+ } else {
+ str += L"\r\n";
+ Recttmp = info.m_CharBox;
+ str += info.m_Unicode;
+ }
+ }
+ }
+ if(str.IsEmpty()) {
+ return L"";
+ } else {
+ return str;
+ }
+}
+void CRF_TextPage::GetRectsArrayByRect(CFX_FloatRect rect, CFX_RectArray& resRectArray) const
+{
+ int count, i;
+ FX_BOOL bstart = TRUE;
+ FPDF_CHAR_INFO info;
+ CFX_FloatRect recttmp;
+ count = CountChars();
+ for(i = 0; i < count; i++) {
+ GetCharInfo(i, info);
+ if(_IsIntersect(rect, info.m_CharBox)) {
+ if(bstart) {
+ recttmp = info.m_CharBox;
+ bstart = FALSE;
+ } else if(_IsInsameline(recttmp, info.m_CharBox)) {
+ recttmp.right = info.m_CharBox.right;
+ if(info.m_CharBox.top > recttmp.top) {
+ recttmp.top = info.m_CharBox.top;
+ }
+ if(info.m_CharBox.bottom < recttmp.bottom) {
+ recttmp.bottom = info.m_CharBox.bottom;
+ }
+ } else {
+ resRectArray.Add(recttmp);
+ recttmp = info.m_CharBox;
+ }
+ }
+ }
+ resRectArray.Add(recttmp);
+}
+int CRF_TextPage::CountRects(int start, int nCount)
+{
+ m_rectArray.RemoveAll();
+ GetRectArray(start, nCount, m_rectArray);
+ return m_rectArray.GetSize();
+}
+void CRF_TextPage::GetRect(int rectIndex, FX_FLOAT& left, FX_FLOAT& top, FX_FLOAT& right, FX_FLOAT &bottom) const
+{
+ if(m_rectArray.GetSize() <= rectIndex) {
+ return;
+ }
+ left = m_rectArray[rectIndex].left;
+ top = m_rectArray[rectIndex].top;
+ right = m_rectArray[rectIndex].right;
+ bottom = m_rectArray[rectIndex].bottom;
+}
+FX_BOOL CRF_TextPage::GetBaselineRotate(int rectIndex, int& Rotate)
+{
+ Rotate = 0;
+ return TRUE;
+}
+FX_BOOL CRF_TextPage::GetBaselineRotate(CFX_FloatRect rect, int& Rotate)
+{
+ Rotate = 0;
+ return TRUE;
+}
+int CRF_TextPage::CountBoundedSegments(FX_FLOAT left, FX_FLOAT top, FX_FLOAT right, FX_FLOAT bottom, FX_BOOL bContains)
+{
+ if (!m_CountBSArray) {
+ return -1;
+ }
+ m_CountBSArray->RemoveAll();
+ CFX_FloatRect floatrect(left, bottom, right, top);
+ int totalcount, i, j = 0, counttmp = 0;
+ FX_BOOL bstart = TRUE;
+ FPDF_CHAR_INFO info;
+ CFX_FloatRect recttmp;
+ totalcount = CountChars();
+ for(i = 0; i < totalcount; i++) {
+ GetCharInfo(i, info);
+ if(_IsIntersect(floatrect, info.m_CharBox)) {
+ if(bstart) {
+ m_CountBSArray->Add(i);
+ counttmp = 1;
+ recttmp = info.m_CharBox;
+ bstart = FALSE;
+ } else if(_IsInsameline(recttmp, info.m_CharBox)) {
+ recttmp.right = info.m_CharBox.right;
+ if(info.m_CharBox.top > recttmp.top) {
+ recttmp.top = info.m_CharBox.top;
+ }
+ if(info.m_CharBox.bottom < recttmp.bottom) {
+ recttmp.bottom = info.m_CharBox.bottom;
+ }
+ counttmp ++;
+ } else {
+ m_CountBSArray->Add(counttmp);
+ m_CountBSArray->Add(i);
+ counttmp = 1;
+ j++;
+ recttmp = info.m_CharBox;
+ }
+ }
+ }
+ m_CountBSArray->Add(counttmp);
+ j++;
+ return j;
+}
+void CRF_TextPage::GetBoundedSegment(int index, int& start, int& count) const
+{
+ if (!m_CountBSArray) {
+ return;
+ }
+ if(m_CountBSArray->GetSize() <= index * 2) {
+ start = 0;
+ count = 0;
+ return;
+ }
+ start = *(int *)m_CountBSArray->GetAt(index * 2);
+ count = *(int *)m_CountBSArray->GetAt(index * 2 + 1);
+}
+
+int CRF_TextPage::GetWordBreak(int index, int direction) const
+{
+ return -1;
+}
+CFX_WideString CRF_TextPage::GetPageText(int start, int nCount ) const
+{
+ if(nCount == -1) {
+ nCount = CountChars();
+ start = 0;
+ } else if(nCount < 1) {
+ return L"";
+ } else if(start >= CountChars()) {
+ return L"";
+ }
+ int i, index = start + nCount;
+ FPDF_CHAR_INFO info;
+ CFX_WideString str;
+ CFX_FloatRect recttmp;
+ FX_BOOL bstart = TRUE;
+ for(i = start; i < index; i++) {
+ GetCharInfo(i, info);
+ if(bstart) {
+ recttmp = info.m_CharBox;
+ str += info.m_Unicode;
+ bstart = FALSE;
+ } else if (_IsInsameline(recttmp, info.m_CharBox)) {
+ str += info.m_Unicode;
+ } else {
+ str += L"\r\n";
+ recttmp = info.m_CharBox;
+ str += info.m_Unicode;
+ }
+ }
+ if(str.IsEmpty()) {
+ return L"";
+ }
+ return str;
+}