Ejemplo n.º 1
0
bool SkDrawColor::setProperty(int index, SkScriptValue& value) {
    SkASSERT(value.fType == SkType_Float);
    SkScalar scalar = value.fOperand.fScalar;
    switch (index) {
        case SK_PROPERTY(alpha):
            uint8_t alpha;
        #ifdef SK_SCALAR_IS_FLOAT
            alpha = scalar == SK_Scalar1 ? 255 : SkToU8((U8CPU) (scalar * 256));
        #else
            alpha = SkToU8((scalar - (scalar >= SK_ScalarHalf)) >> 8);
        #endif
            color = SkColorSetARGB(alpha, SkColorGetR(color), 
                SkColorGetG(color), SkColorGetB(color));
            break;
        case SK_PROPERTY(blue):
            scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1);
            color = SkColorSetARGB(SkColorGetA(color), SkColorGetR(color), 
                SkColorGetG(color), SkToU8((U8CPU) scalar));
            break;
        case SK_PROPERTY(green):
            scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1);
            color = SkColorSetARGB(SkColorGetA(color), SkColorGetR(color), 
                SkToU8((U8CPU) scalar), SkColorGetB(color));
            break;
        case SK_PROPERTY(hue):
            fHue = scalar;//RGB_to_HSV(color, kGetHue);
            fDirty = true;
            break;
        case SK_PROPERTY(red):
            scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1);
            color = SkColorSetARGB(SkColorGetA(color), SkToU8((U8CPU) scalar), 
                SkColorGetG(color), SkColorGetB(color));
        break;
        case SK_PROPERTY(saturation):
            fSaturation = scalar;//RGB_to_HSV(color, kGetSaturation);
            fDirty = true;
            break;
        case SK_PROPERTY(value):
            fValue = scalar;//RGB_to_HSV(color, kGetValue);
            fDirty = true;
            break;
        default:
            SkASSERT(0);
            return false;
    }
    return true;
}
Ejemplo n.º 2
0
inline SkPMColor cubicBlend(const SkScalar c[16], SkScalar t, SkPMColor c0, SkPMColor c1, SkPMColor c2, SkPMColor c3) {
    SkScalar t2 = t * t, t3 = t2 * t;
    SkScalar cc[4];
    // FIXME:  For the fractx case, this should be refactored out of this function.
    cc[0] = c[0]  + SkScalarMul(c[1], t) + SkScalarMul(c[2], t2) + SkScalarMul(c[3], t3);
    cc[1] = c[4]  + SkScalarMul(c[5], t) + SkScalarMul(c[6], t2) + SkScalarMul(c[7], t3);
    cc[2] = c[8]  + SkScalarMul(c[9], t) + SkScalarMul(c[10], t2) + SkScalarMul(c[11], t3);
    cc[3] = c[12] + SkScalarMul(c[13], t) + SkScalarMul(c[14], t2) + SkScalarMul(c[15], t3);
    SkScalar a = SkScalarClampMax(SkScalarMul(cc[0], SkGetPackedA32(c0)) + SkScalarMul(cc[1], SkGetPackedA32(c1)) + SkScalarMul(cc[2], SkGetPackedA32(c2)) + SkScalarMul(cc[3], SkGetPackedA32(c3)), 255);
    SkScalar r = SkScalarMul(cc[0], SkGetPackedR32(c0)) + SkScalarMul(cc[1], SkGetPackedR32(c1)) + SkScalarMul(cc[2], SkGetPackedR32(c2)) + SkScalarMul(cc[3], SkGetPackedR32(c3));
    SkScalar g = SkScalarMul(cc[0], SkGetPackedG32(c0)) + SkScalarMul(cc[1], SkGetPackedG32(c1)) + SkScalarMul(cc[2], SkGetPackedG32(c2)) + SkScalarMul(cc[3], SkGetPackedG32(c3));
    SkScalar b = SkScalarMul(cc[0], SkGetPackedB32(c0)) + SkScalarMul(cc[1], SkGetPackedB32(c1)) + SkScalarMul(cc[2], SkGetPackedB32(c2)) + SkScalarMul(cc[3], SkGetPackedB32(c3));
    return SkPackARGB32(SkScalarRoundToInt(a),
                        SkScalarRoundToInt(SkScalarClampMax(r, a)),
                        SkScalarRoundToInt(SkScalarClampMax(g, a)),
                        SkScalarRoundToInt(SkScalarClampMax(b, a)));
}
Ejemplo n.º 3
0
bool SkPatchUtils::getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12],
                   const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY) {
    if (lodX < 1 || lodY < 1 || NULL == cubics || NULL == data) {
        return false;
    }

    // check for overflow in multiplication
    const int64_t lodX64 = (lodX + 1),
                   lodY64 = (lodY + 1),
                   mult64 = lodX64 * lodY64;
    if (mult64 > SK_MaxS32) {
        return false;
    }
    data->fVertexCount = SkToS32(mult64);

    // it is recommended to generate draw calls of no more than 65536 indices, so we never generate
    // more than 60000 indices. To accomplish that we resize the LOD and vertex count
    if (data->fVertexCount > 10000 || lodX > 200 || lodY > 200) {
        SkScalar weightX = static_cast<SkScalar>(lodX) / (lodX + lodY);
        SkScalar weightY = static_cast<SkScalar>(lodY) / (lodX + lodY);

        // 200 comes from the 100 * 2 which is the max value of vertices because of the limit of
        // 60000 indices ( sqrt(60000 / 6) that comes from data->fIndexCount = lodX * lodY * 6)
        lodX = static_cast<int>(weightX * 200);
        lodY = static_cast<int>(weightY * 200);
        data->fVertexCount = (lodX + 1) * (lodY + 1);
    }
    data->fIndexCount = lodX * lodY * 6;
    
    data->fPoints = SkNEW_ARRAY(SkPoint, data->fVertexCount);
    data->fIndices = SkNEW_ARRAY(uint16_t, data->fIndexCount);
    
    // if colors is not null then create array for colors
    SkPMColor colorsPM[kNumCorners];
    if (NULL != colors) {
        // premultiply colors to avoid color bleeding.
        for (int i = 0; i < kNumCorners; i++) {
            colorsPM[i] = SkPreMultiplyColor(colors[i]);
        }
        data->fColors = SkNEW_ARRAY(uint32_t, data->fVertexCount);
    }
    
    // if texture coordinates are not null then create array for them
    if (NULL != texCoords) {
        data->fTexCoords = SkNEW_ARRAY(SkPoint, data->fVertexCount);
    }
    
    SkPoint pts[kNumPtsCubic];
    SkPatchUtils::getBottomCubic(cubics, pts);
    FwDCubicEvaluator fBottom(pts);
    SkPatchUtils::getTopCubic(cubics, pts);
    FwDCubicEvaluator fTop(pts);
    SkPatchUtils::getLeftCubic(cubics, pts);
    FwDCubicEvaluator fLeft(pts);
    SkPatchUtils::getRightCubic(cubics, pts);
    FwDCubicEvaluator fRight(pts);
    
    fBottom.restart(lodX);
    fTop.restart(lodX);
    
    SkScalar u = 0.0f;
    int stride = lodY + 1;
    for (int x = 0; x <= lodX; x++) {
        SkPoint bottom = fBottom.next(), top = fTop.next();
        fLeft.restart(lodY);
        fRight.restart(lodY);
        SkScalar v = 0.f;
        for (int y = 0; y <= lodY; y++) {
            int dataIndex = x * (lodY + 1) + y;
            
            SkPoint left = fLeft.next(), right = fRight.next();
            
            SkPoint s0 = SkPoint::Make((1.0f - v) * top.x() + v * bottom.x(),
                                       (1.0f - v) * top.y() + v * bottom.y());
            SkPoint s1 = SkPoint::Make((1.0f - u) * left.x() + u * right.x(),
                                       (1.0f - u) * left.y() + u * right.y());
            SkPoint s2 = SkPoint::Make(
                                       (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].x()
                                                     + u * fTop.getCtrlPoints()[3].x())
                                       + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].x()
                                              + u * fBottom.getCtrlPoints()[3].x()),
                                       (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].y()
                                                     + u * fTop.getCtrlPoints()[3].y())
                                       + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].y()
                                              + u * fBottom.getCtrlPoints()[3].y()));
            data->fPoints[dataIndex] = s0 + s1 - s2;
            
            if (NULL != colors) {
                uint8_t a = uint8_t(bilerp(u, v,
                                   SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])),
                                   SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])),
                                   SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])),
                                   SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner]))));
                uint8_t r = uint8_t(bilerp(u, v,
                                   SkScalar(SkColorGetR(colorsPM[kTopLeft_Corner])),
                                   SkScalar(SkColorGetR(colorsPM[kTopRight_Corner])),
                                   SkScalar(SkColorGetR(colorsPM[kBottomLeft_Corner])),
                                   SkScalar(SkColorGetR(colorsPM[kBottomRight_Corner]))));
                uint8_t g = uint8_t(bilerp(u, v,
                                   SkScalar(SkColorGetG(colorsPM[kTopLeft_Corner])),
                                   SkScalar(SkColorGetG(colorsPM[kTopRight_Corner])),
                                   SkScalar(SkColorGetG(colorsPM[kBottomLeft_Corner])),
                                   SkScalar(SkColorGetG(colorsPM[kBottomRight_Corner]))));
                uint8_t b = uint8_t(bilerp(u, v,
                                   SkScalar(SkColorGetB(colorsPM[kTopLeft_Corner])),
                                   SkScalar(SkColorGetB(colorsPM[kTopRight_Corner])),
                                   SkScalar(SkColorGetB(colorsPM[kBottomLeft_Corner])),
                                   SkScalar(SkColorGetB(colorsPM[kBottomRight_Corner]))));
                data->fColors[dataIndex] = SkPackARGB32(a,r,g,b);
            }
            
            if (NULL != texCoords) {
                data->fTexCoords[dataIndex] = SkPoint::Make(
                                            bilerp(u, v, texCoords[kTopLeft_Corner].x(),
                                                   texCoords[kTopRight_Corner].x(),
                                                   texCoords[kBottomLeft_Corner].x(),
                                                   texCoords[kBottomRight_Corner].x()),
                                            bilerp(u, v, texCoords[kTopLeft_Corner].y(),
                                                   texCoords[kTopRight_Corner].y(),
                                                   texCoords[kBottomLeft_Corner].y(),
                                                   texCoords[kBottomRight_Corner].y()));
                
            }
            
            if(x < lodX && y < lodY) {
                int i = 6 * (x * lodY + y);
                data->fIndices[i] = x * stride + y;
                data->fIndices[i + 1] = x * stride + 1 + y;
                data->fIndices[i + 2] = (x + 1) * stride + 1 + y;
                data->fIndices[i + 3] = data->fIndices[i];
                data->fIndices[i + 4] = data->fIndices[i + 2];
                data->fIndices[i + 5] = (x + 1) * stride + y;
            }
            v = SkScalarClampMax(v + 1.f / lodY, 1);
        }
        u = SkScalarClampMax(u + 1.f / lodX, 1);
    }
    return true;

}