1 #include "SkFontHost.h" 2 #include <math.h> 3 4 // define this to use pre-compiled tables for gamma. This is slightly faster, 5 // and doesn't create any RW global memory, but means we cannot change the 6 // gamma at runtime. 7 //#define USE_PREDEFINED_GAMMA_TABLES 8 9 #ifndef USE_PREDEFINED_GAMMA_TABLES 10 // define this if you want to spew out the "C" code for the tables, given 11 // the current values for SK_BLACK_GAMMA and SK_WHITE_GAMMA. 12 #define DUMP_GAMMA_TABLESx 13 #endif 14 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #include "SkGraphics.h" 18 19 // declared here, so we can link against it elsewhere 20 void skia_set_text_gamma(float blackGamma, float whiteGamma); 21 22 #ifdef USE_PREDEFINED_GAMMA_TABLES 23 24 #include "sk_predefined_gamma.h" 25 26 void skia_set_text_gamma(float blackGamma, float whiteGamma) {} 27 28 #else // use writable globals for gamma tables 29 30 static void build_power_table(uint8_t table[], float ee) { 31 // SkDebugf("------ build_power_table %g\n", ee); 32 for (int i = 0; i < 256; i++) { 33 float x = i / 255.f; 34 // printf(" %d %g", i, x); 35 x = powf(x, ee); 36 // printf(" %g", x); 37 int xx = SkScalarRound(SkFloatToScalar(x * 255)); 38 // printf(" %d\n", xx); 39 table[i] = SkToU8(xx); 40 } 41 } 42 43 static bool gGammaIsBuilt; 44 static uint8_t gBlackGamma[256], gWhiteGamma[256]; 45 46 static float gBlackGammaCoeff = 1.4f; 47 static float gWhiteGammaCoeff = 1/1.4f; 48 49 void skia_set_text_gamma(float blackGamma, float whiteGamma) { 50 gBlackGammaCoeff = blackGamma; 51 gWhiteGammaCoeff = whiteGamma; 52 gGammaIsBuilt = false; 53 SkGraphics::SetFontCacheUsed(0); 54 build_power_table(gBlackGamma, gBlackGammaCoeff); 55 build_power_table(gWhiteGamma, gWhiteGammaCoeff); 56 } 57 58 #ifdef DUMP_GAMMA_TABLES 59 60 #include "SkString.h" 61 62 static void dump_a_table(const char name[], const uint8_t table[], 63 float gamma) { 64 SkDebugf("\n"); 65 SkDebugf("\/\/ Gamma table for %g\n", gamma); 66 SkDebugf("static const uint8_t %s[] = {\n", name); 67 for (int y = 0; y < 16; y++) { 68 SkString line, tmp; 69 for (int x = 0; x < 16; x++) { 70 tmp.printf("0x%02X, ", *table++); 71 line.append(tmp); 72 } 73 SkDebugf(" %s\n", line.c_str()); 74 } 75 SkDebugf("};\n"); 76 } 77 78 #endif 79 80 #endif 81 82 /////////////////////////////////////////////////////////////////////////////// 83 84 void SkFontHost::GetGammaTables(const uint8_t* tables[2]) { 85 #ifndef USE_PREDEFINED_GAMMA_TABLES 86 if (!gGammaIsBuilt) { 87 build_power_table(gBlackGamma, gBlackGammaCoeff); 88 build_power_table(gWhiteGamma, gWhiteGammaCoeff); 89 gGammaIsBuilt = true; 90 91 #ifdef DUMP_GAMMA_TABLES 92 dump_a_table("gBlackGamma", gBlackGamma, gBlackGammaCoeff); 93 dump_a_table("gWhiteGamma", gWhiteGamma, gWhiteGammaCoeff); 94 #endif 95 } 96 #endif 97 tables[0] = gBlackGamma; 98 tables[1] = gWhiteGamma; 99 } 100 101 // If the luminance is <= this value, then apply the black gamma table 102 #define BLACK_GAMMA_THRESHOLD 0x40 103 104 // If the luminance is >= this value, then apply the white gamma table 105 #define WHITE_GAMMA_THRESHOLD 0xC0 106 107 int SkFontHost::ComputeGammaFlag(const SkPaint& paint) { 108 if (paint.getShader() == NULL) { 109 SkColor c = paint.getColor(); 110 int r = SkColorGetR(c); 111 int g = SkColorGetG(c); 112 int b = SkColorGetB(c); 113 int luminance = (r * 2 + g * 5 + b) >> 3; 114 115 if (luminance <= BLACK_GAMMA_THRESHOLD) { 116 // printf("------ black gamma for [%d %d %d]\n", r, g, b); 117 return SkScalerContext::kGammaForBlack_Flag; 118 } 119 if (luminance >= WHITE_GAMMA_THRESHOLD) { 120 // printf("------ white gamma for [%d %d %d]\n", r, g, b); 121 return SkScalerContext::kGammaForWhite_Flag; 122 } 123 } 124 return 0; 125 } 126 127