void Path::translate(const FloatSize& size) { m_path.offset(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height())); }
bool Path::contains(const FloatPoint& point) const { return m_path.contains(WebCoreFloatToSkScalar(point.x()), WebCoreFloatToSkScalar(point.y())); }
bool Path::strokeContains(const FloatPoint& point, const StrokeData& strokeData) const { return strokePath(strokeData) .contains(WebCoreFloatToSkScalar(point.x()), WebCoreFloatToSkScalar(point.y())); }
void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { m_path.arcTo(p1.data(), p2.data(), WebCoreFloatToSkScalar(radius)); }
SkShader* Gradient::platformGradient() { if (m_gradient) return m_gradient; sortStopsIfNecessary(); ASSERT(m_stopsSorted); size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); // FIXME: Why is all this manual pointer math needed?! SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar))); SkColor* colors = (SkColor*)storage.get(); SkScalar* pos = (SkScalar*)(colors + countUsed); fillStops(m_stops.data(), m_stops.size(), pos, colors); SkShader::TileMode tile = SkShader::kClamp_TileMode; switch (m_spreadMethod) { case SpreadMethodReflect: tile = SkShader::kMirror_TileMode; break; case SpreadMethodRepeat: tile = SkShader::kRepeat_TileMode; break; case SpreadMethodPad: tile = SkShader::kClamp_TileMode; break; } if (m_radial) { // Since the two-point radial gradient is slower than the plain radial, // only use it if we have to. if (m_p0 == m_p1 && m_r0 <= 0.0f) { // The radius we give to Skia must be positive (and non-zero). If // we're given a zero radius, just ask for a very small radius so // Skia will still return an object. SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : WebCoreFloatToSkScalar(FLT_EPSILON); m_gradient = SkGradientShader::CreateRadial(m_p1, radius, colors, pos, static_cast<int>(countUsed), tile); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile); } if (aspectRatio() != 1) { // CSS3 elliptical gradients: apply the elliptical scaling at the // gradient center point. m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); ASSERT(m_p0 == m_p1); } } else { SkPoint pts[2] = { m_p0, m_p1 }; m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile); } ASSERT(m_gradient); SkMatrix matrix = m_gradientSpaceTransformation; m_gradient->setLocalMatrix(matrix); return m_gradient; }
FloatPoint::operator SkPoint() const { SkPoint p = { WebCoreFloatToSkScalar(m_x), WebCoreFloatToSkScalar(m_y) }; return p; }
sk_sp<SkShader> Gradient::createShader() { sortStopsIfNecessary(); ASSERT(m_stopsSorted); size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); ColorStopOffsetVector pos(countUsed); ColorStopColorVector colors(countUsed); fillStops(m_stops.data(), m_stops.size(), pos, colors); SkShader::TileMode tile = SkShader::kClamp_TileMode; switch (m_spreadMethod) { case SpreadMethodReflect: tile = SkShader::kMirror_TileMode; break; case SpreadMethodRepeat: tile = SkShader::kRepeat_TileMode; break; case SpreadMethodPad: tile = SkShader::kClamp_TileMode; break; } sk_sp<SkShader> shader; uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0; if (m_radial) { if (aspectRatio() != 1) { // CSS3 elliptical gradients: apply the elliptical scaling at the // gradient center point. m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); ASSERT(m_p0 == m_p1); } SkMatrix localMatrix = affineTransformToSkMatrix(m_gradientSpaceTransformation); // Since the two-point radial gradient is slower than the plain radial, // only use it if we have to. if (m_p0 == m_p1 && m_r0 <= 0.0f) { shader = SkGradientShader::MakeRadial(m_p1.data(), m_r1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; shader = SkGradientShader::MakeTwoPointConical(m_p0.data(), radius0, m_p1.data(), radius1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix); } } else { SkPoint pts[2] = { m_p0.data(), m_p1.data() }; SkMatrix localMatrix = affineTransformToSkMatrix(m_gradientSpaceTransformation); shader = SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix); } if (!shader) { // use last color, since our "geometry" was degenerate (e.g. radius==0) shader = SkShader::MakeColorShader(colors[countUsed - 1]); } return shader; }
void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& pt, float width, DocumentMarkerLineStyle style) { if (paintingDisabled()) return; // Create the pattern we'll use to draw the underline. int index = style == DocumentMarkerGrammarLineStyle ? 1 : 0; static SkBitmap* misspellBitmap[2] = { 0, 0 }; if (!misspellBitmap[index]) { #if PLATFORM(CHROMIUM) && OS(DARWIN) // Match the artwork used by the Mac. const int rowPixels = 4; const int colPixels = 3; #else // 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; #endif misspellBitmap[index] = new SkBitmap; misspellBitmap[index]->setConfig(SkBitmap::kARGB_8888_Config, rowPixels, colPixels); misspellBitmap[index]->allocPixels(); misspellBitmap[index]->eraseARGB(0, 0, 0, 0); #if PLATFORM(CHROMIUM) && OS(DARWIN) const uint32_t colors[2][6] = { { 0x2A2A0600, 0x57571000, 0xA8A81B00, 0xBFBF1F00, 0x70701200, 0xE0E02400 }, { 0x2A001503, 0x57002A08, 0xA800540D, 0xBF005F0F, 0x70003809, 0xE0007012 } }; const uint32_t transparentColor = 0x00000000; // Pattern: a b a a b a // c d c c d c // e f e e f e for (int x = 0; x < colPixels; ++x) { uint32_t* row = misspellBitmap[index]->getAddr32(0, x); row[0] = colors[index][x * 2]; row[1] = colors[index][x * 2 + 1]; row[2] = colors[index][x * 2]; row[3] = transparentColor; } #else static const uint32_t lineColors[2] = { 0xFF << SK_A32_SHIFT | 0xFF << SK_R32_SHIFT, // Opaque red. 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Opaque gray. }; static const uint32_t antiColors[2] = { 0x60 << SK_A32_SHIFT | 0x60 << SK_R32_SHIFT, // Semitransparent red 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Semitransparent gray }; const uint32_t lineColor = lineColors[index]; const uint32_t antiColor = antiColors[index]; // Pattern: X o o X o o X // o X o o X o uint32_t* row1 = misspellBitmap[index]->getAddr32(0, 0); uint32_t* row2 = misspellBitmap[index]->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; } } #endif } SkScalar originX = WebCoreFloatToSkScalar(pt.x()); #if PLATFORM(CHROMIUM) && OS(DARWIN) SkScalar originY = WebCoreFloatToSkScalar(pt.y()); // Make sure to draw only complete dots. int rowPixels = misspellBitmap[index]->width(); float widthMod = fmodf(width, rowPixels); if (rowPixels - widthMod > 1) width -= widthMod; #else // Offset it vertically by 1 so that there's some space under the text. SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1; #endif // 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[index], 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 + WebCoreFloatToSkScalar(width), originY + SkIntToScalar(misspellBitmap[index]->height())); platformContext()->canvas()->drawRect(rect, paint); platformContext()->didDrawRect(rect, paint); }
void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { ensurePlatformPath()->arcTo(p1, p2, WebCoreFloatToSkScalar(radius)); }
void Path::translate(const FloatSize& size) { ensurePlatformPath()->offset(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height())); }
SkShader* Gradient::shader() { if (m_gradient) return m_gradient.get(); sortStopsIfNecessary(); ASSERT(m_stopsSorted); size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); // FIXME: Why is all this manual pointer math needed?! SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar))); SkColor* colors = (SkColor*)storage.get(); SkScalar* pos = (SkScalar*)(colors + countUsed); fillStops(m_stops.data(), m_stops.size(), pos, colors); SkShader::TileMode tile = SkShader::kClamp_TileMode; switch (m_spreadMethod) { case SpreadMethodReflect: tile = SkShader::kMirror_TileMode; break; case SpreadMethodRepeat: tile = SkShader::kRepeat_TileMode; break; case SpreadMethodPad: tile = SkShader::kClamp_TileMode; break; } uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0; if (m_radial) { // Since the two-point radial gradient is slower than the plain radial, // only use it if we have to. if (m_p0 == m_p1 && m_r0 <= 0.0f) { m_gradient = adoptRef(SkGradientShader::CreateRadial(m_p1, m_r1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace)); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = adoptRef(SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace)); } if (aspectRatio() != 1) { // CSS3 elliptical gradients: apply the elliptical scaling at the // gradient center point. m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); ASSERT(m_p0 == m_p1); } } else { SkPoint pts[2] = { m_p0, m_p1 }; m_gradient = adoptRef(SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace)); } if (!m_gradient) { // use last color, since our "geometry" was degenerate (e.g. radius==0) m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1])); } else { m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTransformation)); } return m_gradient.get(); }
SkPoint FloatPoint::data() const { SkPoint p = { WebCoreFloatToSkScalar(m_x), WebCoreFloatToSkScalar(m_y) }; return p; }
SkShader* Gradient::platformGradient() { if (m_gradient) return m_gradient; // FIXME: This and compareStops() are also in Gradient.cpp and // CSSGradientValue.cpp; probably should refactor in WebKit. if (!m_stopsSorted) { if (m_stops.size()) std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); m_stopsSorted = true; } size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); // FIXME: Why is all this manual pointer math needed?! SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar))); SkColor* colors = (SkColor*)storage.get(); SkScalar* pos = (SkScalar*)(colors + countUsed); fillStops(m_stops.data(), m_stops.size(), pos, colors); SkShader::TileMode tile = SkShader::kClamp_TileMode; switch (m_spreadMethod) { case SpreadMethodReflect: tile = SkShader::kMirror_TileMode; break; case SpreadMethodRepeat: tile = SkShader::kRepeat_TileMode; break; case SpreadMethodPad: tile = SkShader::kClamp_TileMode; break; } if (m_radial) { // Since the two-point radial gradient is slower than the plain radial, // only use it if we have to. if (m_p0 == m_p1 && m_r0 <= 0.0f) { // The radius we give to Skia must be positive (and non-zero). If // we're given a zero radius, just ask for a very small radius so // Skia will still return an object. SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : SK_ScalarMin; m_gradient = SkGradientShader::CreateRadial(m_p1, radius, colors, pos, static_cast<int>(countUsed), tile); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile); } } else { SkPoint pts[2] = { m_p0, m_p1 }; m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile); } ASSERT(m_gradient); SkMatrix matrix = m_gradientSpaceTransformation; m_gradient->setLocalMatrix(matrix); return m_gradient; }