void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) { if (IsVisible() && m_bFlash) { CFX_FloatRect rcRect = GetCaretRect(); CFX_FloatRect rcClip = GetClipRect(); CFX_PathData path; path.SetPointCount(2); FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f; FX_FLOAT fCaretTop = rcRect.top; FX_FLOAT fCaretBottom = rcRect.bottom; if (!rcClip.IsEmpty()) { rcRect.Intersect(rcClip); if (!rcRect.IsEmpty()) { fCaretTop = rcRect.top; fCaretBottom = rcRect.bottom; path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); } else { return; } } else { path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); } CFX_GraphStateData gsd; gsd.m_LineWidth = m_fWidth; pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE); } }
bool CPDF_TextPage::IsSameTextObject(CPDF_TextObject* pTextObj1, CPDF_TextObject* pTextObj2) { if (!pTextObj1 || !pTextObj2) return false; CFX_FloatRect rcPreObj = pTextObj2->GetRect(); const CFX_FloatRect& rcCurObj = pTextObj1->GetRect(); if (rcPreObj.IsEmpty() && rcCurObj.IsEmpty()) { float dbXdif = fabs(rcPreObj.left - rcCurObj.left); size_t nCount = m_CharList.size(); if (nCount >= 2) { PAGECHAR_INFO perCharTemp = m_CharList[nCount - 2]; float dbSpace = perCharTemp.m_CharBox.Width(); if (dbXdif > dbSpace) return false; } } if (!rcPreObj.IsEmpty() || !rcCurObj.IsEmpty()) { rcPreObj.Intersect(rcCurObj); if (rcPreObj.IsEmpty()) return false; if (fabs(rcPreObj.Width() - rcCurObj.Width()) > rcCurObj.Width() / 2) { return false; } if (pTextObj2->GetFontSize() != pTextObj1->GetFontSize()) return false; } size_t nPreCount = pTextObj2->CountItems(); if (nPreCount != pTextObj1->CountItems()) return false; // If both objects have no items, consider them same. if (nPreCount == 0) return true; CPDF_TextObjectItem itemPer; CPDF_TextObjectItem itemCur; for (size_t i = 0; i < nPreCount; ++i) { pTextObj2->GetItemInfo(i, &itemPer); pTextObj1->GetItemInfo(i, &itemCur); if (itemCur.m_CharCode != itemPer.m_CharCode) return false; } CFX_PointF diff = pTextObj1->GetPos() - pTextObj2->GetPos(); float font_size = pTextObj2->GetFontSize(); float char_size = GetCharWidth(itemPer.m_CharCode, pTextObj2->GetFont()); float max_pre_size = std::max(std::max(rcPreObj.Height(), rcPreObj.Width()), font_size); return fabs(diff.x) <= 0.9 * char_size * font_size / 1000 && fabs(diff.y) <= max_pre_size / 8; }
void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { CPWL_Wnd::GetThisAppearanceStream(sAppStream); CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect(); if (IsVisible() && !rectWnd.IsEmpty()) { CFX_ByteTextBuf sButton; CFX_FloatPoint ptCenter = GetCenterPoint(); CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_FloatPoint pt3(ptCenter.x, ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); if (IsFloatBigger(rectWnd.right - rectWnd.left, PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) && IsFloatBigger(rectWnd.top - rectWnd.bottom, PWL_CBBUTTON_TRIANGLE_HALFLEN)) { sButton << "0 g\n"; sButton << pt1.x << " " << pt1.y << " m\n"; sButton << pt2.x << " " << pt2.y << " l\n"; sButton << pt3.x << " " << pt3.y << " l\n"; sButton << pt1.x << " " << pt1.y << " l f\n"; sAppStream << "q\n" << sButton << "Q\n"; } } }
void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) { CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect(); if (IsVisible() && !rectWnd.IsEmpty()) { CFX_PointF ptCenter = GetCenterPoint(); CFX_PointF pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_PointF pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_PointF pt3(ptCenter.x, ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); if (IsFloatBigger(rectWnd.right - rectWnd.left, PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) && IsFloatBigger(rectWnd.top - rectWnd.bottom, PWL_CBBUTTON_TRIANGLE_HALFLEN)) { CFX_PathData path; path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false); path.AppendPoint(pt2, FXPT_TYPE::LineTo, false); path.AppendPoint(pt3, FXPT_TYPE::LineTo, false); path.AppendPoint(pt1, FXPT_TYPE::LineTo, false); pDevice->DrawPath(&path, pUser2Device, nullptr, PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0, FXFILL_ALTERNATE); } } }
void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) { CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect(); if (IsVisible() && !rectWnd.IsEmpty()) { CFX_FloatPoint ptCenter = GetCenterPoint(); CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); CFX_FloatPoint pt3(ptCenter.x, ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); if (IsFloatBigger(rectWnd.right - rectWnd.left, PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) && IsFloatBigger(rectWnd.top - rectWnd.bottom, PWL_CBBUTTON_TRIANGLE_HALFLEN)) { CFX_PathData path; path.SetPointCount(4); path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); pDevice->DrawPath(&path, pUser2Device, nullptr, CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR, GetTransparency()), 0, FXFILL_ALTERNATE); } } }
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 CFFL_InteractiveFormFiller::OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, const CFX_Matrix& mtUser2Device) { ASSERT(pPageView); CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot); if (!IsVisible(pWidget)) return; CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false); if (pFormFiller && pFormFiller->IsValid()) { pFormFiller->OnDraw(pPageView, pAnnot, pDevice, mtUser2Device); pAnnot->GetPDFPage(); if (m_pFormFillEnv->GetFocusAnnot() != pAnnot) return; CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView); if (rcFocus.IsEmpty()) return; CFX_PathData path; path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), FXPT_TYPE::MoveTo, false); path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.bottom), FXPT_TYPE::LineTo, false); path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.bottom), FXPT_TYPE::LineTo, false); path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.top), FXPT_TYPE::LineTo, false); path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), FXPT_TYPE::LineTo, false); CFX_GraphStateData gsd; gsd.m_DashArray = {1.0f}; gsd.m_DashPhase = 0; gsd.m_LineWidth = 1.0f; pDevice->DrawPath(&path, &mtUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE); return; } pFormFiller = GetFormFiller(pAnnot, false); if (pFormFiller) { pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, mtUser2Device); } else { pWidget->DrawAppearance(pDevice, mtUser2Device, CPDF_Annot::Normal, nullptr); } if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget)) pWidget->DrawShadow(pDevice, pPageView); }
void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, FX_DWORD dwFlags) { ASSERT(pPageView); CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot; if (IsVisible(pWidget)) { if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) { if (pFormFiller->IsValid()) { pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags); pAnnot->GetPDFPage(); CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument(); if (pDocument->GetFocusAnnot() == pAnnot) { CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView); if (!rcFocus.IsEmpty()) { CFX_PathData path; path.SetPointCount(5); path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO); path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO); path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO); path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO); path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO); CFX_GraphStateData gsd; gsd.SetDashCount(1); gsd.m_DashArray[0] = 1.0f; gsd.m_DashPhase = 0; gsd.m_LineWidth = 1.0f; pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE); } } return; } } if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device, dwFlags); else pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL); if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget)) pWidget->DrawShadow(pDevice, pPageView); } }
FX_RECT CFFL_InteractiveFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) { if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false)) return pFormFiller->GetViewBBox(pPageView, pAnnot); ASSERT(pPageView); CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot(); CFX_FloatRect rcWin = pPDFAnnot->GetRect(); if (!rcWin.IsEmpty()) { rcWin.Inflate(1, 1); rcWin.Normalize(); } return rcWin.GetOuterRect(); }
CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot, CFX_FloatRect rcStream, const CFX_Matrix& matrix) { if (rcStream.IsEmpty()) return CFX_Matrix(); matrix.TransformRect(rcStream); rcStream.Normalize(); FX_FLOAT a = rcAnnot.Width() / rcStream.Width(); FX_FLOAT d = rcAnnot.Height() / rcStream.Height(); FX_FLOAT e = rcAnnot.left - rcStream.left * a; FX_FLOAT f = rcAnnot.bottom - rcStream.bottom * d; return CFX_Matrix(a, 0, 0, d, e, f); }
FX_BOOL IsValiableRect(CFX_FloatRect rect, CFX_FloatRect rcPage) { if (rect.left - rect.right > 0.000001f || rect.bottom - rect.top > 0.000001f) return FALSE; if (rect.left == 0.0f && rect.top == 0.0f && rect.right == 0.0f && rect.bottom == 0.0f) return FALSE; if (!rcPage.IsEmpty()) { if (rect.left - rcPage.left < -10.000001f || rect.right - rcPage.right > 10.000001f || rect.top - rcPage.top > 10.000001f || rect.bottom - rcPage.bottom < -10.000001f) return FALSE; } return TRUE; }
void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) { CFX_FloatRect rectWnd = GetWindowRect(); if (!rectWnd.IsEmpty()) { if (HasFlag(PWS_BACKGROUND)) { CFX_FloatRect rcClient = CPWL_Utils::DeflateRect( rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient, GetBackgroundColor(), GetTransparency()); } if (HasFlag(PWS_BORDER)) CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(), GetBorderLeftTopColor(GetBorderStyle()), GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(), GetTransparency()); } }
// if don't set,Get default apperance stream void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { CFX_FloatRect rectWnd = GetWindowRect(); if (!rectWnd.IsEmpty()) { CFX_ByteTextBuf sThis; if (HasFlag(PWS_BACKGROUND)) sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor()); if (HasFlag(PWS_BORDER)) { sThis << CPWL_Utils::GetBorderAppStream( rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(), GetBorderLeftTopColor(GetBorderStyle()), GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(), GetBorderDash()); } sAppStream << sThis; } }
FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) { ASSERT(pPageView); ASSERT(pAnnot); CFX_FloatRect rcAnnot = m_pWidget->GetRect(); if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) { CFX_FloatRect rcWindow = pWnd->GetWindowRect(); rcAnnot = PWLtoFFL(rcWindow); } CFX_FloatRect rcWin = rcAnnot; CFX_FloatRect rcFocus = GetFocusBox(pPageView); if (!rcFocus.IsEmpty()) rcWin.Union(rcFocus); CFX_FloatRect rect = CPWL_Utils::InflateRect(rcWin, 1); return rect.GetOutterRect(); }
void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream, const CFX_FloatPoint& ptOffset) { if (IsVisible() && m_bFlash) { CFX_ByteTextBuf sCaret; CFX_FloatRect rcRect = GetCaretRect(); CFX_FloatRect rcClip = GetClipRect(); rcRect = CPWL_Utils::OffsetRect(rcRect, ptOffset.x, ptOffset.y); rcClip = CPWL_Utils::OffsetRect(rcClip, ptOffset.x, ptOffset.y); sCaret << "q\n"; if (!rcClip.IsEmpty()) { sCaret << rcClip.left << " " << rcClip.bottom + 2.5f << " " << rcClip.right - rcClip.left << " " << rcClip.top - rcClip.bottom - 4.5f << " re W n\n"; } sCaret << m_fWidth << " w\n0 G\n"; sCaret << rcRect.left + m_fWidth / 2 << " " << rcRect.bottom << " m\n"; sCaret << rcRect.left + m_fWidth / 2 << " " << rcRect.top << " l S\nQ\n"; sAppStream << sCaret; } }
void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) { if (IsValid()) { CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect(); if (!HasFlag(PWS_NOREFRESHCLIP)) { CFX_FloatRect rcClip = GetClipRect(); if (!rcClip.IsEmpty()) { rcRefresh.Intersect(rcClip); } } FX_RECT rcWin = PWLtoWnd(rcRefresh); rcWin.left -= PWL_INVALIDATE_INFLATE; rcWin.top -= PWL_INVALIDATE_INFLATE; rcWin.right += PWL_INVALIDATE_INFLATE; rcWin.bottom += PWL_INVALIDATE_INFLATE; if (CFX_SystemHandler* pSH = GetSystemHandler()) { if (FX_HWND hWnd = GetAttachedHWnd()) { pSH->InvalidateRect(hWnd, rcWin); } } } }
void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BOOL bPageCache) { m_pDocument = (CPDF_Document*)pDocument; m_pFormDict = pPageDict; if (bPageCache) { m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this); } if (pPageDict == NULL) { m_PageWidth = m_PageHeight = 100 * 1.0f; m_pPageResources = m_pResources = NULL; return; } CPDF_Object* pageAttr = GetPageAttr(FX_BSTRC("Resources")); m_pResources = pageAttr ? pageAttr->GetDict() : NULL; m_pPageResources = m_pResources; CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate")); int rotate = 0; if (pRotate) { rotate = pRotate->GetInteger() / 90 % 4; } if (rotate < 0) { rotate += 4; } CPDF_Array* pMediaBox, *pCropBox; pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox")); CFX_FloatRect mediabox; if (pMediaBox) { mediabox = pMediaBox->GetRect(); mediabox.Normalize(); } if (mediabox.IsEmpty()) { mediabox = CFX_FloatRect(0, 0, 612, 792); } pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox")); if (pCropBox) { m_BBox = pCropBox->GetRect(); m_BBox.Normalize(); } if (m_BBox.IsEmpty()) { m_BBox = mediabox; } else { m_BBox.Intersect(mediabox); } if (rotate % 2) { m_PageHeight = m_BBox.right - m_BBox.left; m_PageWidth = m_BBox.top - m_BBox.bottom; } else { m_PageWidth = m_BBox.right - m_BBox.left; m_PageHeight = m_BBox.top - m_BBox.bottom; } switch (rotate) { case 0: m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); break; case 1: m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); break; case 2: m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); break; case 3: m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); break; } m_Transparency = PDFTRANS_ISOLATED; LoadTransInfo(); }
DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!page) { return FLATTEN_FAIL; } CPDF_Document* pDocument = pPage->m_pDocument; CPDF_Dictionary* pPageDict = pPage->m_pFormDict; if (!pDocument || !pPageDict) { return FLATTEN_FAIL; } CPDF_ObjectArray ObjectArray; CPDF_RectArray RectArray; int iRet = FLATTEN_FAIL; iRet = ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag); if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL) return iRet; CFX_FloatRect rcOriginalCB; CFX_FloatRect rcMerger = CalculateRect(&RectArray); CFX_FloatRect rcOriginalMB = pPageDict->GetRectFor("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRectFor("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CFX_FloatRect(0.0f, 0.0f, 612.0f, 792.0f); } rcMerger.left = rcMerger.left < rcOriginalMB.left ? rcOriginalMB.left : rcMerger.left; rcMerger.right = rcMerger.right > rcOriginalMB.right ? rcOriginalMB.right : rcMerger.right; rcMerger.top = rcMerger.top > rcOriginalMB.top ? rcOriginalMB.top : rcMerger.top; rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom ? rcOriginalMB.bottom : rcMerger.bottom; if (pPageDict->KeyExist("ArtBox")) rcOriginalCB = pPageDict->GetRectFor("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = new CPDF_Array(); pMediaBox->Add(new CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.top)); pPageDict->SetFor("MediaBox", pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = new CPDF_Array(); pCropBox->Add(new CPDF_Number(rcOriginalCB.left)); pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(new CPDF_Number(rcOriginalCB.right)); pCropBox->Add(new CPDF_Number(rcOriginalCB.top)); pPageDict->SetFor("ArtBox", pCropBox); } CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); if (!pRes) { pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pPageDict->SetFor("Resources", pRes); } CPDF_Stream* pNewXObject = new CPDF_Stream( nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); uint32_t dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); if (!pPageXObject) { pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pRes->SetFor("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = nullptr; if (!key.IsEmpty()) { pPageXObject->SetReferenceFor(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewOXbjectDic->SetFor("Resources", pNewXORes); pNewOXbjectDic->SetNameFor("Type", "XObject"); pNewOXbjectDic->SetNameFor("Subtype", "Form"); pNewOXbjectDic->SetIntegerFor("FormType", 1); pNewOXbjectDic->SetNameFor("Name", "FRM"); CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox"); pNewOXbjectDic->SetRectFor("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic) continue; CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP"); if (!pAnnotAP) continue; CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N"); if (!pAPDic) continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStreamFor(sAnnotState); } else { auto it = pAPDic->begin(); if (it != pAPDic->end()) { CPDF_Object* pFirstObj = it->second; if (pFirstObj) { if (pFirstObj->IsReference()) pFirstObj = pFirstObj->GetDirect(); if (!pFirstObj->IsStream()) continue; pAPStream = pFirstObj->AsStream(); } } } } if (!pAPStream) continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix"); CFX_FloatRect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRectFor("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRectFor("BBox"); if (rcStream.IsEmpty()) continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetNameFor("Type", "XObject"); pObjDic->SetNameFor("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); if (!pXObject) { pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewXORes->SetFor("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); pXObject->SetReferenceFor(sFormName, pDocument, pDocument->AddIndirectObject(pObj)); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); const uint8_t* pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); if (matrix.IsIdentity()) { matrix.a = 1.0f; matrix.b = 0.0f; matrix.c = 0.0f; matrix.d = 1.0f; matrix.e = 0.0f; matrix.f = 0.0f; } CFX_ByteString sTemp; CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); } pPageDict->RemoveFor("Annots"); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }
CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( const CPDF_TextObject* pObj, const CFX_Matrix& formMatrix) { FindPreviousTextObject(); TextOrientation WritingMode = GetTextObjectWritingMode(pObj); if (WritingMode == TextOrientation::Unknown) WritingMode = GetTextObjectWritingMode(m_pPreTextObj.Get()); size_t nItem = m_pPreTextObj->CountItems(); if (nItem == 0) return GenerateCharacter::None; CPDF_TextObjectItem PrevItem; m_pPreTextObj->GetItemInfo(nItem - 1, &PrevItem); CPDF_TextObjectItem item; pObj->GetItemInfo(0, &item); const CFX_FloatRect& this_rect = pObj->GetRect(); const CFX_FloatRect& prev_rect = m_pPreTextObj->GetRect(); WideString wstrItem = pObj->GetFont()->UnicodeFromCharCode(item.m_CharCode); if (wstrItem.IsEmpty()) wstrItem += static_cast<wchar_t>(item.m_CharCode); wchar_t curChar = wstrItem[0]; if (WritingMode == TextOrientation::Horizontal) { if (EndHorizontalLine(this_rect, prev_rect)) { return IsHyphen(curChar) ? GenerateCharacter::Hyphen : GenerateCharacter::LineBreak; } } else if (WritingMode == TextOrientation::Vertical) { if (EndVerticalLine(this_rect, prev_rect, m_CurlineRect, pObj->GetFontSize(), m_pPreTextObj->GetFontSize())) { return IsHyphen(curChar) ? GenerateCharacter::Hyphen : GenerateCharacter::LineBreak; } } float last_pos = PrevItem.m_Origin.x; uint32_t nLastWidth = GetCharWidth(PrevItem.m_CharCode, m_pPreTextObj->GetFont()); float last_width = nLastWidth * m_pPreTextObj->GetFontSize() / 1000; last_width = fabs(last_width); uint32_t nThisWidth = GetCharWidth(item.m_CharCode, pObj->GetFont()); float this_width = fabs(nThisWidth * pObj->GetFontSize() / 1000); float threshold = std::max(last_width, this_width) / 4; CFX_Matrix prev_matrix = m_pPreTextObj->GetTextMatrix() * m_perMatrix; CFX_Matrix prev_reverse = prev_matrix.GetInverse(); CFX_PointF pos = prev_reverse.Transform(formMatrix.Transform(pObj->GetPos())); if (last_width < this_width) threshold = prev_reverse.TransformDistance(threshold); bool bNewline = false; if (WritingMode == TextOrientation::Horizontal) { CFX_FloatRect rect = m_pPreTextObj->GetRect(); float rect_height = rect.Height(); rect.Normalize(); if ((rect.IsEmpty() && rect_height > 5) || ((pos.y > threshold * 2 || pos.y < threshold * -3) && (fabs(pos.y) >= 1 || fabs(pos.y) > fabs(pos.x)))) { bNewline = true; if (nItem > 1) { CPDF_TextObjectItem tempItem; m_pPreTextObj->GetItemInfo(0, &tempItem); CFX_Matrix m = m_pPreTextObj->GetTextMatrix(); if (PrevItem.m_Origin.x > tempItem.m_Origin.x && m_DisplayMatrix.a > 0.9 && m_DisplayMatrix.b < 0.1 && m_DisplayMatrix.c < 0.1 && m_DisplayMatrix.d < -0.9 && m.b < 0.1 && m.c < 0.1) { CFX_FloatRect re(0, m_pPreTextObj->GetRect().bottom, 1000, m_pPreTextObj->GetRect().top); if (re.Contains(pObj->GetPos())) { bNewline = false; } else { if (CFX_FloatRect(0, pObj->GetRect().bottom, 1000, pObj->GetRect().top) .Contains(m_pPreTextObj->GetPos())) { bNewline = false; } } } } } } if (bNewline) { return IsHyphen(curChar) ? GenerateCharacter::Hyphen : GenerateCharacter::LineBreak; } if (pObj->CountChars() == 1 && IsHyphenCode(curChar) && IsHyphen(curChar)) return GenerateCharacter::Hyphen; if (curChar == L' ') return GenerateCharacter::None; WideString PrevStr = m_pPreTextObj->GetFont()->UnicodeFromCharCode(PrevItem.m_CharCode); wchar_t preChar = PrevStr.Last(); if (preChar == L' ') return GenerateCharacter::None; CFX_Matrix matrix = pObj->GetTextMatrix() * formMatrix; float threshold2 = static_cast<float>(std::max(nLastWidth, nThisWidth)); threshold2 = NormalizeThreshold(threshold2, 400, 700, 800); if (nLastWidth >= nThisWidth) { threshold2 *= fabs(m_pPreTextObj->GetFontSize()); } else { threshold2 *= fabs(pObj->GetFontSize()); threshold2 = matrix.TransformDistance(threshold2); threshold2 = prev_reverse.TransformDistance(threshold2); } threshold2 /= 1000; if ((threshold2 < 1.4881 && threshold2 > 1.4879) || (threshold2 < 1.39001 && threshold2 > 1.38999)) { threshold2 *= 1.5; } return GenerateSpace(pos, last_pos, this_width, last_width, threshold2) ? GenerateCharacter::Space : GenerateCharacter::None; }
CPDF_Page::CPDF_Page(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, bool bPageCache) : m_PageWidth(100), m_PageHeight(100), m_pView(nullptr), m_pPageRender(bPageCache ? new CPDF_PageRenderCache(this) : nullptr) { m_pFormDict = pPageDict; m_pDocument = pDocument; if (!pPageDict) return; CPDF_Object* pageAttr = GetPageAttr("Resources"); m_pResources = pageAttr ? pageAttr->GetDict() : nullptr; m_pPageResources = m_pResources; CPDF_Object* pRotate = GetPageAttr("Rotate"); int rotate = pRotate ? pRotate->GetInteger() / 90 % 4 : 0; if (rotate < 0) rotate += 4; CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox")); CFX_FloatRect mediabox; if (pMediaBox) { mediabox = pMediaBox->GetRect(); mediabox.Normalize(); } if (mediabox.IsEmpty()) mediabox = CFX_FloatRect(0, 0, 612, 792); CPDF_Array* pCropBox = ToArray(GetPageAttr("CropBox")); if (pCropBox) { m_BBox = pCropBox->GetRect(); m_BBox.Normalize(); } if (m_BBox.IsEmpty()) m_BBox = mediabox; else m_BBox.Intersect(mediabox); m_PageWidth = m_BBox.right - m_BBox.left; m_PageHeight = m_BBox.top - m_BBox.bottom; if (rotate % 2) std::swap(m_PageWidth, m_PageHeight); switch (rotate) { case 0: m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); break; case 1: m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); break; case 2: m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); break; case 3: m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); break; } m_Transparency = PDFTRANS_ISOLATED; LoadTransInfo(); }