LibreOffice Module oox (master)  1
textrun.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <drawingml/textrun.hxx>
21 
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <com/sun/star/text/ControlCharacter.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/beans/XPropertyState.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/text/XTextField.hpp>
28 
29 #include <sal/log.hxx>
30 
31 #include <oox/helper/helper.hxx>
34 #include <oox/token/properties.hxx>
35 #include <oox/token/tokens.hxx>
36 #include <tools/diagnose_ex.h>
37 
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::text;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::lang;
42 
43 namespace oox::drawingml {
44 
46  mbIsLineBreak( false )
47 {
48 }
49 
51 {
52 }
53 
55  const ::oox::core::XmlFilterBase& rFilterBase,
56  const Reference < XText > & xText,
57  const Reference < XTextCursor > &xAt,
58  const TextCharacterProperties& rTextCharacterStyle,
59  float nDefaultCharHeight) const
60 {
61  sal_Int32 nCharHeight = 0;
62  try {
63  Reference< XTextRange > xStart = xAt;
64  PropertySet aPropSet( xStart );
65 
66  Reference<XPropertyState> xState(xStart, UNO_QUERY);
67  Any aOldFontName = xState->getPropertyDefault("CharFontName");
68  Any aOldFontPitch = xState->getPropertyDefault("CharFontPitch");
69  Any aOldFontFamily = xState->getPropertyDefault("CharFontFamily");
70 
71  TextCharacterProperties aTextCharacterProps( rTextCharacterStyle );
72  aTextCharacterProps.assignUsed( maTextCharacterProperties );
73  if ( aTextCharacterProps.moHeight.has() )
74  nCharHeight = aTextCharacterProps.moHeight.get();
75  else
76  // UNO API has the character height as float, DML has it as int, but in hundreds.
77  aTextCharacterProps.moHeight = static_cast<sal_Int32>(nDefaultCharHeight * 100);
78  aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase );
79 
81  {
82  if( mbIsLineBreak )
83  {
84  SAL_WARN("oox", "OOX: TextRun::insertAt() insert line break" );
85  xText->insertControlCharacter( xStart, ControlCharacter::LINE_BREAK, false );
86  }
87  else if (!getText().isEmpty())
88  {
89  sal_Int32 nIndex = 0;
90  sal_Int32 nMax = getText().getLength();
91  while(true)
92  {
93  bool bSymbol = (getText()[nIndex] & 0xff00) == 0xf000;
94  sal_Int32 nCount = 1;
95  while(nIndex + nCount < nMax
96  && ((getText()[nIndex + nCount] & 0xff00) == 0xf000) == bSymbol)
97  ++nCount;
98 
99  OUString aFontName;
100  sal_Int16 nFontFamily = 0, nFontPitch = 0;
101  bool bReset = false;
102 
103  // Direct formatting for symbols.
104  if (bSymbol && aTextCharacterProps.maSymbolFont.getFontData(aFontName, nFontPitch, nFontFamily, rFilterBase))
105 
106  {
107  aPropSet.setAnyProperty(PROP_CharFontName, Any(aFontName));
108  aPropSet.setAnyProperty(PROP_CharFontPitch, Any(nFontPitch));
109  aPropSet.setAnyProperty(PROP_CharFontFamily, Any(nFontFamily));
110  bReset = true;
111  }
112 
113  OUString aSubString(getText().copy(nIndex, nCount));
114  xText->insertString(xStart, aSubString, false);
115 
116  aPropSet = PropertySet(xStart);
117  // Reset to whatever it was.
118  if (bReset)
119  {
120  aPropSet.setAnyProperty(PROP_CharFontName, aOldFontName);
121  aPropSet.setAnyProperty(PROP_CharFontPitch, aOldFontPitch);
122  aPropSet.setAnyProperty(PROP_CharFontFamily, aOldFontFamily);
123  }
124 
125  nIndex += nCount;
126 
127  if (nIndex >= nMax)
128  break;
129 
130  aTextCharacterProps.pushToPropSet(aPropSet, rFilterBase);
131  }
132  }
133  }
134  else
135  {
136  SAL_WARN("oox", "OOX: URL field" );
137  Reference< XMultiServiceFactory > xFactory( rFilterBase.getModel(), UNO_QUERY );
138  Reference< XTextField > xField( xFactory->createInstance( "com.sun.star.text.TextField.URL" ), UNO_QUERY );
139  if( xField.is() )
140  {
141  Reference< XTextCursor > xTextFieldCursor = xText->createTextCursor();
142  xTextFieldCursor->gotoEnd( false );
143 
144  PropertySet aFieldProps( xField );
146  aFieldProps.setProperty( PROP_Representation, getText() );
147  xText->insertTextContent( xStart, xField, false );
148 
149  xTextFieldCursor->gotoEnd( true );
150 
152  aTextCharacterProps.maFillProperties.maFillColor.setSchemeClr(XML_hlink);
153 
154  aTextCharacterProps.maFillProperties.moFillType.set(XML_solidFill);
156  aTextCharacterProps.moUnderline.set( XML_sng );
157 
158  PropertySet aFieldTextPropSet( xTextFieldCursor );
159  aTextCharacterProps.pushToPropSet( aFieldTextPropSet, rFilterBase );
160 
162  aTextField.xText = xText;
163  aTextField.xTextCursor = xTextFieldCursor;
164  aTextField.xTextField = xField;
165  rFilterBase.getTextFieldStack().push_back( aTextField );
166  }
167  else
168  {
169  SAL_WARN("oox", "OOX: URL field couldn't be created" );
170  xText->insertString( xStart, getText(), false );
171  }
172  }
173  }
174  catch( const Exception& )
175  {
176  TOOLS_WARN_EXCEPTION("oox", "OOX: TextRun::insertAt()");
177  }
178 
179  return nCharHeight;
180 }
181 
182 }
183 
184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nIndex
void setSchemeClr(sal_Int32 nToken)
Sets a scheme color from the a:schemeClr element.
Definition: color.cxx:305
virtual sal_Int32 insertAt(const ::oox::core::XmlFilterBase &rFilterBase, const css::uno::Reference< css::text::XText > &xText, const css::uno::Reference< css::text::XTextCursor > &xAt, const TextCharacterProperties &rTextCharacterStyle, float nDefaultCharHeight) const
Definition: textrun.cxx:54
OptValue< sal_Int32 > moFillType
css::uno::Reference< css::text::XTextField > xTextField
bool getFontData(OUString &rFontName, sal_Int16 &rnFontPitch, sal_Int16 &rnFontFamily, const ::oox::core::XmlFilterBase &rFilter) const
Returns the font name, pitch, and family; tries to resolve theme placeholder names, e.g.
Definition: textfont.cxx:78
void setProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
Puts the passed properties into the property set.
void set(const Type &rValue)
Definition: helper.hxx:188
int nCount
const Type & get() const
Definition: helper.hxx:185
bool setAnyProperty(sal_Int32 nPropId, const css::uno::Any &rValue)
Puts the passed any into the property set.
Definition: propertyset.cxx:70
bool hasProperty(sal_Int32 nPropId) const
Returns true, if the map contains a property with the passed identifier.
#define TOOLS_WARN_EXCEPTION(area, stream)
A wrapper for a UNO property set.
Definition: propertyset.hxx:57
bool empty() const
OUString & getText()
Definition: textrun.hxx:37
css::uno::Reference< css::text::XText > xText
void copy(const fs::path &src, const fs::path &dest)
void assignUsed(const TextCharacterProperties &rSourceProps)
Overwrites all members that are explicitly set in rSourceProps.
css::uno::Reference< css::text::XTextCursor > xTextCursor
#define SAL_WARN(area, stream)
Reference< XSingleServiceFactory > xFactory
Color maFillColor
Fill type (OOXML token).
constexpr OUStringLiteral aTextField
TextCharacterProperties maTextCharacterProperties
Definition: textrun.hxx:61
bool has() const
Definition: helper.hxx:181
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
void pushToPropSet(PropertySet &rPropSet, const ::oox::core::XmlFilterBase &rFilter) const
Writes the properties to the passed property set.