1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  *  The Contents of this file are made available subject to the terms of
5  *  either of the following licenses
6  *
7  *         - GNU Lesser General Public License Version 2.1
8  *         - Sun Industry Standards Source License Version 1.1
9  *
10  *  Sun Microsystems Inc., October, 2000
11  *
12  *  GNU Lesser General Public License Version 2.1
13  *  =============================================
14  *  Copyright 2000 by Sun Microsystems, Inc.
15  *  901 San Antonio Road, Palo Alto, CA 94303, USA
16  *
17  *  This library is free software; you can redistribute it and/or
18  *  modify it under the terms of the GNU Lesser General Public
19  *  License version 2.1, as published by the Free Software Foundation.
20  *
21  *  This library is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  *  Lesser General Public License for more details.
25  *
26  *  You should have received a copy of the GNU Lesser General Public
27  *  License along with this library; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29  *  MA  02111-1307  USA
30  *
31  *
32  *  Sun Industry Standards Source License Version 1.1
33  *  =================================================
34  *  The contents of this file are subject to the Sun Industry Standards
35  *  Source License Version 1.1 (the "License"); You may not use this file
36  *  except in compliance with the License. You may obtain a copy of the
37  *  License at http://www.openoffice.org/license.html.
38  *
39  *  Software provided under this License is provided on an "AS IS" basis,
40  *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41  *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42  *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43  *  See the License for the specific provisions governing your rights and
44  *  obligations concerning the Software.
45  *
46  *  The Initial Developer of the Original Code is: IBM Corporation
47  *
48  *  Copyright: 2008 by IBM Corporation
49  *
50  *  All Rights Reserved.
51  *
52  *  Contributor(s): _______________________________________
53  *
54  *
55  ************************************************************************/
56 /*************************************************************************
57  * @file
58  *  For LWP filter architecture prototype
59  ************************************************************************/
60 
61 #include <memory>
62 #include <lwpfrib.hxx>
63 #include "lwpcharsetmgr.hxx"
64 #include "lwpsection.hxx"
65 #include "lwphyperlinkmgr.hxx"
66 #include <xfilter/xfhyperlink.hxx>
67 #include <xfilter/xfstylemanager.hxx>
68 #include <xfilter/xfsection.hxx>
69 #include <xfilter/xfsectionstyle.hxx>
70 #include <xfilter/xftextspan.hxx>
71 #include <xfilter/xftextcontent.hxx>
72 #include "lwpfribheader.hxx"
73 #include "lwpfribtext.hxx"
74 #include "lwpfribtable.hxx"
75 #include "lwpfribbreaks.hxx"
76 #include "lwpfribframe.hxx"
77 #include "lwpfribsection.hxx"
78 #include "lwpcharacterstyle.hxx"
79 #include "lwpfootnote.hxx"
80 #include "lwpnotes.hxx"
81 #include "lwpfribmark.hxx"
82 #include <lwpchangemgr.hxx>
83 #include <lwpdocdata.hxx>
84 #include <lwpglobalmgr.hxx>
85 
86 #include <osl/diagnose.h>
87 
88 
LwpFrib(LwpPara * pPara)89 LwpFrib::LwpFrib(LwpPara* pPara)
90     : m_pFribMap(nullptr)
91     , m_pPara(pPara)
92     , m_pNext(nullptr)
93     , m_nFribType(0)
94     , m_ModFlag(false)
95     , m_nRevisionType(0)
96     , m_bRevisionFlag(false)
97     , m_nEditor(0)
98 {
99 }
100 
~LwpFrib()101 LwpFrib::~LwpFrib()
102 {
103     Deregister();
104 }
105 
CreateFrib(LwpPara * pPara,LwpObjectStream * pObjStrm,sal_uInt8 fribtag,sal_uInt8 editID)106 LwpFrib* LwpFrib::CreateFrib(LwpPara* pPara, LwpObjectStream* pObjStrm, sal_uInt8 fribtag,sal_uInt8 editID)
107 {
108     //Read Modifier
109     std::unique_ptr<ModifierInfo> xModInfo;
110     if(fribtag & FRIB_TAG_MODIFIER)
111     {
112         xModInfo.reset(new ModifierInfo);
113         xModInfo->CodePage = 0;
114         xModInfo->FontID = 0;
115         xModInfo->RevisionType = 0;
116         xModInfo->RevisionFlag = false;
117         xModInfo->HasCharStyle = false;
118         xModInfo->HasLangOverride = false;
119         xModInfo->HasHighlight = false;
120         ReadModifiers(pObjStrm, xModInfo.get());
121     }
122 
123     //Read frib data
124     std::unique_ptr<LwpFrib> newFrib;
125     sal_uInt16 friblen = pObjStrm->QuickReaduInt16();
126     sal_uInt8 fribtype = fribtag&~FRIB_TAG_TYPEMASK;
127     switch(fribtype)
128     {
129         case FRIB_TAG_INVALID:  //fall through
130         case FRIB_TAG_EOP:      //fall through
131         default:
132             newFrib.reset(new LwpFrib(pPara));
133             break;
134         case FRIB_TAG_TEXT:
135         {
136             newFrib.reset(new LwpFribText(pPara, (fribtag & FRIB_TAG_NOUNICODE) != 0));
137             break;
138         }
139         case FRIB_TAG_TABLE:
140             newFrib.reset(new LwpFribTable(pPara));
141             break;
142         case FRIB_TAG_TAB:
143             newFrib.reset(new LwpFribTab(pPara));
144             break;
145         case FRIB_TAG_PAGEBREAK:
146             newFrib.reset(new LwpFribPageBreak(pPara));
147             break;
148         case FRIB_TAG_FRAME:
149             newFrib.reset(new LwpFribFrame(pPara));
150             break;
151         case FRIB_TAG_FOOTNOTE:
152             newFrib.reset(new LwpFribFootnote(pPara));
153             break;
154         case FRIB_TAG_COLBREAK:
155             newFrib.reset(new LwpFribColumnBreak(pPara));
156             break;
157         case FRIB_TAG_LINEBREAK:
158             newFrib.reset(new LwpFribLineBreak(pPara));
159             break;
160         case FRIB_TAG_HARDSPACE:
161             newFrib.reset(new LwpFribHardSpace(pPara));
162             break;
163         case FRIB_TAG_SOFTHYPHEN:
164             newFrib.reset(new LwpFribSoftHyphen(pPara));
165             break;
166         case FRIB_TAG_PARANUMBER:
167             newFrib.reset(new LwpFribParaNumber(pPara));
168             break;
169         case FRIB_TAG_UNICODE: //fall through
170         case FRIB_TAG_UNICODE2: //fall through
171         case FRIB_TAG_UNICODE3: //fall through
172             newFrib.reset(new LwpFribUnicode(pPara));
173             break;
174         case FRIB_TAG_NOTE:
175             newFrib.reset(new LwpFribNote(pPara));
176             break;
177         case FRIB_TAG_SECTION:
178             newFrib.reset(new LwpFribSection(pPara));
179             break;
180         case FRIB_TAG_PAGENUMBER:
181             newFrib.reset(new LwpFribPageNumber(pPara));
182             break;
183         case FRIB_TAG_DOCVAR:
184             newFrib.reset(new LwpFribDocVar(pPara));
185             break;
186         case FRIB_TAG_BOOKMARK:
187             newFrib.reset(new LwpFribBookMark(pPara));
188             break;
189         case FRIB_TAG_FIELD:
190             newFrib.reset(new LwpFribField(pPara));
191             break;
192         case FRIB_TAG_CHBLOCK:
193             newFrib.reset(new LwpFribCHBlock(pPara));
194             break;
195         case FRIB_TAG_RUBYMARKER:
196             newFrib.reset(new LwpFribRubyMarker(pPara));
197             break;
198         case FRIB_TAG_RUBYFRAME:
199             newFrib.reset(new LwpFribRubyFrame(pPara));
200             break;
201     }
202 
203     //Do not know why the fribTag judgement is necessary, to be checked with
204     if (fribtag & FRIB_TAG_MODIFIER)
205     {
206         newFrib->SetModifiers(xModInfo.release());
207     }
208 
209     newFrib->m_nFribType = fribtype;
210     newFrib->m_nEditor = editID;
211     newFrib->Read(pObjStrm, friblen);
212     return newFrib.release();
213 }
214 
Read(LwpObjectStream * pObjStrm,sal_uInt16 len)215 void LwpFrib::Read(LwpObjectStream* pObjStrm, sal_uInt16 len)
216 {
217     pObjStrm->SeekRel(len);
218 }
219 
SetModifiers(ModifierInfo * pModifiers)220 void LwpFrib::SetModifiers(ModifierInfo* pModifiers)
221 {
222     if (pModifiers)
223     {
224         m_pModifiers.reset( pModifiers );
225         m_ModFlag = true;
226         if (pModifiers->RevisionFlag)
227         {
228             m_bRevisionFlag = true;
229             m_nRevisionType = pModifiers->RevisionType;
230         }
231     }
232 }
233 
RegisterStyle(LwpFoundry * pFoundry)234 void LwpFrib::RegisterStyle(LwpFoundry* pFoundry)
235 {
236     if (!m_pModifiers)
237         return;
238     if (!m_pModifiers->FontID && !m_pModifiers->HasCharStyle && !m_pModifiers->HasHighlight)
239     {
240         m_ModFlag = false;
241         return;
242     }
243     //we only read four modifiers, in these modifiers,CodePage and LangOverride are not styles,
244     //so we can only handle fontid and charstyle, if others, we should not reg style
245     //note by ,1-27
246     rtl::Reference<XFFont> pFont;
247     XFTextStyle* pStyle = nullptr;
248     m_StyleName.clear();
249     XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
250     XFTextStyle* pNamedStyle = nullptr;
251     if (m_pModifiers->HasCharStyle && pFoundry)
252     {
253         pNamedStyle = dynamic_cast<XFTextStyle*>
254                                 (pFoundry->GetStyleManager()->GetStyle(m_pModifiers->CharStyleID));
255     }
256     if (pNamedStyle)
257     {
258         LwpCharacterStyle* pCharStyle = nullptr;
259         if (m_pModifiers->FontID && pFoundry)
260             pCharStyle = dynamic_cast<LwpCharacterStyle*>(m_pModifiers->CharStyleID.obj().get());
261         if (pCharStyle)
262         {
263             std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
264             *pNewStyle = *pNamedStyle;
265 
266             pNewStyle->SetStyleName("");
267             pFont = pFoundry->GetFontManger().CreateOverrideFont(pCharStyle->GetFinalFontID(),m_pModifiers->FontID);
268             pNewStyle->SetFont(pFont);
269             IXFStyleRet aNewStyle = pXFStyleManager->AddStyle(std::move(pNewStyle));
270             m_StyleName = aNewStyle.m_pStyle->GetStyleName();
271             pStyle = dynamic_cast<XFTextStyle*>(aNewStyle.m_pStyle);
272             if (aNewStyle.m_bOrigDeleted)
273                 pStyle = nullptr;
274         }
275         else
276             m_StyleName =  pNamedStyle->GetStyleName();
277     }
278     else
279     {
280         if (m_pModifiers->FontID && pFoundry)
281         {
282             std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
283             pFont = pFoundry->GetFontManger().CreateFont(m_pModifiers->FontID);
284             pNewStyle->SetFont(pFont);
285             IXFStyleRet aNewStyle = pXFStyleManager->AddStyle(std::move(pNewStyle));
286             m_StyleName = aNewStyle.m_pStyle->GetStyleName();
287             pStyle = dynamic_cast<XFTextStyle*>(aNewStyle.m_pStyle);
288             if (aNewStyle.m_bOrigDeleted)
289                 pStyle = nullptr;
290         }
291     }
292 
293     if (m_pModifiers->HasHighlight)
294     {
295         XFColor  aColor = GetHighlightColor();//right yellow
296         if (pStyle)//change the style directly
297             pStyle->GetFont()->SetBackColor(aColor);
298         else //register a new style
299         {
300             std::unique_ptr<XFTextStyle> pNewStyle(new XFTextStyle());
301 
302             if (!m_StyleName.isEmpty())
303             {
304                 XFTextStyle* pOldStyle = pXFStyleManager->FindTextStyle(m_StyleName);
305                 *pNewStyle = *pOldStyle;
306                 pNewStyle->GetFont()->SetBackColor(aColor);
307             }
308             else
309             {
310                 pFont = new XFFont;
311                 pFont->SetBackColor(aColor);
312                 pNewStyle->SetFont(pFont);
313             }
314             m_StyleName = pXFStyleManager->AddStyle(std::move(pNewStyle)).m_pStyle->GetStyleName();
315         }
316     }
317 }
318 
ReadModifiers(LwpObjectStream * pObjStrm,ModifierInfo * pModInfo)319 void LwpFrib::ReadModifiers(LwpObjectStream* pObjStrm,ModifierInfo* pModInfo)
320 {
321     for(;;)
322     {
323         bool bFailure;
324 
325         // Get the modifier type
326         sal_uInt8 Modifier = pObjStrm->QuickReaduInt8(&bFailure);
327         if (bFailure)
328             break;
329 
330         // Stop when we hit the last modifier
331         if (Modifier == FRIB_MTAG_NONE)
332             break;
333 
334         // Get the modifier length
335         sal_uInt8 len = pObjStrm->QuickReaduInt8(&bFailure);
336         if (bFailure)
337             break;
338 
339         switch (Modifier)
340         {
341             case FRIB_MTAG_FONT:
342                 if (len != sizeof(pModInfo->FontID))
343                 {
344                     OSL_FAIL("FRIB_MTAG_FONT entry wrong size");
345                     pObjStrm->SeekRel(len);
346                 }
347                 else
348                     pModInfo->FontID = pObjStrm->QuickReaduInt32();
349                 break;
350             case FRIB_MTAG_CHARSTYLE:
351                 pModInfo->HasCharStyle = true;
352                 pModInfo->CharStyleID.ReadIndexed(pObjStrm);
353                 break;
354             case FRIB_MTAG_LANGUAGE:
355                 pModInfo->HasLangOverride = true;
356                 pModInfo->Language.Read(pObjStrm);
357                 break;
358             case FRIB_MTAG_CODEPAGE:
359                 if (len != sizeof(pModInfo->CodePage))
360                 {
361                     OSL_FAIL("FRIB_MTAG_CODEPAGE entry wrong size");
362                     pObjStrm->SeekRel(len);
363                 }
364                 else
365                     pModInfo->CodePage = pObjStrm->QuickReaduInt16();
366                 break;
367             case FRIB_MTAG_ATTRIBUTE:
368                 pModInfo->aTxtAttrOverride.Read(pObjStrm);
369                 if (pModInfo->aTxtAttrOverride.IsHighlight())
370                     pModInfo->HasHighlight = true;
371                 break;
372             case FRIB_MTAG_REVISION:
373                 pModInfo->RevisionType = pObjStrm->QuickReaduInt8();
374                 pModInfo->RevisionFlag = true;
375                 break;
376             default:
377                 pObjStrm->SeekRel(len);
378                 break;
379         }
380         // TODO: read the modifier data
381     }
382 }
383 
384 /**
385 *  @descr:   Whether there are other fribs following current frib.
386 *  @return:  True if having following fribs, or false.
387 */
HasNextFrib()388 bool LwpFrib::HasNextFrib()
389 {
390     return GetNext() && GetNext()->GetType() != FRIB_TAG_EOP;
391 }
392 
ConvertChars(XFContentContainer * pXFPara,const OUString & text)393 void LwpFrib::ConvertChars(XFContentContainer* pXFPara,const OUString& text)
394 {
395     if (m_ModFlag)
396     {
397         OUString strStyleName = GetStyleName();
398         XFTextSpan *pSpan = new XFTextSpan(text,strStyleName);
399         pXFPara->Add(pSpan);
400     }
401     else
402     {
403         XFTextContent *pSpan = new XFTextContent();
404         pSpan->SetText(text);
405         pXFPara->Add(pSpan);
406     }
407 }
408 
ConvertHyperLink(XFContentContainer * pXFPara,const LwpHyperlinkMgr * pHyperlink,const OUString & text)409 void LwpFrib::ConvertHyperLink(XFContentContainer* pXFPara, const LwpHyperlinkMgr* pHyperlink,const OUString& text)
410 {
411     XFHyperlink* pHyper = new XFHyperlink;
412     pHyper->SetHRef(pHyperlink->GetHyperlink());
413     pHyper->SetText(text);
414     pHyper->SetStyleName(GetStyleName());
415     pXFPara->Add(pHyper);
416 }
417 
418 /**
419 *  @descr:   Get the current frib font style
420 *  @return:  XFFont pointer
421 */
GetFont()422 rtl::Reference<XFFont> LwpFrib::GetFont()
423 {
424     rtl::Reference<XFFont> pFont;
425     if(m_pModifiers&&m_pModifiers->FontID)
426     {
427         LwpFoundry* pFoundry = m_pPara->GetFoundry();
428         if (pFoundry)
429             pFont = pFoundry->GetFontManger().CreateFont(m_pModifiers->FontID);
430     }
431     else
432     {
433         XFParaStyle* pXFParaStyle = m_pPara->GetXFParaStyle();
434         pFont = pXFParaStyle->GetFont();
435     }
436     return pFont;
437 }
438 
GetEditor()439 OUString LwpFrib::GetEditor()
440 {
441     LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
442     return pGlobal->GetEditorName(m_nEditor);
443 }
444 
GetHighlightColor()445 XFColor LwpFrib::GetHighlightColor()
446 {
447     LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
448     return pGlobal->GetHighlightColor(m_nEditor);
449 }
450 
Register(std::map<LwpFrib *,OUString> * pFribMap)451 void LwpFrib::Register(std::map<LwpFrib*,OUString>* pFribMap)
452 {
453     if (m_pFribMap)
454         throw std::runtime_error("registered already");
455     m_pFribMap = pFribMap;
456 }
457 
Deregister()458 void LwpFrib::Deregister()
459 {
460     if (m_pFribMap)
461     {
462         m_pFribMap->erase(this);
463         m_pFribMap = nullptr;
464     }
465 }
466 
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
468