// 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, int32_t 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, int32_t 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 = (int32_t)rcTemp.left;
		rcDevClip.right = (int32_t)rcTemp.right;
		rcDevClip.top = (int32_t)rcTemp.top;
		rcDevClip.bottom = (int32_t)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)
{

	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();
	int32_t nHorzScale = pEdit->GetHorzScale();

	FX_COLORREF crCurFill = crTextFill;
	FX_COLORREF crOldFill = crCurFill;

	bool bSelect = false;
	const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);
	const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);

	CFX_ByteTextBuf sTextBuf;
	int32_t 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 = (int32_t)rcTemp.left;
		rcDevClip.right = (int32_t)rcTemp.right;
		rcDevClip.top = (int32_t)rcTemp.top;
		rcDevClip.bottom = (int32_t)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;
	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 = (int32_t)rcTemp.left;
		rcDevClip.right = (int32_t)rcTemp.right;
		rcDevClip.top = (int32_t)rcTemp.top;
		rcDevClip.bottom = (int32_t)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 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, int32_t 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;
}

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

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

