void GraphicsContext::restorePlatformState() { if (paintingDisabled()) return; platformContext()->restore(); }
void GraphicsContext::fillRect(const FloatRect& rect, Gradient& gradient) { if (paintingDisabled()) return; gradient.fill(this, rect); }
void GraphicsContext::fillRect(const FloatRect& rect, Generator& generator) { if (paintingDisabled()) return; generator.fill(this, rect); }
void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) return; notImplemented(); }
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color) { if (paintingDisabled()) return; unsigned rectCount = rects.size(); cairo_t* cr = platformContext()->cr(); cairo_save(cr); cairo_push_group(cr); cairo_new_path(cr); #if PLATFORM(GTK) #ifdef GTK_API_VERSION_2 GdkRegion* reg = gdk_region_new(); #else cairo_region_t* reg = cairo_region_create(); #endif for (unsigned i = 0; i < rectCount; i++) { #ifdef GTK_API_VERSION_2 GdkRectangle rect = rects[i]; gdk_region_union_with_rect(reg, &rect); #else cairo_rectangle_int_t rect = rects[i]; cairo_region_union_rectangle(reg, &rect); #endif } gdk_cairo_region(cr, reg); #ifdef GTK_API_VERSION_2 gdk_region_destroy(reg); #else cairo_region_destroy(reg); #endif #else int radius = (width - 1) / 2; Path path; for (unsigned i = 0; i < rectCount; ++i) { if (i > 0) path.clear(); path.addRoundedRect(rects[i], FloatSize(radius, radius)); appendWebCorePathToCairoContext(cr, path); } #endif Color ringColor = color; adjustFocusRingColor(ringColor); adjustFocusRingLineWidth(width); setSourceRGBAFromColor(cr, ringColor); cairo_set_line_width(cr, width); setPlatformStrokeStyle(focusRingStrokeStyle()); 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::setAlpha(float alpha) { if (paintingDisabled()) return; platformContext()->setAlpha(alpha); }
void GraphicsContext::setMiterLimit(float limit) { if (paintingDisabled()) return; platformContext()->setMiterLimit(limit); }
void GraphicsContext::scale(const FloatSize& size) { if (paintingDisabled()) return; platformContext()->scale(size); }
void GraphicsContext::rotate(float angleInRadians) { if (paintingDisabled()) return; platformContext()->rotate(angleInRadians); }
void GraphicsContext::setLineCap(LineCap cap) { if (paintingDisabled()) return; platformContext()->setLineCap(cap); }
void GraphicsContext::setLineJoin(LineJoin join) { if (paintingDisabled()) return; platformContext()->setLineJoin(join); }
void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op) { if (paintingDisabled()) return; platformContext()->setCompositeOperation(op); }
void GraphicsContext::setPlatformStrokeStyle(StrokeStyle style) { if (paintingDisabled()) return; platformContext()->setStrokeStyle(style); }
void GraphicsContext::setPlatformStrokeThickness(float f) { if (paintingDisabled()) return; platformContext()->setStrokeThickness(f); }
void GraphicsContext::concatCTM(const AffineTransform& affine) { if (paintingDisabled()) return; platformContext()->canvas()->concat(affine); }
void GraphicsContext::setPlatformShouldAntialias(bool useAA) { if (paintingDisabled()) return; platformContext()->setShouldAntialias(useAA); }
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt, int width, bool grammar) { if (paintingDisabled()) return; // Create the pattern we'll use to draw the underline. static SkBitmap* misspellBitmap = 0; if (!misspellBitmap) { // We use a 2-pixel-high misspelling indicator because that seems to be // what WebKit is designed for, and how much room there is in a typical // page for it. const int rowPixels = 32; // Must be multiple of 4 for pattern below. const int colPixels = 2; misspellBitmap = new SkBitmap; misspellBitmap->setConfig(SkBitmap::kARGB_8888_Config, rowPixels, colPixels); misspellBitmap->allocPixels(); misspellBitmap->eraseARGB(0, 0, 0, 0); const uint32_t lineColor = 0xFFFF0000; // Opaque red. const uint32_t antiColor = 0x60600000; // Semitransparent red. // Pattern: X o o X o o X // o X o o X o uint32_t* row1 = misspellBitmap->getAddr32(0, 0); uint32_t* row2 = misspellBitmap->getAddr32(0, 1); for (int x = 0; x < rowPixels; x++) { switch (x % 4) { case 0: row1[x] = lineColor; break; case 1: row1[x] = antiColor; row2[x] = antiColor; break; case 2: row2[x] = lineColor; break; case 3: row1[x] = antiColor; row2[x] = antiColor; break; } } } // Offset it vertically by 1 so that there's some space under the text. SkScalar originX = SkIntToScalar(pt.x()); SkScalar originY = SkIntToScalar(pt.y()) + 1; // Make a shader for the bitmap with an origin of the box we'll draw. This // shader is refcounted and will have an initial refcount of 1. SkShader* shader = SkShader::CreateBitmapShader( *misspellBitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix matrix; matrix.reset(); matrix.postTranslate(originX, originY); shader->setLocalMatrix(matrix); // Assign the shader to the paint & release our reference. The paint will // now own the shader and the shader will be destroyed when the paint goes // out of scope. SkPaint paint; paint.setShader(shader); shader->unref(); SkRect rect; rect.set(originX, originY, originX + SkIntToScalar(width), originY + SkIntToScalar(misspellBitmap->height())); platformContext()->canvas()->drawRect(rect, paint); }
float GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const FloatPoint& point, Font::CustomFontNotReadyAction customFontNotReadyAction, BidiStatus* status, int length) #endif { if (paintingDisabled()) #if !PLATFORM(IOS) return; #else return 0; #endif BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; #if !PLATFORM(IOS) bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride())); #else bidiResolver.setStatus(status ? *status : BidiStatus(run.direction(), run.directionalOverride())); #endif bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0)); // FIXME: This ownership should be reversed. We should pass BidiRunList // to BidiResolver in createBidiRunsForLine. BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs(); #if !PLATFORM(IOS) bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length())); #else bidiResolver.createBidiRunsForLine(TextRunIterator(&run, length < 0 ? run.length() : length)); #endif if (!bidiRuns.runCount()) #if !PLATFORM(IOS) return; #else return 0; #endif FloatPoint currPoint = point; BidiCharacterRun* bidiRun = bidiRuns.firstRun(); while (bidiRun) { TextRun subrun = run.subRun(bidiRun->start(), bidiRun->stop() - bidiRun->start()); bool isRTL = bidiRun->level() % 2; subrun.setDirection(isRTL ? RTL : LTR); subrun.setDirectionalOverride(bidiRun->dirOverride(false)); #if !PLATFORM(IOS) font.drawText(this, subrun, currPoint, 0, -1, customFontNotReadyAction); bidiRun = bidiRun->next(); // FIXME: Have Font::drawText return the width of what it drew so that we don't have to re-measure here. if (bidiRun) currPoint.move(font.width(subrun), 0); #else float width = font.drawText(this, subrun, currPoint, 0, -1, customFontNotReadyAction); currPoint.move(width, 0); bidiRun = bidiRun->next(); #endif } #if PLATFORM(IOS) if (status) *status = bidiResolver.status(); #endif bidiRuns.deleteRuns(); #if PLATFORM(IOS) return currPoint.x() - static_cast<float>(point.x()); #endif }
void GraphicsContext::setCompositeOperation(CompositeOperator op) { if (paintingDisabled()) return; platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op)); }
PlatformGraphicsContext* GraphicsContext::platformContext() const { ASSERT(!paintingDisabled()); return m_data->context(); }
void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) return; platformContext()->setFillColor(color.rgb()); }
void GraphicsContext::endTransparencyLayer() { if (paintingDisabled()) return; platformContext()->canvas()->restore(); }
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar) { if (paintingDisabled()) return; // These are the same for misspelling or bad grammar const int patternHeight = 3; // 3 rows ASSERT(cMisspellingLineThickness == patternHeight); const int patternWidth = 4; // 4 pixels ASSERT(patternWidth == cMisspellingLinePatternWidth); // Make sure to draw only complete dots. // NOTE: Code here used to shift the underline to the left and increase the width // to make sure everything gets underlined, but that results in drawing out of // bounds (e.g. when at the edge of a view) and could make it appear that the // space between adjacent misspelled words was underlined. // allow slightly more considering that the pattern ends with a transparent pixel int widthMod = width % patternWidth; if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; // Draw the underline CGContextRef context = platformContext(); CGContextSaveGState(context); const Color& patternColor = grammar ? grammarPatternColor() : spellingPatternColor(); setCGStrokeColor(context, patternColor); wkSetPatternPhaseInUserSpace(context, point); CGContextSetBlendMode(context, kCGBlendModeNormal); // 3 rows, each offset by half a pixel for blending purposes const CGPoint upperPoints [] = {{point.x(), point.y() + patternHeight - 2.5 }, {point.x() + width, point.y() + patternHeight - 2.5}}; const CGPoint middlePoints [] = {{point.x(), point.y() + patternHeight - 1.5 }, {point.x() + width, point.y() + patternHeight - 1.5}}; const CGPoint lowerPoints [] = {{point.x(), point.y() + patternHeight - 0.5 }, {point.x() + width, point.y() + patternHeight - 0.5 }}; // Dash lengths for the top and bottom of the error underline are the same. // These are magic. static const float edge_dash_lengths[] = {2.0f, 2.0f}; static const float middle_dash_lengths[] = {2.76f, 1.24f}; static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f; static const float middle_offset = -(middle_dash_lengths[1] - 1.0f) / 2.0f; // Line opacities. Once again, these are magic. const float upperOpacity = 0.33f; const float middleOpacity = 0.75f; const float lowerOpacity = 0.88f; //Top line CGContextSetLineDash(context, edge_offset, edge_dash_lengths, sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0])); CGContextSetAlpha(context, upperOpacity); CGContextStrokeLineSegments(context, upperPoints, 2); // Middle line CGContextSetLineDash(context, middle_offset, middle_dash_lengths, sizeof(middle_dash_lengths) / sizeof(middle_dash_lengths[0])); CGContextSetAlpha(context, middleOpacity); CGContextStrokeLineSegments(context, middlePoints, 2); // Bottom line CGContextSetLineDash(context, edge_offset, edge_dash_lengths, sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0])); CGContextSetAlpha(context, lowerOpacity); CGContextStrokeLineSegments(context, lowerPoints, 2); CGContextRestoreGState(context); }
void GraphicsContext::addPath(const Path& path) { if (paintingDisabled()) return; platformContext()->addPath(*path.platformPath()); }
void GraphicsContext::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& rect) { if (paintingDisabled()) return; buffer.clip(*this, rect); }
void GraphicsContext::beginPath() { if (paintingDisabled()) return; platformContext()->beginPath(); }
void GraphicsContext::addFocusRingRect(const IntRect& rect) { if (paintingDisabled() || rect.isEmpty()) return; m_common->m_focusRingRects.append(rect); }
void GraphicsContext::clearPlatformShadow() { if (paintingDisabled()) return; platformContext()->setDrawLooper(0); }
void GraphicsContext::fillRect(const FloatRect& rect) { if (paintingDisabled()) return; }
void GraphicsContext::savePlatformState() { if (paintingDisabled()) return; platformContext()->save(); }