bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const { if (m_path.isEmpty()) return false; if (requiresStroke && !SVGPaintServer::strokePaintServer(style(), this)) return false; BoundingRectStrokeStyleApplier strokeStyle(this, style()); return m_path.strokeContains(&strokeStyle, point); }
bool RenderSVGPath::strokeContains(const FloatPoint& point, bool requiresStroke) { if (!m_strokeAndMarkerBoundingBox.contains(point)) return false; Color fallbackColor; if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor)) return false; BoundingRectStrokeStyleApplier strokeStyle(this, style()); return m_path.strokeContains(&strokeStyle, point); }
CanvasStyle* CanvasRenderingContext2DState::style(PaintType paintType) const { switch (paintType) { case FillPaintType: return fillStyle(); case StrokePaintType: return strokeStyle(); case ImagePaintType: return nullptr; } ASSERT_NOT_REACHED(); return nullptr; }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) { if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha()) return; QPainter *p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); p->drawArc(rect, startAngle * 16, angleSpan * 16); p->setRenderHint(QPainter::Antialiasing, antiAlias); }
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) { if (paintingDisabled()) return; // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659 StrokeStyle savedStrokeStyle = strokeStyle(); setStrokeStyle(SolidStroke); IntPoint endPoint = origin + IntSize(width, 0); drawLine(origin, endPoint); setStrokeStyle(savedStrokeStyle); }
void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* points, bool shouldAntialias) { if (paintingDisabled()) return; BPoint bPoints[pointsLength]; for (size_t i = 0; i < pointsLength; i++) bPoints[i] = points[i]; m_data->m_view->FillPolygon(bPoints, pointsLength); if (strokeStyle() != NoStroke) // Stroke with low color m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle()); }
FloatRect RenderPath::strokeBoundingBox() const { if (m_path.isEmpty()) return FloatRect(); if (!m_cachedLocalStrokeBBox.isEmpty()) return m_cachedLocalStrokeBBox; m_cachedLocalStrokeBBox = objectBoundingBox(); if (style()->svgStyle()->hasStroke()) { BoundingRectStrokeStyleApplier strokeStyle(this, style()); m_cachedLocalStrokeBBox.unite(m_path.strokeBoundingRect(&strokeStyle)); } return m_cachedLocalStrokeBBox; }
// This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) return; FloatPoint p1 = point1; FloatPoint p2 = point2; QPainter *p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); adjustLineToPixelBoundaries(p1, p2, strokeThickness(), strokeStyle()); p->drawLine(p1, p2); p->setRenderHint(QPainter::Antialiasing, antiAlias); }
// This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& elipseRect) { if (paintingDisabled()) return; SkRect rect = elipseRect; SkPaint paint; platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawOval(rect, paint); platformContext()->didDrawBounded(rect, paint); if (strokeStyle() != NoStroke) { paint.reset(); platformContext()->setupPaintForStroking(&paint, &rect, 0); platformContext()->canvas()->drawOval(rect, paint); platformContext()->didDrawBounded(rect, paint); } }
pattern GraphicsContext::getHaikuStrokeStyle() { switch (strokeStyle()) { case SolidStroke: return B_SOLID_HIGH; break; case DottedStroke: return B_MIXED_COLORS; break; case DashedStroke: // FIXME: use a better dashed stroke! notImplemented(); return B_MIXED_COLORS; break; default: return B_SOLID_LOW; break; } }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) { if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha()) return; // TODO: The code below will only make round-corner boxen look nice. For an utterly shocking // implementation of round corner drawing, see RenderBoxModelObject::paintBorder(). It tries // to use one (or two) alpha mask(s) per box corner to cut off a thicker stroke and doubles // the stroke with. All this to align the arc with the box sides... m_data->view()->PushState(); float penSize = strokeThickness() / 2.0f; m_data->view()->SetPenSize(penSize); BRect bRect(rect.x(), rect.y(), rect.maxX(), rect.maxY()); if (startAngle >= 0 && startAngle < 90) { bRect.left += penSize / 2 - 0.5; bRect.top += penSize / 2 - 0.5; bRect.right -= penSize / 2 + 0.5; bRect.bottom -= penSize / 2 - 0.5; } else if (startAngle >= 90 && startAngle < 180) { bRect.left += penSize / 2 - 0.5; bRect.top += penSize / 2 - 0.5; bRect.right -= penSize / 2 - 0.5; bRect.bottom -= penSize / 2 - 0.5; } else if (startAngle >= 180 && startAngle < 270) { bRect.left += penSize / 2 - 0.5; bRect.top += penSize / 2 - 0.5; bRect.right -= penSize / 2 - 0.5; bRect.bottom -= penSize / 2 + 0.5; } else if (startAngle >= 270 && startAngle < 360) { bRect.left += penSize / 2 - 0.5; bRect.top += penSize / 2 - 0.5; bRect.right -= penSize / 2 + 0.5; bRect.bottom -= penSize / 2 + 0.5; } uint32 flags = m_data->view()->Flags(); m_data->view()->SetFlags(flags | B_SUBPIXEL_PRECISE); m_data->view()->StrokeArc(bRect, startAngle, angleSpan, getHaikuStrokeStyle()); m_data->view()->SetFlags(flags); m_data->view()->PopState(); }
// This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& elipseRect) { if (paintingDisabled()) return; SkRect rect = elipseRect; if (!isRectSkiaSafe(getCTM(), rect)) return; platformContext()->prepareForSoftwareDraw(); SkPaint paint; platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawOval(rect, paint); if (strokeStyle() != NoStroke) { paint.reset(); platformContext()->setupPaintForStroking(&paint, &rect, 0); platformContext()->canvas()->drawOval(rect, paint); } }
// This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) return; StrokeStyle penStyle = strokeStyle(); if (penStyle == NoStroke) return; SkPaint paint; SkPoint pts[2] = { (SkPoint)point1, (SkPoint)point2 }; if (!isPointSkiaSafe(getCTM(), pts[0]) || !isPointSkiaSafe(getCTM(), pts[1])) return; // We know these are vertical or horizontal lines, so the length will just // be the sum of the displacement component vectors give or take 1 - // probably worth the speed up of no square root, which also won't be exact. SkPoint disp = pts[1] - pts[0]; int length = SkScalarRound(disp.fX + disp.fY); int width = roundf( platformContext()->setupPaintForStroking(&paint, 0, length)); // "Borrowed" this comment and idea from GraphicsContextCG.cpp // For odd widths, we add in 0.5 to the appropriate x/y so that the float // arithmetic works out. For example, with a border width of 3, KHTML will // pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5. It is // always true that an even width gave us a perfect position, but an odd // width gave us a position that is off by exactly 0.5. bool isVerticalLine = pts[0].fX == pts[1].fX; if (width & 1) { // Odd. if (isVerticalLine) { pts[0].fX = pts[0].fX + SK_ScalarHalf; pts[1].fX = pts[0].fX; } else { // Horizontal line pts[0].fY = pts[0].fY + SK_ScalarHalf; pts[1].fY = pts[0].fY; } } platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint); }
// This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& rect) { if (paintingDisabled()) return; if (m_state.fillPattern || m_state.fillGradient || fillColor().alpha()) { // TODO: What's this shadow business? if (m_state.fillPattern) notImplemented(); else if (m_state.fillGradient) { BGradient* gradient = m_state.fillGradient->platformGradient(); // gradient->SetTransform(m_state.fillGradient->gradientSpaceTransform()); m_data->view()->FillEllipse(rect, *gradient); } else m_data->view()->FillEllipse(rect); } // TODO: Support gradients if (strokeStyle() != NoStroke && strokeThickness() > 0.0f && strokeColor().alpha()) m_data->view()->StrokeEllipse(rect, getHaikuStrokeStyle()); }
// Draws a filled rectangle with a stroked border. void GraphicsContext::drawRect(const IntRect& rect) { if (paintingDisabled()) return; cairo_t* cr = platformContext()->cr(); cairo_save(cr); fillRectWithColor(cr, rect, fillColor()); if (strokeStyle() != NoStroke) { setSourceRGBAFromColor(cr, strokeColor()); FloatRect r(rect); r.inflate(-.5f); cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height()); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); } cairo_restore(cr); }
FloatRect RenderPath::repaintRectInLocalCoordinates() const { if (m_path.isEmpty()) return FloatRect(); // If we already have a cached repaint rect, return that if (!m_cachedLocalRepaintRect.isEmpty()) return m_cachedLocalRepaintRect; if (!style()->svgStyle()->hasStroke()) m_cachedLocalRepaintRect = objectBoundingBox(); else { BoundingRectStrokeStyleApplier strokeStyle(this, style()); m_cachedLocalRepaintRect = m_path.strokeBoundingRect(&strokeStyle); } // Markers and filters can paint outside of the stroke path m_cachedLocalRepaintRect.unite(m_markerBounds); m_cachedLocalRepaintRect.unite(filterBoundingBoxForRenderer(this)); return m_cachedLocalRepaintRect; }
// Draws a filled rectangle with a stroked border. void GraphicsContext::drawRect(const IntRect& rect) { if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); if (fillColor().alpha()) fillRectSourceOver(cr, rect, fillColor()); if (strokeStyle() != NoStroke) { setColor(cr, strokeColor()); FloatRect r(rect); r.inflate(-.5f); cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height()); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); } cairo_restore(cr); }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) { if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f) return; CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextBeginPath(context); CGContextSetShouldAntialias(context, false); int x = rect.x(); int y = rect.y(); float w = (float)rect.width(); float h = (float)rect.height(); float scaleFactor = h / w; float reverseScaleFactor = w / h; if (w != h) scale(FloatSize(1, scaleFactor)); float hRadius = w / 2; float vRadius = h / 2; float fa = startAngle; float falen = fa + angleSpan; float start = -fa * piFloat / 180.0f; float end = -falen * piFloat / 180.0f; CGContextAddArc(context, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, start, end, true); if (w != h) scale(FloatSize(1, reverseScaleFactor)); float width = strokeThickness(); int patWidth = 0; switch (strokeStyle()) { case DottedStroke: patWidth = (int)(width / 2); break; case DashedStroke: patWidth = 3 * (int)(width / 2); break; default: break; } if (patWidth) { // Example: 80 pixels with a width of 30 pixels. // Remainder is 20. The maximum pixels of line we could paint // will be 50 pixels. int distance; if (hRadius == vRadius) distance = static_cast<int>((piFloat * hRadius) / 2.0f); else // We are elliptical and will have to estimate the distance distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f); int remainder = distance % patWidth; int coverage = distance - remainder; int numSegments = coverage / patWidth; float patternOffset = 0.0f; // Special case 1px dotted borders for speed. if (patWidth == 1) patternOffset = 1.0f; else { bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { if (remainder) { patternOffset += patWidth - remainder; patternOffset += remainder / 2.0f; } else patternOffset = patWidth / 2.0f; } else { if (remainder) patternOffset = (patWidth - remainder) / 2.0f; } } const CGFloat dottedLine[2] = { patWidth, patWidth }; CGContextSetLineDash(context, patternOffset, dottedLine, 2); } CGContextStrokePath(context); CGContextRestoreGState(context); }
// This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) return; if (strokeStyle() == NoStroke) return; float width = strokeThickness(); FloatPoint p1 = point1; FloatPoint p2 = point2; bool isVerticalLine = (p1.x() == p2.x()); // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g., // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave // us a perfect position, but an odd width gave us a position that is off by exactly 0.5. if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) { if (isVerticalLine) { p1.move(0, width); p2.move(0, -width); } else { p1.move(width, 0); p2.move(-width, 0); } } if (((int)width) % 2) { if (isVerticalLine) { // We're a vertical line. Adjust our x. p1.move(0.5f, 0.0f); p2.move(0.5f, 0.0f); } else { // We're a horizontal line. Adjust our y. p1.move(0.0f, 0.5f); p2.move(0.0f, 0.5f); } } int patWidth = 0; switch (strokeStyle()) { case NoStroke: case SolidStroke: break; case DottedStroke: patWidth = (int)width; break; case DashedStroke: patWidth = 3 * (int)width; break; } CGContextRef context = platformContext(); if (shouldAntialias()) CGContextSetShouldAntialias(context, false); if (patWidth) { CGContextSaveGState(context); // Do a rect fill of our endpoints. This ensures we always have the // appearance of being a border. We then draw the actual dotted/dashed line. setCGFillColor(context, strokeColor(), strokeColorSpace()); // The save/restore make it safe to mutate the fill color here without setting it back to the old color. if (isVerticalLine) { CGContextFillRect(context, FloatRect(p1.x() - width / 2, p1.y() - width, width, width)); CGContextFillRect(context, FloatRect(p2.x() - width / 2, p2.y(), width, width)); } else { CGContextFillRect(context, FloatRect(p1.x() - width, p1.y() - width / 2, width, width)); CGContextFillRect(context, FloatRect(p2.x(), p2.y() - width / 2, width, width)); } // Example: 80 pixels with a width of 30 pixels. // Remainder is 20. The maximum pixels of line we could paint // will be 50 pixels. int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*(int)width; int remainder = distance % patWidth; int coverage = distance - remainder; int numSegments = coverage / patWidth; float patternOffset = 0.0f; // Special case 1px dotted borders for speed. if (patWidth == 1) patternOffset = 1.0f; else { bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { if (remainder) { patternOffset += patWidth - remainder; patternOffset += remainder / 2; } else patternOffset = patWidth / 2; } else { if (remainder) patternOffset = (patWidth - remainder)/2; } } const CGFloat dottedLine[2] = { patWidth, patWidth }; CGContextSetLineDash(context, patternOffset, dottedLine, 2); } CGContextBeginPath(context); CGContextMoveToPoint(context, p1.x(), p1.y()); CGContextAddLineToPoint(context, p2.x(), p2.y()); CGContextStrokePath(context); if (patWidth) CGContextRestoreGState(context); if (shouldAntialias()) CGContextSetShouldAntialias(context, true); }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) { if (paintingDisabled() || strokeStyle() == NoStroke) return; int x = rect.x(); int y = rect.y(); float w = rect.width(); float h = rect.height(); float scaleFactor = h / w; float reverseScaleFactor = w / h; float hRadius = w / 2; float vRadius = h / 2; float fa = startAngle; float falen = fa + angleSpan; cairo_t* cr = m_data->cr; cairo_save(cr); if (w != h) cairo_scale(cr, 1., scaleFactor); cairo_arc_negative(cr, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, -fa * M_PI/180, -falen * M_PI/180); if (w != h) cairo_scale(cr, 1., reverseScaleFactor); float width = strokeThickness(); int patWidth = 0; switch (strokeStyle()) { case DottedStroke: patWidth = static_cast<int>(width / 2); break; case DashedStroke: patWidth = 3 * static_cast<int>(width / 2); break; default: break; } setColor(cr, strokeColor()); if (patWidth) { // Example: 80 pixels with a width of 30 pixels. // Remainder is 20. The maximum pixels of line we could paint // will be 50 pixels. int distance; if (hRadius == vRadius) distance = static_cast<int>((M_PI * hRadius) / 2.0); else // We are elliptical and will have to estimate the distance distance = static_cast<int>((M_PI * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0)) / 2.0); int remainder = distance % patWidth; int coverage = distance - remainder; int numSegments = coverage / patWidth; float patternOffset = 0.0; // Special case 1px dotted borders for speed. if (patWidth == 1) patternOffset = 1.0; else { bool evenNumberOfSegments = numSegments % 2 == 0; if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { if (remainder) { patternOffset += patWidth - remainder; patternOffset += remainder / 2.0; } else patternOffset = patWidth / 2.0; } else { if (remainder) patternOffset = (patWidth - remainder) / 2.0; } } double dash = patWidth; cairo_set_dash(cr, &dash, 1, patternOffset); } cairo_stroke(cr); cairo_restore(cr); }
int Context2D::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: changed((*reinterpret_cast< const QImage(*)>(_a[1]))); break; case 1: save(); break; case 2: restore(); break; case 3: scale((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break; case 4: rotate((*reinterpret_cast< qreal(*)>(_a[1]))); break; case 5: translate((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break; case 6: transform((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break; case 7: setTransform((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break; case 8: { CanvasGradient _r = createLinearGradient((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); if (_a[0]) *reinterpret_cast< CanvasGradient*>(_a[0]) = _r; } break; case 9: { CanvasGradient _r = createRadialGradient((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); if (_a[0]) *reinterpret_cast< CanvasGradient*>(_a[0]) = _r; } break; case 10: clearRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break; case 11: fillRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break; case 12: strokeRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break; case 13: beginPath(); break; case 14: closePath(); break; case 15: moveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break; case 16: lineTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break; case 17: quadraticCurveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break; case 18: bezierCurveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break; case 19: arcTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5]))); break; case 20: rect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break; case 21: arc((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< bool(*)>(_a[6]))); break; case 22: fill(); break; case 23: stroke(); break; case 24: clip(); break; case 25: { bool _r = isPointInPath((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); if (_a[0]) *reinterpret_cast< bool*>(_a[0]) = _r; } break; case 26: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3]))); break; case 27: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5]))); break; case 28: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6])),(*reinterpret_cast< qreal(*)>(_a[7])),(*reinterpret_cast< qreal(*)>(_a[8])),(*reinterpret_cast< qreal(*)>(_a[9]))); break; case 29: { ImageData _r = getImageData((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); if (_a[0]) *reinterpret_cast< ImageData*>(_a[0]) = _r; } break; case 30: putImageData((*reinterpret_cast< ImageData(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3]))); break; default: ; } _id -= 31; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< qreal*>(_v) = globalAlpha(); break; case 1: *reinterpret_cast< QString*>(_v) = globalCompositeOperation(); break; case 2: *reinterpret_cast< QVariant*>(_v) = strokeStyle(); break; case 3: *reinterpret_cast< QVariant*>(_v) = fillStyle(); break; case 4: *reinterpret_cast< qreal*>(_v) = lineWidth(); break; case 5: *reinterpret_cast< QString*>(_v) = lineCap(); break; case 6: *reinterpret_cast< QString*>(_v) = lineJoin(); break; case 7: *reinterpret_cast< qreal*>(_v) = miterLimit(); break; case 8: *reinterpret_cast< qreal*>(_v) = shadowOffsetX(); break; case 9: *reinterpret_cast< qreal*>(_v) = shadowOffsetY(); break; case 10: *reinterpret_cast< qreal*>(_v) = shadowBlur(); break; case 11: *reinterpret_cast< QString*>(_v) = shadowColor(); break; } _id -= 12; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setGlobalAlpha(*reinterpret_cast< qreal*>(_v)); break; case 1: setGlobalCompositeOperation(*reinterpret_cast< QString*>(_v)); break; case 2: setStrokeStyle(*reinterpret_cast< QVariant*>(_v)); break; case 3: setFillStyle(*reinterpret_cast< QVariant*>(_v)); break; case 4: setLineWidth(*reinterpret_cast< qreal*>(_v)); break; case 5: setLineCap(*reinterpret_cast< QString*>(_v)); break; case 6: setLineJoin(*reinterpret_cast< QString*>(_v)); break; case 7: setMiterLimit(*reinterpret_cast< qreal*>(_v)); break; case 8: setShadowOffsetX(*reinterpret_cast< qreal*>(_v)); break; case 9: setShadowOffsetY(*reinterpret_cast< qreal*>(_v)); break; case 10: setShadowBlur(*reinterpret_cast< qreal*>(_v)); break; case 11: setShadowColor(*reinterpret_cast< QString*>(_v)); break; } _id -= 12; } else if (_c == QMetaObject::ResetProperty) { _id -= 12; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 12; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 12; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 12; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 12; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 12; } #endif // QT_NO_PROPERTIES return _id; }
void GraphicsContext::setPlatformStrokeThickness(float thickness) { if (paintingDisabled()) return; if (m_data->context) m_data->context->SetPen(wxPen(strokeColor(), thickness, strokeStyleToWxPenStyle(strokeStyle()))); }
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) { if (paintingDisabled()) return; if (npoints <= 1) return; wxPoint* polygon = new wxPoint[npoints]; for (size_t i = 0; i < npoints; i++) polygon[i] = wxPoint(points[i].x(), points[i].y()); m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); m_data->context->DrawPolygon((int)npoints, polygon); delete [] polygon; }
void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) return; if (m_data->context) m_data->context->SetPen(wxPen(color, strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) { if (paintingDisabled()) return; m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); m_data->context->DrawEllipticArc(rect.x(), rect.y(), rect.width(), rect.height(), startAngle, angleSpan); }
// This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& rect) { if (paintingDisabled()) return; m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); m_data->context->DrawEllipse(rect.x(), rect.y(), rect.width(), rect.height()); }
// This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) return; FloatPoint p1 = point1; FloatPoint p2 = point2; m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); m_data->context->DrawLine(point1.x(), point1.y(), point2.x(), point2.y()); }
// This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) return; StrokeStyle style = strokeStyle(); if (style == NoStroke) return; cairo_t* cr = m_data->cr; cairo_save(cr); float width = strokeThickness(); if (width < 1) width = 1; FloatPoint p1 = point1; FloatPoint p2 = point2; bool isVerticalLine = (p1.x() == p2.x()); adjustLineToPixelBoundaries(p1, p2, width, style); cairo_set_line_width(cr, width); int patWidth = 0; switch (style) { case NoStroke: case SolidStroke: break; case DottedStroke: patWidth = static_cast<int>(width); break; case DashedStroke: patWidth = 3*static_cast<int>(width); break; } setColor(cr, strokeColor()); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); if (patWidth) { // Do a rect fill of our endpoints. This ensures we always have the // appearance of being a border. We then draw the actual dotted/dashed line. if (isVerticalLine) { fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor()); fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor()); } else { fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor()); fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor()); } // Example: 80 pixels with a width of 30 pixels. // Remainder is 20. The maximum pixels of line we could paint // will be 50 pixels. int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width); int remainder = distance%patWidth; int coverage = distance-remainder; int numSegments = coverage/patWidth; float patternOffset = 0; // Special case 1px dotted borders for speed. if (patWidth == 1) patternOffset = 1.0; else { bool evenNumberOfSegments = numSegments%2 == 0; if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { if (remainder) { patternOffset += patWidth - remainder; patternOffset += remainder/2; } else patternOffset = patWidth/2; } else if (!evenNumberOfSegments) { if (remainder) patternOffset = (patWidth - remainder)/2; } } double dash = patWidth; cairo_set_dash(cr, &dash, 1, patternOffset); } cairo_move_to(cr, p1.x(), p1.y()); cairo_line_to(cr, p2.x(), p2.y()); cairo_stroke(cr); cairo_restore(cr); }
// Draws a filled rectangle with a stroked border. void GraphicsContext::drawRect(const IntRect& rect) { if (paintingDisabled()) return; ASSERT(!rect.isEmpty()); save(); m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle()))); m_data->context->DrawRectangle(rect.x(), rect.y(), rect.width(), rect.height()); restore(); }