📄 graphicscontextcairo.cpp
字号:
const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); cairo_t* cr = m_data->cr; cairo_save(cr); cairo_push_group(cr); cairo_new_path(cr);#if PLATFORM(GTK) GdkRegion* reg = gdk_region_new(); for (unsigned i = 0; i < rectCount; i++) { GdkRectangle rect = rects[i]; gdk_region_union_with_rect(reg, &rect); } gdk_cairo_region(cr, reg); gdk_region_destroy(reg); setColor(cr, color); cairo_set_line_width(cr, 2.0f); setPlatformStrokeStyle(DottedStroke);#else int radius = (focusRingWidth() - 1) / 2; for (unsigned i = 0; i < rectCount; i++) addPath(Path::createRoundedRectangle(rects[i], FloatSize(radius, radius))); // Force the alpha to 50%. This matches what the Mac does with outline rings. Color ringColor(color.red(), color.green(), color.blue(), 127); setColor(cr, ringColor); cairo_set_line_width(cr, focusRingWidth()); setPlatformStrokeStyle(SolidStroke);#endif cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_stroke_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); cairo_fill(cr); cairo_pop_group_to_source(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_paint(cr); cairo_restore(cr);}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::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); // Convention is green for grammar, red for spelling // These need to become configurable if (grammar) cairo_set_source_rgb(cr, 0, 1, 0); else cairo_set_source_rgb(cr, 1, 0, 0);#if PLATFORM(GTK) // We ignore most of the provided constants in favour of the platform style pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);#else notImplemented();#endif cairo_restore(cr);}FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect){ FloatRect result; double x = frect.x(); double y = frect.y(); cairo_t* cr = m_data->cr; cairo_user_to_device(cr, &x, &y); x = round(x); y = round(y); cairo_device_to_user(cr, &x, &y); result.setX(static_cast<float>(x)); result.setY(static_cast<float>(y)); x = frect.width(); y = frect.height(); cairo_user_to_device_distance(cr, &x, &y); x = round(x); y = round(y); cairo_device_to_user_distance(cr, &x, &y); result.setWidth(static_cast<float>(x)); result.setHeight(static_cast<float>(y)); return result;}void GraphicsContext::translate(float x, float y){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_translate(cr, x, y); m_data->translate(x, y);}IntPoint GraphicsContext::origin(){ cairo_matrix_t matrix; cairo_t* cr = m_data->cr; cairo_get_matrix(cr, &matrix); return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));}void GraphicsContext::setPlatformFillColor(const Color& col){ // Cairo contexts can't hold separate fill and stroke colors // so we set them just before we actually fill or stroke}void GraphicsContext::setPlatformStrokeColor(const Color& col){ // Cairo contexts can't hold separate fill and stroke colors // so we set them just before we actually fill or stroke}void GraphicsContext::setPlatformStrokeThickness(float strokeThickness){ if (paintingDisabled()) return; cairo_set_line_width(m_data->cr, strokeThickness);}void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle){ static double dashPattern[] = {5.0, 5.0}; static double dotPattern[] = {1.0, 1.0}; if (paintingDisabled()) return; switch (strokeStyle) { case NoStroke: // FIXME: is it the right way to emulate NoStroke? cairo_set_line_width(m_data->cr, 0); break; case SolidStroke: cairo_set_dash(m_data->cr, 0, 0, 0); break; case DottedStroke: cairo_set_dash(m_data->cr, dotPattern, 2, 0); break; case DashedStroke: cairo_set_dash(m_data->cr, dashPattern, 2, 0); break; }}void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect){ notImplemented();}void GraphicsContext::concatCTM(const TransformationMatrix& transform){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; const cairo_matrix_t matrix = cairo_matrix_t(transform); cairo_transform(cr, &matrix); m_data->concatCTM(transform);}void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness){ if (paintingDisabled()) return; clip(rect); Path p; FloatRect r(rect); // Add outer ellipse p.addEllipse(r); // Add inner ellipse r.inflate(-thickness); p.addEllipse(r); addPath(p); cairo_t* cr = m_data->cr; cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_clip(cr); cairo_set_fill_rule(cr, savedFillRule);}void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer){ if (paintingDisabled()) return; notImplemented();}void GraphicsContext::setPlatformShadow(IntSize const&, int, Color const&){ notImplemented();}void GraphicsContext::clearPlatformShadow(){ notImplemented();}void GraphicsContext::beginTransparencyLayer(float opacity){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_push_group(cr); m_data->layers.append(opacity); m_data->beginTransparencyLayer();}void GraphicsContext::endTransparencyLayer(){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_pop_group_to_source(cr); cairo_paint_with_alpha(cr, m_data->layers.last()); m_data->layers.removeLast(); m_data->endTransparencyLayer();}void GraphicsContext::clearRect(const FloatRect& rect){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_fill(cr); cairo_restore(cr);}void GraphicsContext::strokeRect(const FloatRect& rect, float width){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); cairo_set_line_width(cr, width); strokePath(); cairo_restore(cr);}void GraphicsContext::setLineCap(LineCap lineCap){ if (paintingDisabled()) return; cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT; switch (lineCap) { case ButtCap: // no-op break; case RoundCap: cairoCap = CAIRO_LINE_CAP_ROUND; break; case SquareCap: cairoCap = CAIRO_LINE_CAP_SQUARE; break; } cairo_set_line_cap(m_data->cr, cairoCap);}void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset){ cairo_set_dash(m_data->cr, dashes.data(), dashes.size(), dashOffset);}void GraphicsContext::setLineJoin(LineJoin lineJoin){ if (paintingDisabled()) return; cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER; switch (lineJoin) { case MiterJoin: // no-op break; case RoundJoin: cairoJoin = CAIRO_LINE_JOIN_ROUND; break; case BevelJoin: cairoJoin = CAIRO_LINE_JOIN_BEVEL; break; } cairo_set_line_join(m_data->cr, cairoJoin);}void GraphicsContext::setMiterLimit(float miter){ if (paintingDisabled()) return; cairo_set_miter_limit(m_data->cr, miter);}void GraphicsContext::setAlpha(float alpha){ m_common->state.globalAlpha = alpha;}float GraphicsContext::getAlpha(){ return m_common->state.globalAlpha;}static inline cairo_operator_t toCairoOperator(CompositeOperator op){ switch (op) { case CompositeClear: return CAIRO_OPERATOR_CLEAR; case CompositeCopy: return CAIRO_OPERATOR_SOURCE; case CompositeSourceOver: return CAIRO_OPERATOR_OVER; case CompositeSourceIn: return CAIRO_OPERATOR_IN; case CompositeSourceOut: return CAIRO_OPERATOR_OUT; case CompositeSourceAtop: return CAIRO_OPERATOR_ATOP; case CompositeDestinationOver: return CAIRO_OPERATOR_DEST_OVER; case CompositeDestinationIn: return CAIRO_OPERATOR_DEST_IN; case CompositeDestinationOut: return CAIRO_OPERATOR_DEST_OUT; case CompositeDestinationAtop: return CAIRO_OPERATOR_DEST_ATOP; case CompositeXOR: return CAIRO_OPERATOR_XOR; case CompositePlusDarker: return CAIRO_OPERATOR_SATURATE; case CompositeHighlight: // There is no Cairo equivalent for CompositeHighlight. return CAIRO_OPERATOR_OVER; case CompositePlusLighter: return CAIRO_OPERATOR_ADD; default: return CAIRO_OPERATOR_SOURCE; }}void GraphicsContext::setCompositeOperation(CompositeOperator op){ if (paintingDisabled()) return; cairo_set_operator(m_data->cr, toCairoOperator(op));}void GraphicsContext::beginPath(){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_new_path(cr);}void GraphicsContext::addPath(const Path& path){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr); cairo_append_path(cr, p); cairo_path_destroy(p);}void GraphicsContext::clip(const Path& path){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr); cairo_append_path(cr, p); cairo_path_destroy(p); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); cairo_clip(cr); cairo_set_fill_rule(cr, savedFillRule); m_data->clip(path);}void GraphicsContext::clipOut(const Path& path){ if (paintingDisabled()) return;#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,4,0) cairo_t* cr = m_data->cr; double x1, y1, x2, y2; cairo_clip_extents(cr, &x1, &y1, &x2, &y2); cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1); addPath(path); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_clip(cr); cairo_set_fill_rule(cr, savedFillRule);#else notImplemented();#endif}void GraphicsContext::rotate(float radians){ if (paintingDisabled()) return; cairo_rotate(m_data->cr, radians); m_data->rotate(radians);}void GraphicsContext::scale(const FloatSize& size){ if (paintingDisabled()) return; cairo_scale(m_data->cr, size.width(), size.height()); m_data->scale(size);}void GraphicsContext::clipOut(const IntRect& r){ if (paintingDisabled()) return;#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,4,0) cairo_t* cr = m_data->cr; double x1, y1, x2, y2; cairo_clip_extents(cr, &x1, &y1, &x2, &y2); cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1); cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height()); cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_clip(cr); cairo_set_fill_rule(cr, savedFillRule);#else notImplemented();#endif}void GraphicsContext::clipOutEllipseInRect(const IntRect& r){ if (paintingDisabled()) return; Path p; p.addEllipse(r); clipOut(p);}void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color){ if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); beginPath(); addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight)); setColor(cr, color); cairo_fill(cr); cairo_restore(cr);}#if PLATFORM(GTK)void GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose){ m_data->expose = expose;}GdkEventExpose* GraphicsContext::gdkExposeEvent() const{ return m_data->expose;}GdkDrawable* GraphicsContext::gdkDrawable() const{ if (!m_data->expose) return 0; return GDK_DRAWABLE(m_data->expose->window);}#endifvoid GraphicsContext::setPlatformShouldAntialias(bool enable){ if (paintingDisabled()) return; // When true, use the default Cairo backend antialias mode (usually this // enables standard 'grayscale' antialiasing); false to explicitly disable // antialiasing. This is the same strategy as used in drawConvexPolygon(). cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);}void GraphicsContext::setImageInterpolationQuality(InterpolationQuality){}InterpolationQuality GraphicsContext::imageInterpolationQuality() const{ return InterpolationDefault;}} // namespace WebCore#endif // PLATFORM(CAIRO)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -