1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrSwizzle_DEFINED 9 #define GrSwizzle_DEFINED 10 11 #include "GrColor.h" 12 #include "SkColorData.h" 13 14 /** Represents a rgba swizzle. It can be converted either into a string or a eight bit int. 15 Currently there is no way to specify an arbitrary swizzle, just some static swizzles and an 16 assignment operator. That could be relaxed. */ 17 class GrSwizzle { 18 public: GrSwizzle()19 constexpr GrSwizzle() : GrSwizzle("rgba") {} 20 GrSwizzle(const GrSwizzle & that)21 constexpr GrSwizzle(const GrSwizzle& that) 22 : fSwiz{that.fSwiz[0], that.fSwiz[1], that.fSwiz[2], that.fSwiz[3], '\0'} 23 , fKey(that.fKey) {} 24 25 constexpr GrSwizzle& operator=(const GrSwizzle& that) { 26 fSwiz[0] = that.fSwiz[0]; 27 fSwiz[1] = that.fSwiz[1]; 28 fSwiz[2] = that.fSwiz[2]; 29 fSwiz[3] = that.fSwiz[3]; 30 SkASSERT(fSwiz[4] == '\0'); 31 fKey = that.fKey; 32 return *this; 33 } 34 35 /** Recreates a GrSwizzle from the output of asKey() */ setFromKey(uint8_t key)36 constexpr void setFromKey(uint8_t key) { 37 fKey = key; 38 for (int i = 0; i < 4; ++i) { 39 fSwiz[i] = IToC(key & 3); 40 key >>= 2; 41 } 42 SkASSERT(fSwiz[4] == 0); 43 } 44 45 constexpr bool operator==(const GrSwizzle& that) const { return fKey == that.fKey; } 46 constexpr bool operator!=(const GrSwizzle& that) const { return !(*this == that); } 47 48 /** Compact representation of the swizzle suitable for a key. */ asKey()49 constexpr uint8_t asKey() const { return fKey; } 50 51 /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */ c_str()52 const char* c_str() const { return fSwiz; } 53 54 char operator[](int i) const { 55 SkASSERT(i >= 0 && i < 4); 56 return fSwiz[i]; 57 } 58 59 /** Applies this swizzle to the input color and returns the swizzled color. */ applyTo(const SkPMColor4f & color)60 SkPMColor4f applyTo(const SkPMColor4f& color) const { 61 int idx; 62 uint32_t key = fKey; 63 // Index of the input color that should be mapped to output r. 64 idx = (key & 3); 65 float outR = color[idx]; 66 key >>= 2; 67 idx = (key & 3); 68 float outG = color[idx]; 69 key >>= 2; 70 idx = (key & 3); 71 float outB = color[idx]; 72 key >>= 2; 73 idx = (key & 3); 74 float outA = color[idx]; 75 return { outR, outG, outB, outA }; 76 } 77 RGBA()78 static constexpr GrSwizzle RGBA() { return GrSwizzle("rgba"); } AAAA()79 static constexpr GrSwizzle AAAA() { return GrSwizzle("aaaa"); } RRRR()80 static constexpr GrSwizzle RRRR() { return GrSwizzle("rrrr"); } RRRA()81 static constexpr GrSwizzle RRRA() { return GrSwizzle("rrra"); } BGRA()82 static constexpr GrSwizzle BGRA() { return GrSwizzle("bgra"); } RGRG()83 static constexpr GrSwizzle RGRG() { return GrSwizzle("rgrg"); } 84 85 private: 86 char fSwiz[5]; 87 uint8_t fKey; 88 CToI(char c)89 static constexpr int CToI(char c) { 90 switch (c) { 91 case 'r': return (GrColor_SHIFT_R / 8); 92 case 'g': return (GrColor_SHIFT_G / 8); 93 case 'b': return (GrColor_SHIFT_B / 8); 94 case 'a': return (GrColor_SHIFT_A / 8); 95 default: return -1; 96 } 97 } 98 IToC(int idx)99 static constexpr char IToC(int idx) { 100 switch (8 * idx) { 101 case GrColor_SHIFT_R : return 'r'; 102 case GrColor_SHIFT_G : return 'g'; 103 case GrColor_SHIFT_B : return 'b'; 104 case GrColor_SHIFT_A : return 'a'; 105 default: return -1; 106 } 107 } 108 GrSwizzle(const char c[4])109 constexpr GrSwizzle(const char c[4]) 110 : fSwiz{c[0], c[1], c[2], c[3], '\0'} 111 , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 2) | (CToI(c[2]) << 4) | (CToI(c[3]) << 6)) {} 112 }; 113 114 #endif 115