aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-22 19:25:14 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-22 19:25:14 +0000
commit532470f34dbe9fc0b8b71e3917eca8894feaf336 (patch)
tree32189d576d8183776ac6ace8cdebce1d55600bb3 /src/core
parentda7cb287682a1bcc1c2703fdf75a4dce867e5cc9 (diff)
Expose geometry and gamma on device.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkDevice.cpp36
-rw-r--r--src/core/SkDraw.cpp4
-rw-r--r--src/core/SkGlyphCache.h7
-rw-r--r--src/core/SkPaint.cpp92
-rw-r--r--src/core/SkScalerContext.h3
5 files changed, 92 insertions, 50 deletions
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index b3209b37b7..c79b4f8aa3 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -6,6 +6,7 @@
* found in the LICENSE file.
*/
#include "SkDevice.h"
+#include "SkDeviceProperties.h"
#include "SkDraw.h"
#include "SkImageFilter.h"
#include "SkMetaData.h"
@@ -23,7 +24,17 @@ SK_DEFINE_INST_COUNT(SkDevice)
///////////////////////////////////////////////////////////////////////////////
SkDevice::SkDevice(const SkBitmap& bitmap)
- : fBitmap(bitmap)
+ : fBitmap(bitmap), fLeakyProperties(SkDeviceProperties::MakeDefault())
+#ifdef SK_DEBUG
+ , fAttachedToCanvas(false)
+#endif
+{
+ fOrigin.setZero();
+ fMetaData = NULL;
+}
+
+SkDevice::SkDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
+ : fBitmap(bitmap), fLeakyProperties(deviceProperties)
#ifdef SK_DEBUG
, fAttachedToCanvas(false)
#endif
@@ -33,8 +44,27 @@ SkDevice::SkDevice(const SkBitmap& bitmap)
}
SkDevice::SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque)
+ : fLeakyProperties(SkDeviceProperties::MakeDefault())
+#ifdef SK_DEBUG
+ , fAttachedToCanvas(false)
+#endif
+{
+ fOrigin.setZero();
+ fMetaData = NULL;
+
+ fBitmap.setConfig(config, width, height);
+ fBitmap.allocPixels();
+ fBitmap.setIsOpaque(isOpaque);
+ if (!isOpaque) {
+ fBitmap.eraseColor(SK_ColorTRANSPARENT);
+ }
+}
+
+SkDevice::SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
+ const SkDeviceProperties& deviceProperties)
+ : fLeakyProperties(deviceProperties)
#ifdef SK_DEBUG
- : fAttachedToCanvas(false)
+ , fAttachedToCanvas(false)
#endif
{
fOrigin.setZero();
@@ -77,7 +107,7 @@ SkDevice* SkDevice::onCreateCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque,
Usage usage) {
- return SkNEW_ARGS(SkDevice,(config, width, height, isOpaque));
+ return SkNEW_ARGS(SkDevice,(config, width, height, isOpaque, fLeakyProperties));
}
SkMetaData& SkDevice::getMetaData() {
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index cf638e9b4c..ad8a0be8c0 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1658,7 +1658,7 @@ void SkDraw::drawText(const char text[], size_t byteLength,
const SkMatrix* matrix = fMatrix;
- SkAutoGlyphCache autoCache(paint, matrix);
+ SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, matrix);
SkGlyphCache* cache = autoCache.getCache();
// transform our starting point
@@ -1852,7 +1852,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength,
const SkMatrix* matrix = fMatrix;
SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
- SkAutoGlyphCache autoCache(paint, matrix);
+ SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, matrix);
SkGlyphCache* cache = autoCache.getCache();
SkAAClipBlitterWrapper wrapper;
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 472bcde522..8509011f0a 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -18,6 +18,7 @@
#include "SkTemplates.h"
#include "SkTDArray.h"
+struct SkDeviceProperties;
class SkPaint;
class SkGlyphCache_Globals;
@@ -275,8 +276,10 @@ public:
SkAutoGlyphCache(const SkDescriptor* desc) {
fCache = SkGlyphCache::DetachCache(desc);
}
- SkAutoGlyphCache(const SkPaint& paint, const SkMatrix* matrix) {
- fCache = paint.detachCache(matrix);
+ SkAutoGlyphCache(const SkPaint& paint,
+ const SkDeviceProperties* deviceProperties,
+ const SkMatrix* matrix) {
+ fCache = paint.detachCache(deviceProperties, matrix);
}
~SkAutoGlyphCache() {
if (fCache) {
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 8270e3b4dd..754098cca5 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -9,6 +9,7 @@
#include "SkPaint.h"
#include "SkAnnotation.h"
#include "SkColorFilter.h"
+#include "SkDeviceProperties.h"
#include "SkFontHost.h"
#include "SkImageFilter.h"
#include "SkMaskFilter.h"
@@ -476,7 +477,7 @@ int SkPaint::textToGlyphs(const void* textData, size_t byteLength,
return byteLength >> 1;
}
- SkAutoGlyphCache autoCache(*this, NULL);
+ SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
const char* text = (const char*)textData;
@@ -530,7 +531,7 @@ bool SkPaint::containsText(const void* textData, size_t byteLength) const {
return true;
}
- SkAutoGlyphCache autoCache(*this, NULL);
+ SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
switch (this->getTextEncoding()) {
@@ -580,7 +581,7 @@ void SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count,
SkASSERT(glyphs != NULL);
SkASSERT(textData != NULL);
- SkAutoGlyphCache autoCache(*this, NULL);
+ SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
for (int index = 0; index < count; index++) {
@@ -1048,7 +1049,7 @@ SkScalar SkPaint::measureText(const void* textData, size_t length,
zoomPtr = &zoomMatrix;
}
- SkAutoGlyphCache autoCache(*this, zoomPtr);
+ SkAutoGlyphCache autoCache(*this, NULL, zoomPtr);
SkGlyphCache* cache = autoCache.getCache();
SkScalar width = 0;
@@ -1124,7 +1125,7 @@ size_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
}
- SkAutoGlyphCache autoCache(*this, NULL);
+ SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
@@ -1212,7 +1213,7 @@ SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
metrics = &storage;
}
- this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics, true);
+ this->descriptorProc(NULL, zoomPtr, FontMetricsDescProc, metrics, true);
if (scale) {
metrics->fTop = SkScalarMul(metrics->fTop, scale);
@@ -1254,7 +1255,7 @@ int SkPaint::getTextWidths(const void* textData, size_t byteLength,
((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
}
- SkAutoGlyphCache autoCache(*this, NULL);
+ SkAutoGlyphCache autoCache(*this, NULL, NULL);
SkGlyphCache* cache = autoCache.getCache();
SkMeasureCacheProc glyphCacheProc;
glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
@@ -1487,22 +1488,10 @@ static SkScalar sk_relax(SkScalar x) {
#endif
}
-//#define SK_GAMMA_SRGB
-#ifndef SK_GAMMA_CONTRAST
- /**
- * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
- * With lower values small text appears washed out (though correctly so).
- * With higher values lcd fringing is worse and the smoothing effect of
- * partial coverage is diminished.
- */
- #define SK_GAMMA_CONTRAST (0.5f)
-#endif
-#ifndef SK_GAMMA_EXPONENT
- #define SK_GAMMA_EXPONENT (2.2f)
-#endif
-
void SkScalerContext::MakeRec(const SkPaint& paint,
- const SkMatrix* deviceMatrix, Rec* rec) {
+ const SkDeviceProperties* deviceProperties,
+ const SkMatrix* deviceMatrix,
+ Rec* rec) {
SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective());
SkTypeface* typeface = paint.getTypeface();
@@ -1572,19 +1561,18 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
- if (SkMask::kLCD16_Format == rec->fMaskFormat ||
- SkMask::kLCD32_Format == rec->fMaskFormat)
- {
- SkFontHost::LCDOrder order = SkFontHost::GetSubpixelOrder();
- SkFontHost::LCDOrientation orient = SkFontHost::GetSubpixelOrientation();
- if (SkFontHost::kNONE_LCDOrder == order || tooBigForLCD(*rec)) {
+ SkDeviceProperties::Geometry geometry = deviceProperties
+ ? deviceProperties->fGeometry
+ : SkDeviceProperties::Geometry::MakeDefault();
+ if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) {
+ if (!geometry.isOrientationKnown() || !geometry.isLayoutKnown() || tooBigForLCD(*rec)) {
// eeek, can't support LCD
rec->fMaskFormat = SkMask::kA8_Format;
} else {
- if (SkFontHost::kVertical_LCDOrientation == orient) {
+ if (SkDeviceProperties::Geometry::kVertical_Orientation == geometry.getOrientation()) {
flags |= SkScalerContext::kLCD_Vertical_Flag;
}
- if (SkFontHost::kBGR_LCDOrder == order) {
+ if (SkDeviceProperties::Geometry::kBGR_Layout == geometry.getLayout()) {
flags |= SkScalerContext::kLCD_BGROrder_Flag;
}
}
@@ -1611,14 +1599,32 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
rec->setHinting(computeHinting(paint));
rec->setLuminanceColor(computeLuminanceColor(paint));
-#ifdef SK_GAMMA_SRGB
- rec->setDeviceGamma(0);
- rec->setPaintGamma(0);
+
+ if (NULL == deviceProperties) {
+ rec->setDeviceGamma(SK_GAMMA_EXPONENT);
+ rec->setPaintGamma(SK_GAMMA_EXPONENT);
+ } else {
+ rec->setDeviceGamma(deviceProperties->fGamma);
+
+ //For now always set the paint gamma equal to the device gamma.
+ //The math in SkMaskGamma can handle them being different,
+ //but it requires superluminous masks when
+ //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
+ rec->setPaintGamma(deviceProperties->fGamma);
+ }
+
+#ifdef SK_GAMMA_CONTRAST
+ rec->setContrast(SK_GAMMA_CONTRAST);
#else
- rec->setDeviceGamma(SkFloatToScalar(SK_GAMMA_EXPONENT));
- rec->setPaintGamma(SkFloatToScalar(SK_GAMMA_EXPONENT));
+ /**
+ * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
+ * With lower values small text appears washed out (though correctly so).
+ * With higher values lcd fringing is worse and the smoothing effect of
+ * partial coverage is diminished.
+ */
+ rec->setContrast(SkFloatToScalar(0.5f));
#endif
- rec->setContrast(SkFloatToScalar(SK_GAMMA_CONTRAST));
+
rec->fReservedAlign = 0;
/* Allow the fonthost to modify our rec before we use it as a key into the
@@ -1712,7 +1718,7 @@ void SkScalerContext::PostMakeRec(const SkPaint& paint, SkScalerContext::Rec* re
}
case SkMask::kBW_Format:
// No need to differentiate gamma if we're BW
- rec->setLuminanceColor(0);
+ rec->ignorePreBlend();
break;
}
}
@@ -1730,12 +1736,13 @@ void SkScalerContext::PostMakeRec(const SkPaint& paint, SkScalerContext::Rec* re
* would be for the fontcache lookup to know to ignore the luminance field
* entirely, but not sure how to do that and keep it fast.
*/
-void SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
+void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
+ const SkMatrix* deviceMatrix,
void (*proc)(const SkDescriptor*, void*),
void* context, bool ignoreGamma) const {
SkScalerContext::Rec rec;
- SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
+ SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec);
if (ignoreGamma) {
rec.setLuminanceColor(0);
}
@@ -1846,9 +1853,10 @@ void SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
proc(desc, context);
}
-SkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const {
+SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties,
+ const SkMatrix* deviceMatrix) const {
SkGlyphCache* cache;
- this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
+ this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, false);
return cache;
}
@@ -2241,7 +2249,7 @@ SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
fPaint.setPathEffect(NULL);
}
- fCache = fPaint.detachCache(NULL);
+ fCache = fPaint.detachCache(NULL, NULL);
SkPaint::Style style = SkPaint::kFill_Style;
SkPathEffect* pe = NULL;
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index 05d5bc013d..f30bbd3eb6 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -202,7 +202,8 @@ public:
}
#endif
- static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
+ static inline void MakeRec(const SkPaint&, const SkDeviceProperties* deviceProperties,
+ const SkMatrix*, Rec* rec);
static inline void PostMakeRec(const SkPaint&, Rec*);
static SkScalerContext* Create(const SkDescriptor*);