Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: Source/WebCore/platform/graphics/cg/PathCG.cpp

Issue 9111020: Merge 101903 - REGRESSION (r91125): Polyline tool in google docs is broken (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/963/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/ChangeLog ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
3 * 2006, 2008 Rob Buis <buis@kde.org> 3 * 2006, 2008 Rob Buis <buis@kde.org>
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 23 matching lines...) Expand all
34 #include "GraphicsContext.h" 34 #include "GraphicsContext.h"
35 #include "IntRect.h" 35 #include "IntRect.h"
36 #include "PlatformString.h" 36 #include "PlatformString.h"
37 #include "StrokeStyleApplier.h" 37 #include "StrokeStyleApplier.h"
38 #include <ApplicationServices/ApplicationServices.h> 38 #include <ApplicationServices/ApplicationServices.h>
39 #include <wtf/MathExtras.h> 39 #include <wtf/MathExtras.h>
40 #include <wtf/RetainPtr.h> 40 #include <wtf/RetainPtr.h>
41 41
42 namespace WebCore { 42 namespace WebCore {
43 43
44 // A class to provide an isEmpty test that considers a one-element path with onl y a MoveTo element
45 // to be empty. This behavior is consistent with other platforms in WebKit, and is needed to prevent
46 // incorrect (according to the spec) linecap stroking for zero length paths in S VG.
47 class PathIsEmptyOrSingleMoveTester {
48 public:
49 PathIsEmptyOrSingleMoveTester() : m_moveCount(0) { }
50
51 bool isEmpty() const
52 {
53 return m_moveCount <= 1;
54 }
55
56 static void testPathElement(void* info, const CGPathElement* element)
57 {
58 PathIsEmptyOrSingleMoveTester* tester = static_cast<PathIsEmptyOrSingleM oveTester*>(info);
59 if (element->type == kCGPathElementMoveToPoint)
60 ++tester->m_moveCount;
61 else {
62 // Any non move element implies a non-empty path; set the count to 2 to force
63 // isEmpty to return false.
64 tester->m_moveCount = 2;
65 }
66 }
67
68 private:
69 // Any non-move-to element, or more than one move-to element, will make the count >= 2.
70 unsigned m_moveCount;
71 };
72
73 // Paths with only move-to elements do not draw under any circumstances, so thei r bound should
74 // be empty. Currently, CoreGraphics returns non-empty bounds for such paths. Ra dar 10450621
75 // tracks this. This class reports paths that have only move-to elements, allowi ng the
76 // bounding box code to work around the CoreGraphics problem.
77 class PathHasOnlyMoveToTester {
78 public:
79 PathHasOnlyMoveToTester() : m_hasSeenOnlyMoveTo(true) { }
80
81 bool hasOnlyMoveTo() const
82 {
83 return m_hasSeenOnlyMoveTo;
84 }
85
86 static void testPathElement(void* info, const CGPathElement* element)
87 {
88 PathHasOnlyMoveToTester* tester = static_cast<PathHasOnlyMoveToTester*>( info);
89 if (tester->m_hasSeenOnlyMoveTo && element->type != kCGPathElementMoveTo Point)
90 tester->m_hasSeenOnlyMoveTo = false;
91 }
92
93 private:
94 bool m_hasSeenOnlyMoveTo;
95 };
96
44 static size_t putBytesNowhere(void*, const void*, size_t count) 97 static size_t putBytesNowhere(void*, const void*, size_t count)
45 { 98 {
46 return count; 99 return count;
47 } 100 }
48 101
49 static CGContextRef createScratchContext() 102 static CGContextRef createScratchContext()
50 { 103 {
51 CGDataConsumerCallbacks callbacks = { putBytesNowhere, 0 }; 104 CGDataConsumerCallbacks callbacks = { putBytesNowhere, 0 };
52 RetainPtr<CGDataConsumerRef> consumer(AdoptCF, CGDataConsumerCreate(0, &call backs)); 105 RetainPtr<CGDataConsumerRef> consumer(AdoptCF, CGDataConsumerCreate(0, &call backs));
53 CGContextRef context = CGPDFContextCreate(consumer.get(), 0, 0); 106 CGContextRef context = CGPDFContextCreate(consumer.get(), 0, 0);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 CGMutablePathRef newPath = CGPathCreateMutable(); 211 CGMutablePathRef newPath = CGPathCreateMutable();
159 CGPathAddPath(newPath, &translation, m_path); 212 CGPathAddPath(newPath, &translation, m_path);
160 CGPathRelease(m_path); 213 CGPathRelease(m_path);
161 m_path = newPath; 214 m_path = newPath;
162 } 215 }
163 216
164 FloatRect Path::boundingRect() const 217 FloatRect Path::boundingRect() const
165 { 218 {
166 // CGPathGetBoundingBox includes the path's control points, CGPathGetPathBou ndingBox 219 // CGPathGetBoundingBox includes the path's control points, CGPathGetPathBou ndingBox
167 // does not, but only exists on 10.6 and above. 220 // does not, but only exists on 10.6 and above.
221 // A bug in CoreGraphics leads to an incorrect bound on paths containing onl y move-to elements
222 // with a linecap style that is non-butt. All paths with only move-to elemen ts (regardless of
223 // linecap) are effectively empty for bounding purposes and here we make it so.
224 PathHasOnlyMoveToTester tester;
225 CGPathApply(m_path, &tester, PathHasOnlyMoveToTester::testPathElement);
226 if (tester.hasOnlyMoveTo())
227 return FloatRect(0, 0, 0, 0);
228
168 #if !defined(BUILDING_ON_LEOPARD) 229 #if !defined(BUILDING_ON_LEOPARD)
169 return CGPathGetPathBoundingBox(m_path); 230 return CGPathGetPathBoundingBox(m_path);
170 #else 231 #else
171 return CGPathGetBoundingBox(m_path); 232 return CGPathGetBoundingBox(m_path);
172 #endif 233 #endif
173 } 234 }
174 235
175 FloatRect Path::fastBoundingRect() const 236 FloatRect Path::fastBoundingRect() const
176 { 237 {
238 // A bug in CoreGraphics leads to an incorrect bound on paths containing onl y move-to elements
239 // with a linecap style that is non-butt. All paths with only move-to elemen ts (regardless of
240 // linecap) are effectively empty for bounding purposes and here we make it so.
241 PathHasOnlyMoveToTester tester;
242 CGPathApply(m_path, &tester, PathHasOnlyMoveToTester::testPathElement);
243 if (tester.hasOnlyMoveTo())
244 return FloatRect(0, 0, 0, 0);
245
177 return CGPathGetBoundingBox(m_path); 246 return CGPathGetBoundingBox(m_path);
178 } 247 }
179 248
180 FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const 249 FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
181 { 250 {
182 CGContextRef context = scratchContext(); 251 CGContextRef context = scratchContext();
183 252
184 CGContextSaveGState(context); 253 CGContextSaveGState(context);
185 CGContextBeginPath(context); 254 CGContextBeginPath(context);
186 CGContextAddPath(context, platformPath()); 255 CGContextAddPath(context, platformPath());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 314 }
246 315
247 void Path::clear() 316 void Path::clear()
248 { 317 {
249 CGPathRelease(m_path); 318 CGPathRelease(m_path);
250 m_path = CGPathCreateMutable(); 319 m_path = CGPathCreateMutable();
251 } 320 }
252 321
253 bool Path::isEmpty() const 322 bool Path::isEmpty() const
254 { 323 {
255 return CGPathIsEmpty(m_path); 324 // The SVG rendering code that uses this method relies on paths with a singl e move-to
325 // element, and nothing else, as being empty. Until that code is refactored to avoid
326 // the dependence on isEmpty, we match the behavior of other platforms.
327 // When the SVG code is refactored, we could use CGPathIsEmpty(m_path);
328 PathIsEmptyOrSingleMoveTester tester;
329 CGPathApply(m_path, &tester, PathIsEmptyOrSingleMoveTester::testPathElement) ;
330 return tester.isEmpty();
256 } 331 }
257 332
258 bool Path::hasCurrentPoint() const 333 bool Path::hasCurrentPoint() const
259 { 334 {
260 return !isEmpty(); 335 return !CGPathIsEmpty(m_path);
261 } 336 }
262 337
263 FloatPoint Path::currentPoint() const 338 FloatPoint Path::currentPoint() const
264 { 339 {
265 return CGPathGetCurrentPoint(m_path); 340 return CGPathGetCurrentPoint(m_path);
266 } 341 }
267 342
268 // MARK: - 343 // MARK: -
269 // MARK: Path Management 344 // MARK: Path Management
270 345
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 void Path::apply(void* info, PathApplierFunction function) const 379 void Path::apply(void* info, PathApplierFunction function) const
305 { 380 {
306 PathApplierInfo pinfo; 381 PathApplierInfo pinfo;
307 pinfo.info = info; 382 pinfo.info = info;
308 pinfo.function = function; 383 pinfo.function = function;
309 CGPathApply(m_path, &pinfo, CGPathApplierToPathApplier); 384 CGPathApply(m_path, &pinfo, CGPathApplierToPathApplier);
310 } 385 }
311 386
312 void Path::transform(const AffineTransform& transform) 387 void Path::transform(const AffineTransform& transform)
313 { 388 {
314 if (transform.isIdentity() || isEmpty()) 389 if (transform.isIdentity() || CGPathIsEmpty(m_path))
315 return; 390 return;
316 391
317 CGMutablePathRef path = CGPathCreateMutable(); 392 CGMutablePathRef path = CGPathCreateMutable();
318 CGAffineTransform transformCG = transform; 393 CGAffineTransform transformCG = transform;
319 CGPathAddPath(path, &transformCG, m_path); 394 CGPathAddPath(path, &transformCG, m_path);
320 CGPathRelease(m_path); 395 CGPathRelease(m_path);
321 m_path = path; 396 m_path = path;
322 } 397 }
323 398
324 } 399 }
325 400
326 #endif // USE(CG) 401 #endif // USE(CG)
OLDNEW
« no previous file with comments | « Source/WebCore/ChangeLog ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698