~smartboyhw/ubuntu/raring/calligra/2.6.0-0ubuntu1

« back to all changes in this revision

Viewing changes to .pc/kubuntu_04_arm_compile.diff/krita/ui/canvas/kis_coordinates_converter.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-10-23 21:09:16 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20121023210916-m82w6zxnxhaxz7va
Tags: 1:2.5.90-0ubuntu1
* New upstream alpha release (LP: #1070436)
  - Add libkactivities-dev and libopenimageio-dev to build-depends
  - Add kubuntu_build_calligraactive.diff to build calligraactive by default
  - Add package for calligraauthor and move files that are shared between
    calligrawords and calligraauthor to calligrawords-common
* Document the patches
* Remove numbers from patches so they follow the same naming scheme as
  the rest of our patches.
* calligra-data breaks replaces krita-data (<< 1:2.5.3) (LP: #1071686)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (c) 2010 Dmitry Kazakov <dimula73@gmail.com>
3
 
 *  Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
4
 
 *
5
 
 *  This program is free software; you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation; either version 2 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 
 */
19
 
 
20
 
#include <cmath>
21
 
 
22
 
#include "kis_coordinates_converter.h"
23
 
 
24
 
#include <QTransform>
25
 
#include <KoViewConverter.h>
26
 
 
27
 
#include <kis_config.h>
28
 
#include <kis_image.h>
29
 
 
30
 
 
31
 
struct KisCoordinatesConverter::Private {
32
 
    Private():
33
 
        isXAxisMirrored(false), isYAxisMirrored(false), rotationAngle(0.0) { }
34
 
    
35
 
    KisImageWSP image;
36
 
    
37
 
    bool isXAxisMirrored;
38
 
    bool isYAxisMirrored;
39
 
    qreal rotationAngle;
40
 
    QSizeF canvasWidgetSize;
41
 
    QPointF documentOffset;
42
 
    
43
 
    QTransform flakeToWidget;
44
 
    QTransform imageToDocument;
45
 
    QTransform documentToFlake;
46
 
    QTransform widgetToViewport;
47
 
};
48
 
 
49
 
/**
50
 
 * When vastScrolling value is less than 0.5 it is possible
51
 
 * that the whole scrolling area (viewport) will be smaller than
52
 
 * the size of the widget. In such cases the image should be
53
 
 * centered in the widget. Previously we used a special parameter
54
 
 * documentOrigin for this purpose, now the value for this
55
 
 * centering is calculated dynamically, helping the offset to
56
 
 * center the image inside the widget
57
 
 *
58
 
 * Note that the correction is null when the size of the document
59
 
 * plus vast scrolling reserve is larger than the widget. This
60
 
 * is always true for vastScrolling parameter > 0.5.
61
 
 */
62
 
 
63
 
QPointF KisCoordinatesConverter::centeringCorrection() const
64
 
{
65
 
    KisConfig cfg;
66
 
 
67
 
    QSize documentSize = imageRectInWidgetPixels().toAlignedRect().size();
68
 
    QPointF dPoint(documentSize.width(), documentSize.height());
69
 
    QPointF wPoint(m_d->canvasWidgetSize.width(), m_d->canvasWidgetSize.height());
70
 
 
71
 
    QPointF minOffset = -cfg.vastScrolling() * wPoint;
72
 
    QPointF maxOffset = dPoint - wPoint + cfg.vastScrolling() * wPoint;
73
 
 
74
 
    QPointF range = maxOffset - minOffset;
75
 
 
76
 
    range.rx() = qMin(range.x(), 0.0);
77
 
    range.ry() = qMin(range.y(), 0.0);
78
 
 
79
 
    range /= 2;
80
 
 
81
 
    return -range;
82
 
}
83
 
 
84
 
/**
85
 
 * The document offset and the position of the top left corner of the
86
 
 * image must always coincide, that is why we need to correct them to
87
 
 * and fro.
88
 
 *
89
 
 * When we change zoom level, the calculation of the new offset is
90
 
 * done by KoCanvasControllerWidget, that is why we just passively fix
91
 
 * the flakeToWidget transform to conform the offset and wait until
92
 
 * the canvas controller will recenter us.
93
 
 *
94
 
 * But when we do our own transformations of the canvas, like rotation
95
 
 * and mirroring, we cannot rely on the centering of the canvas
96
 
 * controller and we do it ourselves. Then we just set new offset and
97
 
 * return its value to be set in the canvas controller explicitly.
98
 
 */
99
 
 
100
 
void KisCoordinatesConverter::correctOffsetToTransformation()
101
 
{
102
 
    m_d->documentOffset = -(imageRectInWidgetPixels().topLeft() -
103
 
          centeringCorrection()).toPoint();
104
 
}
105
 
 
106
 
void KisCoordinatesConverter::correctTransformationToOffset()
107
 
{
108
 
    QPointF topLeft = imageRectInWidgetPixels().topLeft();
109
 
    QPointF diff = (-topLeft) - m_d->documentOffset;
110
 
    diff += centeringCorrection();
111
 
    m_d->flakeToWidget *= QTransform::fromTranslate(diff.x(), diff.y());
112
 
}
113
 
 
114
 
void KisCoordinatesConverter::recalculateTransformations()
115
 
{
116
 
    if(!m_d->image) return;
117
 
 
118
 
    m_d->imageToDocument = QTransform::fromScale(1 / m_d->image->xRes(),
119
 
                                                 1 / m_d->image->yRes());
120
 
 
121
 
    qreal zoomX, zoomY;
122
 
    KoZoomHandler::zoom(&zoomX, &zoomY);
123
 
    m_d->documentToFlake = QTransform::fromScale(zoomX, zoomY);
124
 
 
125
 
    correctTransformationToOffset();
126
 
 
127
 
    QRectF irect = imageRectInWidgetPixels();
128
 
    QRectF wrect = QRectF(QPoint(0,0), m_d->canvasWidgetSize);
129
 
    QRectF rrect = irect & wrect;
130
 
 
131
 
    QTransform reversedTransform = flakeToWidgetTransform().inverted();
132
 
    QRectF     canvasBounds      = reversedTransform.mapRect(rrect);
133
 
    QPointF    offset            = canvasBounds.topLeft();
134
 
 
135
 
    m_d->widgetToViewport = reversedTransform * QTransform::fromTranslate(-offset.x(), -offset.y());
136
 
}
137
 
 
138
 
 
139
 
KisCoordinatesConverter::KisCoordinatesConverter()
140
 
    : m_d(new Private) { }
141
 
 
142
 
KisCoordinatesConverter::~KisCoordinatesConverter()
143
 
{
144
 
    delete m_d;
145
 
}
146
 
 
147
 
void KisCoordinatesConverter::setCanvasWidgetSize(QSize size)
148
 
{
149
 
    m_d->canvasWidgetSize = size;
150
 
    recalculateTransformations();
151
 
}
152
 
 
153
 
void KisCoordinatesConverter::setImage(KisImageWSP image)
154
 
{
155
 
    m_d->image = image;
156
 
    recalculateTransformations();
157
 
}
158
 
 
159
 
void KisCoordinatesConverter::setDocumentOffset(const QPoint& offset)
160
 
{
161
 
    QPointF diff = m_d->documentOffset - offset;
162
 
    
163
 
    m_d->documentOffset = offset;
164
 
    m_d->flakeToWidget *= QTransform::fromTranslate(diff.x(), diff.y());
165
 
    recalculateTransformations();
166
 
}
167
 
 
168
 
QPoint KisCoordinatesConverter::documentOffset() const
169
 
{
170
 
    return QPoint(int(m_d->documentOffset.x()), int(m_d->documentOffset.y()));
171
 
}
172
 
 
173
 
qreal KisCoordinatesConverter::rotationAngle() const
174
 
{
175
 
    return m_d->rotationAngle;
176
 
}
177
 
 
178
 
void KisCoordinatesConverter::setZoom(qreal zoom)
179
 
{
180
 
    KoZoomHandler::setZoom(zoom);
181
 
    recalculateTransformations();
182
 
}
183
 
 
184
 
QPoint KisCoordinatesConverter::rotate(QPointF center, qreal angle)
185
 
{
186
 
    QTransform rot;
187
 
    rot.rotate(angle);
188
 
 
189
 
    m_d->flakeToWidget *= QTransform::fromTranslate(-center.x(),-center.y());
190
 
    m_d->flakeToWidget *= rot;
191
 
    m_d->flakeToWidget *= QTransform::fromTranslate(center.x(), center.y());
192
 
    m_d->rotationAngle = std::fmod(m_d->rotationAngle + angle, 360.0);
193
 
 
194
 
    correctOffsetToTransformation();
195
 
    recalculateTransformations();
196
 
 
197
 
    return m_d->documentOffset.toPoint();
198
 
}
199
 
 
200
 
QPoint KisCoordinatesConverter::mirror(QPointF center, bool mirrorXAxis, bool mirrorYAxis, bool keepOrientation)
201
 
{
202
 
    bool       doXMirroring = m_d->isXAxisMirrored ^ mirrorXAxis;
203
 
    bool       doYMirroring = m_d->isYAxisMirrored ^ mirrorYAxis;
204
 
    qreal      scaleX       = doYMirroring ? -1.0 : 1.0;
205
 
    qreal      scaleY       = doXMirroring ? -1.0 : 1.0;
206
 
    QTransform mirror       = QTransform::fromScale(scaleX, scaleY);
207
 
    
208
 
    QTransform rot;
209
 
    rot.rotate(m_d->rotationAngle);
210
 
    
211
 
    m_d->flakeToWidget *= QTransform::fromTranslate(-center.x(),-center.y());
212
 
    
213
 
    if(keepOrientation)
214
 
        m_d->flakeToWidget *= rot.inverted();
215
 
    
216
 
    m_d->flakeToWidget *= mirror;
217
 
    
218
 
    if(keepOrientation)
219
 
        m_d->flakeToWidget *= rot;
220
 
    
221
 
    m_d->flakeToWidget *= QTransform::fromTranslate(center.x(),center.y());
222
 
    
223
 
    if(!keepOrientation && (doXMirroring ^ doYMirroring))
224
 
        m_d->rotationAngle = -m_d->rotationAngle;
225
 
    
226
 
    m_d->isXAxisMirrored = mirrorXAxis;
227
 
    m_d->isYAxisMirrored = mirrorYAxis;
228
 
 
229
 
    correctOffsetToTransformation();
230
 
    recalculateTransformations();
231
 
 
232
 
    return m_d->documentOffset.toPoint();
233
 
}
234
 
 
235
 
QPoint KisCoordinatesConverter::resetRotation(QPointF center)
236
 
{
237
 
    QTransform rot;
238
 
    rot.rotate(-m_d->rotationAngle);
239
 
    
240
 
    m_d->flakeToWidget *= QTransform::fromTranslate(-center.x(), -center.y());
241
 
    m_d->flakeToWidget *= rot;
242
 
    m_d->flakeToWidget *= QTransform::fromTranslate(center.x(), center.y());
243
 
    m_d->rotationAngle = 0.0;
244
 
 
245
 
    correctOffsetToTransformation();
246
 
    recalculateTransformations();
247
 
 
248
 
    return m_d->documentOffset.toPoint();
249
 
}
250
 
 
251
 
QTransform KisCoordinatesConverter::imageToWidgetTransform() const{
252
 
    return m_d->imageToDocument * m_d->documentToFlake * m_d->flakeToWidget;
253
 
}
254
 
 
255
 
QTransform KisCoordinatesConverter::imageToDocumentTransform() const {
256
 
    return m_d->imageToDocument;
257
 
}
258
 
 
259
 
QTransform KisCoordinatesConverter::flakeToWidgetTransform() const {
260
 
    return m_d->flakeToWidget;
261
 
}
262
 
 
263
 
QTransform KisCoordinatesConverter::documentToWidgetTransform() const
264
 
{
265
 
    return m_d->documentToFlake * m_d->flakeToWidget;
266
 
}
267
 
 
268
 
QTransform KisCoordinatesConverter::viewportToWidgetTransform() const {
269
 
    return m_d->widgetToViewport.inverted();
270
 
}
271
 
 
272
 
QTransform KisCoordinatesConverter::imageToViewportTransform() const {
273
 
    return m_d->imageToDocument * m_d->documentToFlake * m_d->flakeToWidget * m_d->widgetToViewport;
274
 
}
275
 
 
276
 
void KisCoordinatesConverter::getQPainterCheckersInfo(QTransform *transform,
277
 
                                                      QPointF *brushOrigin,
278
 
                                                      QPolygonF *polygon) const
279
 
{
280
 
    /**
281
 
     * Qt has different rounding for QPainter::drawRect/drawImage.
282
 
     * The image is rounded mathematically, while rect in aligned
283
 
     * to the next integer. That causes transparent line appear on
284
 
     * the canvas.
285
 
     *
286
 
     * See: https://bugreports.qt.nokia.com/browse/QTBUG-22827
287
 
     */
288
 
 
289
 
    QRectF imageRect = imageRectInViewportPixels();
290
 
    imageRect.adjust(0,0,-0.5,-0.5);
291
 
 
292
 
    KisConfig cfg;
293
 
    if (cfg.scrollCheckers()) {
294
 
        *transform = viewportToWidgetTransform();
295
 
        *polygon = imageRect;
296
 
        *brushOrigin = imageToViewport(QPointF(0,0));
297
 
    }
298
 
    else {
299
 
        *transform = QTransform();
300
 
        *polygon = viewportToWidgetTransform().map(imageRect);
301
 
        *brushOrigin = QPoint(0,0);
302
 
    }
303
 
}
304
 
 
305
 
void KisCoordinatesConverter::getOpenGLCheckersInfo(QTransform *textureTransform,
306
 
                                                    QTransform *modelTransform,
307
 
                                                    QRectF *textureRect,
308
 
                                                    QRectF *modelRect) const
309
 
{
310
 
    KisConfig cfg;
311
 
    QRectF viewportRect = imageRectInViewportPixels();
312
 
 
313
 
    if(cfg.scrollCheckers()) {
314
 
        *textureTransform = QTransform();
315
 
        *textureRect = QRectF(0, 0, viewportRect.width(),viewportRect.height());
316
 
    }
317
 
    else {
318
 
        *textureTransform = viewportToWidgetTransform();
319
 
        *textureRect = viewportRect;
320
 
    }
321
 
 
322
 
    *modelTransform = viewportToWidgetTransform();
323
 
    *modelRect = viewportRect;
324
 
}
325
 
 
326
 
QPointF KisCoordinatesConverter::imageCenterInWidgetPixel() const
327
 
{
328
 
    if(!m_d->image)
329
 
        return QPointF();
330
 
    
331
 
    QPolygonF poly = imageToWidget(QPolygon(m_d->image->bounds()));
332
 
    return (poly[0] + poly[1] + poly[2] + poly[3]) / 4.0;
333
 
}
334
 
 
335
 
 
336
 
// these functions return a bounding rect if the canvas is rotated
337
 
 
338
 
QRectF KisCoordinatesConverter::imageRectInWidgetPixels() const
339
 
{
340
 
    if(!m_d->image) return QRectF();
341
 
    return imageToWidget(m_d->image->bounds());
342
 
}
343
 
 
344
 
QRectF KisCoordinatesConverter::imageRectInViewportPixels() const
345
 
{
346
 
    if(!m_d->image) return QRectF();
347
 
    return imageToViewport(m_d->image->bounds());
348
 
}
349
 
 
350
 
QSizeF KisCoordinatesConverter::imageSizeInFlakePixels() const
351
 
{
352
 
    if(!m_d->image) return QSizeF();
353
 
 
354
 
    qreal scaleX, scaleY;
355
 
    imageScale(&scaleX, &scaleY);
356
 
    QSize imageSize = m_d->image->size();
357
 
 
358
 
    return QSizeF(imageSize.width() * scaleX, imageSize.height() * scaleY);
359
 
}
360
 
 
361
 
QRectF KisCoordinatesConverter::widgetRectInFlakePixels() const
362
 
{
363
 
    return widgetToFlake(QRectF(QPoint(0,0), m_d->canvasWidgetSize));
364
 
}
365
 
 
366
 
QPointF KisCoordinatesConverter::flakeCenterPoint() const
367
 
{
368
 
    QRectF widgetRect = widgetRectInFlakePixels();
369
 
    return QPointF(widgetRect.left() + widgetRect.width() / 2,
370
 
                   widgetRect.top() + widgetRect.height() / 2);
371
 
}
372
 
 
373
 
QPointF KisCoordinatesConverter::widgetCenterPoint() const
374
 
{
375
 
    return QPointF(m_d->canvasWidgetSize.width() / 2.0, m_d->canvasWidgetSize.height() / 2.0);
376
 
}
377
 
 
378
 
void KisCoordinatesConverter::imageScale(qreal *scaleX, qreal *scaleY) const
379
 
{
380
 
    // get the x and y zoom level of the canvas
381
 
    qreal zoomX, zoomY;
382
 
    KoZoomHandler::zoom(&zoomX, &zoomY);
383
 
 
384
 
    // Get the KisImage resolution
385
 
    qreal resX = m_d->image->xRes();
386
 
    qreal resY = m_d->image->yRes();
387
 
 
388
 
    // Compute the scale factors
389
 
    *scaleX = zoomX / resX;
390
 
    *scaleY = zoomY / resY;
391
 
}