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