void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rect, const WebCore::ImageBuffer* imageBuffer) { // Skia doesn't support clipping to an image, so we create a layer. The next // time restore is invoked the layer and |imageBuffer| are combined to // create the resulting image. m_state->m_clip = rect; SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) }; canvas()->clipRect(bounds); canvas()->saveLayerAlpha(&bounds, 255, static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); // Copy off the image as |imageBuffer| may be deleted before restore is invoked. const SkBitmap* bitmap = imageBuffer->context()->platformContext()->bitmap(); if (!bitmap->pixelRef()) { // The bitmap owns it's pixels. This happens when we've allocated the // pixels in some way and assigned them directly to the bitmap (as // happens when we allocate a DIB). In this case the assignment operator // does not copy the pixels, rather the copied bitmap ends up // referencing the same pixels. As the pixels may not live as long as we // need it to, we copy the image. bitmap->copyTo(&m_state->m_imageBufferClip, SkBitmap::kARGB_8888_Config); } else { // If there is a pixel ref, we can safely use the assignment operator. m_state->m_imageBufferClip = *bitmap; } }
void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, const SkBitmap& imageBuffer) { // NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we // only look at the alpha when compositing. I'm not 100% sure this is what WebKit expects for image clipping. SkPaint paint; paint.setXfermodeMode(SkXfermode::kDstIn_Mode); m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint); }
inline static float offsetToMiddleOfGlyph(const WebCore::SimpleFontData* fontData, WebCore::Glyph glyph) { if (fontData->platformData().orientation() == WebCore::Horizontal) { WebCore::FloatRect bounds = fontData->boundsForGlyph(glyph); return bounds.x() + bounds.width() / 2; } // FIXME: Use glyph bounds once they make sense for vertical fonts. return fontData->widthForGlyph(glyph) / 2; }
static void round(SkIRect* dst, const WebCore::FloatRect& src) { dst->set(SkScalarRound(SkFloatToScalar(src.x())), SkScalarRound(SkFloatToScalar(src.y())), SkScalarRound(SkFloatToScalar((src.x() + src.width()))), SkScalarRound(SkFloatToScalar((src.y() + src.height())))); }