File indexing completed on 2024-05-12 16:34:58
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2011 C. Boemann <cbo@boemann.dk> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Library General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Library General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Library General Public License 0015 * along with this library; see the file COPYING.LIB. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "SimpleRootAreaProvider.h" 0021 0022 #include "TextShape.h" 0023 0024 #include <KoBorder.h> 0025 #include <KoTextLayoutRootArea.h> 0026 #include <KoTextLayoutObstruction.h> 0027 #include <KoInsets.h> 0028 0029 SimpleRootAreaProvider::SimpleRootAreaProvider(KoTextShapeData *data, TextShape *textshape) 0030 : m_textShape(textshape) 0031 , m_area(0) 0032 , m_textShapeData(data) 0033 , m_fixAutogrow(false) 0034 0035 { 0036 } 0037 0038 KoTextLayoutRootArea *SimpleRootAreaProvider::provide(KoTextDocumentLayout *documentLayout, const RootAreaConstraint &, int requestedPosition, bool *isNewRootArea) 0039 { 0040 if(m_area == 0) { 0041 *isNewRootArea = true; 0042 m_area = new KoTextLayoutRootArea(documentLayout); 0043 m_area->setAssociatedShape(m_textShape); 0044 m_textShapeData->setRootArea(m_area); 0045 0046 return m_area; 0047 } 0048 if (requestedPosition == 0) { 0049 *isNewRootArea = false; 0050 return m_area; 0051 } 0052 return 0; 0053 } 0054 0055 void SimpleRootAreaProvider::releaseAllAfter(KoTextLayoutRootArea *afterThis) 0056 { 0057 Q_UNUSED(afterThis); 0058 } 0059 0060 void SimpleRootAreaProvider::doPostLayout(KoTextLayoutRootArea *rootArea, bool isNewRootArea) 0061 { 0062 Q_UNUSED(isNewRootArea); 0063 0064 m_textShape->update(m_textShape->outlineRect()); 0065 0066 QSizeF newSize = m_textShape->size() 0067 - QSizeF(m_textShapeData->leftPadding() + m_textShapeData->rightPadding(), 0068 m_textShapeData->topPadding() + m_textShapeData->bottomPadding()); 0069 0070 KoBorder *border = m_textShape->border(); 0071 if (border) { 0072 newSize -= QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); 0073 } else { 0074 KoInsets inset = m_textShape->strokeInsets(); 0075 newSize -= QSizeF((inset.right+inset.left), (inset.bottom+inset.top)); 0076 } 0077 0078 0079 if (m_textShapeData->verticalAlignment() & Qt::AlignBottom) { 0080 } 0081 if (m_textShapeData->verticalAlignment() & Qt::AlignVCenter) { 0082 } 0083 0084 if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoResize) { 0085 newSize = QSizeF(rootArea->right() - rootArea->left(), rootArea->bottom() - rootArea->top()); 0086 // HACK: The size we get from the shape will cut descents, 0087 // so we add some reasonable (approximate) value that works ok in normal cases 0088 QSizeF s(0.0, 0.0); 0089 int lines = m_textShapeData->document()->lineCount(); 0090 if (lines > 0) { 0091 s.setHeight(newSize.height() / lines * 0.2); 0092 } 0093 newSize += s; 0094 } else { 0095 if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight 0096 ||m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowHeight) { 0097 qreal height = rootArea->bottom() - rootArea->top(); 0098 if (height > newSize.height()) { 0099 newSize.setHeight(height); 0100 } 0101 if (m_textShape->shapeId() == "AnnotationTextShapeID") { 0102 if (height < newSize.height()) { 0103 newSize.setHeight(rootArea->bottom() - rootArea->top()); 0104 } 0105 } 0106 } 0107 if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight 0108 ||m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidth) { 0109 qreal width = rootArea->right() - rootArea->left(); 0110 if (width > newSize.width()) { 0111 newSize.setWidth(rootArea->right() - rootArea->left()); 0112 } 0113 } 0114 } 0115 0116 qreal newBottom = rootArea->top() + newSize.height(); 0117 KoFlake::Position sizeAnchor= KoFlake::TopLeftCorner; 0118 0119 if (m_textShapeData->verticalAlignment() & Qt::AlignBottom) { 0120 if (true /*FIXME test no page based shapes interfering*/) { 0121 rootArea->setVerticalAlignOffset(newBottom - rootArea->bottom()); 0122 sizeAnchor= KoFlake::BottomLeftCorner; 0123 } 0124 } 0125 if (m_textShapeData->verticalAlignment() & Qt::AlignVCenter) { 0126 if (true /*FIXME test no page based shapes interfering*/) { 0127 rootArea->setVerticalAlignOffset((newBottom - rootArea->bottom()) / 2); 0128 sizeAnchor = KoFlake::CenteredPosition; 0129 } 0130 } 0131 newSize += QSizeF(m_textShapeData->leftPadding() + m_textShapeData->rightPadding(), 0132 m_textShapeData->topPadding() + m_textShapeData->bottomPadding()); 0133 if (border) { 0134 newSize += QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); 0135 } else { 0136 KoInsets inset = m_textShape->strokeInsets(); 0137 newSize += QSizeF((inset.right+inset.left), (inset.bottom+inset.top)); 0138 } 0139 0140 if (newSize != m_textShape->size()) { 0141 // OO grows to both sides so when to small the initial layouting needs 0142 // to keep that into account. 0143 if (m_fixAutogrow) { 0144 m_fixAutogrow = false; 0145 QSizeF tmpSize = m_textShape->size(); 0146 tmpSize.setWidth(newSize.width()); 0147 QPointF centerpos = rootArea->associatedShape()->absolutePosition(KoFlake::CenteredPosition); 0148 m_textShape->setSize(tmpSize); 0149 m_textShape->setAbsolutePosition(centerpos, KoFlake::CenteredPosition); 0150 centerpos = rootArea->associatedShape()->absolutePosition(sizeAnchor); 0151 m_textShape->setSize(newSize); 0152 m_textShape->setAbsolutePosition(centerpos, sizeAnchor); 0153 } 0154 m_textShape->setSize(newSize); 0155 } 0156 0157 m_textShape->update(m_textShape->outlineRect()); 0158 } 0159 0160 void SimpleRootAreaProvider::updateAll() 0161 { 0162 if (m_area && m_area->associatedShape()) { 0163 m_area->associatedShape()->update(); 0164 } 0165 } 0166 0167 QRectF SimpleRootAreaProvider::suggestRect(KoTextLayoutRootArea *rootArea) 0168 { 0169 //Come up with a rect, but actually we don't need the height, as we set it to infinite below 0170 // Still better keep it for completeness sake 0171 QRectF rect(QPointF(), m_textShape->size()); 0172 rect.adjust(m_textShapeData->leftPadding(), m_textShapeData->topPadding(), -m_textShapeData->rightPadding(), - m_textShapeData->bottomPadding()); 0173 0174 KoBorder *border = m_textShape->border(); 0175 if (border) { 0176 rect.adjust(border->borderWidth(KoBorder::LeftBorder), border->borderWidth(KoBorder::TopBorder), 0177 -border->borderWidth(KoBorder::RightBorder), - border->borderWidth(KoBorder::BottomBorder)); 0178 } else { 0179 KoInsets inset = m_textShape->strokeInsets(); 0180 rect.adjust(inset.left, inset.top, -inset.right, -inset.bottom); 0181 } 0182 0183 // In simple cases we always set height way too high so that we have no breaking 0184 // If the shape grows afterwards or not is handled in doPostLayout() 0185 rect.setHeight(1E6); 0186 0187 if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight 0188 ||m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidth 0189 ||m_textShapeData->resizeMethod() == KoTextShapeData::AutoResize) { 0190 rootArea->setNoWrap(1E6); 0191 } 0192 0193 // Make sure the size is not negative due to padding and border width 0194 // This can happen on vertical lines containing text on shape. 0195 if (rect.width() < 0) { 0196 rect.setWidth(0); 0197 } 0198 return rect; 0199 } 0200 0201 QList<KoTextLayoutObstruction *> SimpleRootAreaProvider::relevantObstructions(KoTextLayoutRootArea *rootArea) 0202 { 0203 Q_UNUSED(rootArea); 0204 0205 QList<KoTextLayoutObstruction*> obstructions; 0206 /* 0207 m_textShape->boundingRect(); 0208 QList<KoShape *> shapes; 0209 shapes = manager->shapesAt(canvasRect): 0210 */ 0211 return obstructions; 0212 }