aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkFontHost_gamma.cpp
blob: 4a7f2f7677c1b1d01f1cd2d52a3689a06a4e36a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkFontHost.h"
#include <math.h>

// define this to use pre-compiled tables for gamma. This is slightly faster,
// and doesn't create any RW global memory, but means we cannot change the
// gamma at runtime.
//#define USE_PREDEFINED_GAMMA_TABLES

#ifndef USE_PREDEFINED_GAMMA_TABLES
    // define this if you want to spew out the "C" code for the tables, given
    // the current values for SK_BLACK_GAMMA and SK_WHITE_GAMMA.
    #define DUMP_GAMMA_TABLESx
#endif

///////////////////////////////////////////////////////////////////////////////

#include "SkGraphics.h"

// declared here, so we can link against it elsewhere
void skia_set_text_gamma(float blackGamma, float whiteGamma);

#ifdef USE_PREDEFINED_GAMMA_TABLES

#include "sk_predefined_gamma.h"

void skia_set_text_gamma(float blackGamma, float whiteGamma) {}

#else   // use writable globals for gamma tables

static void build_power_table(uint8_t table[], float ee) {
//    SkDebugf("------ build_power_table %g\n", ee);
    for (int i = 0; i < 256; i++) {
        float x = i / 255.f;
        //   printf(" %d %g", i, x);
        x = powf(x, ee);
        //   printf(" %g", x);
        int xx = SkScalarRound(SkFloatToScalar(x * 255));
        //   printf(" %d\n", xx);
        table[i] = SkToU8(xx);
    }
}

static bool gGammaIsBuilt;
static uint8_t gBlackGamma[256], gWhiteGamma[256];

static float gBlackGammaCoeff = 1.4f;
static float gWhiteGammaCoeff = 1/1.4f;

void skia_set_text_gamma(float blackGamma, float whiteGamma) {
    gBlackGammaCoeff = blackGamma;
    gWhiteGammaCoeff = whiteGamma;
    gGammaIsBuilt = false;
    SkGraphics::PurgeFontCache();
    build_power_table(gBlackGamma, gBlackGammaCoeff);
    build_power_table(gWhiteGamma, gWhiteGammaCoeff);
}

#ifdef DUMP_GAMMA_TABLES

#include "SkString.h"

static void dump_a_table(const char name[], const uint8_t table[],
                         float gamma) {
    SkDebugf("\n");
    SkDebugf("\/\/ Gamma table for %g\n", gamma);
    SkDebugf("static const uint8_t %s[] = {\n", name);
    for (int y = 0; y < 16; y++) {
        SkString line, tmp;
        for (int x = 0; x < 16; x++) {
            tmp.printf("0x%02X, ", *table++);
            line.append(tmp);
        }
        SkDebugf("    %s\n", line.c_str());
    }
    SkDebugf("};\n");
}

#endif

#endif

///////////////////////////////////////////////////////////////////////////////

void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
#ifndef USE_PREDEFINED_GAMMA_TABLES
    if (!gGammaIsBuilt) {
        build_power_table(gBlackGamma, gBlackGammaCoeff);
        build_power_table(gWhiteGamma, gWhiteGammaCoeff);
        gGammaIsBuilt = true;

#ifdef DUMP_GAMMA_TABLES
        dump_a_table("gBlackGamma", gBlackGamma, gBlackGammaCoeff);
        dump_a_table("gWhiteGamma", gWhiteGamma, gWhiteGammaCoeff);
#endif
    }
#endif
    tables[0] = gBlackGamma;
    tables[1] = gWhiteGamma;
}

// If the luminance is <= this value, then apply the black gamma table
#define BLACK_GAMMA_THRESHOLD   0x40

// If the luminance is >= this value, then apply the white gamma table
#define WHITE_GAMMA_THRESHOLD   0xC0

int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
    if (paint.getShader() == NULL) {
        SkColor c = paint.getColor();
        int r = SkColorGetR(c);
        int g = SkColorGetG(c);
        int b = SkColorGetB(c);
        int luminance = (r * 2 + g * 5 + b) >> 3;
        
        if (luminance <= BLACK_GAMMA_THRESHOLD) {
        //    printf("------ black gamma for [%d %d %d]\n", r, g, b);
            return SkScalerContext::kGammaForBlack_Flag;
        }
        if (luminance >= WHITE_GAMMA_THRESHOLD) {
        //    printf("------ white gamma for [%d %d %d]\n", r, g, b);
            return SkScalerContext::kGammaForWhite_Flag;
        }
    }
    return 0;
}