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/fpdfdoc/fpdf_doc.h"
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "../../include/fpdfdoc/fpdf_vt.h"
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "pdf_vt.h"
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "../../include/fpdfdoc/fpdf_ap.h"
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_BOOL FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict)
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (!pAnnotDict || pAnnotDict->GetConstString("Subtype") != FX_BSTRC("Widget")) {
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString field_type = FPDF_GetFieldAttr(pAnnotDict, "FT")->GetString();
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_DWORD flags = FPDF_GetFieldAttr(pAnnotDict, "Ff")? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger() : 0;
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (field_type == "Tx") {
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CPVT_GenerateAP::GenerateTextFieldAP(pDoc, pAnnotDict);
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    } else if (field_type == "Ch") {
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (flags & (1 << 17)) {
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CPVT_GenerateAP::GenerateComboBoxAP(pDoc, pAnnotDict);
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        } else {
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CPVT_GenerateAP::GenerateListBoxAP(pDoc, pAnnotDict);
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    } else if (field_type == "Btn") {
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (!(flags & (1 << 16))) {
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (!pAnnotDict->KeyExist("AS")) {
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (CPDF_Dictionary* pParentDict = pAnnotDict->GetDict("Parent")) {
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (pParentDict->KeyExist("AS")) {
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        pAnnotDict->SetAtString("AS", pParentDict->GetString("AS"));
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return FALSE;
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CPVT_FontMap : public IPVT_FontMap
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic:
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_FontMap(CPDF_Document * pDoc, CPDF_Dictionary * pResDict, CPDF_Font * pDefFont,
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                 const CFX_ByteString & sDefFontAlias);
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    virtual ~CPVT_FontMap();
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Font*						GetPDFFont(FX_INT32 nFontIndex);
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString					GetPDFFontAlias(FX_INT32 nFontIndex);
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static void						GetAnnotSysPDFFont(CPDF_Document * pDoc, CPDF_Dictionary * pResDict,
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            CPDF_Font * & pSysFont, CFX_ByteString & sSysFontAlias);
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprivate:
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Document*					m_pDocument;
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary*				m_pResDict;
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Font*						m_pDefFont;
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString					m_sDefFontAlias;
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Font*						m_pSysFont;
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString					m_sSysFontAlias;
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCPVT_FontMap::CPVT_FontMap(CPDF_Document * pDoc, CPDF_Dictionary * pResDict, CPDF_Font * pDefFont,
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                           const CFX_ByteString & sDefFontAlias) :
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_pDocument(pDoc),
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_pResDict(pResDict),
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_pDefFont(pDefFont),
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_sDefFontAlias(sDefFontAlias),
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_pSysFont(NULL),
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_sSysFontAlias()
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCPVT_FontMap::~CPVT_FontMap()
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovextern CPDF_Font*		AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag);
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid CPVT_FontMap::GetAnnotSysPDFFont(CPDF_Document * pDoc, CPDF_Dictionary * pResDict,
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                      CPDF_Font * & pSysFont, CFX_ByteString & sSysFontAlias)
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pDoc && pResDict) {
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        CFX_ByteString sFontAlias;
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        CPDF_Dictionary* pFormDict = pDoc->GetRoot()->GetDict("AcroForm");
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (CPDF_Font * pPDFFont = AddNativeInterFormFont(pFormDict, pDoc, sSysFontAlias)) {
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (CPDF_Dictionary * pFontList = pResDict->GetDict("Font")) {
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (!pFontList->KeyExist(sSysFontAlias)) {
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    pFontList->SetAtReference(sSysFontAlias, pDoc, pPDFFont->GetFontDict());
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pSysFont = pPDFFont;
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCPDF_Font* CPVT_FontMap::GetPDFFont(FX_INT32 nFontIndex)
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (nFontIndex) {
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 0:
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return m_pDefFont;
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 1:
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (!m_pSysFont) {
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                GetAnnotSysPDFFont(m_pDocument, m_pResDict, m_pSysFont, m_sSysFontAlias);
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return m_pSysFont;
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return NULL;
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString CPVT_FontMap::GetPDFFontAlias(FX_INT32 nFontIndex)
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (nFontIndex) {
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 0:
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return m_sDefFontAlias;
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 1:
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (!m_pSysFont) {
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                GetAnnotSysPDFFont(m_pDocument, m_pResDict, m_pSysFont, m_sSysFontAlias);
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return m_sSysFontAlias;
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return "";
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCPVT_Provider::CPVT_Provider(IPVT_FontMap * pFontMap) : m_pFontMap(pFontMap)
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    ASSERT (m_pFontMap != NULL);
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCPVT_Provider::~CPVT_Provider()
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_INT32 CPVT_Provider::GetCharWidth(FX_INT32 nFontIndex, FX_WORD word, FX_INT32 nWordStyle)
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_DWORD charcode = pPDFFont->CharCodeFromUnicode(word);
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (charcode != -1) {
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return pPDFFont->GetCharWidthF(charcode);
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 0;
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_INT32 CPVT_Provider::GetTypeAscent(FX_INT32 nFontIndex)
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return pPDFFont->GetTypeAscent();
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 0;
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_INT32 CPVT_Provider::GetTypeDescent(FX_INT32 nFontIndex)
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return pPDFFont->GetTypeDescent();
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 0;
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_INT32 CPVT_Provider::GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex)
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Font* pDefFont = m_pFontMap->GetPDFFont(0)) {
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pDefFont->CharCodeFromUnicode(word) != -1) {
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return 0;
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Font* pSysFont = m_pFontMap->GetPDFFont(1))
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pSysFont->CharCodeFromUnicode(word) != -1) {
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return 1;
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return -1;
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_BOOL CPVT_Provider::IsLatinWord(FX_WORD word)
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if ((word >= 0x61 && word <= 0x7A) || (word >= 0x41 && word <= 0x5A) || word == 0x2D || word == 0x27) {
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return TRUE;
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return FALSE;
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_INT32 CPVT_Provider::GetDefaultFontIndex()
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 0;
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CFX_ByteString GetPDFWordString(IPVT_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord)
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString sWord;
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (SubWord > 0) {
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        sWord.Format("%c", SubWord);
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    } else {
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pFontMap) {
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex)) {
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (pPDFFont->GetBaseFont().Compare("Symbol") == 0 || pPDFFont->GetBaseFont().Compare("ZapfDingbats") == 0) {
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sWord.Format("%c", Word);
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                } else {
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    FX_DWORD dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (dwCharCode != -1) {
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        pPDFFont->AppendChar(sWord, dwCharCode);
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return sWord;
188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)
190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (strWords.GetLength() > 0) {
192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return PDF_EncodeString(strWords) + " Tj\n";
193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return "";
195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CFX_ByteString GetFontSetString(IPVT_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)
197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteTextBuf sRet;
199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pFontMap) {
200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (sFontAlias.GetLength() > 0 && fFontSize > 0 ) {
202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return sRet.GetByteString();
206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CPVT_Color ParseColor(const CFX_ByteString & str)
208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_SimpleParser syntax(str);
210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    syntax.SetPos(0);
211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (syntax.FindTagParam("g", 1)) {
212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CPVT_Color(CT_GRAY, FX_atof(syntax.GetWord()));
213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    syntax.SetPos(0);
215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (syntax.FindTagParam("rg", 3)) {
216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f1 = FX_atof(syntax.GetWord());
217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f2 = FX_atof(syntax.GetWord());
218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f3 = FX_atof(syntax.GetWord());
219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CPVT_Color(CT_RGB, f1, f2, f3);
220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    syntax.SetPos(0);
222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (syntax.FindTagParam("k", 4)) {
223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f1 = FX_atof(syntax.GetWord());
224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f2 = FX_atof(syntax.GetWord());
225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f3 = FX_atof(syntax.GetWord());
226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT f4 = FX_atof(syntax.GetWord());
227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CPVT_Color(CT_CMYK, f1, f2, f3, f4);
228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CPVT_Color(CT_TRANSPARENT);
230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic CPVT_Color ParseColor(const CPDF_Array & array)
232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_Color rt;
234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (array.GetCount()) {
235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 1:
236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rt = CPVT_Color(CT_GRAY, array.GetFloat(0));
237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 3:
239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rt = CPVT_Color(CT_RGB, array.GetFloat(0), array.GetFloat(1), array.GetFloat(2));
240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 4:
242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rt = CPVT_Color(CT_CMYK, array.GetFloat(0), array.GetFloat(1), array.GetFloat(2), array.GetFloat(3));
243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rt;
246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstatic FX_BOOL GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict, const FX_INT32 & nWidgetType)
248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary* pFormDict = NULL;
250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Dictionary * pRootDict = pDoc->GetRoot()) {
251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFormDict = pRootDict->GetDict("AcroForm");
252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (!pFormDict) {
254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString DA;
257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Object* pDAObj = FPDF_GetFieldAttr(pAnnotDict, "DA")) {
258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        DA = pDAObj->GetString();
259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (DA.IsEmpty()) {
261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        DA = pFormDict->GetString("DA");
262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (DA.IsEmpty()) {
264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_SimpleParser syntax(DA);
267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    syntax.FindTagParam("Tf", 2);
268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString sFontName = syntax.GetWord();
269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    sFontName = PDF_NameDecode(sFontName);
270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (sFontName.IsEmpty()) {
271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fFontSize = FX_atof(syntax.GetWord());
274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_Color crText = ParseColor(DA);
275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_BOOL bUseFormRes = FALSE;
276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary * pFontDict = NULL;
277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary* pDRDict = pAnnotDict->GetDict(FX_BSTRC("DR"));
278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pDRDict == NULL) {
279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pDRDict = pFormDict->GetDict(FX_BSTRC("DR"));
280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        bUseFormRes = TRUE;
281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary * pDRFontDict = NULL;
283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pDRDict && (pDRFontDict = pDRDict->GetDict("Font"))) {
284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict = pDRFontDict->GetDict(sFontName.Mid(1));
285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (!pFontDict && !bUseFormRes) {
286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pDRDict = pFormDict->GetDict(FX_BSTRC("DR"));
287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pDRFontDict = pDRDict->GetDict("Font");
288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (pDRFontDict) {
289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pFontDict = pDRFontDict->GetDict(sFontName.Mid(1));
290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (!pDRFontDict) {
294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (!pFontDict) {
297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict = CPDF_Dictionary::Create();
298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pFontDict == NULL) {
299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return FALSE;
300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict->SetAtName(FX_BSTRC("Type"), "Font");
302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict->SetAtName(FX_BSTRC("Subtype"), "Type1");
303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict->SetAtName(FX_BSTRC("BaseFont"), "Helvetica");
304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pFontDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pDoc->AddIndirectObject(pFontDict);
306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pDRFontDict->SetAtReference(sFontName.Mid(1), pDoc, pFontDict);
307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Font* pDefFont = pDoc->LoadFont(pFontDict);
309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (!pDefFont) {
310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FALSE;
311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Rect rcAnnot = pAnnotDict->GetRect("Rect");
313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_INT32 nRotate = 0;
314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Dictionary * pMKDict = pAnnotDict->GetDict("MK")) {
315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        nRotate = pMKDict->GetInteger("R");
316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Rect rcBBox;
318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Matrix matrix;
319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (nRotate % 360) {
320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 0:
321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rcBBox = CPDF_Rect(0, 0, rcAnnot.right - rcAnnot.left, rcAnnot.top - rcAnnot.bottom);
322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 90:
324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            matrix = CPDF_Matrix(0, 1, -1, 0, rcAnnot.right - rcAnnot.left, 0);
325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rcBBox = CPDF_Rect(0, 0, rcAnnot.top - rcAnnot.bottom, rcAnnot.right - rcAnnot.left);
326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 180:
328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            matrix = CPDF_Matrix(-1, 0, 0, -1, rcAnnot.right - rcAnnot.left, rcAnnot.top - rcAnnot.bottom);
329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rcBBox = CPDF_Rect(0, 0, rcAnnot.right - rcAnnot.left, rcAnnot.top - rcAnnot.bottom);
330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 270:
332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            matrix = CPDF_Matrix(0, -1, 1, 0, 0, rcAnnot.top - rcAnnot.bottom);
333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            rcBBox = CPDF_Rect(0, 0, rcAnnot.top - rcAnnot.bottom, rcAnnot.right - rcAnnot.left);
334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_INT32 nBorderStyle = PBS_SOLID;
337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fBorderWidth = 1;
338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_Dash dsBorder(3, 0, 0);
339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_Color crLeftTop, crRightBottom;
340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Dictionary * pBSDict = pAnnotDict->GetDict("BS")) {
341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pBSDict->KeyExist("W")) {
342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            fBorderWidth = pBSDict->GetNumber("W");
343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (CPDF_Array * pArray = pBSDict->GetArray("D")) {
345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            dsBorder = CPVT_Dash(pArray->GetInteger(0), pArray->GetInteger(1), pArray->GetInteger(2));
346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        switch (pBSDict->GetString("S").GetAt(0)) {
348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case 'S':
349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                nBorderStyle = PBS_SOLID;
350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case 'D':
352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                nBorderStyle = PBS_DASH;
353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case 'B':
355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                nBorderStyle = PBS_BEVELED;
356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                fBorderWidth *= 2;
357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                crLeftTop = CPVT_Color(CT_GRAY, 1);
358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                crRightBottom = CPVT_Color(CT_GRAY, 0.5);
359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case 'I':
361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                nBorderStyle = PBS_INSET;
362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                fBorderWidth *= 2;
363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                crLeftTop = CPVT_Color(CT_GRAY, 0.5);
364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                crRightBottom = CPVT_Color(CT_GRAY, 0.75);
365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case 'U':
367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                nBorderStyle = PBS_UNDERLINED;
368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPVT_Color crBorder, crBG;
372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (CPDF_Dictionary * pMKDict = pAnnotDict->GetDict("MK")) {
373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (CPDF_Array * pArray = pMKDict->GetArray("BC")) {
374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            crBorder = ParseColor(*pArray);
375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (CPDF_Array * pArray = pMKDict->GetArray("BG")) {
377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            crBG = ParseColor(*pArray);
378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteTextBuf sAppStream;
381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString sBG = CPVT_GenerateAP::GenerateColorAP(crBG, TRUE);
382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (sBG.GetLength() > 0) {
383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        sAppStream << "q\n" << sBG << rcBBox.left << " " << rcBBox.bottom << " "
384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                   << rcBBox.Width() << " " << rcBBox.Height() << " re f\n" << "Q\n";
385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString sBorderStream = CPVT_GenerateAP::GenerateBorderAP(rcBBox, fBorderWidth,
387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                   crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder);
388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (sBorderStream.GetLength() > 0) {
389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        sAppStream << "q\n" << sBorderStream << "Q\n";
390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Rect rcBody = CPDF_Rect(rcBBox.left + fBorderWidth, rcBBox.bottom + fBorderWidth,
392e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                 rcBBox.right - fBorderWidth, rcBBox.top - fBorderWidth);
393e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    rcBody.Normalize();
394e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary* pAPDict = pAnnotDict->GetDict("AP");
395e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pAPDict == NULL) {
396e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pAPDict = CPDF_Dictionary::Create();
397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pAPDict == NULL) {
398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return FALSE;
399e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
400e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pAnnotDict->SetAt("AP", pAPDict);
401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Stream* pNormalStream = pAPDict->GetStream("N");
403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pNormalStream == NULL) {
404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pNormalStream = CPDF_Stream::Create(NULL, 0, NULL);
405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pNormalStream == NULL) {
406e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return FALSE;
407e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
408e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_INT32 objnum = pDoc->AddIndirectObject(pNormalStream);
409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pAnnotDict->GetDict("AP")->SetAtReference("N", pDoc, objnum);
410e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
411e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Dictionary * pStreamDict = pNormalStream->GetDict();
412e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pStreamDict) {
413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pStreamDict->SetAtMatrix("Matrix", matrix);
414e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pStreamDict->SetAtRect("BBox", rcBBox);
415e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pStreamResList) {
417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
418e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (!pStreamResFontList) {
419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pStreamResFontList = CPDF_Dictionary::Create();
420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (pStreamResFontList == NULL) {
421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    return FALSE;
422e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
423e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pStreamResList->SetAt("Font", pStreamResFontList);
424e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
425e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (!pStreamResFontList->KeyExist(sFontName)) {
426e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pStreamResFontList->SetAtReference(sFontName, pDoc, pFontDict);
427e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
428e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        } else {
429e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pStreamDict->SetAt("Resources", pFormDict->GetDict("DR")->Clone());
430e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pStreamResList = pStreamDict->GetDict("Resources");
431e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
432e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
433e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (nWidgetType) {
434e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 0: {
435e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_WideString swValue = FPDF_GetFieldAttr(pAnnotDict, "V")? FPDF_GetFieldAttr(pAnnotDict, "V")->GetUnicodeText() : CFX_WideString();
436e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_INT32 nAlign = FPDF_GetFieldAttr(pAnnotDict, "Q")? FPDF_GetFieldAttr(pAnnotDict, "Q")->GetInteger() : 0;
437e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_DWORD dwFlags = FPDF_GetFieldAttr(pAnnotDict, "Ff")? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger() : 0;
438e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_DWORD dwMaxLen = FPDF_GetFieldAttr(pAnnotDict, "MaxLen") ? FPDF_GetFieldAttr(pAnnotDict, "MaxLen")->GetInteger() : 0;
439e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_FontMap map(pDoc, pStreamDict ? pStreamDict->GetDict("Resources") : NULL , pDefFont, sFontName.Right(sFontName.GetLength() - 1));
440e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_Provider prd(&map);
441e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_VariableText vt;
442e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetProvider(&prd);
443e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetPlateRect(rcBody);
444e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetAlignment(nAlign);
445e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (IsFloatZero(fFontSize)) {
446e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetAutoFontSize(TRUE);
447e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                } else {
448e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetFontSize(fFontSize);
449e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
450e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_BOOL bMultiLine = (dwFlags >> 12) & 1;
451e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (bMultiLine) {
452e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetMultiLine(TRUE);
453e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetAutoReturn(TRUE);
454e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
455e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_WORD subWord = 0;
456e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if ((dwFlags >> 13) & 1) {
457e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    subWord = '*';
458e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetPasswordChar(subWord);
459e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
460e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_BOOL bCharArray = (dwFlags >> 24) & 1;
461e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (bCharArray) {
462e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetCharArray(dwMaxLen);
463e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                } else {
464e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetLimitChar(dwMaxLen);
465e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
466e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.Initialize();
467e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetText(swValue.c_str());
468e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.RearrangeAll();
469e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Rect rcContent = vt.GetContentRect();
470e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Point ptOffset(0.0f, 0.0f);
471e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (!bMultiLine) {
472e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    ptOffset = CPDF_Point(0.0f, (rcContent.Height() - rcBody.Height()) / 2.0f);
473e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
474e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_ByteString sBody = CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), ptOffset, !bCharArray, subWord);
475e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sBody.GetLength() > 0) {
476e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "/Tx BMC\n" << "q\n";
477e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (rcContent.Width() > rcBody.Width() ||
478e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            rcContent.Height() > rcBody.Height()) {
479e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << rcBody.left << " " << rcBody.bottom << " "
480e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                   << rcBody.Width() << " " << rcBody.Height() << " re\nW\nn\n";
481e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
482e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "BT\n" << CPVT_GenerateAP::GenerateColorAP(crText, TRUE) << sBody << "ET\n" << "Q\nEMC\n";
483e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
484e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
485e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
486e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 1: {
487e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_WideString swValue = FPDF_GetFieldAttr(pAnnotDict, "V") ? FPDF_GetFieldAttr(pAnnotDict, "V")->GetUnicodeText() : CFX_WideString();
488e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_FontMap map(pDoc, pStreamDict ? pStreamDict->GetDict("Resources"):NULL, pDefFont, sFontName.Right(sFontName.GetLength() - 1));
489e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_Provider prd(&map);
490e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_VariableText vt;
491e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetProvider(&prd);
492e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Rect rcButton = rcBody;
493e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                rcButton.left = rcButton.right - 13;
494e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                rcButton.Normalize();
495e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Rect rcEdit = rcBody;
496e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                rcEdit.right = rcButton.left;
497e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                rcEdit.Normalize();
498e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetPlateRect(rcEdit);
499e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (IsFloatZero(fFontSize)) {
500e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetAutoFontSize(TRUE);
501e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                } else {
502e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    vt.SetFontSize(fFontSize);
503e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
504e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.Initialize();
505e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.SetText(swValue.c_str());
506e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                vt.RearrangeAll();
507e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Rect rcContent = vt.GetContentRect();
508e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Point ptOffset = CPDF_Point(0.0f, (rcContent.Height() - rcEdit.Height()) / 2.0f);
509e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_ByteString sEdit = CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), ptOffset, TRUE, 0);
510e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sEdit.GetLength() > 0) {
511e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "/Tx BMC\n" << "q\n";
512e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << rcEdit.left << " " << rcEdit.bottom << " "
513e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                               << rcEdit.Width() << " " << rcEdit.Height() << " re\nW\nn\n";
514e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "BT\n" << CPVT_GenerateAP::GenerateColorAP(crText, TRUE) << sEdit << "ET\n" << "Q\nEMC\n";
515e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
516e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_ByteString sButton = CPVT_GenerateAP::GenerateColorAP(CPVT_Color(CT_RGB, 220.0f / 255.0f, 220.0f / 255.0f, 220.0f / 255.0f), TRUE);
517e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sButton.GetLength() > 0 && !rcButton.IsEmpty()) {
518e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "q\n" << sButton;
519e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << rcButton.left << " " << rcButton.bottom << " "
520e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                               << rcButton.Width() << " " << rcButton.Height() << " re f\n";
521e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "Q\n";
522e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    CFX_ByteString sButtonBorder = CPVT_GenerateAP::GenerateBorderAP(rcButton, 2, CPVT_Color(CT_GRAY, 0), CPVT_Color(CT_GRAY, 1), CPVT_Color(CT_GRAY, 0.5), PBS_BEVELED, CPVT_Dash(3, 0, 0));
523e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (sButtonBorder.GetLength() > 0) {
524e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << "q\n" << sButtonBorder << "Q\n";
525e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
526e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    CPDF_Point ptCenter = CPDF_Point((rcButton.left + rcButton.right) / 2, (rcButton.top + rcButton.bottom) / 2);
527e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (IsFloatBigger(rcButton.Width(), 6) && IsFloatBigger(rcButton.Height(), 6)) {
528e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << "q\n" << " 0 g\n";
529e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n";
530e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n";
531e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n";
532e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n";
533e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sAppStream << sButton << "Q\n";
534e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
535e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
536e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
537e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
538e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case 2: {
539e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_FontMap map(pDoc, pStreamDict ? pStreamDict->GetDict("Resources"):NULL, pDefFont, sFontName.Right(sFontName.GetLength() - 1));
540e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_Provider prd(&map);
541e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Array * pOpts = FPDF_GetFieldAttr(pAnnotDict, "Opt") ? FPDF_GetFieldAttr(pAnnotDict, "Opt")->GetArray() : NULL;
542e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Array * pSels = FPDF_GetFieldAttr(pAnnotDict, "I") ? FPDF_GetFieldAttr(pAnnotDict, "I")->GetArray() : NULL;
543e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FX_INT32 nTop = FPDF_GetFieldAttr(pAnnotDict, "TI") ? FPDF_GetFieldAttr(pAnnotDict, "TI")->GetInteger() : 0;
544e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CFX_ByteTextBuf sBody;
545e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (pOpts) {
546e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    FX_FLOAT fy = rcBody.top;
547e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    for (FX_INT32 i = nTop, sz = pOpts->GetCount(); i < sz; i++) {
548e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        if (IsFloatSmaller(fy, rcBody.bottom)) {
549e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            break;
550e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        }
551e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        if (CPDF_Object* pOpt = pOpts->GetElementValue(i)) {
552e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            CFX_WideString swItem;
553e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            if (pOpt->GetType() == PDFOBJ_STRING) {
554e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                swItem = pOpt->GetUnicodeText();
555e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            } else if (pOpt->GetType() == PDFOBJ_ARRAY) {
556e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                swItem = ((CPDF_Array*)pOpt)->GetElementValue(1)->GetUnicodeText();
557e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            }
558e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            FX_BOOL bSelected = FALSE;
559e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            if (pSels) {
560e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                for (FX_DWORD s = 0, ssz = pSels->GetCount(); s < ssz; s++) {
561e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                    if (i == pSels->GetInteger(s)) {
562e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                        bSelected = TRUE;
563e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                        break;
564e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                    }
565e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                }
566e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            }
567e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            CPDF_VariableText vt;
568e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            vt.SetProvider(&prd);
569e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            vt.SetPlateRect(CPDF_Rect(rcBody.left, 0.0f, rcBody.right, 0.0f));
570e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            if (IsFloatZero(fFontSize)) {
571e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                vt.SetFontSize(12.0f);
572e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            } else {
573e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                vt.SetFontSize(fFontSize);
574e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            }
575e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            vt.Initialize();
576e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            vt.SetText(swItem.c_str());
577e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            vt.RearrangeAll();
578e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            FX_FLOAT fItemHeight = vt.GetContentRect().Height();
579e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            if (bSelected) {
580e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                CPDF_Rect rcItem = CPDF_Rect(rcBody.left, fy - fItemHeight, rcBody.right, fy);
581e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                sBody << "q\n" << CPVT_GenerateAP::GenerateColorAP(CPVT_Color(CT_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f), TRUE)
582e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                      << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() << " " << rcItem.Height() << " re f\n" << "Q\n";
583e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                sBody << "BT\n" << CPVT_GenerateAP::GenerateColorAP(CPVT_Color(CT_GRAY, 1), TRUE) << CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), CPDF_Point(0.0f, fy), TRUE, 0) << "ET\n";
584e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            } else {
585e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                                sBody << "BT\n" << CPVT_GenerateAP::GenerateColorAP(crText, TRUE) << CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), CPDF_Point(0.0f, fy), TRUE, 0) << "ET\n";
586e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            }
587e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            fy -= fItemHeight;
588e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        }
589e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
590e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
591e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sBody.GetSize() > 0) {
592e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "/Tx BMC\n" << "q\n";
593e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << rcBody.left << " " << rcBody.bottom << " "
594e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                               << rcBody.Width() << " " << rcBody.Height() << " re\nW\nn\n";
595e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sBody.GetByteString() << "Q\nEMC\n";
596e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
597e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
598e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
599e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
600e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pNormalStream) {
601e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pNormalStream->SetData((FX_BYTE*)sAppStream.GetBuffer(), sAppStream.GetSize(), FALSE, FALSE);
602e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        pStreamDict = pNormalStream->GetDict();
603e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pStreamDict) {
604e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pStreamDict->SetAtMatrix("Matrix", matrix);
605e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pStreamDict->SetAtRect("BBox", rcBBox);
606e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
607e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (pStreamResList) {
608e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
609e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (!pStreamResFontList) {
610e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    pStreamResFontList = CPDF_Dictionary::Create();
611e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (pStreamResFontList == NULL) {
612e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        return FALSE;
613e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
614e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    pStreamResList->SetAt("Font", pStreamResFontList);
615e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
616e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (!pStreamResFontList->KeyExist(sFontName)) {
617e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    pStreamResFontList->SetAtReference(sFontName, pDoc, pFontDict);
618e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
619e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            } else {
620e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pStreamDict->SetAt("Resources", pFormDict->GetDict("DR")->Clone());
621e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                pStreamResList = pStreamDict->GetDict("Resources");
622e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
623e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
624e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
625e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return TRUE;
626e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
627e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_BOOL CPVT_GenerateAP::GenerateTextFieldAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict)
628e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
629e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return GenerateWidgetAP(pDoc, pAnnotDict, 0);
630e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
631e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_BOOL CPVT_GenerateAP::GenerateComboBoxAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict)
632e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
633e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return GenerateWidgetAP(pDoc, pAnnotDict, 1);
634e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
635e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_BOOL CPVT_GenerateAP::GenerateListBoxAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict)
636e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
637e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return GenerateWidgetAP(pDoc, pAnnotDict, 2);
638e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
639e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString CPVT_GenerateAP::GenerateEditAP(IPVT_FontMap * pFontMap, IPDF_VariableText_Iterator* pIterator, const CPDF_Point & ptOffset, FX_BOOL bContinuous, FX_WORD SubWord, const CPVT_WordRange * pVisible)
640e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
641e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteTextBuf sEditStream, sLineStream, sWords;
642e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CPDF_Point ptOld(0.0f, 0.0f), ptNew(0.0f, 0.0f);
643e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_INT32 nCurFontIndex = -1;
644e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (pIterator) {
645e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (pVisible) {
646e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pIterator->SetAt(pVisible->BeginPos);
647e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        } else {
648e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            pIterator->SetAt(0);
649e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
650e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        CPVT_WordPlace oldplace;
651e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        while (pIterator->NextWord()) {
652e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            CPVT_WordPlace place = pIterator->GetAt();
653e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (pVisible && place.WordCmp(pVisible->EndPos) > 0) {
654e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
655e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
656e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            if (bContinuous) {
657e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (place.LineCmp(oldplace) != 0) {
658e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (sWords.GetSize() > 0) {
659e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sLineStream << GetWordRenderString(sWords.GetByteString());
660e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sEditStream << sLineStream;
661e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sLineStream.Clear();
662e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sWords.Clear();
663e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
664e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    CPVT_Word word;
665e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (pIterator->GetWord(word)) {
666e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
667e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    } else {
668e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        CPVT_Line line;
669e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        pIterator->GetLine(line);
670e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);
671e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
672e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
673e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sLineStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
674e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        ptOld = ptNew;
675e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
676e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
677e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_Word word;
678e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (pIterator->GetWord(word)) {
679e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (word.nFontIndex != nCurFontIndex) {
680e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        if (sWords.GetSize() > 0) {
681e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            sLineStream << GetWordRenderString(sWords.GetByteString());
682e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                            sWords.Clear();
683e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        }
684e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sLineStream << GetFontSetString(pFontMap, word.nFontIndex, word.fFontSize);
685e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        nCurFontIndex = word.nFontIndex;
686e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
687e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sWords << GetPDFWordString(pFontMap, nCurFontIndex, word.Word, SubWord);
688e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
689e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                oldplace = place;
690e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            } else {
691e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                CPVT_Word word;
692e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (pIterator->GetWord(word)) {
693e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
694e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
695e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
696e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        ptOld = ptNew;
697e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
698e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    if (word.nFontIndex != nCurFontIndex) {
699e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        sEditStream << GetFontSetString(pFontMap, word.nFontIndex, word.fFontSize);
700e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                        nCurFontIndex = word.nFontIndex;
701e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    }
702e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sEditStream << GetWordRenderString(GetPDFWordString(pFontMap, nCurFontIndex, word.Word, SubWord));
703e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
704e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            }
705e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
706e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (sWords.GetSize() > 0) {
707e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sLineStream << GetWordRenderString(sWords.GetByteString());
708e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sEditStream << sLineStream;
709e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sWords.Clear();
710e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
711e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
712e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return sEditStream.GetByteString();
713e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
714e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString CPVT_GenerateAP::GenerateBorderAP(const CPDF_Rect & rect, FX_FLOAT fWidth,
715e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        const CPVT_Color & color, const CPVT_Color & crLeftTop, const CPVT_Color & crRightBottom,
716e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_INT32 nStyle, const CPVT_Dash & dash)
717e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
718e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteTextBuf sAppStream;
719e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString sColor;
720e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fLeft = rect.left;
721e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fRight = rect.right;
722e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fTop = rect.top;
723e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT fBottom = rect.bottom;
724e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (fWidth > 0.0f) {
725e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_FLOAT fHalfWidth = fWidth / 2.0f;
726e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        switch (nStyle) {
727e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            default:
728e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case PBS_SOLID:
729e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(color, TRUE);
730e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
731e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
732e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft << " " << fBottom << " " << fRight - fLeft << " " << fTop - fBottom << " re\n";
733e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fWidth << " " << fBottom + fWidth << " "
734e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                               << fRight - fLeft - fWidth * 2 << " " << fTop - fBottom - fWidth * 2 << " re\n";
735e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << "f*\n";
736e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
737e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
738e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case PBS_DASH:
739e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(color, FALSE);
740e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
741e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
742e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fWidth << " w" << " [" << dash.nDash << " " << dash.nGap << "] " << dash.nPhase << " d\n";
743e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fWidth / 2 << " " << fBottom + fWidth / 2 << " m\n";
744e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fWidth / 2 << " " << fTop - fWidth / 2 << " l\n";
745e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fWidth / 2 << " " << fTop - fWidth / 2 << " l\n";
746e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fWidth / 2 << " " << fBottom + fWidth / 2 << " l\n";
747e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fWidth / 2 << " " << fBottom + fWidth / 2 << " l S\n";
748e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
749e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
750e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case PBS_BEVELED:
751e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case PBS_INSET:
752e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(crLeftTop, TRUE);
753e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
754e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
755e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth << " m\n";
756e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth << " " << fTop - fHalfWidth << " l\n";
757e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth << " " << fTop - fHalfWidth << " l\n";
758e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth * 2 << " " << fTop - fHalfWidth * 2 << " l\n";
759e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth * 2 << " " << fTop - fHalfWidth * 2 << " l\n";
760e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth * 2 << " " << fBottom + fHalfWidth * 2 << " l f\n";
761e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
762e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(crRightBottom, TRUE);
763e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
764e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
765e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth << " " <<	fTop - fHalfWidth << " m\n";
766e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth << " " <<	fBottom + fHalfWidth << " l\n";
767e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth << " " << 	fBottom + fHalfWidth << " l\n";
768e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth * 2 << " " << fBottom + fHalfWidth * 2 << " l\n";
769e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth * 2 << " " << fBottom + fHalfWidth * 2 << " l\n";
770e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight - fHalfWidth * 2 << " " << fTop - fHalfWidth * 2 << " l f\n";
771e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
772e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(color, TRUE);
773e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
774e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
775e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft << " " << fBottom << " " <<	fRight - fLeft << " " << fTop - fBottom << " re\n";
776e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth << " "
777e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                               << fRight - fLeft - fHalfWidth * 2 << " " << fTop - fBottom - fHalfWidth * 2 << " re f*\n";
778e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
779e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
780e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            case PBS_UNDERLINED:
781e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                sColor = GenerateColorAP(color, FALSE);
782e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                if (sColor.GetLength() > 0) {
783e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << sColor;
784e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fWidth << " w\n";
785e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fLeft << " " << fBottom + fWidth / 2 << " m\n";
786e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    sAppStream << fRight << " " << fBottom + fWidth / 2 << " l S\n";
787e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                }
788e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                break;
789e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
790e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
791e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return sAppStream.GetByteString();
792e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
793e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString CPVT_GenerateAP::GenerateColorAP(const CPVT_Color & color, const FX_BOOL & bFillOrStroke)
794e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
795e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteTextBuf sColorStream;
796e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (color.nColorType) {
797e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case CT_RGB:
798e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sColorStream << color.fColor1 << " " << color.fColor2 << " " << color.fColor3 << " "
799e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                         << (bFillOrStroke ? "rg" : "RG") << "\n";
800e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
801e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case CT_GRAY:
802e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sColorStream << color.fColor1 << " " << (bFillOrStroke ? "g" : "G") << "\n";
803e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
804e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        case CT_CMYK:
805e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            sColorStream << color.fColor1 << " " << color.fColor2 << " " << color.fColor3 << " " << color.fColor4 << " "
806e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                         << (bFillOrStroke ? "k" : "K") << "\n";
807e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            break;
808e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
809e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return sColorStream.GetByteString();
810e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
811