]>
Commit | Line | Data |
---|---|---|
1 | git clone git://gitorious.org/~antialize/qt/antializes-qt.git, then checkout 4.8.4 | |
2 | # check 4.8.4 commit ID on git://gitorious.org/qt/qt.git | |
3 | git diff 96311def2466dd44de64d77a1c815b22fbf68f71 | |
4 | # parts related to static QtWebkit build are disabled | |
5 | ||
6 | #diff --git a/configure b/configure | |
7 | #index e3d464b..114933e 100755 | |
8 | #--- a/configure | |
9 | #+++ b/configure | |
10 | #@@ -7749,12 +7749,12 @@ if [ "$CFG_GUI" = "no" ]; then | |
11 | # canBuildWebKit="no" | |
12 | # fi | |
13 | # | |
14 | #-if [ "$CFG_SHARED" = "no" ]; then | |
15 | #- echo | |
16 | #- echo "WARNING: Using static linking will disable the WebKit module." | |
17 | #- echo | |
18 | #- canBuildWebKit="no" | |
19 | #-fi | |
20 | #+#if [ "$CFG_SHARED" = "no" ]; then | |
21 | #+ # echo | |
22 | #+ # echo "WARNING: Using static linking will disable the WebKit module." | |
23 | #+ # echo | |
24 | #+ # canBuildWebKit="no" | |
25 | #+#fi | |
26 | # | |
27 | # CFG_CONCURRENT="yes" | |
28 | # if [ "$canBuildQtConcurrent" = "no" ]; then | |
29 | #diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro | |
30 | #index a109179..146cb2d 100644 | |
31 | #--- a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro | |
32 | #+++ b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro | |
33 | #@@ -217,6 +217,12 @@ symbian: { | |
34 | # QMAKE_CXXFLAGS.ARMCC += -OTime -O3 | |
35 | # } | |
36 | # | |
37 | #+static { | |
38 | #+ !isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS | |
39 | #+ else: target.path = $$[QT_INSTALL_LIBS] | |
40 | #+ INSTALLS += target | |
41 | #+} | |
42 | #+ | |
43 | # lessThan(QT_GCC_MAJOR_VERSION, 5) { | |
44 | # # GCC 4.5 and before | |
45 | # lessThan(QT_GCC_MINOR_VERSION, 6) { | |
46 | diff --git a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp | |
47 | index ef72fb7..54ff69c 100644 | |
48 | --- a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp | |
49 | +++ b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp | |
50 | @@ -1080,7 +1080,9 @@ void FrameView::adjustMediaTypeForPrinting(bool printing) | |
51 | if (printing) { | |
52 | if (m_mediaTypeWhenNotPrinting.isNull()) | |
53 | m_mediaTypeWhenNotPrinting = mediaType(); | |
54 | - setMediaType("print"); | |
55 | + | |
56 | + String mediaType = (m_frame && m_frame->settings())?m_frame->settings()->printingMediaType():"print"; | |
57 | + setMediaType(mediaType); | |
58 | } else { | |
59 | if (!m_mediaTypeWhenNotPrinting.isNull()) | |
60 | setMediaType(m_mediaTypeWhenNotPrinting); | |
61 | diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp | |
62 | index 660ad11..8dffd52 100644 | |
63 | --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp | |
64 | +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp | |
65 | @@ -26,6 +26,7 @@ | |
66 | #include "FrameView.h" | |
67 | #include "RenderLayer.h" | |
68 | #include "RenderView.h" | |
69 | +#include "Settings.h" | |
70 | #include <wtf/text/StringConcatenate.h> | |
71 | ||
72 | namespace WebCore { | |
73 | @@ -182,11 +183,21 @@ void PrintContext::begin(float width, float height) | |
74 | // This function can be called multiple times to adjust printing parameters without going back to screen mode. | |
75 | m_isPrinting = true; | |
76 | ||
77 | - float minLayoutWidth = width * printingMinimumShrinkFactor; | |
78 | - float minLayoutHeight = height * printingMinimumShrinkFactor; | |
79 | + float minimumShrinkFactor = m_frame->settings() ? | |
80 | + m_frame->settings()->printingMinimumShrinkFactor() : 0.0f; | |
81 | + float maximumShrinkFactor = m_frame->settings() ? | |
82 | + m_frame->settings()->printingMaximumShrinkFactor() : 0.0f; | |
83 | + | |
84 | + if (maximumShrinkFactor < minimumShrinkFactor || minimumShrinkFactor <= 0.0f) { | |
85 | + minimumShrinkFactor = printingMinimumShrinkFactor; | |
86 | + maximumShrinkFactor = printingMaximumShrinkFactor; | |
87 | + } | |
88 | + | |
89 | + float minLayoutWidth = width * minimumShrinkFactor; | |
90 | + float minLayoutHeight = height * minimumShrinkFactor; | |
91 | ||
92 | // This changes layout, so callers need to make sure that they don't paint to screen while in printing mode. | |
93 | - m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize); | |
94 | + m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), maximumShrinkFactor / minimumShrinkFactor, Frame::AdjustViewSize); | |
95 | } | |
96 | ||
97 | float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize) | |
98 | diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h | |
99 | index aadff47..19f378e 100644 | |
100 | --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h | |
101 | +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h | |
102 | @@ -83,6 +83,8 @@ public: | |
103 | // (pageSizeInPixels.height() + 1) * number-of-pages - 1 | |
104 | static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels); | |
105 | ||
106 | +public: | |
107 | + const Vector<IntRect> & getPageRects() const {return m_pageRects;} | |
108 | protected: | |
109 | Frame* m_frame; | |
110 | Vector<IntRect> m_pageRects; | |
111 | diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp | |
112 | index 2025bd0..5414246 100644 | |
113 | --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp | |
114 | +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp | |
115 | @@ -87,6 +87,7 @@ static EditingBehaviorType editingBehaviorTypeForPlatform() | |
116 | ||
117 | Settings::Settings(Page* page) | |
118 | : m_page(page) | |
119 | + , m_printingMediaType("print") | |
120 | , m_editableLinkBehavior(EditableLinkDefaultBehavior) | |
121 | , m_textDirectionSubmenuInclusionBehavior(TextDirectionSubmenuAutomaticallyIncluded) | |
122 | , m_passwordEchoDurationInSeconds(1) | |
123 | @@ -184,6 +185,8 @@ Settings::Settings(Page* page) | |
124 | , m_allowDisplayOfInsecureContent(true) | |
125 | , m_allowRunningOfInsecureContent(true) | |
126 | , m_passwordEchoEnabled(false) | |
127 | + , m_printingMinimumShrinkFactor(0.0) | |
128 | + , m_printingMaximumShrinkFactor(0.0) | |
129 | { | |
130 | // A Frame may not have been created yet, so we initialize the AtomicString | |
131 | // hash before trying to use it. | |
132 | @@ -569,6 +572,11 @@ void Settings::setApplicationChromeMode(bool mode) | |
133 | m_inApplicationChromeMode = mode; | |
134 | } | |
135 | ||
136 | +void Settings::setPrintingMediaType(const String& type) | |
137 | +{ | |
138 | + m_printingMediaType = type; | |
139 | +} | |
140 | + | |
141 | void Settings::setOfflineWebApplicationCacheEnabled(bool enabled) | |
142 | { | |
143 | m_offlineWebApplicationCacheEnabled = enabled; | |
144 | @@ -744,4 +752,15 @@ void Settings::setTiledBackingStoreEnabled(bool enabled) | |
145 | #endif | |
146 | } | |
147 | ||
148 | +void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor) | |
149 | +{ | |
150 | + m_printingMinimumShrinkFactor = printingMinimumShrinkFactor; | |
151 | +} | |
152 | + | |
153 | +void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor) | |
154 | +{ | |
155 | + m_printingMaximumShrinkFactor = printingMaximumShrinkFactor; | |
156 | +} | |
157 | + | |
158 | + | |
159 | } // namespace WebCore | |
160 | diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.h b/src/3rdparty/webkit/Source/WebCore/page/Settings.h | |
161 | index 1d2a138..d827693 100644 | |
162 | --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.h | |
163 | +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.h | |
164 | @@ -258,6 +258,9 @@ namespace WebCore { | |
165 | void setApplicationChromeMode(bool); | |
166 | bool inApplicationChromeMode() const { return m_inApplicationChromeMode; } | |
167 | ||
168 | + void setPrintingMediaType(const String&); | |
169 | + const String& printingMediaType() const { return m_printingMediaType; } | |
170 | + | |
171 | void setOfflineWebApplicationCacheEnabled(bool); | |
172 | bool offlineWebApplicationCacheEnabled() const { return m_offlineWebApplicationCacheEnabled; } | |
173 | ||
174 | @@ -349,6 +352,12 @@ namespace WebCore { | |
175 | ||
176 | void setTiledBackingStoreEnabled(bool); | |
177 | bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; } | |
178 | + | |
179 | + void setPrintingMinimumShrinkFactor(float); | |
180 | + float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; } | |
181 | + | |
182 | + void setPrintingMaximumShrinkFactor(float); | |
183 | + float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; } | |
184 | ||
185 | void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; } | |
186 | bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; } | |
187 | @@ -419,6 +428,7 @@ namespace WebCore { | |
188 | String m_defaultTextEncodingName; | |
189 | String m_ftpDirectoryTemplatePath; | |
190 | String m_localStorageDatabasePath; | |
191 | + String m_printingMediaType; | |
192 | KURL m_userStyleSheetLocation; | |
193 | AtomicString m_standardFontFamily; | |
194 | AtomicString m_fixedFontFamily; | |
195 | @@ -429,6 +439,8 @@ namespace WebCore { | |
196 | EditableLinkBehavior m_editableLinkBehavior; | |
197 | TextDirectionSubmenuInclusionBehavior m_textDirectionSubmenuInclusionBehavior; | |
198 | double m_passwordEchoDurationInSeconds; | |
199 | + float m_printingMinimumShrinkFactor; | |
200 | + float m_printingMaximumShrinkFactor; | |
201 | int m_minimumFontSize; | |
202 | int m_minimumLogicalFontSize; | |
203 | int m_defaultFontSize; | |
204 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp | |
205 | index c348870..4069687 100644 | |
206 | --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp | |
207 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp | |
208 | @@ -73,7 +73,8 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato | |
209 | font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing); | |
210 | const bool smallCaps = description.smallCaps(); | |
211 | font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase); | |
212 | - font.setStyleStrategy(QFont::ForceIntegerMetrics); | |
213 | + // Commented out to work around webkit bug 93263 | |
214 | + //font.setStyleStrategy(QFont::ForceIntegerMetrics); | |
215 | ||
216 | m_data->bold = font.bold(); | |
217 | // WebKit allows font size zero but QFont does not. We will return | |
218 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp | |
219 | index 0c8ce9e..5ba54d0 100644 | |
220 | --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp | |
221 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp | |
222 | @@ -41,6 +41,7 @@ | |
223 | #include "PlatformString.h" | |
224 | #include "StillImageQt.h" | |
225 | #include "qwebsettings.h" | |
226 | +#include "SharedBuffer.h" | |
227 | ||
228 | #include <QPixmap> | |
229 | #include <QPainter> | |
230 | @@ -234,7 +235,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, | |
231 | } | |
232 | } | |
233 | ||
234 | - ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc); | |
235 | + QByteArray a = QByteArray::fromRawData(data()->data(), data()->size()); | |
236 | + ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc, &a); | |
237 | ||
238 | ctxt->setCompositeOperation(previousOperator); | |
239 | ||
240 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp | |
241 | index 4db8bd1..0f405cb 100644 | |
242 | --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp | |
243 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp | |
244 | @@ -53,11 +53,17 @@ static int screenNumber(Widget* w) | |
245 | ||
246 | int screenDepth(Widget* w) | |
247 | { | |
248 | + if (QApplication::type() == QApplication::Tty) | |
249 | + return 32; | |
250 | + | |
251 | return QApplication::desktop()->screen(screenNumber(w))->depth(); | |
252 | } | |
253 | ||
254 | int screenDepthPerComponent(Widget* w) | |
255 | { | |
256 | + if (QApplication::type() == QApplication::Tty) | |
257 | + return 8; | |
258 | + | |
259 | int depth = QApplication::desktop()->screen(0)->depth(); | |
260 | if (w) { | |
261 | QWebPageClient* client = w->root()->hostWindow()->platformPageClient(); | |
262 | @@ -86,17 +92,26 @@ int screenDepthPerComponent(Widget* w) | |
263 | ||
264 | bool screenIsMonochrome(Widget* w) | |
265 | { | |
266 | + if (QApplication::type() == QApplication::Tty) | |
267 | + return false; | |
268 | + | |
269 | return QApplication::desktop()->screen(screenNumber(w))->colorCount() == 2; | |
270 | } | |
271 | ||
272 | FloatRect screenRect(Widget* w) | |
273 | { | |
274 | + if (QApplication::type() == QApplication::Tty) | |
275 | + return FloatRect(0,0,800,600); | |
276 | + | |
277 | QRect r = QApplication::desktop()->screenGeometry(screenNumber(w)); | |
278 | return FloatRect(r.x(), r.y(), r.width(), r.height()); | |
279 | } | |
280 | ||
281 | FloatRect screenAvailableRect(Widget* w) | |
282 | { | |
283 | + if (QApplication::type() == QApplication::Tty) | |
284 | + return FloatRect(0,0,800,600); | |
285 | + | |
286 | QRect r = QApplication::desktop()->availableGeometry(screenNumber(w)); | |
287 | return FloatRect(r.x(), r.y(), r.width(), r.height()); | |
288 | } | |
289 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp | |
290 | index f98df88..b1fe30d 100644 | |
291 | --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp | |
292 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp | |
293 | @@ -178,7 +178,13 @@ RenderThemeQt::RenderThemeQt(Page* page) | |
294 | : RenderTheme() | |
295 | , m_page(page) | |
296 | , m_lineEdit(0) | |
297 | + , m_fallbackStyle(0) | |
298 | { | |
299 | + if (QApplication::type() == QApplication::Tty) { | |
300 | + m_buttonFontFamily = "sans-serif"; | |
301 | + return; | |
302 | + } | |
303 | + | |
304 | QPushButton button; | |
305 | button.setAttribute(Qt::WA_MacSmallSize); | |
306 | QFont defaultButtonFont = QApplication::font(&button); | |
307 | @@ -339,6 +345,9 @@ bool RenderThemeQt::supportsControlTints() const | |
308 | ||
309 | int RenderThemeQt::findFrameLineWidth(QStyle* style) const | |
310 | { | |
311 | + if (QApplication::type()==QApplication::Tty) | |
312 | + return 1; | |
313 | + | |
314 | #ifndef QT_NO_LINEEDIT | |
315 | if (!m_lineEdit) | |
316 | m_lineEdit = new QLineEdit(); | |
317 | @@ -445,6 +454,9 @@ Color RenderThemeQt::systemColor(int cssValueId) const | |
318 | ||
319 | int RenderThemeQt::minimumMenuListSize(RenderStyle*) const | |
320 | { | |
321 | + if (QApplication::type() == QApplication::Tty) | |
322 | + return 1; | |
323 | + | |
324 | const QFontMetrics &fm = QApplication::fontMetrics(); | |
325 | return fm.width(QLatin1Char('x')); | |
326 | } | |
327 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp | |
328 | index d648c53..f844d54 100644 | |
329 | --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp | |
330 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp | |
331 | @@ -54,6 +54,9 @@ static QWidget* qwidgetForPage(const Page* page) | |
332 | ||
333 | FloatRect screenRect(const Page* page) | |
334 | { | |
335 | + if (QApplication::type() == QApplication::Tty) | |
336 | + return FloatRect(0,0,800,600); | |
337 | + | |
338 | QWidget* qw = qwidgetForPage(page); | |
339 | if (!qw) | |
340 | return FloatRect(); | |
341 | @@ -68,6 +71,9 @@ FloatRect screenRect(const Page* page) | |
342 | ||
343 | int screenDepth(const Page* page) | |
344 | { | |
345 | + if (QApplication::type() == QApplication::Tty) | |
346 | + return 32; | |
347 | + | |
348 | QWidget* qw = qwidgetForPage(page); | |
349 | if (!qw) | |
350 | return 32; | |
351 | @@ -77,6 +83,9 @@ int screenDepth(const Page* page) | |
352 | ||
353 | FloatRect usableScreenRect(const Page* page) | |
354 | { | |
355 | + if (QApplication::type() == QApplication::Tty) | |
356 | + return FloatRect(); | |
357 | + | |
358 | QWidget* qw = qwidgetForPage(page); | |
359 | if (!qw) | |
360 | return FloatRect(); | |
361 | diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp | |
362 | index 5215e66..e033279 100644 | |
363 | --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp | |
364 | +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp | |
365 | @@ -41,6 +41,7 @@ | |
366 | #include "QWebPageClient.h" | |
367 | #include "ScrollView.h" | |
368 | ||
369 | +#include <QApplication> | |
370 | #include <QCoreApplication> | |
371 | #include <QDebug> | |
372 | #include <QPaintEngine> | |
373 | @@ -78,6 +79,9 @@ void Widget::setFocus(bool focused) | |
374 | void Widget::setCursor(const Cursor& cursor) | |
375 | { | |
376 | #ifndef QT_NO_CURSOR | |
377 | + if (QApplication::type() == QApplication::Tty) | |
378 | + return; | |
379 | + | |
380 | ScrollView* view = root(); | |
381 | if (!view) | |
382 | return; | |
383 | diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp | |
384 | index 2e92801..1690c2f 100644 | |
385 | --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp | |
386 | +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp | |
387 | @@ -956,7 +956,8 @@ void RenderBlock::layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vect | |
388 | repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow()); | |
389 | } | |
390 | ||
391 | - if (paginated) { | |
392 | + // table cell pagination is handled in RenderTableSection | |
393 | + if (paginated && !isTableCell()) { | |
394 | int adjustment = 0; | |
395 | adjustLinePositionForPagination(lineBox, adjustment); | |
396 | if (adjustment) { | |
397 | diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp | |
398 | index f052ee7..a5afea5 100644 | |
399 | --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp | |
400 | +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp | |
401 | @@ -804,7 +804,8 @@ void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo) | |
402 | ||
403 | // The background of the box generated by the root element covers the entire canvas, so just use | |
404 | // the RenderView's docTop/Left/Width/Height accessors. | |
405 | - paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject); | |
406 | + if (bgColor.rgb() != Color::white) | |
407 | + paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject); | |
408 | } | |
409 | ||
410 | void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) | |
411 | diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp | |
412 | index 73b0801..c34b1c2 100644 | |
413 | --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp | |
414 | +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp | |
415 | @@ -302,11 +302,20 @@ void RenderTable::layout() | |
416 | ||
417 | bool collapsing = collapseBorders(); | |
418 | ||
419 | + // repeat header and footer on each page | |
420 | + int headHeight = 0; | |
421 | + int footHeight = 0; | |
422 | for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { | |
423 | if (child->isTableSection()) { | |
424 | child->layoutIfNeeded(); | |
425 | RenderTableSection* section = toRenderTableSection(child); | |
426 | - totalSectionLogicalHeight += section->calcRowLogicalHeight(); | |
427 | + int rowHeight = section->calcRowLogicalHeight(); | |
428 | + if (child == m_head) { | |
429 | + headHeight = rowHeight; | |
430 | + } else if (child == m_foot) { | |
431 | + footHeight = rowHeight; | |
432 | + } | |
433 | + totalSectionLogicalHeight += rowHeight; | |
434 | if (collapsing) | |
435 | section->recalcOuterBorder(); | |
436 | ASSERT(!section->needsLayout()); | |
437 | @@ -320,6 +329,30 @@ void RenderTable::layout() | |
438 | if (m_caption) | |
439 | m_caption->layoutIfNeeded(); | |
440 | ||
441 | + // Bump table to next page if we can't fit the caption, thead and first body cell | |
442 | + setPaginationStrut(0); | |
443 | + if (view()->layoutState()->pageLogicalHeight()) { | |
444 | + LayoutState* layoutState = view()->layoutState(); | |
445 | + const int pageLogicalHeight = layoutState->m_pageLogicalHeight; | |
446 | + const int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(0) % pageLogicalHeight; | |
447 | + if (remainingLogicalHeight > 0) { | |
448 | + int requiredHeight = headHeight; | |
449 | + if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) { | |
450 | + requiredHeight += m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter(); | |
451 | + } | |
452 | + if (m_firstBody) { | |
453 | + // FIXME: Calculate maximum required height across all cells in first body row | |
454 | + RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0); | |
455 | + if (firstCell) { | |
456 | + requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing(); | |
457 | + } | |
458 | + } | |
459 | + if (requiredHeight > remainingLogicalHeight) { | |
460 | + setPaginationStrut(remainingLogicalHeight); | |
461 | + } | |
462 | + } | |
463 | + } | |
464 | + | |
465 | // If any table section moved vertically, we will just repaint everything from that | |
466 | // section down (it is quite unlikely that any of the following sections | |
467 | // did not shift). | |
468 | @@ -352,12 +385,6 @@ void RenderTable::layout() | |
469 | computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength); | |
470 | computedLogicalHeight = max(0, computedLogicalHeight); | |
471 | ||
472 | - for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { | |
473 | - if (child->isTableSection()) | |
474 | - // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one. | |
475 | - toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0); | |
476 | - } | |
477 | - | |
478 | if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) { | |
479 | // Completely empty tables (with no sections or anything) should at least honor specified height | |
480 | // in strict mode. | |
481 | @@ -377,6 +404,9 @@ void RenderTable::layout() | |
482 | } | |
483 | section->setLogicalLocation(sectionLogicalLeft, logicalHeight()); | |
484 | ||
485 | + // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one. | |
486 | + section->layoutRows(section == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, section == m_head ? 0 : headHeight, section == m_foot ? 0 : footHeight); | |
487 | + | |
488 | setLogicalHeight(logicalHeight() + section->logicalHeight()); | |
489 | section = sectionBelow(section); | |
490 | } | |
491 | @@ -503,7 +533,59 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty) | |
492 | child->paint(info, childPoint.x(), childPoint.y()); | |
493 | } | |
494 | } | |
495 | - | |
496 | + | |
497 | + bool repaintedHead = false; | |
498 | + IntPoint repaintedHeadPoint; | |
499 | + bool repaintedFoot = false; | |
500 | + IntPoint repaintedFootPoint; | |
501 | + if (view()->pageLogicalHeight()) { | |
502 | + // re-paint header/footer if table is split over multiple pages | |
503 | + if (m_head) { | |
504 | + IntPoint childPoint = flipForWritingMode(m_head, IntPoint(tx, ty), ParentToChildFlippingAdjustment); | |
505 | + if (info.rect.y() > childPoint.y() + m_head->y()) { | |
506 | + repaintedHeadPoint = IntPoint(childPoint.x(), info.rect.y() - m_head->y()); | |
507 | + repaintedHead = true; | |
508 | + dynamic_cast<RenderObject*>(m_head)->paint(info, repaintedHeadPoint.x(), repaintedHeadPoint.y()); | |
509 | + } | |
510 | + } | |
511 | + if (m_foot) { | |
512 | + IntPoint childPoint = flipForWritingMode(m_foot, IntPoint(tx, ty), ParentToChildFlippingAdjustment); | |
513 | + if (info.rect.y() + info.rect.height() < childPoint.y() + m_foot->y()) { | |
514 | + // find actual end of table on current page | |
515 | + int dy = 0; | |
516 | + const int max_dy = info.rect.y() + info.rect.height(); | |
517 | + const int vspace = vBorderSpacing(); | |
518 | + for (RenderObject* section = firstChild(); section; section = section->nextSibling()) { | |
519 | + if (section->isTableSection()) { | |
520 | + if (toRenderBox(section)->y() > max_dy) { | |
521 | + continue; | |
522 | + } | |
523 | + int i = 0; | |
524 | + for(RenderObject* row = section->firstChild(); row; row = row->nextSibling()) { | |
525 | + if (!row->isTableRow()) { | |
526 | + continue; | |
527 | + } | |
528 | + // get actual bottom-y position of this row - pretty complicated, how could this be simplified? | |
529 | + // note how we have to take the rowPoint and section's y-offset into account, see e.g. | |
530 | + // RenderTableSection::paint where this is also done... | |
531 | + IntPoint rowPoint = flipForWritingMode(toRenderBox(row), IntPoint(tx, ty), ParentToChildFlippingAdjustment); | |
532 | + int row_dy = rowPoint.y() + toRenderBox(row)->y() + toRenderBox(row)->logicalHeight() + toRenderBox(section)->y(); | |
533 | + if (row_dy < max_dy && row_dy > dy) { | |
534 | + dy = row_dy; | |
535 | + } else if (row_dy > max_dy) { | |
536 | + break; | |
537 | + } | |
538 | + i++; | |
539 | + } | |
540 | + } | |
541 | + } | |
542 | + repaintedFoot = true; | |
543 | + repaintedFootPoint = IntPoint(childPoint.x(), dy - m_foot->y()); | |
544 | + dynamic_cast<RenderObject*>(m_foot)->paint(info, repaintedFootPoint.x(), repaintedFootPoint.y()); | |
545 | + } | |
546 | + } | |
547 | + } | |
548 | + | |
549 | if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) { | |
550 | // Collect all the unique border styles that we want to paint in a sorted list. Once we | |
551 | // have all the styles sorted, we then do individual passes, painting each style of border | |
552 | @@ -522,6 +604,12 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty) | |
553 | for (RenderObject* child = firstChild(); child; child = child->nextSibling()) | |
554 | if (child->isTableSection()) { | |
555 | IntPoint childPoint = flipForWritingMode(toRenderTableSection(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment); | |
556 | + // also repaint borders of header/footer if required | |
557 | + if (child == m_head && repaintedHead) { | |
558 | + childPoint = repaintedHeadPoint; | |
559 | + } else if (child == m_foot && repaintedFoot) { | |
560 | + childPoint = repaintedFootPoint; | |
561 | + } | |
562 | child->paint(info, childPoint.x(), childPoint.y()); | |
563 | } | |
564 | } | |
565 | diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp | |
566 | index 7d414a0..6c814b3 100644 | |
567 | --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp | |
568 | +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp | |
569 | @@ -414,7 +414,7 @@ void RenderTableSection::layout() | |
570 | setNeedsLayout(false); | |
571 | } | |
572 | ||
573 | -int RenderTableSection::layoutRows(int toAdd) | |
574 | +int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight) | |
575 | { | |
576 | #ifndef NDEBUG | |
577 | setNeedsLayoutIsForbidden(true); | |
578 | @@ -496,12 +496,47 @@ int RenderTableSection::layoutRows(int toAdd) | |
579 | ||
580 | LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode()); | |
581 | ||
582 | + // Calculate logical row heights | |
583 | + Vector<int> logicalRowHeights; | |
584 | + logicalRowHeights.resize(totalRows); | |
585 | + for (int r = 0; r < totalRows; r++) { | |
586 | + logicalRowHeights[r] = m_rowPos[r + 1] - m_rowPos[r] - vspacing; | |
587 | + } | |
588 | + | |
589 | + // Make sure that cell contents do not overlap a page break | |
590 | + if (view()->layoutState()->pageLogicalHeight()) { | |
591 | + LayoutState* layoutState = view()->layoutState(); | |
592 | + int pageLogicalHeight = layoutState->m_pageLogicalHeight; | |
593 | + int pageOffset = 0; | |
594 | + | |
595 | + for (int r = 0; r < totalRows; ++r) { | |
596 | + int rowLogicalOffset = m_rowPos[r] + pageOffset; | |
597 | + int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(rowLogicalOffset) % pageLogicalHeight; | |
598 | + | |
599 | + for (int c = 0; c < nEffCols; c++) { | |
600 | + CellStruct& cs = cellAt(r, c); | |
601 | + RenderTableCell* cell = cs.primaryCell(); | |
602 | + | |
603 | + if (!cell || cs.inColSpan || cell->row() != r) | |
604 | + continue; | |
605 | + | |
606 | + int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false); | |
607 | + if (max(logicalRowHeights[r], cellRequiredHeight) > remainingLogicalHeight - footHeight - vspacing) { | |
608 | + pageOffset += remainingLogicalHeight + headHeight; | |
609 | + break; | |
610 | + } | |
611 | + } | |
612 | + m_rowPos[r] += pageOffset; | |
613 | + } | |
614 | + m_rowPos[totalRows] += pageOffset; | |
615 | + } | |
616 | + | |
617 | for (int r = 0; r < totalRows; r++) { | |
618 | // Set the row's x/y position and width/height. | |
619 | if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { | |
620 | rowRenderer->setLocation(0, m_rowPos[r]); | |
621 | rowRenderer->setLogicalWidth(logicalWidth()); | |
622 | - rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); | |
623 | + rowRenderer->setLogicalHeight(logicalRowHeights[r]); | |
624 | rowRenderer->updateLayerTransform(); | |
625 | } | |
626 | ||
627 | @@ -513,7 +548,11 @@ int RenderTableSection::layoutRows(int toAdd) | |
628 | continue; | |
629 | ||
630 | rindx = cell->row(); | |
631 | - rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing; | |
632 | + if (cell->rowSpan() == 1) { | |
633 | + rHeight = logicalRowHeights[rindx]; | |
634 | + } else { | |
635 | + rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing; | |
636 | + } | |
637 | ||
638 | // Force percent height children to lay themselves out again. | |
639 | // This will cause these children to grow to fill the cell. | |
640 | diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h | |
641 | index db6edc2..9d912a0 100644 | |
642 | --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h | |
643 | +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h | |
644 | @@ -49,7 +49,7 @@ public: | |
645 | ||
646 | void setCellLogicalWidths(); | |
647 | int calcRowLogicalHeight(); | |
648 | - int layoutRows(int logicalHeight); | |
649 | + int layoutRows(int logicalHeight, int headHeight, int footHeight); | |
650 | ||
651 | RenderTable* table() const { return toRenderTable(parent()); } | |
652 | ||
653 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h | |
654 | index 4b1a758..2ad7f1f 100644 | |
655 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h | |
656 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h | |
657 | @@ -170,6 +170,7 @@ private: | |
658 | friend class QWebHitTestResult; | |
659 | friend class QWebHitTestResultPrivate; | |
660 | friend class QWebPage; | |
661 | + friend class QWebPrinter; | |
662 | ||
663 | #if defined(WTF_USE_V8) && WTF_USE_V8 | |
664 | friend class V8::Bindings::QtWebElementRuntime; | |
665 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp | |
666 | index 5ea7059..b0229ed 100644 | |
667 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp | |
668 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp | |
669 | @@ -216,6 +216,114 @@ static inline ResourceRequestCachePolicy cacheLoadControlToCachePolicy(uint cach | |
670 | return WebCore::UseProtocolCachePolicy; | |
671 | } | |
672 | ||
673 | +#ifndef QT_NO_PRINTER | |
674 | +QWebPrinterPrivate::QWebPrinterPrivate(const QWebFrame *f, QPaintDevice *printer, QPainter &p) | |
675 | + : printContext(f->d->frame) | |
676 | + , painter(p) | |
677 | + , frame(f) | |
678 | + , graphicsContext(&p) | |
679 | +{ | |
680 | + const qreal zoomFactorX = printer->logicalDpiX() / qt_defaultDpi(); | |
681 | + const qreal zoomFactorY = printer->logicalDpiY() / qt_defaultDpi(); | |
682 | + IntRect pageRect(0, 0, | |
683 | + int(printer->width() / zoomFactorX), | |
684 | + int(printer->height() / zoomFactorY)); | |
685 | + | |
686 | + printContext.begin(pageRect.width(), pageRect.height()); | |
687 | + float pageHeight = 0; | |
688 | + printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); | |
689 | + | |
690 | + painter.scale(zoomFactorX, zoomFactorY); | |
691 | + printWidth = pageRect.width(); | |
692 | +} | |
693 | + | |
694 | +QWebPrinterPrivate::~QWebPrinterPrivate() | |
695 | +{ | |
696 | + printContext.end(); | |
697 | +} | |
698 | + | |
699 | +/*! | |
700 | + \class QWebPrinter | |
701 | + \since 4.7 | |
702 | + \brief The QWebPrinter controls printing of a \l{QWebFrame::} | |
703 | + | |
704 | + \inmodule QtWebKit | |
705 | + | |
706 | + \sa QWebFrame | |
707 | +*/ | |
708 | +QWebPrinter::QWebPrinter(const QWebFrame *frame, QPaintDevice *printer, QPainter &painter) | |
709 | + : d(new QWebPrinterPrivate(frame, printer, painter)) | |
710 | +{} | |
711 | + | |
712 | +QWebPrinter::~QWebPrinter() | |
713 | +{ | |
714 | + delete d; | |
715 | +} | |
716 | + | |
717 | +/*! | |
718 | + Print a page of the frame. \a i is the number of the page to print, | |
719 | + and must be between 1 and \fn QWebPrinter::pageCount() . | |
720 | +*/ | |
721 | +void QWebPrinter::spoolPage(int i) const | |
722 | +{ | |
723 | + if (i < 1 || i > d->printContext.pageCount()) | |
724 | + return; | |
725 | + d->printContext.spoolPage(d->graphicsContext, i - 1, d->printWidth); | |
726 | +} | |
727 | + | |
728 | +/*! | |
729 | + Returns the number of pages of the frame when printed. | |
730 | +*/ | |
731 | +int QWebPrinter::pageCount() const | |
732 | +{ | |
733 | + return d->printContext.pageCount(); | |
734 | +} | |
735 | + | |
736 | +QPair<int, QRectF> QWebPrinter::elementLocation(const QWebElement & e) | |
737 | +{ | |
738 | + //Compute a mapping from node to render object once and for all | |
739 | + if (d->elementToRenderObject.empty()) | |
740 | + for (WebCore::RenderObject * o=d->frame->d->frame->document()->renderer(); o; o=o->nextInPreOrder()) | |
741 | + if (o->node()) | |
742 | + d->elementToRenderObject[o->node()] = o; | |
743 | + | |
744 | + if (!d->elementToRenderObject.contains(e.m_element)) | |
745 | + return QPair<int,QRectF>(-1, QRectF()); | |
746 | + const WebCore::RenderObject * ro = d->elementToRenderObject[e.m_element]; | |
747 | + const Vector<IntRect> & pageRects = d->printContext.getPageRects(); | |
748 | + | |
749 | + WebCore::RenderView *root = toRenderView(d->frame->d->frame->document()->renderer()); | |
750 | + //We need the scale factor, because pages are shrinked | |
751 | + float scale = (float)d->printWidth / (float)root->width(); | |
752 | + | |
753 | + QRectF r(const_cast<WebCore::RenderObject *>(ro)->absoluteBoundingBoxRect()); | |
754 | + | |
755 | + int low=0; | |
756 | + int high=pageRects.size(); | |
757 | + int c = r.y() + r.height() / 2; | |
758 | + while(low <= high) { | |
759 | + int m = (low+high)/2; | |
760 | + if(c < pageRects[m].y()) | |
761 | + high = m-1; | |
762 | + else if(c > pageRects[m].maxY()) | |
763 | + low = m +1; | |
764 | + else { | |
765 | + QRectF tr = r.translated(0, -pageRects[m].y()); | |
766 | + return QPair<int, QRectF>(m+1, QRect(tr.x() * scale, tr.y()*scale, tr.width()*scale, tr.height()*scale)); | |
767 | + } | |
768 | + | |
769 | + } | |
770 | + return QPair<int,QRectF>(-1, QRectF()); | |
771 | +} | |
772 | + | |
773 | +/*! | |
774 | + Return the painter used for printing. | |
775 | +*/ | |
776 | +QPainter * QWebPrinter::painter() { | |
777 | + return &d->painter; | |
778 | +} | |
779 | +#endif //QT_NO_PRINTER | |
780 | + | |
781 | QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame, | |
782 | WebCore::HTMLFrameOwnerElement* ownerFrameElement, | |
783 | const WTF::String& frameName) | |
784 | @@ -1434,25 +1542,8 @@ bool QWebFrame::event(QEvent *e) | |
785 | void QWebFrame::print(QPrinter *printer) const | |
786 | { | |
787 | QPainter painter; | |
788 | - if (!painter.begin(printer)) | |
789 | - return; | |
790 | - | |
791 | - const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi(); | |
792 | - const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi(); | |
793 | - | |
794 | - PrintContext printContext(d->frame); | |
795 | - float pageHeight = 0; | |
796 | - | |
797 | - QRect qprinterRect = printer->pageRect(); | |
798 | - | |
799 | - IntRect pageRect(0, 0, | |
800 | - int(qprinterRect.width() / zoomFactorX), | |
801 | - int(qprinterRect.height() / zoomFactorY)); | |
802 | - | |
803 | - printContext.begin(pageRect.width()); | |
804 | - | |
805 | - printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); | |
806 | - | |
807 | + painter.begin(printer); | |
808 | + QWebPrinter p(this, printer, painter); | |
809 | int docCopies; | |
810 | int pageCopies; | |
811 | if (printer->collateCopies()) { | |
812 | @@ -1469,11 +1560,12 @@ void QWebFrame::print(QPrinter *printer) const | |
813 | ||
814 | if (fromPage == 0 && toPage == 0) { | |
815 | fromPage = 1; | |
816 | - toPage = printContext.pageCount(); | |
817 | + toPage = p.pageCount(); | |
818 | } | |
819 | // paranoia check | |
820 | fromPage = qMax(1, fromPage); | |
821 | - toPage = qMin(static_cast<int>(printContext.pageCount()), toPage); | |
822 | + toPage = qMin(static_cast<int>(p.pageCount()), toPage); | |
823 | + | |
824 | if (toPage < fromPage) { | |
825 | // if the user entered a page range outside the actual number | |
826 | // of printable pages, just return | |
827 | @@ -1486,20 +1578,15 @@ void QWebFrame::print(QPrinter *printer) const | |
828 | toPage = tmp; | |
829 | ascending = false; | |
830 | } | |
831 | - | |
832 | - painter.scale(zoomFactorX, zoomFactorY); | |
833 | - GraphicsContext ctx(&painter); | |
834 | - | |
835 | for (int i = 0; i < docCopies; ++i) { | |
836 | int page = fromPage; | |
837 | while (true) { | |
838 | for (int j = 0; j < pageCopies; ++j) { | |
839 | if (printer->printerState() == QPrinter::Aborted | |
840 | || printer->printerState() == QPrinter::Error) { | |
841 | - printContext.end(); | |
842 | return; | |
843 | } | |
844 | - printContext.spoolPage(ctx, page - 1, pageRect.width()); | |
845 | + p.spoolPage(page); | |
846 | if (j < pageCopies - 1) | |
847 | printer->newPage(); | |
848 | } | |
849 | @@ -1518,8 +1605,7 @@ void QWebFrame::print(QPrinter *printer) const | |
850 | if ( i < docCopies - 1) | |
851 | printer->newPage(); | |
852 | } | |
853 | - | |
854 | - printContext.end(); | |
855 | + painter.end(); | |
856 | } | |
857 | #endif // QT_NO_PRINTER | |
858 | ||
859 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h | |
860 | index 3c5a28e..99771f8 100644 | |
861 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h | |
862 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h | |
863 | @@ -21,6 +21,8 @@ | |
864 | #ifndef QWEBFRAME_H | |
865 | #define QWEBFRAME_H | |
866 | ||
867 | +#define __EXTENSIVE_WKHTMLTOPDF_QT_HACK__ | |
868 | + | |
869 | #include <QtCore/qobject.h> | |
870 | #include <QtCore/qurl.h> | |
871 | #include <QtCore/qvariant.h> | |
872 | @@ -42,6 +44,9 @@ class QPrinter; | |
873 | QT_END_NAMESPACE | |
874 | ||
875 | class QWebNetworkRequest; | |
876 | +#ifndef QT_NO_PRINTER | |
877 | +class QWebPrinterPrivate; | |
878 | +#endif | |
879 | class QWebFramePrivate; | |
880 | class QWebPage; | |
881 | class QWebHitTestResult; | |
882 | @@ -103,6 +108,20 @@ private: | |
883 | friend class QWebPage; | |
884 | }; | |
885 | ||
886 | +#ifndef QT_NO_PRINTER | |
887 | +class QWEBKIT_EXPORT QWebPrinter { | |
888 | +public: | |
889 | + QWebPrinter(const QWebFrame * frame, QPaintDevice * printer, QPainter &painter); | |
890 | + ~QWebPrinter(); | |
891 | + void spoolPage(int i) const; | |
892 | + QPainter * painter(); | |
893 | + int pageCount() const; | |
894 | + QPair<int, QRectF> elementLocation(const QWebElement & e); | |
895 | +private: | |
896 | + QWebPrinterPrivate * d; | |
897 | +}; | |
898 | +#endif | |
899 | + | |
900 | class QWEBKIT_EXPORT QWebFrame : public QObject { | |
901 | Q_OBJECT | |
902 | Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false) | |
903 | @@ -228,6 +247,8 @@ private: | |
904 | friend class QWebPage; | |
905 | friend class QWebPagePrivate; | |
906 | friend class QWebFramePrivate; | |
907 | + friend class QWebPrinterPrivate; | |
908 | + friend class QWebPrinter; | |
909 | friend class DumpRenderTreeSupportQt; | |
910 | friend class WebCore::WidgetPrivate; | |
911 | friend class WebCore::FrameLoaderClientQt; | |
912 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h | |
913 | index 4108972..3698eed 100644 | |
914 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h | |
915 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h | |
916 | @@ -35,6 +35,9 @@ | |
917 | #include "wtf/RefPtr.h" | |
918 | #include "Frame.h" | |
919 | #include "ViewportArguments.h" | |
920 | +#include <qpainter.h> | |
921 | +#include "PrintContext.h" | |
922 | +#include "GraphicsContext.h" | |
923 | ||
924 | #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) | |
925 | #include "texmap/TextureMapper.h" | |
926 | @@ -69,6 +72,19 @@ public: | |
927 | int marginHeight; | |
928 | }; | |
929 | ||
930 | +class QWebPrinterPrivate { | |
931 | +public: | |
932 | + WebCore::PrintContext printContext; | |
933 | + QPainter & painter; | |
934 | + const QWebFrame * frame; | |
935 | + WebCore::GraphicsContext graphicsContext; | |
936 | + int printWidth; | |
937 | + QHash<const WebCore::Node*, const WebCore::RenderObject *> elementToRenderObject; | |
938 | + | |
939 | + QWebPrinterPrivate(const QWebFrame * frame, QPaintDevice *printer, QPainter &p); | |
940 | + ~QWebPrinterPrivate(); | |
941 | +}; | |
942 | + | |
943 | class QWebFramePrivate { | |
944 | public: | |
945 | QWebFramePrivate() | |
946 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp | |
947 | index c1ef92e..dc4de39 100644 | |
948 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp | |
949 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp | |
950 | @@ -75,8 +75,11 @@ public: | |
951 | QUrl userStyleSheetLocation; | |
952 | QString defaultTextEncoding; | |
953 | QString localStoragePath; | |
954 | + QString printingMediaType; | |
955 | QString offlineWebApplicationCachePath; | |
956 | qint64 offlineStorageDefaultQuota; | |
957 | + qreal printingMinimumShrinkFactor; | |
958 | + qreal printingMaximumShrinkFactor; | |
959 | ||
960 | void apply(); | |
961 | WebCore::Settings* settings; | |
962 | @@ -229,9 +232,18 @@ void QWebSettingsPrivate::apply() | |
963 | QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding; | |
964 | settings->setDefaultTextEncodingName(encoding); | |
965 | ||
966 | + QString type = !printingMediaType.isEmpty() ? printingMediaType : global->printingMediaType; | |
967 | + settings->setPrintingMediaType(type.isEmpty() ? "print" : type); | |
968 | + | |
969 | QString storagePath = !localStoragePath.isEmpty() ? localStoragePath : global->localStoragePath; | |
970 | settings->setLocalStorageDatabasePath(storagePath); | |
971 | ||
972 | + float minimumShrinkFactor = printingMinimumShrinkFactor > 0.0f ? printingMinimumShrinkFactor : global->printingMinimumShrinkFactor; | |
973 | + settings->setPrintingMinimumShrinkFactor(minimumShrinkFactor); | |
974 | + | |
975 | + float maximumShrinkFactor = printingMaximumShrinkFactor > 0.0f ? printingMaximumShrinkFactor : global->printingMaximumShrinkFactor; | |
976 | + settings->setPrintingMaximumShrinkFactor(maximumShrinkFactor); | |
977 | + | |
978 | value = attributes.value(QWebSettings::PrintElementBackgrounds, | |
979 | global->attributes.value(QWebSettings::PrintElementBackgrounds)); | |
980 | settings->setShouldPrintBackgrounds(value); | |
981 | @@ -519,6 +531,8 @@ QWebSettings::QWebSettings() | |
982 | d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true); | |
983 | d->offlineStorageDefaultQuota = 5 * 1024 * 1024; | |
984 | d->defaultTextEncoding = QLatin1String("iso-8859-1"); | |
985 | + d->printingMinimumShrinkFactor = 1.25f; | |
986 | + d->printingMaximumShrinkFactor = 2.0f; | |
987 | } | |
988 | ||
989 | /*! | |
990 | @@ -527,6 +541,8 @@ QWebSettings::QWebSettings() | |
991 | QWebSettings::QWebSettings(WebCore::Settings* settings) | |
992 | : d(new QWebSettingsPrivate(settings)) | |
993 | { | |
994 | + d->printingMinimumShrinkFactor = 0.0f; | |
995 | + d->printingMaximumShrinkFactor = 0.0f; | |
996 | d->settings = settings; | |
997 | d->apply(); | |
998 | allSettings()->append(d); | |
999 | @@ -635,6 +651,86 @@ QString QWebSettings::defaultTextEncoding() const | |
1000 | } | |
1001 | ||
1002 | /*! | |
1003 | + \since 4.7 | |
1004 | + Specifies which media type to use when printing. If | |
1005 | + left empty the default "print" will be used, other choices include "screen". | |
1006 | + See \l{http://www.w3.org/TR/CSS2/media.html}{CSS Standard}, for a complete list. | |
1007 | + | |
1008 | + \sa printingMediaType() | |
1009 | +*/ | |
1010 | +void QWebSettings::setPrintingMediaType(const QString& type) | |
1011 | +{ | |
1012 | + d->printingMediaType = type; | |
1013 | + d->apply(); | |
1014 | +} | |
1015 | + | |
1016 | +/*! | |
1017 | + \since 4.7 | |
1018 | + Returns the media type used when printing or QString() if the | |
1019 | + default value is used. | |
1020 | + | |
1021 | + \sa setPrintingMediaType() | |
1022 | +*/ | |
1023 | +QString QWebSettings::printingMediaType() const | |
1024 | +{ | |
1025 | + return d->printingMediaType; | |
1026 | +} | |
1027 | + | |
1028 | +/*! | |
1029 | + \since 4.6 | |
1030 | + Specifies minimum shrink fator allowed for printing. If set to 0 a | |
1031 | + default value is used. | |
1032 | + | |
1033 | + When printing, content will be shrunk to reduce page usage, it | |
1034 | + will reduced by a factor between printingMinimumShrinkFactor and | |
1035 | + printingMaximumShrinkFactor. | |
1036 | + | |
1037 | + \sa printingMinimumShrinkFactor() | |
1038 | + \sa setPrintingMaximumShrinkFactor() | |
1039 | + \sa printingMaximumShrinkFactor() | |
1040 | +*/ | |
1041 | +void QWebSettings::setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor) | |
1042 | +{ | |
1043 | + d->printingMinimumShrinkFactor = printingMinimumShrinkFactor; | |
1044 | + d->apply(); | |
1045 | +} | |
1046 | + | |
1047 | +/*! | |
1048 | + \since 4.6 | |
1049 | + returns the minimum shrink factor used for printing. | |
1050 | + | |
1051 | + \sa setPrintingMinimumShrinkFactor() | |
1052 | +*/ | |
1053 | +qreal QWebSettings::printingMinimumShrinkFactor() const | |
1054 | +{ | |
1055 | + return d->printingMinimumShrinkFactor; | |
1056 | +} | |
1057 | + | |
1058 | +/*! | |
1059 | + \since 4.6 | |
1060 | + Specifies maximum shrink fator allowed for printing. If set to 0 a | |
1061 | + default value is used. | |
1062 | + | |
1063 | + \sa setPrintingMinimumShrinkFactor() | |
1064 | +*/ | |
1065 | +void QWebSettings::setPrintingMaximumShrinkFactor(qreal printingMaximumShrinkFactor) | |
1066 | +{ | |
1067 | + d->printingMaximumShrinkFactor = printingMaximumShrinkFactor; | |
1068 | + d->apply(); | |
1069 | +} | |
1070 | + | |
1071 | +/*! | |
1072 | + \since 4.6 | |
1073 | + returns the maximum shrink factor used for printing. | |
1074 | + | |
1075 | + \sa setPrintingMinimumShrinkFactor() | |
1076 | +*/ | |
1077 | +qreal QWebSettings::printingMaximumShrinkFactor() const | |
1078 | +{ | |
1079 | + return d->printingMaximumShrinkFactor; | |
1080 | +} | |
1081 | + | |
1082 | +/*! | |
1083 | Sets the path of the icon database to \a path. The icon database is used | |
1084 | to store "favicons" associated with web sites. | |
1085 | ||
1086 | diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h | |
1087 | index 008035b..bb134a3 100644 | |
1088 | --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h | |
1089 | +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h | |
1090 | @@ -116,6 +116,15 @@ public: | |
1091 | void setDefaultTextEncoding(const QString &encoding); | |
1092 | QString defaultTextEncoding() const; | |
1093 | ||
1094 | + void setPrintingMediaType(const QString &type); | |
1095 | + QString printingMediaType() const; | |
1096 | + | |
1097 | + void setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor); | |
1098 | + qreal printingMinimumShrinkFactor() const; | |
1099 | + | |
1100 | + void setPrintingMaximumShrinkFactor(qreal printingMaximimShrinkFactor); | |
1101 | + qreal printingMaximumShrinkFactor() const; | |
1102 | + | |
1103 | static void setIconDatabasePath(const QString &location); | |
1104 | static QString iconDatabasePath(); | |
1105 | static void clearIconDatabase(); | |
1106 | diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp | |
1107 | index 3fc65d3..6657879 100644 | |
1108 | --- a/src/gui/image/qpixmap.cpp | |
1109 | +++ b/src/gui/image/qpixmap.cpp | |
1110 | @@ -134,12 +134,6 @@ extern QApplication::Type qt_appType; | |
1111 | ||
1112 | void QPixmap::init(int w, int h, int type) | |
1113 | { | |
1114 | - if (qt_appType == QApplication::Tty) { | |
1115 | - qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used"); | |
1116 | - data = 0; | |
1117 | - return; | |
1118 | - } | |
1119 | - | |
1120 | if ((w > 0 && h > 0) || type == QPixmapData::BitmapType) | |
1121 | data = QPixmapData::create(w, h, (QPixmapData::PixelType) type); | |
1122 | else | |
1123 | diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp | |
1124 | index 5950c5d..36303a0 100644 | |
1125 | --- a/src/gui/image/qpixmap_raster.cpp | |
1126 | +++ b/src/gui/image/qpixmap_raster.cpp | |
1127 | @@ -47,6 +47,7 @@ | |
1128 | #include "qnativeimage_p.h" | |
1129 | #include "qimage_p.h" | |
1130 | #include "qpaintengine.h" | |
1131 | +#include "kernel/qapplication_p.h" | |
1132 | ||
1133 | #include "qbitmap.h" | |
1134 | #include "qimage.h" | |
1135 | @@ -115,8 +116,10 @@ void QRasterPixmapData::resize(int width, int height) | |
1136 | #else | |
1137 | if (pixelType() == BitmapType) | |
1138 | format = QImage::Format_MonoLSB; | |
1139 | - else | |
1140 | + else if (qt_is_gui_used) | |
1141 | format = QNativeImage::systemFormat(); | |
1142 | + else | |
1143 | + format = QImage::Format_RGB32; | |
1144 | #endif | |
1145 | ||
1146 | image = QImage(width, height, format); | |
1147 | @@ -431,7 +434,7 @@ void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConve | |
1148 | ? QImage::Format_ARGB32_Premultiplied | |
1149 | : QImage::Format_RGB32; | |
1150 | } else { | |
1151 | - QImage::Format opaqueFormat = QNativeImage::systemFormat(); | |
1152 | + QImage::Format opaqueFormat = qt_is_gui_used ? QNativeImage::systemFormat() : QImage::Format_RGB32; | |
1153 | QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; | |
1154 | ||
1155 | #if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2) | |
1156 | diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp | |
1157 | index 9582abf..ebaea4b 100644 | |
1158 | --- a/src/gui/kernel/qapplication_x11.cpp | |
1159 | +++ b/src/gui/kernel/qapplication_x11.cpp | |
1160 | @@ -2280,6 +2280,8 @@ void qt_init(QApplicationPrivate *priv, int, | |
1161 | QSegfaultHandler::initialize(priv->argv, priv->argc); | |
1162 | #endif | |
1163 | QCursorData::initialize(); | |
1164 | + } else if (!QApplicationPrivate::graphics_system_name.isNull()) { | |
1165 | + QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name); | |
1166 | } | |
1167 | QFont::initialize(); | |
1168 | ||
1169 | diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp | |
1170 | index d8aefb6..37106f7 100644 | |
1171 | --- a/src/gui/kernel/qguiplatformplugin.cpp | |
1172 | +++ b/src/gui/kernel/qguiplatformplugin.cpp | |
1173 | @@ -85,7 +85,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin() | |
1174 | ||
1175 | QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN")); | |
1176 | #ifdef Q_WS_X11 | |
1177 | - if (key.isEmpty()) { | |
1178 | + if (QApplication::type() != QApplication::Tty && key.isEmpty()) { | |
1179 | switch(X11->desktopEnvironment) { | |
1180 | case DE_KDE: | |
1181 | key = QString::fromLatin1("kde"); | |
1182 | diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h | |
1183 | index cd7075e..74508b3 100644 | |
1184 | --- a/src/gui/painting/qpaintengine.h | |
1185 | +++ b/src/gui/painting/qpaintengine.h | |
1186 | @@ -162,6 +162,19 @@ public: | |
1187 | virtual void drawRects(const QRect *rects, int rectCount); | |
1188 | virtual void drawRects(const QRectF *rects, int rectCount); | |
1189 | ||
1190 | + virtual void addHyperlink(const QRectF &r, const QUrl &url) {Q_UNUSED(r); Q_UNUSED(url);} | |
1191 | + virtual void addAnchor(const QRectF &r, const QString &name) {Q_UNUSED(r); Q_UNUSED(name);} | |
1192 | + virtual void addLink(const QRectF &r, const QString &anchor) {Q_UNUSED(r); Q_UNUSED(anchor);} | |
1193 | + virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) { | |
1194 | + Q_UNUSED(r); Q_UNUSED(text); Q_UNUSED(name); Q_UNUSED(multiLine); Q_UNUSED(password); Q_UNUSED(readOnly); Q_UNUSED(maxLength); | |
1195 | + } | |
1196 | + virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) { | |
1197 | + Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly); | |
1198 | + } | |
1199 | + virtual void addRadioButton(const QRectF &r, const QString & group="", bool checked=false, const QString &name="", bool readOnly=false) { | |
1200 | + Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly); Q_UNUSED(group); | |
1201 | + } | |
1202 | + | |
1203 | virtual void drawLines(const QLine *lines, int lineCount); | |
1204 | virtual void drawLines(const QLineF *lines, int lineCount); | |
1205 | ||
1206 | @@ -177,6 +190,10 @@ public: | |
1207 | virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); | |
1208 | ||
1209 | virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) = 0; | |
1210 | + virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data) { | |
1211 | + Q_UNUSED(data); | |
1212 | + drawPixmap(r,pm,sr); | |
1213 | + } | |
1214 | virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); | |
1215 | virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); | |
1216 | virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, | |
1217 | diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp | |
1218 | index 10ca689..d690761 100644 | |
1219 | --- a/src/gui/painting/qpaintengine_raster.cpp | |
1220 | +++ b/src/gui/painting/qpaintengine_raster.cpp | |
1221 | @@ -2243,11 +2243,11 @@ namespace { | |
1222 | /*! | |
1223 | \reimp | |
1224 | */ | |
1225 | -void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr, | |
1226 | +void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &_img, const QRectF &_sr, | |
1227 | Qt::ImageConversionFlags) | |
1228 | { | |
1229 | #ifdef QT_DEBUG_DRAW | |
1230 | - qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << sr << " image=" << img.size() << "depth=" << img.depth(); | |
1231 | + qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << _sr << " image=" << _img.size() << "depth=" << img.depth(); | |
1232 | #endif | |
1233 | ||
1234 | if (r.isEmpty()) | |
1235 | @@ -2255,6 +2255,17 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe | |
1236 | ||
1237 | Q_D(QRasterPaintEngine); | |
1238 | QRasterPaintEngineState *s = state(); | |
1239 | + | |
1240 | + QImage img; | |
1241 | + QRectF sr=_sr; | |
1242 | + if (s->matrix.isAffine()) { | |
1243 | + img = _img.copy(sr.toRect()).scaled( | |
1244 | + s->matrix.mapRect(r).size().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); | |
1245 | + sr = img.rect(); | |
1246 | + } else { | |
1247 | + img=_img; | |
1248 | + } | |
1249 | + | |
1250 | int sr_l = qFloor(sr.left()); | |
1251 | int sr_r = qCeil(sr.right()) - 1; | |
1252 | int sr_t = qFloor(sr.top()); | |
1253 | diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp | |
1254 | index 30f986d..7836b5a 100644 | |
1255 | --- a/src/gui/painting/qpainter.cpp | |
1256 | +++ b/src/gui/painting/qpainter.cpp | |
1257 | @@ -5393,7 +5393,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) | |
1258 | } | |
1259 | } | |
1260 | ||
1261 | -void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) | |
1262 | +void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data) | |
1263 | { | |
1264 | #if defined QT_DEBUG_DRAW | |
1265 | if (qt_show_painter_debug_output) | |
1266 | @@ -5518,7 +5518,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) | |
1267 | x += d->state->matrix.dx(); | |
1268 | y += d->state->matrix.dy(); | |
1269 | } | |
1270 | - d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh)); | |
1271 | + d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh), data); | |
1272 | } | |
1273 | } | |
1274 | ||
1275 | @@ -7254,6 +7254,200 @@ void QPainter::fillRect(const QRectF &r, const QColor &color) | |
1276 | \since 4.5 | |
1277 | */ | |
1278 | ||
1279 | + | |
1280 | +/*! | |
1281 | + \fn void QPainter::addAnchor(int x, int y, int w, int h, const QString &name); | |
1282 | + | |
1283 | + \overload | |
1284 | + | |
1285 | + Add an anchor to the current page at the rect specified by \a x, \a y, \a w and \a h | |
1286 | + named \a name. | |
1287 | + | |
1288 | + Note that for output formats not supporting links, currently all other then PDF, | |
1289 | + this call has no effect. | |
1290 | + | |
1291 | + \sa addLink() | |
1292 | + | |
1293 | + \since 4.7 | |
1294 | +*/ | |
1295 | + | |
1296 | +/*! | |
1297 | + \fn void QPainter::addAnchor(const QRect &r, const QString &name); | |
1298 | + | |
1299 | + \overload | |
1300 | + | |
1301 | + Add an anchor to the current page at the rect specified by \a r named \a name. | |
1302 | + | |
1303 | + Note that for output formats not supporting links, currently all other then PDF, | |
1304 | + this call has no effect. | |
1305 | + | |
1306 | + \sa addLink() | |
1307 | + | |
1308 | + \since 4.7 | |
1309 | +*/ | |
1310 | + | |
1311 | +/*! | |
1312 | + \fn void addAnchor(const QRectF &r, const QString &name); | |
1313 | + | |
1314 | + \overload | |
1315 | + | |
1316 | + Add an anchor to the current page at the rect specified by \a r named \a name. | |
1317 | + | |
1318 | + Note that for output formats not supporting links, currently all other then PDF, | |
1319 | + this call has no effect. | |
1320 | + | |
1321 | + \sa addLink() | |
1322 | + | |
1323 | + \since 4.7 | |
1324 | +*/ | |
1325 | +void QPainter::addAnchor(const QRectF &r, const QString &name) | |
1326 | +{ | |
1327 | + Q_D(QPainter); | |
1328 | + if (!d->engine) { | |
1329 | + qWarning("QPainter::addAnchor: Painter not active"); | |
1330 | + return; | |
1331 | + } | |
1332 | + d->engine->addAnchor(worldTransform().mapRect(r), name); | |
1333 | +} | |
1334 | + | |
1335 | +/*! | |
1336 | + \fn void QPainter::addLink(int x, int y, int w, int h, const QString &anchor); | |
1337 | + | |
1338 | + \overload | |
1339 | + | |
1340 | + Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h | |
1341 | + linking to the anchor named \a anchor. | |
1342 | + | |
1343 | + Note that for output formats not supporting links, currently all other then PDF, | |
1344 | + this call has no effect. | |
1345 | + | |
1346 | + \sa addAnchor() | |
1347 | + | |
1348 | + \since 4.7 | |
1349 | +*/ | |
1350 | + | |
1351 | +/*! | |
1352 | + \fn void QPainter::addLink(const QRect &r, const QString &anchor); | |
1353 | + | |
1354 | + \overload | |
1355 | + | |
1356 | + Add a link to the current page at the rect specified by \a r | |
1357 | + linking to the anchor named \a anchor. | |
1358 | + | |
1359 | + Note that for output formats not supporting links, currently all other then PDF, | |
1360 | + this call has no effect. | |
1361 | + | |
1362 | + \sa addAnchor() | |
1363 | + | |
1364 | + \since 4.7 | |
1365 | +*/ | |
1366 | + | |
1367 | +/*! | |
1368 | + \fn void QPainter::addLink(const QRectF &r, const QString &anchor); | |
1369 | + | |
1370 | + \overload | |
1371 | + | |
1372 | + Add a link to the current page at the rect specified by \a r | |
1373 | + linking to the anchor named \a anchor. | |
1374 | + | |
1375 | + Note that for output formats not supporting links, currently all other then PDF, | |
1376 | + this call has no effect. | |
1377 | + | |
1378 | + \sa addAnchor() | |
1379 | + | |
1380 | + \since 4.7 | |
1381 | +*/ | |
1382 | +void QPainter::addLink(const QRectF &r, const QString &anchor) | |
1383 | +{ | |
1384 | + Q_D(QPainter); | |
1385 | + if (!d->engine) { | |
1386 | + qWarning("QPainter::addLink: Painter not active"); | |
1387 | + return; | |
1388 | + } | |
1389 | + | |
1390 | + d->engine->addLink(worldTransform().mapRect(r), anchor); | |
1391 | +} | |
1392 | + | |
1393 | + | |
1394 | +/*! | |
1395 | + \fn void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url); | |
1396 | + | |
1397 | + \overload | |
1398 | + | |
1399 | + Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h | |
1400 | + linking to \a url. | |
1401 | + | |
1402 | + Note that for output formats not supporting links, currently all other then PDF, | |
1403 | + this call has no effect. | |
1404 | + | |
1405 | + \since 4.7 | |
1406 | +*/ | |
1407 | + | |
1408 | +/*! | |
1409 | + \fn void QPainter::addHyperlink(const QRect &r, const QUrl &url); | |
1410 | + | |
1411 | + \overload | |
1412 | + | |
1413 | + Add a link to the current page at the rect specified by \a r | |
1414 | + linking to \a url. | |
1415 | + | |
1416 | + Note that for output formats not supporting links, currently all other then PDF, | |
1417 | + this call has no effect. | |
1418 | + | |
1419 | + \since 4.7 | |
1420 | +*/ | |
1421 | + | |
1422 | +/*! | |
1423 | + \fn void QPainter::addHyperlink(const QRectF &r, const QUrl &url); | |
1424 | + | |
1425 | + \overload | |
1426 | + | |
1427 | + Add a link to the current page at the rect specified by \a r | |
1428 | + linking to \a url. | |
1429 | + | |
1430 | + Note that for output formats not supporting links, currently all other then PDF, | |
1431 | + this call has no effect. | |
1432 | + | |
1433 | + \since 4.7 | |
1434 | +*/ | |
1435 | +void QPainter::addHyperlink(const QRectF &r, const QUrl &url) | |
1436 | +{ | |
1437 | + Q_D(QPainter); | |
1438 | + if (!d->engine) { | |
1439 | + qWarning("QPainter::addHyperlink: Painter not active"); | |
1440 | + return; | |
1441 | + } | |
1442 | + d->engine->addHyperlink(worldTransform().mapRect(r), url); | |
1443 | +} | |
1444 | + | |
1445 | +void QPainter::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) { | |
1446 | + Q_D(QPainter); | |
1447 | + if (!d->engine) { | |
1448 | + qWarning("QPainter::addTextField: Painter not active"); | |
1449 | + return; | |
1450 | + } | |
1451 | + d->engine->addTextField(worldTransform().mapRect(r), text, name, multiLine, password, readOnly, maxLength); | |
1452 | +} | |
1453 | + | |
1454 | +void QPainter::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) { | |
1455 | + Q_D(QPainter); | |
1456 | + if (!d->engine) { | |
1457 | + qWarning("QPainter::addCheckBox: Painter not active"); | |
1458 | + return; | |
1459 | + } | |
1460 | + d->engine->addCheckBox(worldTransform().mapRect(r), checked, name, readOnly); | |
1461 | +} | |
1462 | + | |
1463 | + | |
1464 | +void QPainter::addRadioButton(const QRectF &r, const QString & group, bool checked, const QString &name, bool readOnly) { | |
1465 | + Q_D(QPainter); | |
1466 | + if (!d->engine) { | |
1467 | + qWarning("QPainter::addRadioButton: Painter not active"); | |
1468 | + return; | |
1469 | + } | |
1470 | + d->engine->addRadioButton(worldTransform().mapRect(r), group, checked, name, readOnly); | |
1471 | +} | |
1472 | + | |
1473 | /*! | |
1474 | Sets the given render \a hint on the painter if \a on is true; | |
1475 | otherwise clears the render hint. | |
1476 | diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h | |
1477 | index f0312e5..d853a9b 100644 | |
1478 | --- a/src/gui/painting/qpainter.h | |
1479 | +++ b/src/gui/painting/qpainter.h | |
1480 | @@ -364,7 +364,7 @@ public: | |
1481 | inline void drawPicture(const QPoint &p, const QPicture &picture); | |
1482 | #endif | |
1483 | ||
1484 | - void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect); | |
1485 | + void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect, const QByteArray * data=0); | |
1486 | inline void drawPixmap(const QRect &targetRect, const QPixmap &pixmap, const QRect &sourceRect); | |
1487 | inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm, | |
1488 | int sx, int sy, int sw, int sh); | |
1489 | @@ -447,6 +447,22 @@ public: | |
1490 | inline void fillRect(const QRect &r, Qt::BrushStyle style); | |
1491 | inline void fillRect(const QRectF &r, Qt::BrushStyle style); | |
1492 | ||
1493 | + inline void addAnchor(int x, int y, int w, int h, const QString &name); | |
1494 | + inline void addAnchor(const QRect &r, const QString &name); | |
1495 | + void addAnchor(const QRectF &r, const QString &name); | |
1496 | + | |
1497 | + inline void addLink(int x, int y, int w, int h, const QString &anchor); | |
1498 | + inline void addLink(const QRect &r, const QString &anchor); | |
1499 | + void addLink(const QRectF &r, const QString &anchor); | |
1500 | + | |
1501 | + void addTextField(const QRectF &r, const QString &text="", const QString &name="", bool multiLine=false, bool password=false, bool readOnly=false, int maxLength=-1); | |
1502 | + void addCheckBox(const QRectF &r, bool checked=false, const QString &name="", bool readOnly=false); | |
1503 | + void addRadioButton(const QRectF &r, const QString & group="", bool checked=false, const QString &name="", bool readOnly=false);; | |
1504 | + | |
1505 | + inline void addHyperlink(int x, int y, int w, int h, const QUrl &url); | |
1506 | + inline void addHyperlink(const QRect &r, const QUrl &url); | |
1507 | + void addHyperlink(const QRectF &r, const QUrl &url); | |
1508 | + | |
1509 | void eraseRect(const QRectF &); | |
1510 | inline void eraseRect(int x, int y, int w, int h); | |
1511 | inline void eraseRect(const QRect &); | |
1512 | @@ -821,6 +837,35 @@ inline void QPainter::fillRect(const QRectF &r, Qt::BrushStyle style) | |
1513 | fillRect(r, QBrush(style)); | |
1514 | } | |
1515 | ||
1516 | +inline void QPainter::addAnchor(int x, int y, int w, int h, const QString &name) | |
1517 | +{ | |
1518 | + addAnchor(QRectF(x, y, w, h), name); | |
1519 | +} | |
1520 | + | |
1521 | +inline void QPainter::addAnchor(const QRect &r, const QString &name) | |
1522 | +{ | |
1523 | + addAnchor(QRectF(r), name); | |
1524 | +} | |
1525 | + | |
1526 | +inline void QPainter::addLink(int x, int y, int w, int h, const QString &anchor) | |
1527 | +{ | |
1528 | + addLink(QRectF(x, y, w, h), anchor); | |
1529 | +} | |
1530 | + | |
1531 | +inline void QPainter::addLink(const QRect &r, const QString &anchor) | |
1532 | +{ | |
1533 | + addLink(QRectF(r), anchor); | |
1534 | +} | |
1535 | + | |
1536 | +inline void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url) | |
1537 | +{ | |
1538 | + addHyperlink(QRectF(x, y, w, h), url); | |
1539 | +} | |
1540 | + | |
1541 | +inline void QPainter::addHyperlink(const QRect &r, const QUrl &url) | |
1542 | +{ | |
1543 | + addHyperlink(QRectF(r), url); | |
1544 | +} | |
1545 | ||
1546 | inline void QPainter::setBrushOrigin(int x, int y) | |
1547 | { | |
1548 | diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h | |
1549 | index 83bbf96..809b51a 100644 | |
1550 | --- a/src/gui/painting/qprintengine.h | |
1551 | +++ b/src/gui/painting/qprintengine.h | |
1552 | @@ -90,6 +90,9 @@ public: | |
1553 | PPK_SupportsMultipleCopies, | |
1554 | PPK_PaperSize = PPK_PageSize, | |
1555 | ||
1556 | + PPK_UseCompression, | |
1557 | + PPK_ImageQuality, | |
1558 | + PPK_ImageDPI, | |
1559 | PPK_CustomBase = 0xff00 | |
1560 | }; | |
1561 | ||
1562 | @@ -97,6 +100,8 @@ public: | |
1563 | virtual QVariant property(PrintEnginePropertyKey key) const = 0; | |
1564 | ||
1565 | virtual bool newPage() = 0; | |
1566 | + virtual void beginSectionOutline(const QString &text, const QString &anchor) {Q_UNUSED(text); Q_UNUSED(anchor);} | |
1567 | + virtual void endSectionOutline() {} | |
1568 | virtual bool abort() = 0; | |
1569 | ||
1570 | virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0; | |
1571 | diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp | |
1572 | index 239a94f..36eec2e 100644 | |
1573 | --- a/src/gui/painting/qprintengine_pdf.cpp | |
1574 | +++ b/src/gui/painting/qprintengine_pdf.cpp | |
1575 | @@ -51,6 +51,7 @@ | |
1576 | #include <qimagewriter.h> | |
1577 | #include <qbuffer.h> | |
1578 | #include <qdatetime.h> | |
1579 | +#include <QCryptographicHash> | |
1580 | ||
1581 | #ifndef QT_NO_PRINTER | |
1582 | #include <limits.h> | |
1583 | @@ -77,12 +78,6 @@ extern qint64 qt_image_id(const QImage &image); | |
1584 | // Can't use it though, as gs generates completely wrong images if this is true. | |
1585 | static const bool interpolateImages = false; | |
1586 | ||
1587 | -#ifdef QT_NO_COMPRESS | |
1588 | -static const bool do_compress = false; | |
1589 | -#else | |
1590 | -static const bool do_compress = true; | |
1591 | -#endif | |
1592 | - | |
1593 | QPdfPage::QPdfPage() | |
1594 | : QPdf::ByteStream(true) // Enable file backing | |
1595 | { | |
1596 | @@ -109,6 +104,30 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features() | |
1597 | return f; | |
1598 | } | |
1599 | ||
1600 | +void QPdfEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { | |
1601 | + Q_D(QPdfEngine); | |
1602 | + if (key==PPK_UseCompression) | |
1603 | + d->doCompress = value.toBool(); | |
1604 | + else if (key==PPK_ImageQuality) | |
1605 | + d->imageQuality = value.toInt(); | |
1606 | + else if (key==PPK_ImageDPI) | |
1607 | + d->imageDPI = value.toInt(); | |
1608 | + else | |
1609 | + QPdfBaseEngine::setProperty(key, value); | |
1610 | +} | |
1611 | + | |
1612 | +QVariant QPdfEngine::property(PrintEnginePropertyKey key) const { | |
1613 | + Q_D(const QPdfEngine); | |
1614 | + if (key==PPK_UseCompression) | |
1615 | + return d->doCompress; | |
1616 | + else if (key==PPK_ImageQuality) | |
1617 | + return d->imageQuality; | |
1618 | + else if (key==PPK_ImageDPI) | |
1619 | + return d->imageDPI; | |
1620 | + else | |
1621 | + return QPdfBaseEngine::property(key); | |
1622 | +} | |
1623 | + | |
1624 | QPdfEngine::QPdfEngine(QPrinter::PrinterMode m) | |
1625 | : QPdfBaseEngine(*new QPdfEnginePrivate(m), qt_pdf_decide_features()) | |
1626 | { | |
1627 | @@ -156,6 +175,59 @@ bool QPdfEngine::begin(QPaintDevice *pdev) | |
1628 | bool QPdfEngine::end() | |
1629 | { | |
1630 | Q_D(QPdfEngine); | |
1631 | + | |
1632 | + uint dests; | |
1633 | + if (d->anchors.size()) { | |
1634 | + dests = d->addXrefEntry(-1); | |
1635 | + d->xprintf("<<\n"); | |
1636 | + for (QHash<QString, uint>::iterator i=d->anchors.begin(); | |
1637 | + i != d->anchors.end(); ++i) { | |
1638 | + d->printAnchor(i.key()); | |
1639 | + d->xprintf(" %d 0 R\n", i.value()); | |
1640 | + } | |
1641 | + d->xprintf(">>\n"); | |
1642 | + } | |
1643 | + | |
1644 | + if (d->outlineRoot) { | |
1645 | + d->outlineRoot->obj = d->requestObject(); | |
1646 | + d->writeOutlineChildren(d->outlineRoot); | |
1647 | + d->addXrefEntry(d->outlineRoot->obj); | |
1648 | + d->xprintf("<</Type /Outlines /First %d 0 R\n/Last %d 0 R>>\nendobj\n", | |
1649 | + d->outlineRoot->firstChild->obj, d->outlineRoot->lastChild->obj); | |
1650 | + } | |
1651 | + | |
1652 | + if (d->formFields.size()) { | |
1653 | + uint font = d->addXrefEntry(-1); | |
1654 | + d->xprintf("<</Type/Font/Name/Helv/BaseFont/Helvetica/Subtype/Type1>>\n" | |
1655 | + "endobj\n"); | |
1656 | + d->addXrefEntry(d->formFieldList); | |
1657 | + d->xprintf("<</Fields["); | |
1658 | + foreach(const uint & i, d->formFields) | |
1659 | + d->xprintf("%d 0 R ",i); | |
1660 | + d->xprintf("]\n" | |
1661 | + "/DR<</Font<</Helv %d 0 R>>>>\n" | |
1662 | + "/DA(/Helv 0 Tf 0 g)\n" | |
1663 | + ">>\n" | |
1664 | + "endobj\n", font); | |
1665 | + } | |
1666 | + | |
1667 | + d->catalog = d->addXrefEntry(-1); | |
1668 | + d->xprintf("<<\n" | |
1669 | + "/Type /Catalog\n" | |
1670 | + "/Pages %d 0 R\n", d->pageRoot); | |
1671 | + if (d->outlineRoot) | |
1672 | + d->xprintf("/Outlines %d 0 R\n" | |
1673 | + "/PageMode /UseOutlines\n", d->outlineRoot->obj); | |
1674 | + | |
1675 | + if (d->formFields.size()) | |
1676 | + d->xprintf("/AcroForm %d 0 R\n", d->formFieldList); | |
1677 | + | |
1678 | + if (d->anchors.size()) | |
1679 | + d->xprintf("/Dests %d 0 R\n", dests); | |
1680 | + | |
1681 | + d->xprintf(">>\n" | |
1682 | + "endobj\n"); | |
1683 | + | |
1684 | d->writeTail(); | |
1685 | ||
1686 | d->stream->unsetDevice(); | |
1687 | @@ -165,8 +237,83 @@ bool QPdfEngine::end() | |
1688 | return true; | |
1689 | } | |
1690 | ||
1691 | +void QPdfEngine::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) { | |
1692 | + Q_D(QPdfEngine); | |
1693 | + uint obj = d->addXrefEntry(-1); | |
1694 | + char buf[256]; | |
1695 | + QRectF rr = d->pageMatrix().mapRect(r); | |
1696 | + //Note that the pdf spec sayes that we should add some sort of default appearence atleast for yes, which we dont ghost script provides one, however acroread does not | |
1697 | + if (d->formFieldList == -1) d->formFieldList = d->requestObject(); | |
1698 | + d->xprintf("<<\n" | |
1699 | + "/Type /Annot\n" | |
1700 | + "/Parrent %d 0 R\n" | |
1701 | + "/Rect[", d->formFieldList); | |
1702 | + d->xprintf("%s ", qt_real_to_string(rr.left(),buf)); | |
1703 | + d->xprintf("%s ", qt_real_to_string(rr.top(),buf)); | |
1704 | + d->xprintf("%s ", qt_real_to_string(rr.right(),buf)); | |
1705 | + d->xprintf("%s", qt_real_to_string(rr.bottom(),buf)); | |
1706 | + d->xprintf("]\n" | |
1707 | + "/FT/Btn\n" | |
1708 | + "/Subtype/Widget\n" | |
1709 | + "/P %d 0 R\n", d->pages.back()); | |
1710 | + if (checked) | |
1711 | + d->xprintf("/AS /Yes\n"); | |
1712 | + if (!name.isEmpty()) { | |
1713 | + d->xprintf("/T"); | |
1714 | + d->printString(name); | |
1715 | + d->xprintf("\n"); | |
1716 | + } | |
1717 | + d->xprintf("/Ff %d\n" | |
1718 | + ">>\n" | |
1719 | + "endobj\n", | |
1720 | + (readOnly?1:0)<<0); | |
1721 | + d->currentPage->annotations.push_back(obj); | |
1722 | + d->formFields.push_back(obj); | |
1723 | +} | |
1724 | + | |
1725 | +void QPdfEngine::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) | |
1726 | +{ | |
1727 | + Q_D(QPdfEngine); | |
1728 | + uint obj = d->addXrefEntry(-1); | |
1729 | + char buf[256]; | |
1730 | + QRectF rr = d->pageMatrix().mapRect(r); | |
1731 | + if (d->formFieldList == -1) d->formFieldList = d->requestObject(); | |
1732 | + d->xprintf("<<\n" | |
1733 | + "/Type /Annot\n" | |
1734 | + "/Parrent %d 0 R\n" | |
1735 | + "/Rect[", d->formFieldList); | |
1736 | + d->xprintf("%s ", qt_real_to_string(rr.left(),buf)); | |
1737 | + d->xprintf("%s ", qt_real_to_string(rr.top(),buf)); | |
1738 | + d->xprintf("%s ", qt_real_to_string(rr.right(),buf)); | |
1739 | + d->xprintf("%s", qt_real_to_string(rr.bottom(),buf)); | |
1740 | + d->xprintf("]\n" | |
1741 | + "/BS<</S/I>>\n" | |
1742 | + "/FT/Tx\n" | |
1743 | + "/Subtype/Widget\n" | |
1744 | + "/P %d 0 R\n", d->pages.back()); | |
1745 | + if (!text.isEmpty()) { | |
1746 | + d->xprintf("/V"); | |
1747 | + d->printString(text); | |
1748 | + d->xprintf("\n"); | |
1749 | + } | |
1750 | + if (!name.isEmpty()) { | |
1751 | + d->xprintf("/T"); | |
1752 | + d->printString(name); | |
1753 | + d->xprintf("\n"); | |
1754 | + } | |
1755 | + if (maxLength >= 0) | |
1756 | + d->xprintf("/MaxLen %d\n",maxLength); | |
1757 | + d->xprintf("/DA(/Helv 12 Tf 0 g)\n" | |
1758 | + "/Ff %d\n" | |
1759 | + ">>\n" | |
1760 | + "endobj\n", | |
1761 | + (readOnly?1:0)<<0 | (password?1:0)<<13 | (multiLine?1:0)<<12 | |
1762 | + ); | |
1763 | + d->currentPage->annotations.push_back(obj); | |
1764 | + d->formFields.push_back(obj); | |
1765 | +} | |
1766 | ||
1767 | -void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr) | |
1768 | +void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr, const QByteArray * data) | |
1769 | { | |
1770 | if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull()) | |
1771 | return; | |
1772 | @@ -176,22 +323,35 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con | |
1773 | ||
1774 | QRect sourceRect = sr.toRect(); | |
1775 | QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap; | |
1776 | - QImage image = pm.toImage(); | |
1777 | + QImage unscaled = pm.toImage(); | |
1778 | + QImage image = unscaled; | |
1779 | + | |
1780 | + QRectF a = d->stroker.matrix.mapRect(rectangle); | |
1781 | + QRectF c = d->paperRect(); | |
1782 | + int maxWidth = int(a.width() / c.width() * d->width() / 72.0 * d->imageDPI); | |
1783 | + int maxHeight = int(a.height() / c.height() * d->height() / 72.0 * d->imageDPI); | |
1784 | + if (image.width() > maxWidth || image.height() > maxHeight) | |
1785 | + image = unscaled.scaled( image.size().boundedTo( QSize(maxWidth, maxHeight) ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); | |
1786 | + | |
1787 | + bool useScaled=true; | |
1788 | bool bitmap = true; | |
1789 | - const int object = d->addImage(image, &bitmap, pm.cacheKey()); | |
1790 | + const int object = d->addImage(image, &bitmap, pm.cacheKey(), &unscaled, (sr == pixmap.rect()?data:0), &useScaled ); | |
1791 | + int width = useScaled?image.width():unscaled.width(); | |
1792 | + int height = useScaled?image.height():unscaled.height(); | |
1793 | + | |
1794 | if (object < 0) | |
1795 | return; | |
1796 | ||
1797 | *d->currentPage << "q\n/GSa gs\n"; | |
1798 | *d->currentPage | |
1799 | - << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(), | |
1800 | + << QPdf::generateMatrix(QTransform(rectangle.width() / width, 0, 0, rectangle.height() / height, | |
1801 | rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix)); | |
1802 | if (bitmap) { | |
1803 | // set current pen as d->brush | |
1804 | d->brush = d->pen.brush(); | |
1805 | } | |
1806 | setBrush(); | |
1807 | - d->currentPage->streamImage(image.width(), image.height(), object); | |
1808 | + d->currentPage->streamImage(width, height, object); | |
1809 | *d->currentPage << "Q\n"; | |
1810 | ||
1811 | d->brush = b; | |
1812 | @@ -301,18 +461,68 @@ QPdfEnginePrivate::QPdfEnginePrivate(QPrinter::PrinterMode m) | |
1813 | : QPdfBaseEnginePrivate(m) | |
1814 | { | |
1815 | streampos = 0; | |
1816 | - | |
1817 | + doCompress = true; | |
1818 | + imageDPI = 1400; | |
1819 | + imageQuality = 94; | |
1820 | stream = new QDataStream; | |
1821 | pageOrder = QPrinter::FirstPageFirst; | |
1822 | orientation = QPrinter::Portrait; | |
1823 | + outlineRoot = NULL; | |
1824 | + outlineCurrent = NULL; | |
1825 | fullPage = false; | |
1826 | } | |
1827 | ||
1828 | QPdfEnginePrivate::~QPdfEnginePrivate() | |
1829 | { | |
1830 | + if (outlineRoot) | |
1831 | + delete outlineRoot; | |
1832 | delete stream; | |
1833 | } | |
1834 | ||
1835 | +void QPdfEnginePrivate::printAnchor(const QString &name) { | |
1836 | + QByteArray a = name.toUtf8(); | |
1837 | + if (a.size() >= 127) | |
1838 | + a = QCryptographicHash::hash(a,QCryptographicHash::Sha1); | |
1839 | + xprintf("/"); | |
1840 | + for (int i=0; i < a.size(); ++i) { | |
1841 | + unsigned char c = a[i]; | |
1842 | + if (('a' <= c && c <= 'z') || | |
1843 | + ('A' <= c && c <= 'Z') || | |
1844 | + ('0' <= c && c <= '9') || | |
1845 | + c == '.' || c == '_') | |
1846 | + xprintf("%c", c); | |
1847 | + else if(c == 0) | |
1848 | + xprintf("!"); | |
1849 | + else | |
1850 | + xprintf("#%02x", c); | |
1851 | + } | |
1852 | +} | |
1853 | + | |
1854 | +void QPdfEnginePrivate::writeOutlineChildren(OutlineItem * node) { | |
1855 | + for (OutlineItem * i = node->firstChild; i != NULL; i = i->next) | |
1856 | + i->obj = requestObject(); | |
1857 | + for (OutlineItem * i = node->firstChild; i != NULL; i = i->next) { | |
1858 | + QPdfEnginePrivate::writeOutlineChildren(i); | |
1859 | + addXrefEntry(i->obj); | |
1860 | + xprintf("<</Title "); | |
1861 | + printString(i->text); | |
1862 | + xprintf("\n" | |
1863 | + " /Parent %d 0 R\n" | |
1864 | + " /Dest ", i->parent->obj); | |
1865 | + printAnchor(i->anchor); | |
1866 | + xprintf("\n /Count 0\n"); | |
1867 | + if (i->next) | |
1868 | + xprintf(" /Next %d 0 R\n", i->next->obj); | |
1869 | + if (i->prev) | |
1870 | + xprintf(" /Prev %d 0 R\n", i->prev->obj); | |
1871 | + if (i->firstChild) | |
1872 | + xprintf(" /First %d 0 R\n", i->firstChild->obj); | |
1873 | + if (i->lastChild) | |
1874 | + xprintf(" /Last %d 0 R\n", i->lastChild->obj); | |
1875 | + xprintf(">>\n" | |
1876 | + "endobj\n"); | |
1877 | + } | |
1878 | +} | |
1879 | ||
1880 | #ifdef USE_NATIVE_GRADIENTS | |
1881 | int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject) | |
1882 | @@ -520,10 +730,112 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, | |
1883 | return patternObj; | |
1884 | } | |
1885 | ||
1886 | + | |
1887 | +void QPdfEnginePrivate::convertImage(const QImage & image, QByteArray & imageData) { | |
1888 | + int w = image.width(); | |
1889 | + int h = image.height(); | |
1890 | + imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h); | |
1891 | + uchar *data = (uchar *)imageData.data(); | |
1892 | + for (int y = 0; y < h; ++y) { | |
1893 | + const QRgb *rgb = (const QRgb *)image.scanLine(y); | |
1894 | + if (colorMode == QPrinter::GrayScale) { | |
1895 | + for (int x = 0; x < w; ++x) { | |
1896 | + *(data++) = qGray(*rgb); | |
1897 | + ++rgb; | |
1898 | + } | |
1899 | + } else { | |
1900 | + for (int x = 0; x < w; ++x) { | |
1901 | + *(data++) = qRed(*rgb); | |
1902 | + *(data++) = qGreen(*rgb); | |
1903 | + *(data++) = qBlue(*rgb); | |
1904 | + ++rgb; | |
1905 | + } | |
1906 | + } | |
1907 | + } | |
1908 | +} | |
1909 | + | |
1910 | +#include <iostream> | |
1911 | + | |
1912 | +class jpg_header_reader { | |
1913 | +private: | |
1914 | + const QByteArray * data; | |
1915 | + int index; | |
1916 | + | |
1917 | + class jpeg_exception {}; | |
1918 | + | |
1919 | + unsigned char next() { | |
1920 | + if (index == data->size()) throw jpeg_exception(); | |
1921 | + return data->data()[index++]; | |
1922 | + } | |
1923 | + | |
1924 | + void skip() { | |
1925 | + int l = (next() << 8) + next(); | |
1926 | + if (l < 2) throw jpeg_exception(); | |
1927 | + for (int i=2; i < l; ++i) next(); | |
1928 | + } | |
1929 | + | |
1930 | + void read_header() { | |
1931 | + int l = (next() << 8) + next(); | |
1932 | + if (l < 2) throw jpeg_exception(); | |
1933 | + precision = next(); | |
1934 | + height = (next() << 8) + next(); | |
1935 | + width = (next() << 8) + next(); | |
1936 | + components = next(); | |
1937 | + if (l != 8 + components*3) throw jpeg_exception(); | |
1938 | + } | |
1939 | + | |
1940 | +public: | |
1941 | + bool read(const QByteArray * d) { | |
1942 | + index=0; | |
1943 | + data=d; | |
1944 | + try { | |
1945 | + if (next() != 0xFF) throw jpeg_exception(); | |
1946 | + unsigned char marker = next(); | |
1947 | + if (marker != 0xD8) throw jpeg_exception(); | |
1948 | + while (true) { | |
1949 | + marker = next(); | |
1950 | + while (marker != 0xFF) marker=next(); | |
1951 | + while (marker == 0xFF) marker=next(); | |
1952 | + switch(marker) { | |
1953 | + case 0xC0: | |
1954 | + case 0xC1: | |
1955 | + case 0xC2: | |
1956 | + case 0xC3: | |
1957 | + case 0xC5: | |
1958 | + case 0xC6: | |
1959 | + case 0xC7: | |
1960 | + case 0xC9: | |
1961 | + case 0xCA: | |
1962 | + case 0xCB: | |
1963 | + case 0xCD: | |
1964 | + case 0xCE: | |
1965 | + case 0xCF: | |
1966 | + read_header(); | |
1967 | + return true; | |
1968 | + case 0xDA: | |
1969 | + case 0xD9: | |
1970 | + return false; | |
1971 | + default: | |
1972 | + skip(); | |
1973 | + break; | |
1974 | + } | |
1975 | + } | |
1976 | + } catch(jpeg_exception) { | |
1977 | + return false; | |
1978 | + } | |
1979 | + return true; | |
1980 | + } | |
1981 | + | |
1982 | + int precision, height, width, components; | |
1983 | + | |
1984 | +}; | |
1985 | + | |
1986 | + | |
1987 | + | |
1988 | /*! | |
1989 | * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed. | |
1990 | */ | |
1991 | -int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no) | |
1992 | +int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no, const QImage * noneScaled, const QByteArray * data, bool * useScaled) | |
1993 | { | |
1994 | if (img.isNull()) | |
1995 | return -1; | |
1996 | @@ -564,65 +876,97 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n | |
1997 | } | |
1998 | object = writeImage(data, w, h, d, 0, 0); | |
1999 | } else { | |
2000 | - QByteArray softMaskData; | |
2001 | - bool dct = false; | |
2002 | QByteArray imageData; | |
2003 | - bool hasAlpha = false; | |
2004 | - bool hasMask = false; | |
2005 | - | |
2006 | + uLongf target=1024*1024*1024; | |
2007 | + bool uns=false; | |
2008 | + bool dct = false; | |
2009 | + | |
2010 | + d = (colorMode == QPrinter::GrayScale) ? 8 : 32; | |
2011 | + | |
2012 | if (QImageWriter::supportedImageFormats().contains("jpeg") && colorMode != QPrinter::GrayScale) { | |
2013 | - QBuffer buffer(&imageData); | |
2014 | + QByteArray imageData2; | |
2015 | + | |
2016 | + QBuffer buffer(&imageData2); | |
2017 | QImageWriter writer(&buffer, "jpeg"); | |
2018 | - writer.setQuality(94); | |
2019 | + writer.setQuality(imageQuality); | |
2020 | writer.write(image); | |
2021 | - dct = true; | |
2022 | - | |
2023 | - if (format != QImage::Format_RGB32) { | |
2024 | - softMaskData.resize(w * h); | |
2025 | - uchar *sdata = (uchar *)softMaskData.data(); | |
2026 | - for (int y = 0; y < h; ++y) { | |
2027 | - const QRgb *rgb = (const QRgb *)image.scanLine(y); | |
2028 | - for (int x = 0; x < w; ++x) { | |
2029 | - uchar alpha = qAlpha(*rgb); | |
2030 | - *sdata++ = alpha; | |
2031 | - hasMask |= (alpha < 255); | |
2032 | - hasAlpha |= (alpha != 0 && alpha != 255); | |
2033 | - ++rgb; | |
2034 | - } | |
2035 | - } | |
2036 | + | |
2037 | + if ((uLongf)imageData2.size() < target) { | |
2038 | + imageData=imageData2; | |
2039 | + target = imageData2.size(); | |
2040 | + dct = true; | |
2041 | + uns=false; | |
2042 | } | |
2043 | - } else { | |
2044 | - imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h); | |
2045 | - uchar *data = (uchar *)imageData.data(); | |
2046 | + } | |
2047 | + | |
2048 | + if (noneScaled && noneScaled->rect() != image.rect()) { | |
2049 | + QByteArray imageData2; | |
2050 | + convertImage(*noneScaled, imageData2); | |
2051 | + uLongf len = imageData2.size(); | |
2052 | + uLongf destLen = len + len/100 + 13; // zlib requirement | |
2053 | + Bytef* dest = new Bytef[destLen]; | |
2054 | + if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) && | |
2055 | + (uLongf)destLen < target) { | |
2056 | + imageData=imageData2; | |
2057 | + target=destLen; | |
2058 | + dct=false; | |
2059 | + uns=true; | |
2060 | + } | |
2061 | + delete[] dest; | |
2062 | + } | |
2063 | + | |
2064 | + { | |
2065 | + QByteArray imageData2; | |
2066 | + convertImage(image, imageData2); | |
2067 | + uLongf len = imageData2.size(); | |
2068 | + uLongf destLen = len + len/100 + 13; // zlib requirement | |
2069 | + Bytef* dest = new Bytef[destLen]; | |
2070 | + if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) && | |
2071 | + (uLongf)destLen < target) { | |
2072 | + imageData=imageData2; | |
2073 | + target=destLen; | |
2074 | + dct=false; | |
2075 | + uns=false; | |
2076 | + } | |
2077 | + delete[] dest; | |
2078 | + } | |
2079 | + | |
2080 | + | |
2081 | + if (colorMode != QPrinter::GrayScale && noneScaled != 0 && data != 0) { | |
2082 | + jpg_header_reader header; | |
2083 | + if (header.read(data)) { | |
2084 | + d = header.components == 3?32:8; | |
2085 | + imageData = *data; | |
2086 | + target=data->size(); | |
2087 | + dct=true; | |
2088 | + uns=true; | |
2089 | + } | |
2090 | + } | |
2091 | + | |
2092 | + if (uns) { | |
2093 | + w = noneScaled->width(); | |
2094 | + h = noneScaled->height(); | |
2095 | + } | |
2096 | + if (useScaled) *useScaled = (uns?false:true); | |
2097 | + QByteArray softMaskData; | |
2098 | + bool hasAlpha = false; | |
2099 | + bool hasMask = false; | |
2100 | + | |
2101 | + if (format != QImage::Format_RGB32) { | |
2102 | softMaskData.resize(w * h); | |
2103 | uchar *sdata = (uchar *)softMaskData.data(); | |
2104 | for (int y = 0; y < h; ++y) { | |
2105 | - const QRgb *rgb = (const QRgb *)image.scanLine(y); | |
2106 | - if (colorMode == QPrinter::GrayScale) { | |
2107 | - for (int x = 0; x < w; ++x) { | |
2108 | - *(data++) = qGray(*rgb); | |
2109 | - uchar alpha = qAlpha(*rgb); | |
2110 | - *sdata++ = alpha; | |
2111 | - hasMask |= (alpha < 255); | |
2112 | - hasAlpha |= (alpha != 0 && alpha != 255); | |
2113 | - ++rgb; | |
2114 | - } | |
2115 | - } else { | |
2116 | - for (int x = 0; x < w; ++x) { | |
2117 | - *(data++) = qRed(*rgb); | |
2118 | - *(data++) = qGreen(*rgb); | |
2119 | - *(data++) = qBlue(*rgb); | |
2120 | - uchar alpha = qAlpha(*rgb); | |
2121 | - *sdata++ = alpha; | |
2122 | - hasMask |= (alpha < 255); | |
2123 | - hasAlpha |= (alpha != 0 && alpha != 255); | |
2124 | - ++rgb; | |
2125 | - } | |
2126 | + const QRgb *rgb = (const QRgb *)(uns?noneScaled->scanLine(y):image.scanLine(y)); | |
2127 | + for (int x = 0; x < w; ++x) { | |
2128 | + uchar alpha = qAlpha(*rgb); | |
2129 | + *sdata++ = alpha; | |
2130 | + hasMask |= (alpha < 255); | |
2131 | + hasAlpha |= (alpha != 0 && alpha != 255); | |
2132 | + ++rgb; | |
2133 | } | |
2134 | } | |
2135 | - if (format == QImage::Format_RGB32) | |
2136 | - hasAlpha = hasMask = false; | |
2137 | } | |
2138 | + | |
2139 | int maskObject = 0; | |
2140 | int softMaskObject = 0; | |
2141 | if (hasAlpha) { | |
2142 | @@ -644,7 +988,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n | |
2143 | } | |
2144 | maskObject = writeImage(mask, w, h, 1, 0, 0); | |
2145 | } | |
2146 | - object = writeImage(imageData, w, h, colorMode == QPrinter::GrayScale ? 8 : 32, | |
2147 | + object = writeImage(imageData, w, h, d, | |
2148 | maskObject, softMaskObject, dct); | |
2149 | } | |
2150 | imageCache.insert(serial_no, object); | |
2151 | @@ -754,7 +1098,7 @@ void QPdfEnginePrivate::xprintf(const char* fmt, ...) | |
2152 | int QPdfEnginePrivate::writeCompressed(QIODevice *dev) | |
2153 | { | |
2154 | #ifndef QT_NO_COMPRESS | |
2155 | - if (do_compress) { | |
2156 | + if (doCompress) { | |
2157 | int size = QPdfPage::chunkSize(); | |
2158 | int sum = 0; | |
2159 | ::z_stream zStruct; | |
2160 | @@ -828,7 +1172,7 @@ int QPdfEnginePrivate::writeCompressed(QIODevice *dev) | |
2161 | int QPdfEnginePrivate::writeCompressed(const char *src, int len) | |
2162 | { | |
2163 | #ifndef QT_NO_COMPRESS | |
2164 | - if(do_compress) { | |
2165 | + if(doCompress) { | |
2166 | uLongf destLen = len + len/100 + 13; // zlib requirement | |
2167 | Bytef* dest = new Bytef[destLen]; | |
2168 | if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) { | |
2169 | @@ -881,7 +1225,7 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, | |
2170 | write(data); | |
2171 | len = data.length(); | |
2172 | } else { | |
2173 | - if (do_compress) | |
2174 | + if (doCompress) | |
2175 | xprintf("/Filter /FlateDecode\n>>\nstream\n"); | |
2176 | else | |
2177 | xprintf(">>\nstream\n"); | |
2178 | @@ -904,14 +1248,9 @@ void QPdfEnginePrivate::writeHeader() | |
2179 | ||
2180 | writeInfo(); | |
2181 | ||
2182 | - catalog = addXrefEntry(-1); | |
2183 | pageRoot = requestObject(); | |
2184 | - xprintf("<<\n" | |
2185 | - "/Type /Catalog\n" | |
2186 | - "/Pages %d 0 R\n" | |
2187 | - ">>\n" | |
2188 | - "endobj\n", pageRoot); | |
2189 | - | |
2190 | + | |
2191 | + formFieldList = -1; | |
2192 | // graphics state | |
2193 | graphicsState = addXrefEntry(-1); | |
2194 | xprintf("<<\n" | |
2195 | @@ -939,17 +1278,26 @@ void QPdfEnginePrivate::writeInfo() | |
2196 | xprintf("\n/Creator "); | |
2197 | printString(creator); | |
2198 | xprintf("\n/Producer "); | |
2199 | - printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)")); | |
2200 | - QDateTime now = QDateTime::currentDateTime().toUTC(); | |
2201 | + printString(QString::fromLatin1("wkhtmltopdf")); | |
2202 | + QDateTime now = QDateTime::currentDateTime(); | |
2203 | QTime t = now.time(); | |
2204 | QDate d = now.date(); | |
2205 | - xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n", | |
2206 | + xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d", | |
2207 | d.year(), | |
2208 | d.month(), | |
2209 | d.day(), | |
2210 | t.hour(), | |
2211 | t.minute(), | |
2212 | t.second()); | |
2213 | + QDateTime fake=now; | |
2214 | + fake.setTimeSpec(Qt::UTC); | |
2215 | + int offset = now.secsTo(fake); | |
2216 | + if (offset == 0) | |
2217 | + xprintf("Z)\n"); | |
2218 | + else if (offset < 0) | |
2219 | + xprintf("-%02d'%02d')\n", (-offset)/60/60 , ((-offset)/60) % 60); | |
2220 | + else if (offset > 0) | |
2221 | + xprintf("+%02d'%02d')\n", offset/60/60 , (offset/60) % 60); | |
2222 | xprintf(">>\n" | |
2223 | "endobj\n"); | |
2224 | } | |
2225 | @@ -1035,7 +1383,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font) | |
2226 | s << "<<\n" | |
2227 | "/Length1 " << fontData.size() << "\n" | |
2228 | "/Length " << length_object << "0 R\n"; | |
2229 | - if (do_compress) | |
2230 | + if (doCompress) | |
2231 | s << "/Filter /FlateDecode\n"; | |
2232 | s << ">>\n" | |
2233 | "stream\n"; | |
2234 | @@ -1097,6 +1445,101 @@ void QPdfEnginePrivate::writeFonts() | |
2235 | fonts.clear(); | |
2236 | } | |
2237 | ||
2238 | + | |
2239 | +void QPdfEngine::addHyperlink(const QRectF &r, const QUrl &url) | |
2240 | +{ | |
2241 | + Q_D(QPdfEngine); | |
2242 | + char buf[256]; | |
2243 | + QRectF rr = d->pageMatrix().mapRect(r); | |
2244 | + uint annot = d->addXrefEntry(-1); | |
2245 | + QByteArray urlascii = url.toString().toLatin1(); | |
2246 | + int len = urlascii.size(); | |
2247 | + char *url_esc = new char[len * 2 + 1]; | |
2248 | + const char * urldata = urlascii.constData(); | |
2249 | + int k = 0; | |
2250 | + for (int j = 0; j < len; j++, k++){ | |
2251 | + if (urldata[j] == '(' || | |
2252 | + urldata[j] == ')' || | |
2253 | + urldata[j] == '\\'){ | |
2254 | + url_esc[k] = '\\'; | |
2255 | + k++; | |
2256 | + } | |
2257 | + url_esc[k] = urldata[j]; | |
2258 | + } | |
2259 | + url_esc[k] = 0; | |
2260 | + d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect ["); | |
2261 | + d->xprintf("%s ", qt_real_to_string(rr.left(),buf)); | |
2262 | + d->xprintf("%s ", qt_real_to_string(rr.top(),buf)); | |
2263 | + d->xprintf("%s ", qt_real_to_string(rr.right(),buf)); | |
2264 | + d->xprintf("%s", qt_real_to_string(rr.bottom(),buf)); | |
2265 | + d->xprintf("]\n/Border [0 0 0]\n/A <<\n"); | |
2266 | + d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc); | |
2267 | + d->xprintf(">>\n>>\n"); | |
2268 | + d->xprintf("endobj\n"); | |
2269 | + d->currentPage->annotations.append(annot); | |
2270 | + delete[] url_esc; | |
2271 | +} | |
2272 | + | |
2273 | +void QPdfEngine::addLink(const QRectF &r, const QString &anchor) | |
2274 | +{ | |
2275 | + Q_D(QPdfEngine); | |
2276 | + char buf[256]; | |
2277 | + QRectF rr = d->pageMatrix().mapRect(r); | |
2278 | + uint annot = d->addXrefEntry(-1); | |
2279 | + d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect ["); | |
2280 | + d->xprintf("%s ", qt_real_to_string(rr.left(),buf)); | |
2281 | + d->xprintf("%s ", qt_real_to_string(rr.top(),buf)); | |
2282 | + d->xprintf("%s ", qt_real_to_string(rr.right(),buf)); | |
2283 | + d->xprintf("%s", qt_real_to_string(rr.bottom(),buf)); | |
2284 | + d->xprintf("]\n/Border [0 0 0]\n/Dest "); | |
2285 | + d->printAnchor(anchor); | |
2286 | + d->xprintf("\n>>\n"); | |
2287 | + d->xprintf("endobj\n"); | |
2288 | + d->currentPage->annotations.append(annot); | |
2289 | +} | |
2290 | + | |
2291 | +void QPdfEngine::addAnchor(const QRectF &r, const QString &name) | |
2292 | +{ | |
2293 | + Q_D(QPdfEngine); | |
2294 | + char buf[256]; | |
2295 | + QRectF rr = d->pageMatrix().mapRect(r); | |
2296 | + uint anchor = d->addXrefEntry(-1); | |
2297 | + d->xprintf("[%d /XYZ %s \n", | |
2298 | + d->pages.size() - 1, | |
2299 | + qt_real_to_string(rr.left(), buf)); | |
2300 | + d->xprintf("%s 0]\n", | |
2301 | + qt_real_to_string(rr.bottom(), buf)); | |
2302 | + d->xprintf("endobj\n"); | |
2303 | + d->anchors[name] = anchor; | |
2304 | +} | |
2305 | + | |
2306 | +void QPdfEngine::beginSectionOutline(const QString &text, const QString &anchor) | |
2307 | +{ | |
2308 | + Q_D(QPdfEngine); | |
2309 | + if (d->outlineCurrent == NULL) { | |
2310 | + if (d->outlineRoot) | |
2311 | + delete d->outlineRoot; | |
2312 | + d->outlineCurrent = d->outlineRoot = new QPdfEnginePrivate::OutlineItem(QString(), QString()); | |
2313 | + } | |
2314 | + | |
2315 | + QPdfEnginePrivate::OutlineItem *i = new QPdfEnginePrivate::OutlineItem(text, anchor); | |
2316 | + i->parent = d->outlineCurrent; | |
2317 | + i->prev = d->outlineCurrent->lastChild; | |
2318 | + if (d->outlineCurrent->firstChild) | |
2319 | + d->outlineCurrent->lastChild->next = i; | |
2320 | + else | |
2321 | + d->outlineCurrent->firstChild = i; | |
2322 | + d->outlineCurrent->lastChild = i; | |
2323 | + d->outlineCurrent = i; | |
2324 | +} | |
2325 | + | |
2326 | +void QPdfEngine::endSectionOutline() | |
2327 | +{ | |
2328 | + Q_D(QPdfEngine); | |
2329 | + if (d->outlineCurrent) | |
2330 | + d->outlineCurrent = d->outlineCurrent->parent; | |
2331 | +} | |
2332 | + | |
2333 | void QPdfEnginePrivate::writePage() | |
2334 | { | |
2335 | if (pages.empty()) | |
2336 | @@ -1167,7 +1610,7 @@ void QPdfEnginePrivate::writePage() | |
2337 | addXrefEntry(pageStream); | |
2338 | xprintf("<<\n" | |
2339 | "/Length %d 0 R\n", pageStreamLength); // object number for stream length object | |
2340 | - if (do_compress) | |
2341 | + if (doCompress) | |
2342 | xprintf("/Filter /FlateDecode\n"); | |
2343 | ||
2344 | xprintf(">>\n"); | |
2345 | diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h | |
2346 | index 9b9185a..1586caa 100644 | |
2347 | --- a/src/gui/painting/qprintengine_pdf_p.h | |
2348 | +++ b/src/gui/painting/qprintengine_pdf_p.h | |
2349 | @@ -92,7 +92,12 @@ public: | |
2350 | // reimplementations QPaintEngine | |
2351 | bool begin(QPaintDevice *pdev); | |
2352 | bool end(); | |
2353 | - void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr); | |
2354 | + | |
2355 | + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data=0); | |
2356 | + void drawPixmap(const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr) { | |
2357 | + drawPixmap(rectangle, pixmap, sr, 0); | |
2358 | + } | |
2359 | + | |
2360 | void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, | |
2361 | Qt::ImageConversionFlags flags = Qt::AutoColor); | |
2362 | void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point); | |
2363 | @@ -108,12 +113,23 @@ public: | |
2364 | ||
2365 | void setBrush(); | |
2366 | ||
2367 | + virtual void addHyperlink(const QRectF &r, const QUrl &url); | |
2368 | + virtual void addAnchor(const QRectF &r, const QString &name); | |
2369 | + virtual void addLink(const QRectF &r, const QString &anchor); | |
2370 | + virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength); | |
2371 | + virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly); | |
2372 | + | |
2373 | // ### unused, should have something for this in QPrintEngine | |
2374 | void setAuthor(const QString &author); | |
2375 | QString author() const; | |
2376 | ||
2377 | void setDevice(QIODevice* dev); | |
2378 | ||
2379 | + void beginSectionOutline(const QString &text, const QString &anchor); | |
2380 | + void endSectionOutline(); | |
2381 | + | |
2382 | + void setProperty(PrintEnginePropertyKey key, const QVariant &value); | |
2383 | + QVariant property(PrintEnginePropertyKey key) const; | |
2384 | private: | |
2385 | Q_DISABLE_COPY(QPdfEngine) | |
2386 | ||
2387 | @@ -124,6 +140,35 @@ class QPdfEnginePrivate : public QPdfBaseEnginePrivate | |
2388 | { | |
2389 | Q_DECLARE_PUBLIC(QPdfEngine) | |
2390 | public: | |
2391 | + | |
2392 | + class OutlineItem { | |
2393 | + public: | |
2394 | + OutlineItem *parent; | |
2395 | + OutlineItem *next; | |
2396 | + OutlineItem *prev; | |
2397 | + OutlineItem *firstChild; | |
2398 | + OutlineItem *lastChild; | |
2399 | + uint obj; | |
2400 | + QString text; | |
2401 | + QString anchor; | |
2402 | + | |
2403 | + OutlineItem(const QString &t, const QString &a): | |
2404 | + parent(NULL), next(NULL), prev(NULL), firstChild(NULL), lastChild(NULL), | |
2405 | + obj(0), text(t), anchor(a) {} | |
2406 | + ~OutlineItem() { | |
2407 | + OutlineItem *i = firstChild; | |
2408 | + while(i != NULL) { | |
2409 | + OutlineItem *n = i->next; | |
2410 | + delete i; | |
2411 | + i=n; | |
2412 | + } | |
2413 | + } | |
2414 | + }; | |
2415 | + | |
2416 | + OutlineItem *outlineRoot; | |
2417 | + OutlineItem *outlineCurrent; | |
2418 | + void writeOutlineChildren(OutlineItem *node); | |
2419 | + | |
2420 | QPdfEnginePrivate(QPrinter::PrinterMode m); | |
2421 | ~QPdfEnginePrivate(); | |
2422 | ||
2423 | @@ -141,7 +186,9 @@ public: | |
2424 | void writeHeader(); | |
2425 | void writeTail(); | |
2426 | ||
2427 | - int addImage(const QImage &image, bool *bitmap, qint64 serial_no); | |
2428 | + void convertImage(const QImage & image, QByteArray & imageData); | |
2429 | + | |
2430 | + int addImage(const QImage &image, bool *bitmap, qint64 serial_no, const QImage * noneScaled=0, const QByteArray * data=0, bool * useScaled=0); | |
2431 | int addConstantAlphaObject(int brushAlpha, int penAlpha = 255); | |
2432 | int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject); | |
2433 | ||
2434 | @@ -161,16 +208,25 @@ private: | |
2435 | void writeFonts(); | |
2436 | void embedFont(QFontSubset *font); | |
2437 | ||
2438 | + int formFieldList; | |
2439 | + QVector<uint> formFields; | |
2440 | QVector<int> xrefPositions; | |
2441 | QDataStream* stream; | |
2442 | int streampos; | |
2443 | ||
2444 | + bool doCompress; | |
2445 | + int imageDPI; | |
2446 | + int imageQuality; | |
2447 | + | |
2448 | int writeImage(const QByteArray &data, int width, int height, int depth, | |
2449 | int maskObject, int softMaskObject, bool dct = false); | |
2450 | void writePage(); | |
2451 | ||
2452 | int addXrefEntry(int object, bool printostr = true); | |
2453 | + | |
2454 | void printString(const QString &string); | |
2455 | + void printAnchor(const QString &name); | |
2456 | + | |
2457 | void xprintf(const char* fmt, ...); | |
2458 | inline void write(const QByteArray &data) { | |
2459 | stream->writeRawData(data.constData(), data.size()); | |
2460 | @@ -183,6 +239,8 @@ private: | |
2461 | ||
2462 | // various PDF objects | |
2463 | int pageRoot, catalog, info, graphicsState, patternColorSpace; | |
2464 | + QVector<uint> dests; | |
2465 | + QHash<QString, uint> anchors; | |
2466 | QVector<uint> pages; | |
2467 | QHash<qint64, uint> imageCache; | |
2468 | QHash<QPair<uint, uint>, uint > alphaCache; | |
2469 | diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp | |
2470 | index 134447c..2c58619 100644 | |
2471 | --- a/src/gui/painting/qprinter.cpp | |
2472 | +++ b/src/gui/painting/qprinter.cpp | |
2473 | @@ -933,6 +933,39 @@ void QPrinter::setOutputFileName(const QString &fileName) | |
2474 | d->addToManualSetList(QPrintEngine::PPK_OutputFileName); | |
2475 | } | |
2476 | ||
2477 | +/*! | |
2478 | + Add a section to the document outline. All following sections will be added | |
2479 | + to as subsections to this section, until endSectionOutline() has been called. | |
2480 | + | |
2481 | + \a name is the name of the added section. \a anchor is the name of an anchor | |
2482 | + indicating the beginning of the section. This anchor must be added by calling | |
2483 | + QPainter::addAnchor(). | |
2484 | + | |
2485 | + Note that for output formats not supporting outlines, currently all other then PDF, | |
2486 | + this call has no effect. | |
2487 | + | |
2488 | + \sa endSectionOutline() QPainter::addAnchor() | |
2489 | + | |
2490 | + \since 4.7 | |
2491 | +*/ | |
2492 | +void QPrinter::beginSectionOutline(const QString &name, const QString &anchor) | |
2493 | +{ | |
2494 | + Q_D(QPrinter); | |
2495 | + d->printEngine->beginSectionOutline(name, anchor); | |
2496 | +} | |
2497 | + | |
2498 | +/*! | |
2499 | + End the current section. | |
2500 | + | |
2501 | + \sa beginSectionOutline() | |
2502 | + | |
2503 | + \since 4.7 | |
2504 | +*/ | |
2505 | +void QPrinter::endSectionOutline() | |
2506 | +{ | |
2507 | + Q_D(QPrinter); | |
2508 | + d->printEngine->endSectionOutline(); | |
2509 | +} | |
2510 | ||
2511 | /*! | |
2512 | Returns the name of the program that sends the print output to the | |
2513 | diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h | |
2514 | index f133a5d..46baf8c 100644 | |
2515 | --- a/src/gui/painting/qprinter.h | |
2516 | +++ b/src/gui/painting/qprinter.h | |
2517 | @@ -147,6 +147,9 @@ public: | |
2518 | enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange }; | |
2519 | #endif // QT3_SUPPORT | |
2520 | ||
2521 | + void beginSectionOutline(const QString &text, const QString &anchor); | |
2522 | + void endSectionOutline(); | |
2523 | + | |
2524 | void setOutputFormat(OutputFormat format); | |
2525 | OutputFormat outputFormat() const; | |
2526 | ||
2527 | diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp | |
2528 | index 52ce9a7..eddbb80 100644 | |
2529 | --- a/src/gui/styles/qstyle.cpp | |
2530 | +++ b/src/gui/styles/qstyle.cpp | |
2531 | @@ -47,6 +47,7 @@ | |
2532 | #include "qpixmapcache.h" | |
2533 | #include "qstyleoption.h" | |
2534 | #include "private/qstyle_p.h" | |
2535 | +#include "private/qapplication_p.h" | |
2536 | #ifndef QT_NO_DEBUG | |
2537 | #include "qdebug.h" | |
2538 | #endif | |
2539 | @@ -2229,7 +2230,7 @@ QPalette QStyle::standardPalette() const | |
2540 | { | |
2541 | #ifdef Q_WS_X11 | |
2542 | QColor background; | |
2543 | - if (QX11Info::appDepth() > 8) | |
2544 | + if (!qt_is_gui_used || QX11Info::appDepth() > 8) | |
2545 | background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey | |
2546 | else | |
2547 | background = QColor(192, 192, 192); | |
2548 | diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp | |
2549 | index f512992..9ee9096 100644 | |
2550 | --- a/src/svg/qsvggenerator.cpp | |
2551 | +++ b/src/svg/qsvggenerator.cpp | |
2552 | @@ -103,6 +103,7 @@ public: | |
2553 | ||
2554 | afterFirstUpdate = false; | |
2555 | numGradients = 0; | |
2556 | + clip = false; | |
2557 | } | |
2558 | ||
2559 | QSize size; | |
2560 | @@ -129,6 +130,9 @@ public: | |
2561 | ||
2562 | QString currentGradientName; | |
2563 | int numGradients; | |
2564 | + QString stateString; | |
2565 | + QString oldStateString; | |
2566 | + bool clip; | |
2567 | ||
2568 | struct _attributes { | |
2569 | QString document_title; | |
2570 | @@ -141,6 +145,18 @@ public: | |
2571 | QString dashPattern, dashOffset; | |
2572 | QString fill, fillOpacity; | |
2573 | } attributes; | |
2574 | + | |
2575 | + void emitState() { | |
2576 | + if (stateString == oldStateString) return; | |
2577 | + | |
2578 | + // close old state and start a new one... | |
2579 | + if (afterFirstUpdate) | |
2580 | + *stream << "</g>\n\n"; | |
2581 | + | |
2582 | + *stream << stateString; | |
2583 | + afterFirstUpdate = true; | |
2584 | + oldStateString = stateString; | |
2585 | + } | |
2586 | }; | |
2587 | ||
2588 | static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures() | |
2589 | @@ -322,7 +338,7 @@ public: | |
2590 | } | |
2591 | ||
2592 | ||
2593 | - void qpenToSvg(const QPen &spen) | |
2594 | + void qpenToSvg(const QPen &spen, QTextStream & s) | |
2595 | { | |
2596 | QString width; | |
2597 | ||
2598 | @@ -330,7 +346,7 @@ public: | |
2599 | ||
2600 | switch (spen.style()) { | |
2601 | case Qt::NoPen: | |
2602 | - stream() << QLatin1String("stroke=\"none\" "); | |
2603 | + s << QLatin1String("stroke=\"none\" "); | |
2604 | ||
2605 | d_func()->attributes.stroke = QLatin1String("none"); | |
2606 | d_func()->attributes.strokeOpacity = QString(); | |
2607 | @@ -344,8 +360,8 @@ public: | |
2608 | d_func()->attributes.stroke = color; | |
2609 | d_func()->attributes.strokeOpacity = colorOpacity; | |
2610 | ||
2611 | - stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" "); | |
2612 | - stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" "); | |
2613 | + s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" "); | |
2614 | + s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" "); | |
2615 | } | |
2616 | break; | |
2617 | case Qt::DashLine: | |
2618 | @@ -368,10 +384,10 @@ public: | |
2619 | d_func()->attributes.dashPattern = dashPattern; | |
2620 | d_func()->attributes.dashOffset = dashOffset; | |
2621 | ||
2622 | - stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" "); | |
2623 | - stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" "); | |
2624 | - stream() << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" "); | |
2625 | - stream() << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" "); | |
2626 | + s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" "); | |
2627 | + s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" "); | |
2628 | + s << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" "); | |
2629 | + s << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" "); | |
2630 | break; | |
2631 | } | |
2632 | default: | |
2633 | @@ -380,50 +396,50 @@ public: | |
2634 | } | |
2635 | ||
2636 | if (spen.widthF() == 0) | |
2637 | - stream() <<"stroke-width=\"1\" "; | |
2638 | + s <<"stroke-width=\"1\" "; | |
2639 | else | |
2640 | - stream() <<"stroke-width=\"" << spen.widthF() << "\" "; | |
2641 | + s <<"stroke-width=\"" << spen.widthF() << "\" "; | |
2642 | ||
2643 | switch (spen.capStyle()) { | |
2644 | case Qt::FlatCap: | |
2645 | - stream() << "stroke-linecap=\"butt\" "; | |
2646 | + s << "stroke-linecap=\"butt\" "; | |
2647 | break; | |
2648 | case Qt::SquareCap: | |
2649 | - stream() << "stroke-linecap=\"square\" "; | |
2650 | + s << "stroke-linecap=\"square\" "; | |
2651 | break; | |
2652 | case Qt::RoundCap: | |
2653 | - stream() << "stroke-linecap=\"round\" "; | |
2654 | + s << "stroke-linecap=\"round\" "; | |
2655 | break; | |
2656 | default: | |
2657 | qWarning("Unhandled cap style"); | |
2658 | } | |
2659 | switch (spen.joinStyle()) { | |
2660 | case Qt::MiterJoin: | |
2661 | - stream() << "stroke-linejoin=\"miter\" " | |
2662 | + s << "stroke-linejoin=\"miter\" " | |
2663 | "stroke-miterlimit=\""<<spen.miterLimit()<<"\" "; | |
2664 | break; | |
2665 | case Qt::BevelJoin: | |
2666 | - stream() << "stroke-linejoin=\"bevel\" "; | |
2667 | + s << "stroke-linejoin=\"bevel\" "; | |
2668 | break; | |
2669 | case Qt::RoundJoin: | |
2670 | - stream() << "stroke-linejoin=\"round\" "; | |
2671 | + s << "stroke-linejoin=\"round\" "; | |
2672 | break; | |
2673 | case Qt::SvgMiterJoin: | |
2674 | - stream() << "stroke-linejoin=\"miter\" " | |
2675 | + s << "stroke-linejoin=\"miter\" " | |
2676 | "stroke-miterlimit=\""<<spen.miterLimit()<<"\" "; | |
2677 | break; | |
2678 | default: | |
2679 | qWarning("Unhandled join style"); | |
2680 | } | |
2681 | } | |
2682 | - void qbrushToSvg(const QBrush &sbrush) | |
2683 | + void qbrushToSvg(const QBrush &sbrush, QTextStream & s) | |
2684 | { | |
2685 | d_func()->brush = sbrush; | |
2686 | switch (sbrush.style()) { | |
2687 | case Qt::SolidPattern: { | |
2688 | QString color, colorOpacity; | |
2689 | translate_color(sbrush.color(), &color, &colorOpacity); | |
2690 | - stream() << "fill=\"" << color << "\" " | |
2691 | + s << "fill=\"" << color << "\" " | |
2692 | "fill-opacity=\"" | |
2693 | << colorOpacity << "\" "; | |
2694 | d_func()->attributes.fill = color; | |
2695 | @@ -434,22 +450,22 @@ public: | |
2696 | saveLinearGradientBrush(sbrush.gradient()); | |
2697 | d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName); | |
2698 | d_func()->attributes.fillOpacity = QString(); | |
2699 | - stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2700 | + s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2701 | break; | |
2702 | case Qt::RadialGradientPattern: | |
2703 | saveRadialGradientBrush(sbrush.gradient()); | |
2704 | d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName); | |
2705 | d_func()->attributes.fillOpacity = QString(); | |
2706 | - stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2707 | + s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2708 | break; | |
2709 | case Qt::ConicalGradientPattern: | |
2710 | saveConicalGradientBrush(sbrush.gradient()); | |
2711 | d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName); | |
2712 | d_func()->attributes.fillOpacity = QString(); | |
2713 | - stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2714 | + s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" "); | |
2715 | break; | |
2716 | case Qt::NoBrush: | |
2717 | - stream() << QLatin1String("fill=\"none\" "); | |
2718 | + s << QLatin1String("fill=\"none\" "); | |
2719 | d_func()->attributes.fill = QLatin1String("none"); | |
2720 | d_func()->attributes.fillOpacity = QString(); | |
2721 | return; | |
2722 | @@ -458,7 +474,7 @@ public: | |
2723 | break; | |
2724 | } | |
2725 | } | |
2726 | - void qfontToSvg(const QFont &sfont) | |
2727 | + void qfontToSvg(const QFont &sfont, QTextStream & s) | |
2728 | { | |
2729 | Q_D(QSvgPaintEngine); | |
2730 | ||
2731 | @@ -488,12 +504,23 @@ public: | |
2732 | d->attributes.font_family = d->font.family(); | |
2733 | d->attributes.font_style = d->font.italic() ? QLatin1String("italic") : QLatin1String("normal"); | |
2734 | ||
2735 | - *d->stream << "font-family=\"" << d->attributes.font_family << "\" " | |
2736 | - "font-size=\"" << d->attributes.font_size << "\" " | |
2737 | - "font-weight=\"" << d->attributes.font_weight << "\" " | |
2738 | - "font-style=\"" << d->attributes.font_style << "\" " | |
2739 | - << endl; | |
2740 | + s << "font-family=\"" << d->attributes.font_family << "\" " | |
2741 | + "font-size=\"" << d->attributes.font_size << "\" " | |
2742 | + "font-weight=\"" << d->attributes.font_weight << "\" " | |
2743 | + "font-style=\"" << d->attributes.font_style << "\" " | |
2744 | + << endl; | |
2745 | + } | |
2746 | + | |
2747 | + void setViewBoxClip(bool clip) { | |
2748 | + Q_D(QSvgPaintEngine); | |
2749 | + d->clip = clip; | |
2750 | } | |
2751 | + | |
2752 | + bool viewBoxClip() const { | |
2753 | + Q_D(const QSvgPaintEngine); | |
2754 | + return d->clip; | |
2755 | + } | |
2756 | + | |
2757 | }; | |
2758 | ||
2759 | class QSvgGeneratorPrivate | |
2760 | @@ -808,6 +835,27 @@ int QSvgGenerator::metric(QPaintDevice::PaintDeviceMetric metric) const | |
2761 | return 0; | |
2762 | } | |
2763 | ||
2764 | +/*! | |
2765 | + \property QSvgGenerator::resolution | |
2766 | + \brief do not draw objects outside the viewBox | |
2767 | + \since 4.7 | |
2768 | + | |
2769 | + When specified objects drawn compleatly outsite the viewBox | |
2770 | + are not include in the output SVG. | |
2771 | + | |
2772 | + \sa viewBox | |
2773 | +*/ | |
2774 | + | |
2775 | +bool QSvgGenerator::viewBoxClip() const { | |
2776 | + Q_D(const QSvgGenerator); | |
2777 | + return d->engine->viewBoxClip(); | |
2778 | +} | |
2779 | + | |
2780 | +void QSvgGenerator::setViewBoxClip(bool clip) { | |
2781 | + Q_D(QSvgGenerator); | |
2782 | + d->engine->setViewBoxClip(clip); | |
2783 | +} | |
2784 | + | |
2785 | /***************************************************************************** | |
2786 | * class QSvgPaintEngine | |
2787 | */ | |
2788 | @@ -908,10 +956,13 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image, | |
2789 | const QRectF &sr, | |
2790 | Qt::ImageConversionFlag flags) | |
2791 | { | |
2792 | - //Q_D(QSvgPaintEngine); | |
2793 | + Q_D(QSvgPaintEngine); | |
2794 | ||
2795 | Q_UNUSED(sr); | |
2796 | Q_UNUSED(flags); | |
2797 | + if (d->clip && !d->matrix.mapRect(r).intersects(d->viewBox)) return; | |
2798 | + d->emitState(); | |
2799 | + | |
2800 | stream() << "<image "; | |
2801 | stream() << "x=\""<<r.x()<<"\" " | |
2802 | "y=\""<<r.y()<<"\" " | |
2803 | @@ -932,53 +983,35 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image, | |
2804 | void QSvgPaintEngine::updateState(const QPaintEngineState &state) | |
2805 | { | |
2806 | Q_D(QSvgPaintEngine); | |
2807 | - QPaintEngine::DirtyFlags flags = state.state(); | |
2808 | - | |
2809 | - // always stream full gstate, which is not required, but... | |
2810 | - flags |= QPaintEngine::AllDirty; | |
2811 | - | |
2812 | - // close old state and start a new one... | |
2813 | - if (d->afterFirstUpdate) | |
2814 | - *d->stream << "</g>\n\n"; | |
2815 | - | |
2816 | - *d->stream << "<g "; | |
2817 | ||
2818 | - if (flags & QPaintEngine::DirtyBrush) { | |
2819 | - qbrushToSvg(state.brush()); | |
2820 | - } | |
2821 | - | |
2822 | - if (flags & QPaintEngine::DirtyPen) { | |
2823 | - qpenToSvg(state.pen()); | |
2824 | - } | |
2825 | - | |
2826 | - if (flags & QPaintEngine::DirtyTransform) { | |
2827 | - d->matrix = state.matrix(); | |
2828 | - *d->stream << "transform=\"matrix(" << d->matrix.m11() << ',' | |
2829 | - << d->matrix.m12() << ',' | |
2830 | - << d->matrix.m21() << ',' << d->matrix.m22() << ',' | |
2831 | - << d->matrix.dx() << ',' << d->matrix.dy() | |
2832 | - << ")\"" | |
2833 | - << endl; | |
2834 | - } | |
2835 | - | |
2836 | - if (flags & QPaintEngine::DirtyFont) { | |
2837 | - qfontToSvg(state.font()); | |
2838 | - } | |
2839 | - | |
2840 | - if (flags & QPaintEngine::DirtyOpacity) { | |
2841 | - if (!qFuzzyIsNull(state.opacity() - 1)) | |
2842 | - stream() << "opacity=\""<<state.opacity()<<"\" "; | |
2843 | - } | |
2844 | - | |
2845 | - *d->stream << '>' << endl; | |
2846 | - | |
2847 | - d->afterFirstUpdate = true; | |
2848 | + d->stateString=""; | |
2849 | + QTextStream stateStream(&d->stateString); | |
2850 | + stateStream << "<g "; | |
2851 | + qbrushToSvg(state.brush(), stateStream); | |
2852 | + qpenToSvg(state.pen(), stateStream); | |
2853 | + | |
2854 | + d->matrix = state.matrix(); | |
2855 | + stateStream << "transform=\"matrix(" << d->matrix.m11() << ',' | |
2856 | + << d->matrix.m12() << ',' | |
2857 | + << d->matrix.m21() << ',' << d->matrix.m22() << ',' | |
2858 | + << d->matrix.dx() << ',' << d->matrix.dy() | |
2859 | + << ")\"" | |
2860 | + << endl; | |
2861 | + qfontToSvg(state.font(), stateStream); | |
2862 | + | |
2863 | + if (!qFuzzyIsNull(state.opacity() - 1)) | |
2864 | + stateStream << "opacity=\""<<state.opacity()<<"\" "; | |
2865 | + | |
2866 | + stateStream << '>' << endl; | |
2867 | } | |
2868 | ||
2869 | void QSvgPaintEngine::drawPath(const QPainterPath &p) | |
2870 | { | |
2871 | Q_D(QSvgPaintEngine); | |
2872 | ||
2873 | + if (d->clip && !d->matrix.mapRect(p.boundingRect()).intersects(d->viewBox)) return; | |
2874 | + d->emitState(); | |
2875 | + | |
2876 | *d->stream << "<path vector-effect=\"" | |
2877 | << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none") | |
2878 | << "\" fill-rule=\"" | |
2879 | @@ -1024,12 +1057,15 @@ void QSvgPaintEngine::drawPolygon(const QPointF *points, int pointCount, | |
2880 | { | |
2881 | Q_ASSERT(pointCount >= 2); | |
2882 | ||
2883 | - //Q_D(QSvgPaintEngine); | |
2884 | + Q_D(QSvgPaintEngine); | |
2885 | ||
2886 | QPainterPath path(points[0]); | |
2887 | for (int i=1; i<pointCount; ++i) | |
2888 | path.lineTo(points[i]); | |
2889 | ||
2890 | + if (d->clip && !d->matrix.mapRect(path.boundingRect()).intersects(d->viewBox)) return; | |
2891 | + d->emitState(); | |
2892 | + | |
2893 | if (mode == PolylineMode) { | |
2894 | stream() << "<polyline fill=\"none\" vector-effect=\"" | |
2895 | << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none") | |
2896 | @@ -1051,6 +1087,12 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem) | |
2897 | if (d->pen.style() == Qt::NoPen) | |
2898 | return; | |
2899 | ||
2900 | + if (d->clip) { | |
2901 | + QRectF b=painter()->boundingRect( QRectF(pt, QSize()) , Qt::AlignLeft, textItem.text()); | |
2902 | + if (!d->matrix.mapRect(b).intersects(d->viewBox)) return; | |
2903 | + } | |
2904 | + d->emitState(); | |
2905 | + | |
2906 | const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); | |
2907 | QString s = QString::fromRawData(ti.chars, ti.num_chars); | |
2908 | ||
2909 | @@ -1060,7 +1102,7 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem) | |
2910 | "stroke=\"none\" " | |
2911 | "xml:space=\"preserve\" " | |
2912 | "x=\"" << pt.x() << "\" y=\"" << pt.y() << "\" "; | |
2913 | - qfontToSvg(textItem.font()); | |
2914 | + qfontToSvg(textItem.font(), *d->stream); | |
2915 | *d->stream << " >" | |
2916 | << Qt::escape(s) | |
2917 | << "</text>" | |
2918 | diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h | |
2919 | index 7981f28..2197ad8 100644 | |
2920 | --- a/src/svg/qsvggenerator.h | |
2921 | +++ b/src/svg/qsvggenerator.h | |
2922 | @@ -96,6 +96,9 @@ public: | |
2923 | ||
2924 | void setResolution(int dpi); | |
2925 | int resolution() const; | |
2926 | + | |
2927 | + void setViewBoxClip(bool clip); | |
2928 | + bool viewBoxClip() const; | |
2929 | protected: | |
2930 | QPaintEngine *paintEngine() const; | |
2931 | int metric(QPaintDevice::PaintDeviceMetric metric) const; | |
2932 | diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp | |
2933 | index 4b8000d..6d52696 100644 | |
2934 | --- a/tools/configure/configureapp.cpp | |
2935 | +++ b/tools/configure/configureapp.cpp | |
2936 | @@ -2381,9 +2381,9 @@ bool Configure::checkAvailability(const QString &part) | |
2937 | available = qmakeSpec == "win32-msvc2005" || qmakeSpec == "win32-msvc2008" || | |
2938 | qmakeSpec == "win32-msvc2010" || qmakeSpec == "win32-msvc2012" || qmakeSpec.startsWith("win32-g++"); | |
2939 | if (dictionary[ "SHARED" ] == "no") { | |
2940 | - cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl | |
2941 | - << endl; | |
2942 | - available = false; | |
2943 | + // cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl | |
2944 | + // << endl; | |
2945 | + // available = false; | |
2946 | } | |
2947 | } else if (part == "AUDIO_BACKEND") { | |
2948 | available = true; |