#include "config.h"
#include "SkiaUtils.h"
#include "ImageBuffer.h"
#include "SharedBuffer.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkMatrix.h"
#include "SkRegion.h"
namespace WebCore {
static const struct CompositOpToXfermodeMode {
uint8_t mCompositOp;
uint8_t m_xfermodeMode;
} gMapCompositOpsToXfermodeModes[] = {
{ CompositeClear, SkXfermode::kClear_Mode },
{ CompositeCopy, SkXfermode::kSrc_Mode },
{ CompositeSourceOver, SkXfermode::kSrcOver_Mode },
{ CompositeSourceIn, SkXfermode::kSrcIn_Mode },
{ CompositeSourceOut, SkXfermode::kSrcOut_Mode },
{ CompositeSourceAtop, SkXfermode::kSrcATop_Mode },
{ CompositeDestinationOver, SkXfermode::kDstOver_Mode },
{ CompositeDestinationIn, SkXfermode::kDstIn_Mode },
{ CompositeDestinationOut, SkXfermode::kDstOut_Mode },
{ CompositeDestinationAtop, SkXfermode::kDstATop_Mode },
{ CompositeXOR, SkXfermode::kXor_Mode },
{ CompositePlusDarker, SkXfermode::kDarken_Mode },
{ CompositePlusLighter, SkXfermode::kPlus_Mode }
};
SkXfermode::Mode WebCoreCompositeToSkiaComposite(CompositeOperator op)
{
const CompositOpToXfermodeMode* table = gMapCompositOpsToXfermodeModes;
for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes); i++) {
if (table[i].mCompositOp == op)
return (SkXfermode::Mode)table[i].m_xfermodeMode;
}
SkDEBUGF(("GraphicsContext::setPlatformCompositeOperation unknown CompositeOperator %d\n", op));
return SkXfermode::kSrcOver_Mode; }
static U8CPU InvScaleByte(U8CPU component, uint32_t scale)
{
SkASSERT(component == (uint8_t)component);
return (component * scale + 0x8000) >> 16;
}
SkColor SkPMColorToColor(SkPMColor pm)
{
if (!pm)
return 0;
unsigned a = SkGetPackedA32(pm);
if (!a) {
SkASSERT(false);
return 0;
}
uint32_t scale = (255 << 16) / a;
return SkColorSetARGB(a,
InvScaleByte(SkGetPackedR32(pm), scale),
InvScaleByte(SkGetPackedG32(pm), scale),
InvScaleByte(SkGetPackedB32(pm), scale));
}
Color SkPMColorToWebCoreColor(SkPMColor pm)
{
return SkPMColorToColor(pm);
}
void ClipRectToCanvas(const SkCanvas& canvas, const SkRect& srcRect, SkRect* destRect)
{
if (!canvas.getClipBounds(destRect) || !destRect->intersect(srcRect))
destRect->setEmpty();
}
bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::FillType ft)
{
SkRect bounds = originalPath->getBounds();
SkScalar fX = SkFloatToScalar(point.x());
SkScalar fY = SkFloatToScalar(point.y());
if (fX < bounds.fLeft || fX > bounds.fRight || fY < bounds.fTop || fY > bounds.fBottom)
return false;
SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBottom), -bounds.fLeft), -bounds.fTop);
if (SkScalarNearlyZero(biggestCoord))
return false;
biggestCoord = std::max(std::max(biggestCoord, fX + 1), fY + 1);
const SkScalar kMaxCoordinate = SkIntToScalar(1 << 15);
SkScalar scale = SkScalarDiv(kMaxCoordinate, biggestCoord);
SkRegion rgn;
SkRegion clip;
SkMatrix m;
SkPath scaledPath;
SkPath::FillType originalFillType = originalPath->getFillType();
originalPath->setFillType(ft);
m.setScale(scale, scale);
originalPath->transform(m, &scaledPath);
int x = static_cast<int>(floorf(0.5f + point.x() * scale));
int y = static_cast<int>(floorf(0.5f + point.y() * scale));
clip.setRect(x - 1, y - 1, x + 1, y + 1);
bool contains = rgn.setPath(scaledPath, clip);
originalPath->setFillType(originalFillType);
return contains;
}
GraphicsContext* scratchContext()
{
static ImageBuffer* scratch = ImageBuffer::create(IntSize(1, 1)).leakPtr();
return scratch->context();
}
}