add experimental files to encapsulate device-level font settings
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 1 Mar 2012 19:21:11 +0000 (19:21 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 1 Mar 2012 19:21:11 +0000 (19:21 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@3292 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/core.gyp
include/core/SkDeviceProfile.h [new file with mode: 0644]
src/core/SkDeviceProfile.cpp [new file with mode: 0644]

index 56238eb..077d395 100644 (file)
@@ -63,6 +63,7 @@
         '../src/core/SkDebug.cpp',
         '../src/core/SkDeque.cpp',
         '../src/core/SkDevice.cpp',
+        '../src/core/SkDeviceProfile.cpp',
         '../src/core/SkDither.cpp',
         '../src/core/SkDraw.cpp',
         '../src/core/SkDrawProcs.h',
diff --git a/include/core/SkDeviceProfile.h b/include/core/SkDeviceProfile.h
new file mode 100644 (file)
index 0000000..46b9781
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkDeviceProfile_DEFINED
+#define SkDeviceProfile_DEFINED
+
+#include "SkRefCnt.h"
+
+class SkDeviceProfile : public SkRefCnt {
+public:
+    enum LCDConfig {
+        kNone_LCDConfig,   // disables LCD text rendering, uses A8 instead
+        kRGB_Horizontal_LCDConfig,
+        kBGR_Horizontal_LCDConfig,
+        kRGB_Vertical_LCDConfig,
+        kBGR_Vertical_LCDConfig,
+    };
+
+    enum FontHintLevel {
+        kNone_FontHintLevel,
+        kSlight_FontHintLevel,
+        kNormal_FontHintLevel,
+        kFull_FontHintLevel,
+        kAuto_FontHintLevel,
+    };
+
+    /**
+     *  gammaExp is typically between 1.0 and 2.2. For no gamma adjustment,
+     *  specify 1.0
+     *
+     *  contrastScale will be pinned between 0.0 and 1.0. For no contrast
+     *  adjustment, specify 0.0
+     *
+     *  @param config   Describes the LCD layout for this device. If this is set
+     *                  to kNone, then all requests for LCD text will be
+     *                  devolved to A8 antialiasing.
+     *
+     *  @param level    The hinting level to be used, IF the paint specifies
+     *                  "default". Otherwise the paint's hinting level will be
+     *                  respected.
+     */
+    static SkDeviceProfile* Create(float gammaExp,
+                                   float contrastScale,
+                                   LCDConfig,
+                                   FontHintLevel);
+
+    /**
+     *  Returns the global default profile, that is used if no global profile is
+     *  specified with SetGlobal(), or if NULL is specified to SetGlobal().
+     *  The references count is *not* incremented, and the caller should not
+     *  call unref().
+     */
+    static SkDeviceProfile* GetDefault();
+
+    /**
+     *  Return the current global profile (or the default if no global had yet
+     *  been set) and increment its reference count. The call *must* call unref()
+     *  when it is done using it.
+     */
+    static SkDeviceProfile* RefGlobal();
+
+    /**
+     *  Make the specified profile be the global value for all subsequently
+     *  instantiated devices. Does not affect any existing devices.
+     *  Increments the reference count on the profile.
+     *  Specify NULL for the "identity" profile (where there is no gamma or
+     *  contrast correction).
+     */
+    static void SetGlobal(SkDeviceProfile*);
+
+    float getFontGammaExponent() const { return fGammaExponent; }
+    float getFontContrastScale() const { return fContrastScale; }
+
+    /**
+     *  Given a luminance byte (0 for black, 0xFF for white), generate a table
+     *  that applies the gamma/contrast settings to linear coverage values.
+     */
+    void generateTableForLuminanceByte(U8CPU lumByte, uint8_t table[256]) const;
+
+private:
+    SkDeviceProfile(float gammaExp, float contrastScale, LCDConfig,
+                    FontHintLevel);
+
+    float           fGammaExponent;
+    float           fContrastScale;
+    LCDConfig       fLCDConfig;
+    FontHintLevel   fFontHintLevel;
+};
+
+#endif
+
diff --git a/src/core/SkDeviceProfile.cpp b/src/core/SkDeviceProfile.cpp
new file mode 100644 (file)
index 0000000..2c2cb88
--- /dev/null
@@ -0,0 +1,72 @@
+
+
+#include "SkDeviceProfile.h"
+
+#define DEFAULT_GAMMAEXP        2.2
+#define DEFAULT_CONTRASTSCALE   0.5
+#define DEFAULT_LCDCONFIG       SkDeviceProfile::kNone_LCDConfig
+#define DEFAULT_FONTHINTLEVEL   SkDeviceProfile::kSlight_FontHintLevel
+
+static float pin(float value, float min, float max) {
+    if (value < min) {
+        value = min;
+    } else if (value > max) {
+        value = max;
+    }
+    return value;
+}
+
+SkDeviceProfile::SkDeviceProfile(float gammaExp, float contrast,
+                                 LCDConfig config, FontHintLevel level) {
+    fGammaExponent = pin(gammaExp, 0, 10);
+    fContrastScale = pin(contrast, 0, 1);
+    fLCDConfig = config;
+    fFontHintLevel = level;
+}
+
+void SkDeviceProfile::generateTableForLuminanceByte(U8CPU lumByte,
+                                                    uint8_t table[256]) const {
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkDeviceProfile* SkDeviceProfile::Create(float gammaExp,
+                                         float contrast,
+                                         LCDConfig config,
+                                         FontHintLevel level) {
+    return SkNEW_ARGS(SkDeviceProfile, (gammaExp, contrast, config, level));
+}
+
+static SkMutex gMutex;
+static SkDeviceProfile* gDefaultProfile;
+static SkDeviceProfile* gGlobalProfile;
+
+SkDeviceProfile* SkDeviceProfile::GetDefault() {
+    SkAutoMutexAcquire amc(gMutex);
+
+    if (NULL == gDefaultProfile) {
+        gDefaultProfile = SkDeviceProfile::Create(DEFAULT_GAMMAEXP,
+                                                  DEFAULT_CONTRASTSCALE,
+                                                  DEFAULT_LCDCONFIG,
+                                                  DEFAULT_FONTHINTLEVEL);
+    }
+    return gDefaultProfile;
+}
+
+SkDeviceProfile* SkDeviceProfile::RefGlobal() {
+    SkAutoMutexAcquire amc(gMutex);
+
+    if (NULL == gGlobalProfile) {
+        gGlobalProfile = SkDeviceProfile::GetDefault();
+    }
+    gGlobalProfile->ref();
+    return gGlobalProfile;
+}
+    
+void SkDeviceProfile::SetGlobal(SkDeviceProfile* profile) {
+    SkAutoMutexAcquire amc(gMutex);
+
+    SkRefCnt_SafeAssign(gGlobalProfile, profile);
+}
+
+