/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include namespace oox::vml { using namespace com::sun::star; TextFontModel::TextFontModel() { } TextPortionModel::TextPortionModel( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const OUString& rText ) : maParagraph( rParagraph ), maFont( rFont ), maText( rText ) { } TextBox::TextBox(ShapeTypeModel& rTypeModel) : mrTypeModel(rTypeModel) , borderDistanceSet( false ) , borderDistanceLeft(0) , borderDistanceTop(0) , borderDistanceRight(0) , borderDistanceBottom(0) { } void TextBox::appendPortion( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const OUString& rText ) { maPortions.emplace_back( rParagraph, rFont, rText ); } const TextFontModel* TextBox::getFirstFont() const { return maPortions.empty() ? nullptr : &maPortions.front().maFont; } OUString TextBox::getText() const { OUStringBuffer aBuffer; for (auto const& portion : maPortions) aBuffer.append( portion.maText ); return aBuffer.makeStringAndClear(); } void TextBox::convert(const uno::Reference& xShape) const { uno::Reference xTextAppend(xShape, uno::UNO_QUERY); OUString sParaStyle; bool bAmbiguousStyle = true; for (auto const& portion : maPortions) { beans::PropertyValue aPropertyValue; std::vector aPropVec; const TextParagraphModel& rParagraph = portion.maParagraph; const TextFontModel& rFont = portion.maFont; if (rFont.moName.has()) { aPropertyValue.Name = "CharFontName"; aPropertyValue.Value <<= rFont.moName.get(); aPropVec.push_back(aPropertyValue); aPropertyValue.Name = "CharFontNameAsian"; aPropertyValue.Value <<= rFont.moNameAsian.get(); aPropVec.push_back(aPropertyValue); aPropertyValue.Name = "CharFontNameComplex"; aPropertyValue.Value <<= rFont.moNameComplex.get(); aPropVec.push_back(aPropertyValue); } if (rFont.mobBold.has()) { aPropertyValue.Name = "CharWeight"; aPropertyValue.Value <<= rFont.mobBold.get() ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL; aPropVec.push_back(aPropertyValue); } if (rFont.monSize.has()) { aPropertyValue.Name = "CharHeight"; aPropertyValue.Value <<= double(rFont.monSize.get()) / 2.; aPropVec.push_back(aPropertyValue); } if (rFont.monSpacing.has()) { aPropertyValue.Name = "CharKerning"; // Value is not converted to mm100: SvxKerningItem::PutValue() gets // called with nMemberId = 0, so no mm100 -> twips conversion will // be done there. aPropertyValue.Value <<= sal_Int16(rFont.monSpacing.get()); aPropVec.push_back(aPropertyValue); } if (rParagraph.moParaAdjust.has()) { style::ParagraphAdjust eAdjust = style::ParagraphAdjust_LEFT; if (rParagraph.moParaAdjust.get() == "center") eAdjust = style::ParagraphAdjust_CENTER; else if (rParagraph.moParaAdjust.get() == "right") eAdjust = style::ParagraphAdjust_RIGHT; aPropertyValue.Name = "ParaAdjust"; aPropertyValue.Value <<= eAdjust; aPropVec.push_back(aPropertyValue); } // All paragraphs should be either undefined (default) or the same style, // because it will only be applied to the entire shape, and not per-paragraph. if (sParaStyle.isEmpty() ) { if ( rParagraph.moParaStyleName.has() ) sParaStyle = rParagraph.moParaStyleName.get(); if ( bAmbiguousStyle ) bAmbiguousStyle = false; // both empty parastyle and ambiguous can only be true at the first paragraph else bAmbiguousStyle = rParagraph.moParaStyleName.has(); // ambiguous if both default and specified style used. } else if ( !bAmbiguousStyle ) { if ( !rParagraph.moParaStyleName.has() ) bAmbiguousStyle = true; // ambiguous if both specified and default style used. else if ( rParagraph.moParaStyleName.get() != sParaStyle ) bAmbiguousStyle = true; // ambiguous if two different styles specified. } if (rFont.moColor.has()) { aPropertyValue.Name = "CharColor"; aPropertyValue.Value <<= rFont.moColor.get().toUInt32(16); aPropVec.push_back(aPropertyValue); } xTextAppend->appendTextPortion(portion.maText, comphelper::containerToSequence(aPropVec)); } try { // Track the style in a grabBag for use later when style details are known. comphelper::SequenceAsHashMap aGrabBag; uno::Reference xPropertySet(xShape, uno::UNO_QUERY_THROW); aGrabBag.update( xPropertySet->getPropertyValue("CharInteropGrabBag") ); aGrabBag["mso-pStyle"] <<= sParaStyle; xPropertySet->setPropertyValue("CharInteropGrabBag", uno::makeAny(aGrabBag.getAsConstPropertyValueList())); } catch (const uno::Exception&) { TOOLS_WARN_EXCEPTION( "oox.vml","convert() grabbag exception" ); } // Remove the last character of the shape text, if it would be a newline. uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursor(); xCursor->gotoEnd(false); xCursor->goLeft(1, true); if (xCursor->getString() == "\n") xCursor->setString(""); if ( maLayoutFlow != "vertical" ) return; uno::Reference xProperties(xShape, uno::UNO_QUERY); // VML has the text horizontally aligned to left (all the time), // v-text-anchor for vertical alignment, and vertical mode to swap the // two. drawinglayer supports both horizontal and vertical alignment, // but no vertical mode: we use T->B, R->L instead. // As a result, we need to set horizontal adjustment here to 'right', // that will result in vertical 'top' after writing mode is applied, // which matches the VML behavior. xProperties->setPropertyValue("TextHorizontalAdjust", uno::makeAny(drawing::TextHorizontalAdjust_RIGHT)); xProperties->setPropertyValue( "TextWritingMode", uno::makeAny( text::WritingMode_TB_RL ) ); } } // namespace oox::vml /* vim:set shiftwidth=4 softtabstop=4 expandtab: */