summaryrefslogtreecommitdiff
path: root/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk/src/fxedit/fxet_pageobjs.cpp')
-rw-r--r--fpdfsdk/src/fxedit/fxet_pageobjs.cpp687
1 files changed, 687 insertions, 0 deletions
diff --git a/fpdfsdk/src/fxedit/fxet_pageobjs.cpp b/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
new file mode 100644
index 0000000000..99520619ad
--- /dev/null
+++ b/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
@@ -0,0 +1,687 @@
+// 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 "../../include/fxedit/fxet_stub.h"
+#include "../../include/fxedit/fx_edit.h"
+#include "../../include/fxedit/fxet_edit.h"
+
+#define FX_EDIT_UNDERLINEHALFWIDTH 0.5f
+#define FX_EDIT_CROSSOUTHALFWIDTH 0.5f
+
+extern CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord);
+
+CPDF_Rect GetUnderLineRect(const CPVT_Word& word)
+{
+ return CPDF_Rect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f,
+ word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.25f);
+}
+
+CPDF_Rect GetCrossoutRect(const CPVT_Word& word)
+{
+ return CPDF_Rect(word.ptWord.x, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f + word.fDescent * 0.25f,
+ word.ptWord.x + word.fWidth, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f);
+}
+
+static void DrawTextString(CFX_RenderDevice* pDevice, const CPDF_Point& pt, CPDF_Font* pFont, FX_FLOAT fFontSize, CPDF_Matrix* pUser2Device,
+ const CFX_ByteString& str, FX_ARGB crTextFill, FX_ARGB crTextStroke, FX_INT32 nHorzScale)
+{
+ FX_FLOAT x = pt.x, y = pt.y;
+ pUser2Device->Transform(x, y);
+
+ if (pFont)
+ {
+ if (nHorzScale != 100)
+ {
+ CPDF_Matrix mt(nHorzScale/100.0f,0,0,1,0,0);
+ mt.Concat(*pUser2Device);
+
+ CPDF_RenderOptions ro;
+ ro.m_Flags = RENDER_CLEARTYPE;
+ ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+ if (crTextStroke != 0)
+ {
+ CPDF_Point pt1(0,0), pt2(1,0);
+ pUser2Device->Transform(pt1.x, pt1.y);
+ pUser2Device->Transform(pt2.x, pt2.y);
+ CFX_GraphStateData gsd;
+ gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+ CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, crTextStroke, &gsd, &ro);
+ }
+ else
+ CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, 0, NULL, &ro);
+ }
+ else
+ {
+ CPDF_RenderOptions ro;
+ ro.m_Flags = RENDER_CLEARTYPE;
+ ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+ if (crTextStroke != 0)
+ {
+ CPDF_Point pt1(0,0), pt2(1,0);
+ pUser2Device->Transform(pt1.x, pt1.y);
+ pUser2Device->Transform(pt2.x, pt2.y);
+ CFX_GraphStateData gsd;
+ gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+ CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, crTextStroke, &gsd, &ro);
+ }
+ else
+ CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, 0, NULL, &ro);
+ }
+ }
+}
+
+void IFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF color,
+ const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)
+{
+ pDevice->SaveState();
+
+ if (!rcClip.IsEmpty())
+ {
+ CPDF_Rect rcTemp = rcClip;
+ pUser2Device->TransformRect(rcTemp);
+ FX_RECT rcDevClip;
+ rcDevClip.left = (FX_INT32)rcTemp.left;
+ rcDevClip.right = (FX_INT32)rcTemp.right;
+ rcDevClip.top = (FX_INT32)rcTemp.top;
+ rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
+ pDevice->SetClip_Rect(&rcDevClip);
+ }
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+ CFX_PathData pathUnderline;
+ CPDF_Rect rcUnderline = GetUnderLineRect(word);
+ rcUnderline.left += ptOffset.x;
+ rcUnderline.right += ptOffset.x;
+ rcUnderline.top += ptOffset.y;
+ rcUnderline.bottom += ptOffset.y;
+ pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);
+
+ pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, color, 0, FXFILL_WINDING);
+ }
+ }
+ }
+ }
+
+ pDevice->RestoreState();
+}
+
+void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF crTextFill, FX_COLORREF crTextStroke,
+ const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, IFX_SystemHandler* pSystemHandler, void* pFFLData)
+{
+
+ FX_BOOL bContinuous = pEdit->GetCharArray() == 0;
+ if (pEdit->GetCharSpace() > 0.0f)
+ bContinuous = FALSE;
+
+ FX_WORD SubWord = pEdit->GetPasswordChar();
+ FX_FLOAT fFontSize = pEdit->GetFontSize();
+ CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
+ FX_INT32 nHorzScale = pEdit->GetHorzScale();
+
+ FX_COLORREF crCurFill = crTextFill;
+ FX_COLORREF crOldFill = crCurFill;
+
+ FX_BOOL bSelect = FALSE;
+ const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);
+ const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);
+
+ CFX_ByteTextBuf sTextBuf;
+ FX_INT32 nFontIndex = -1;
+ CPDF_Point ptBT(0.0f,0.0f);
+
+ pDevice->SaveState();
+
+ if (!rcClip.IsEmpty())
+ {
+ CPDF_Rect rcTemp = rcClip;
+ pUser2Device->TransformRect(rcTemp);
+ FX_RECT rcDevClip;
+ rcDevClip.left = (FX_INT32)rcTemp.left;
+ rcDevClip.right = (FX_INT32)rcTemp.right;
+ rcDevClip.top = (FX_INT32)rcTemp.top;
+ rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
+ pDevice->SetClip_Rect(&rcDevClip);
+ }
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ CPVT_WordPlace oldplace;
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ if (wrSelect.IsExist())
+ {
+ bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;
+ if (bSelect)
+ {
+ crCurFill = crWhite;
+ }
+ else
+ {
+ crCurFill = crTextFill;
+ }
+ }
+ if(pSystemHandler && pSystemHandler->IsSelectionImplemented())
+ {
+ crCurFill = crTextFill;
+ crOldFill = crCurFill;
+ }
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+
+ if (bSelect)
+ {
+
+ CPVT_Line line;
+ pIterator->GetLine(line);
+
+ if(pSystemHandler && pSystemHandler->IsSelectionImplemented())
+ {
+ CPDF_Rect rc(word.ptWord.x,line.ptLine.y + line.fLineDescent,
+ word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
+ rc.Intersect(rcClip);
+ //CFX_Edit* pEt = (CFX_Edit*)pEdit;
+ //CPDF_Rect rcEdit = pEt->VTToEdit(rc);
+ pSystemHandler->OutputSelectedRect(pFFLData,rc);
+ }
+ else
+ {
+ CFX_PathData pathSelBK;
+ pathSelBK.AppendRect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
+ word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
+
+ pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);
+ }
+ }
+
+ if (bContinuous)
+ {
+ if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
+ crOldFill != crCurFill)
+ {
+ if (sTextBuf.GetLength() > 0)
+ {
+ DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),
+ fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);
+
+ sTextBuf.Clear();
+ }
+ nFontIndex = word.nFontIndex;
+ ptBT = word.ptWord;
+ crOldFill = crCurFill;
+ }
+
+ sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord);
+ }
+ else
+ {
+ DrawTextString(pDevice,CPDF_Point(word.ptWord.x+ptOffset.x, word.ptWord.y+ptOffset.y), pFontMap->GetPDFFont(word.nFontIndex),
+ fFontSize, pUser2Device, GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord), crCurFill, crTextStroke, nHorzScale);
+
+ }
+ oldplace = place;
+
+
+ }
+ }
+
+ if (sTextBuf.GetLength() > 0)
+ {
+ DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),
+ fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);
+ }
+ }
+ }
+
+ pDevice->RestoreState();
+}
+
+void IFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit,
+ const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)
+{
+ //FX_FLOAT fFontSize = pEdit->GetFontSize();
+ CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
+
+ FX_COLORREF crCurText = ArgbEncode(255, 0,0,0);
+ FX_COLORREF crOld = crCurText;
+ FX_BOOL bSelect = FALSE;
+ const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);
+ const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);
+
+ CFX_ByteTextBuf sTextBuf;
+ CPVT_WordProps wp;
+ CPDF_Point ptBT(0.0f,0.0f);
+
+ pDevice->SaveState();
+
+ if (!rcClip.IsEmpty())
+ {
+ CPDF_Rect rcTemp = rcClip;
+ pUser2Device->TransformRect(rcTemp);
+ FX_RECT rcDevClip;
+ rcDevClip.left = (FX_INT32)rcTemp.left;
+ rcDevClip.right = (FX_INT32)rcTemp.right;
+ rcDevClip.top = (FX_INT32)rcTemp.top;
+ rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
+ pDevice->SetClip_Rect(&rcDevClip);
+ }
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ CPVT_WordPlace oldplace;
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+ word.WordProps.fFontSize = word.fFontSize;
+
+ crCurText = ArgbEncode(255,word.WordProps.dwWordColor);
+
+ if (wrSelect.IsExist())
+ {
+ bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;
+ if (bSelect)
+ {
+ crCurText = crWhite;
+ }
+ }
+
+ if (bSelect)
+ {
+ CPVT_Line line;
+ pIterator->GetLine(line);
+
+ CFX_PathData pathSelBK;
+ pathSelBK.AppendRect(word.ptWord.x + ptOffset.x,
+ line.ptLine.y + line.fLineDescent + ptOffset.y,
+ word.ptWord.x+word.fWidth + ptOffset.x,
+ line.ptLine.y + line.fLineAscent + ptOffset.y);
+
+ pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);
+ }
+
+ if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 ||
+ FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
+ crOld != crCurText)
+ {
+ if (sTextBuf.GetLength() > 0)
+ {
+ DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),
+ wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);
+
+ sTextBuf.Clear();
+ }
+ wp = word.WordProps;
+ ptBT = word.ptWord;
+ crOld = crCurText;
+ }
+
+ sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);
+
+ if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)
+ {
+ CFX_PathData pathUnderline;
+ CPDF_Rect rcUnderline = GetUnderLineRect(word);
+ pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);
+
+ pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);
+ }
+
+ if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)
+ {
+ CFX_PathData pathCrossout;
+ CPDF_Rect rcCrossout = GetCrossoutRect(word);
+ pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom, rcCrossout.right, rcCrossout.top);
+
+ pDevice->DrawPath(&pathCrossout, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);
+ }
+
+ oldplace = place;
+ }
+ }
+
+ if (sTextBuf.GetLength() > 0)
+ {
+ DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),
+ wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);
+ }
+ }
+ }
+
+ pDevice->RestoreState();
+}
+
+static void AddLineToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crStroke,
+ const CPDF_Point& pt1, const CPDF_Point& pt2)
+{
+ CPDF_PathObject* pPathObj = new CPDF_PathObject;
+ CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();
+
+ pPathData->SetPointCount(2);
+ pPathData->SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
+ pPathData->SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
+
+ FX_FLOAT rgb[3];
+ rgb[0] = FXARGB_R(crStroke) / 255.0f;
+ rgb[1] = FXARGB_G(crStroke) / 255.0f;
+ rgb[2] = FXARGB_B(crStroke) / 255.0f;
+ pPathObj->m_ColorState.SetStrokeColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+
+ CFX_GraphStateData* pData = pPathObj->m_GraphState.GetModify();
+ pData->m_LineWidth = 1;
+
+ pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pPathObj);
+}
+
+static void AddRectToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crFill, const CPDF_Rect& rcFill)
+{
+ CPDF_PathObject* pPathObj = new CPDF_PathObject;
+ CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();
+ pPathData->AppendRect(rcFill.left,rcFill.bottom,rcFill.right,rcFill.top);
+
+ FX_FLOAT rgb[3];
+ rgb[0] = FXARGB_R(crFill) / 255.0f ;
+ rgb[1] = FXARGB_G(crFill) / 255.0f;
+ rgb[2] = FXARGB_B(crFill) / 255.0f;
+ pPathObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+
+ pPathObj->m_FillType = FXFILL_ALTERNATE;
+ pPathObj->m_bStroke = FALSE;
+
+ pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pPathObj);
+}
+
+static CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crText,
+ CPDF_Font* pFont, FX_FLOAT fFontSize, FX_FLOAT fCharSpace, FX_INT32 nHorzScale,
+ const CPDF_Point& point, const CFX_ByteString& text)
+{
+ CPDF_TextObject* pTxtObj = new CPDF_TextObject;
+
+ CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
+ pTextStateData->m_pFont = pFont;
+ pTextStateData->m_FontSize = fFontSize;
+ pTextStateData->m_CharSpace = fCharSpace;
+ pTextStateData->m_WordSpace = 0;
+ pTextStateData->m_TextMode = 0;
+ pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;
+ pTextStateData->m_Matrix[1] = 0;
+ pTextStateData->m_Matrix[2] = 0;
+ pTextStateData->m_Matrix[3] = 1;
+
+ FX_FLOAT rgb[3];
+ rgb[0] = FXARGB_R(crText) / 255.0f ;
+ rgb[1] = FXARGB_G(crText) / 255.0f;
+ rgb[2] = FXARGB_B(crText) / 255.0f;
+ pTxtObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);
+ pTxtObj->m_ColorState.SetStrokeColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);
+
+ pTxtObj->SetPosition(point.x,point.y);
+ pTxtObj->SetText(text);
+
+ pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pTxtObj);
+
+ return pTxtObj;
+}
+
+/*
+List of currently supported standard fonts:
+Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique
+Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique
+Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
+Symbol, ZapfDingbats
+*/
+
+const char* g_sFXEDITStandardFontName[] = {"Courier", "Courier-Bold", "Courier-BoldOblique", "Courier-Oblique",
+ "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Oblique",
+ "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
+ "Symbol", "ZapfDingbats"};
+
+static FX_BOOL FX_EDIT_IsStandardFont(const CFX_ByteString& sFontName)
+{
+ for (FX_INT32 i=0; i<14; i++)
+ {
+ if (sFontName == g_sFXEDITStandardFontName[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void IFX_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
+ const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF crText, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)
+{
+ FX_FLOAT fFontSize = pEdit->GetFontSize();
+
+ FX_INT32 nOldFontIndex = -1;
+
+ CFX_ByteTextBuf sTextBuf;
+ CPDF_Point ptBT(0.0f,0.0f);
+
+ ObjArray.RemoveAll();
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ CPVT_WordPlace oldplace;
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+ if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex)
+ {
+ if (sTextBuf.GetLength() > 0)
+ {
+ ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,
+ CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
+
+ sTextBuf.Clear();
+ }
+
+ ptBT = word.ptWord;
+ nOldFontIndex = word.nFontIndex;
+ }
+
+ sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0);
+ oldplace = place;
+ }
+ }
+
+ if (sTextBuf.GetLength() > 0)
+ {
+ ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,
+ CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
+ }
+ }
+ }
+}
+
+void IFX_Edit::GenerateRichPageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
+ const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)
+{
+
+
+ FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
+ FX_COLORREF crOld = crCurText;
+
+
+ CFX_ByteTextBuf sTextBuf;
+ CPVT_WordProps wp;
+ CPDF_Point ptBT(0.0f,0.0f);
+
+ ObjArray.RemoveAll();
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ CPVT_WordPlace oldplace;
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+ word.WordProps.fFontSize = word.fFontSize;
+
+ crCurText = ArgbEncode(255,word.WordProps.dwWordColor);
+
+ if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 ||
+ FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
+ crOld != crCurText)
+ {
+ if (sTextBuf.GetLength() > 0)
+ {
+ ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
+ CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
+
+ sTextBuf.Clear();
+ }
+
+ wp = word.WordProps;
+ ptBT = word.ptWord;
+ crOld = crCurText;
+
+ }
+
+ sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);
+
+ if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)
+ {/*
+ AddLineToPageObjects(pPageObjects, crCurText,
+ CPDF_Point(word.ptWord.x, word.ptWord.y + word.fDescent * 0.4f),
+ CPDF_Point(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.4f));
+*/
+ CPDF_Rect rcUnderline = GetUnderLineRect(word);
+ rcUnderline.left += ptOffset.x;
+ rcUnderline.right += ptOffset.x;
+ rcUnderline.top += ptOffset.y;
+ rcUnderline.bottom += ptOffset.y;
+
+ AddRectToPageObjects(pPageObjects, crCurText, rcUnderline);
+ }
+
+ if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)
+ {
+ CPDF_Rect rcCrossout = GetCrossoutRect(word);
+ rcCrossout.left += ptOffset.x;
+ rcCrossout.right += ptOffset.x;
+ rcCrossout.top += ptOffset.y;
+ rcCrossout.bottom += ptOffset.y;
+
+ AddRectToPageObjects(pPageObjects, crCurText, rcCrossout);
+ }
+
+ oldplace = place;
+ }
+ }
+
+ if (sTextBuf.GetLength() > 0)
+ {
+ ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
+ CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
+ }
+ }
+ }
+}
+
+void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
+ const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF color)
+{
+
+
+ if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
+ {
+ if (pEdit->GetFontMap())
+ {
+ if (pRange)
+ pIterator->SetAt(pRange->BeginPos);
+ else
+ pIterator->SetAt(0);
+
+ CPVT_WordPlace oldplace;
+
+ while (pIterator->NextWord())
+ {
+ CPVT_WordPlace place = pIterator->GetAt();
+ if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
+
+ CPVT_Word word;
+ if (pIterator->GetWord(word))
+ {
+ CPDF_Rect rcUnderline = GetUnderLineRect(word);
+ rcUnderline.left += ptOffset.x;
+ rcUnderline.right += ptOffset.x;
+ rcUnderline.top += ptOffset.y;
+ rcUnderline.bottom += ptOffset.y;
+ AddRectToPageObjects(pPageObjects, color, rcUnderline);
+ }
+ }
+ }
+ }
+}
+