| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2006,2007,2008, Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 | |
| 33 #include "core/platform/graphics/skia/SkiaUtils.h" | |
| 34 | |
| 35 #include "SkColorPriv.h" | |
| 36 #include "SkRegion.h" | |
| 37 #include "core/platform/graphics/GraphicsContext.h" | |
| 38 #include "core/platform/graphics/ImageBuffer.h" | |
| 39 | |
| 40 namespace WebCore { | |
| 41 | |
| 42 static const struct CompositOpToXfermodeMode { | |
| 43 uint8_t mCompositOp; | |
| 44 uint8_t m_xfermodeMode; | |
| 45 } gMapCompositOpsToXfermodeModes[] = { | |
| 46 { CompositeClear, SkXfermode::kClear_Mode }, | |
| 47 { CompositeCopy, SkXfermode::kSrc_Mode }, | |
| 48 { CompositeSourceOver, SkXfermode::kSrcOver_Mode }, | |
| 49 { CompositeSourceIn, SkXfermode::kSrcIn_Mode }, | |
| 50 { CompositeSourceOut, SkXfermode::kSrcOut_Mode }, | |
| 51 { CompositeSourceAtop, SkXfermode::kSrcATop_Mode }, | |
| 52 { CompositeDestinationOver, SkXfermode::kDstOver_Mode }, | |
| 53 { CompositeDestinationIn, SkXfermode::kDstIn_Mode }, | |
| 54 { CompositeDestinationOut, SkXfermode::kDstOut_Mode }, | |
| 55 { CompositeDestinationAtop, SkXfermode::kDstATop_Mode }, | |
| 56 { CompositeXOR, SkXfermode::kXor_Mode }, | |
| 57 { CompositePlusDarker, SkXfermode::kDarken_Mode }, | |
| 58 { CompositePlusLighter, SkXfermode::kPlus_Mode } | |
| 59 }; | |
| 60 | |
| 61 // keep this array in sync with blink::WebBlendMode enum in public/platform/WebB
lendMode.h | |
| 62 static const uint8_t gMapBlendOpsToXfermodeModes[] = { | |
| 63 SkXfermode::kClear_Mode, // blink::WebBlendModeNormal | |
| 64 SkXfermode::kMultiply_Mode, // blink::WebBlendModeMultiply | |
| 65 SkXfermode::kScreen_Mode, // blink::WebBlendModeScreen | |
| 66 SkXfermode::kOverlay_Mode, // blink::WebBlendModeOverlay | |
| 67 SkXfermode::kDarken_Mode, // blink::WebBlendModeDarken | |
| 68 SkXfermode::kLighten_Mode, // blink::WebBlendModeLighten | |
| 69 SkXfermode::kColorDodge_Mode, // blink::WebBlendModeColorDodge | |
| 70 SkXfermode::kColorBurn_Mode, // blink::WebBlendModeColorBurn | |
| 71 SkXfermode::kHardLight_Mode, // blink::WebBlendModeHardLight | |
| 72 SkXfermode::kSoftLight_Mode, // blink::WebBlendModeSoftLight | |
| 73 SkXfermode::kDifference_Mode, // blink::WebBlendModeDifference | |
| 74 SkXfermode::kExclusion_Mode, // blink::WebBlendModeExclusion | |
| 75 SkXfermode::kHue_Mode, // blink::WebBlendModeHue | |
| 76 SkXfermode::kSaturation_Mode, // blink::WebBlendModeSaturation | |
| 77 SkXfermode::kColor_Mode, // blink::WebBlendModeColor | |
| 78 SkXfermode::kLuminosity_Mode // blink::WebBlendModeLuminosity | |
| 79 }; | |
| 80 | |
| 81 PassRefPtr<SkXfermode> WebCoreCompositeToSkiaComposite(CompositeOperator op, bli
nk::WebBlendMode blendMode) | |
| 82 { | |
| 83 if (blendMode != blink::WebBlendModeNormal) { | |
| 84 if ((uint8_t)blendMode >= SK_ARRAY_COUNT(gMapBlendOpsToXfermodeModes)) { | |
| 85 SkDEBUGF(("GraphicsContext::setPlatformCompositeOperation unknown bl
ink::WebBlendMode %d\n", blendMode)); | |
| 86 return adoptRef(SkXfermode::Create(SkXfermode::kSrcOver_Mode)); | |
| 87 } | |
| 88 SkXfermode::Mode mode = (SkXfermode::Mode)gMapBlendOpsToXfermodeModes[(u
int8_t)blendMode]; | |
| 89 return adoptRef(SkXfermode::Create(mode)); | |
| 90 } | |
| 91 | |
| 92 const CompositOpToXfermodeMode* table = gMapCompositOpsToXfermodeModes; | |
| 93 | |
| 94 for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes); i++
) { | |
| 95 if (table[i].mCompositOp == op) | |
| 96 return adoptRef(SkXfermode::Create((SkXfermode::Mode)table[i].m_xfer
modeMode)); | |
| 97 } | |
| 98 | |
| 99 SkDEBUGF(("GraphicsContext::setPlatformCompositeOperation unknown CompositeO
perator %d\n", op)); | |
| 100 return adoptRef(SkXfermode::Create(SkXfermode::kSrcOver_Mode)); // fall-back | |
| 101 } | |
| 102 | |
| 103 static U8CPU InvScaleByte(U8CPU component, uint32_t scale) | |
| 104 { | |
| 105 SkASSERT(component == (uint8_t)component); | |
| 106 return (component * scale + 0x8000) >> 16; | |
| 107 } | |
| 108 | |
| 109 SkColor SkPMColorToColor(SkPMColor pm) | |
| 110 { | |
| 111 if (!pm) | |
| 112 return 0; | |
| 113 unsigned a = SkGetPackedA32(pm); | |
| 114 if (!a) { | |
| 115 // A zero alpha value when there are non-zero R, G, or B channels is an | |
| 116 // invalid premultiplied color (since all channels should have been | |
| 117 // multiplied by 0 if a=0). | |
| 118 SkASSERT(false); | |
| 119 // In production, return 0 to protect against division by zero. | |
| 120 return 0; | |
| 121 } | |
| 122 | |
| 123 uint32_t scale = (255 << 16) / a; | |
| 124 | |
| 125 return SkColorSetARGB(a, | |
| 126 InvScaleByte(SkGetPackedR32(pm), scale), | |
| 127 InvScaleByte(SkGetPackedG32(pm), scale), | |
| 128 InvScaleByte(SkGetPackedB32(pm), scale)); | |
| 129 } | |
| 130 | |
| 131 Color SkPMColorToWebCoreColor(SkPMColor pm) | |
| 132 { | |
| 133 return SkPMColorToColor(pm); | |
| 134 } | |
| 135 | |
| 136 void ClipRectToCanvas(const GraphicsContext* context, const SkRect& srcRect, SkR
ect* destRect) | |
| 137 { | |
| 138 if (!context->getClipBounds(destRect) || !destRect->intersect(srcRect)) | |
| 139 destRect->setEmpty(); | |
| 140 } | |
| 141 | |
| 142 bool SkPathContainsPoint(const SkPath& originalPath, const FloatPoint& point, Sk
Path::FillType ft) | |
| 143 { | |
| 144 SkRect bounds = originalPath.getBounds(); | |
| 145 | |
| 146 // We can immediately return false if the point is outside the bounding | |
| 147 // rect. We don't use bounds.contains() here, since it would exclude | |
| 148 // points on the right and bottom edges of the bounding rect, and we want | |
| 149 // to include them. | |
| 150 SkScalar fX = SkFloatToScalar(point.x()); | |
| 151 SkScalar fY = SkFloatToScalar(point.y()); | |
| 152 if (fX < bounds.fLeft || fX > bounds.fRight || fY < bounds.fTop || fY > boun
ds.fBottom) | |
| 153 return false; | |
| 154 | |
| 155 // Scale the path to a large size before hit testing for two reasons: | |
| 156 // 1) Skia has trouble with coordinates close to the max signed 16-bit value
s, so we scale larger paths down. | |
| 157 // TODO: when Skia is patched to work properly with large values, this wi
ll not be necessary. | |
| 158 // 2) Skia does not support analytic hit testing, so we scale paths up to do
raster hit testing with subpixel accuracy. | |
| 159 SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBo
ttom), -bounds.fLeft), -bounds.fTop); | |
| 160 if (SkScalarNearlyZero(biggestCoord)) | |
| 161 return false; | |
| 162 biggestCoord = std::max(std::max(biggestCoord, fX + 1), fY + 1); | |
| 163 | |
| 164 const SkScalar kMaxCoordinate = SkIntToScalar(1 << 15); | |
| 165 SkScalar scale = SkScalarDiv(kMaxCoordinate, biggestCoord); | |
| 166 | |
| 167 SkRegion rgn; | |
| 168 SkRegion clip; | |
| 169 SkMatrix m; | |
| 170 SkPath scaledPath(originalPath); | |
| 171 | |
| 172 scaledPath.setFillType(ft); | |
| 173 m.setScale(scale, scale); | |
| 174 scaledPath.transform(m, 0); | |
| 175 | |
| 176 int x = static_cast<int>(floorf(0.5f + point.x() * scale)); | |
| 177 int y = static_cast<int>(floorf(0.5f + point.y() * scale)); | |
| 178 clip.setRect(x - 1, y - 1, x + 1, y + 1); | |
| 179 | |
| 180 return rgn.setPath(scaledPath, clip); | |
| 181 } | |
| 182 | |
| 183 SkMatrix affineTransformToSkMatrix(const AffineTransform& source) | |
| 184 { | |
| 185 SkMatrix result; | |
| 186 | |
| 187 result.setScaleX(WebCoreDoubleToSkScalar(source.a())); | |
| 188 result.setSkewX(WebCoreDoubleToSkScalar(source.c())); | |
| 189 result.setTranslateX(WebCoreDoubleToSkScalar(source.e())); | |
| 190 | |
| 191 result.setScaleY(WebCoreDoubleToSkScalar(source.d())); | |
| 192 result.setSkewY(WebCoreDoubleToSkScalar(source.b())); | |
| 193 result.setTranslateY(WebCoreDoubleToSkScalar(source.f())); | |
| 194 | |
| 195 // FIXME: Set perspective properly. | |
| 196 result.setPerspX(0); | |
| 197 result.setPerspY(0); | |
| 198 result.set(SkMatrix::kMPersp2, SK_Scalar1); | |
| 199 | |
| 200 return result; | |
| 201 } | |
| 202 | |
| 203 } // namespace WebCore | |
| OLD | NEW |