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 20void skia_set_text_gamma(float blackGamma, float whiteGamma); 21 22#ifdef USE_PREDEFINED_GAMMA_TABLES 23 24#include "sk_predefined_gamma.h" 25 26void skia_set_text_gamma(float blackGamma, float whiteGamma) {} 27 28#else // use writable globals for gamma tables 29 30static 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 43static bool gGammaIsBuilt; 44static uint8_t gBlackGamma[256], gWhiteGamma[256]; 45 46static float gBlackGammaCoeff = 1.4f; 47static float gWhiteGammaCoeff = 1/1.4f; 48 49void 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 62static 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 84void 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 107int 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