180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColor.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPremultiplyARGBInline(a, r, g, b); 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPMColor SkPreMultiplyColor(SkColor c) { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPremultiplyARGBInline(SkColorGetA(c), SkColorGetR(c), 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkColorGetG(c), SkColorGetB(c)); 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkScalar ByteToScalar(U8CPU x) { 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(x <= 255); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkIntToScalar(x) / 255; 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkScalar ByteDivToScalar(int numer, U8CPU denom) { 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cast to keep the answer signed 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkIntToScalar(numer) / (int)denom; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkRGBToHSV(U8CPU r, U8CPU g, U8CPU b, SkScalar hsv[3]) { 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(hsv); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned min = SkMin32(r, SkMin32(g, b)); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned max = SkMax32(r, SkMax32(g, b)); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned delta = max - min; 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar v = ByteToScalar(max); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(v >= 0 && v <= SK_Scalar1); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == delta) { // we're a shade of gray 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[0] = 0; 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[1] = 0; 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[2] = v; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar s = ByteDivToScalar(delta, max); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(s >= 0 && s <= SK_Scalar1); 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar h; 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (r == max) { 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru h = ByteDivToScalar(g - b, delta); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (g == max) { 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru h = SkIntToScalar(2) + ByteDivToScalar(b - r, delta); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { // b == max 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru h = SkIntToScalar(4) + ByteDivToScalar(r - g, delta); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru h *= 60; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (h < 0) { 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru h += SkIntToScalar(360); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(h >= 0 && h < SkIntToScalar(360)); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[0] = h; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[1] = s; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hsv[2] = v; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U8CPU UnitScalarToByte(SkScalar x) { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (x < 0) { 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (x >= SK_Scalar1) { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 255; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkScalarToFixed(x) >> 8; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColor SkHSVToColor(U8CPU a, const SkScalar hsv[3]) { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(hsv); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU s = UnitScalarToByte(hsv[1]); 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU v = UnitScalarToByte(hsv[2]); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == s) { // shade of gray 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkColorSetARGB(a, v, v, v); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed hx = (hsv[0] < 0 || hsv[0] >= SkIntToScalar(360)) ? 0 : SkScalarToFixed(hsv[0]/60); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed f = hx & 0xFFFF; 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned v_scale = SkAlpha255To256(v); 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned p = SkAlphaMul(255 - s, v_scale); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned q = SkAlphaMul(255 - (s * f >> 16), v_scale); 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned t = SkAlphaMul(255 - (s * (SK_Fixed1 - f) >> 16), v_scale); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned r, g, b; 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)(hx >> 16) < 6); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (hx >> 16) { 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 0: r = v; g = t; b = p; break; 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 1: r = q; g = v; b = p; break; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 2: r = p; g = v; b = t; break; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 3: r = p; g = q; b = v; break; 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 4: r = t; g = p; b = v; break; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: r = v; g = p; b = q; break; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkColorSetARGB(a, r, g, b); 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 114