1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file.
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "../../include/fxedit/fxet_stub.h"
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "../../include/fxedit/fx_edit.h"
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "../../include/fxedit/fxet_edit.h"
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord)
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	ASSERT (pFontMap != NULL);
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CFX_ByteString sWord;
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex))
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (SubWord > 0)
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			Word = SubWord;
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		else
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			FX_DWORD dwCharCode = -1;
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (pPDFFont->IsUnicodeCompatible())
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			else
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (dwCharCode > 0 )
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			{
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				pPDFFont->AppendChar(sWord, dwCharCode);
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				return sWord;
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			}
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		pPDFFont->AppendChar(sWord, Word);
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return sWord;
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (strWords.GetLength() > 0)
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return PDF_EncodeString(strWords) + " Tj\n";
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return "";
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CFX_ByteString GetFontSetString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CFX_ByteTextBuf sRet;
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (pFontMap)
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (sFontAlias.GetLength() > 0 && fFontSize > 0 )
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return sRet.GetByteString();
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov												 const CPVT_WordRange * pRange /* = NULL*/, FX_BOOL bContinuous/* = TRUE*/, FX_WORD SubWord/* = 0*/)
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CFX_ByteTextBuf sEditStream, sWords;
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CPDF_Point ptOld(0.0f,0.0f),ptNew(0.0f,0.0f);
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	FX_INT32 nCurFontIndex = -1;
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (pRange)
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			pIterator->SetAt(pRange->BeginPos);
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		else
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			pIterator->SetAt(0);
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		CPVT_WordPlace oldplace;
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		while (pIterator->NextWord())
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			CPVT_WordPlace place = pIterator->GetAt();
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (bContinuous)
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			{
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				if (place.LineCmp(oldplace) != 0)
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				{
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (sWords.GetSize() > 0)
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sEditStream << GetWordRenderString(sWords.GetByteString());
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sWords.Clear();
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					CPVT_Word word;
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (pIterator->GetWord(word))
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					else
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						CPVT_Line line;
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						pIterator->GetLine(line);
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						ptOld = ptNew;
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				}
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				CPVT_Word word;
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				if (pIterator->GetWord(word))
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				{
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (word.nFontIndex != nCurFontIndex)
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						if (sWords.GetSize() > 0)
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						{
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov							sEditStream << GetWordRenderString(sWords.GetByteString());
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov							sWords.Clear();
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						}
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						nCurFontIndex = word.nFontIndex;
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					sWords << GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord);
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				}
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				oldplace = place;
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			}
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			else
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			{
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				CPVT_Word word;
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				if (pIterator->GetWord(word))
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				{
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						ptOld = ptNew;
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					if (word.nFontIndex != nCurFontIndex)
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					{
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						nCurFontIndex = word.nFontIndex;
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					}
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					sEditStream << GetWordRenderString(GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord));
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				}
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			}
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (sWords.GetSize() > 0)
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sEditStream << GetWordRenderString(sWords.GetByteString());
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sWords.Clear();
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CFX_ByteTextBuf sAppStream;
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sEditStream.GetSize() > 0)
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		FX_INT32 nHorzScale = pEdit->GetHorzScale();
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (nHorzScale != 100)
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sAppStream << nHorzScale << " Tz\n";
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		FX_FLOAT fCharSpace = pEdit->GetCharSpace();
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (!FX_EDIT_IsFloatZero(fCharSpace))
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sAppStream << fCharSpace << " Tc\n";
184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sAppStream << sEditStream;
187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return sAppStream.GetByteString();
190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString IFX_Edit::GetSelectAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov							const CPVT_WordRange * pRange /*= NULL*/)
194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	CFX_ByteTextBuf sRet;
196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (pRange && pRange->IsExist())
198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{
199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		{
201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			pIterator->SetAt(pRange->BeginPos);
202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			while (pIterator->NextWord())
204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			{
205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				CPVT_WordPlace place = pIterator->GetAt();
206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				CPVT_Word word;
210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				CPVT_Line line;
211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				if (pIterator->GetWord(word) && pIterator->GetLine(line))
212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				{
213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					//CPDF_Rect rcWordSel = CPDF_Rect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					//		word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					sRet << word.ptWord.x + ptOffset.x << " " << line.ptLine.y + line.fLineDescent
217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov						<< " " << word.fWidth << " " << line.fLineAscent - line.fLineDescent << " re\nf\n";
218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				}
219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			}
220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return sRet.GetByteString();
224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
226