135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger */ 835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 109521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed#include "SkTableMaskFilter.h" 119521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 129521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkTableMaskFilter::SkTableMaskFilter() { 139521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int i = 0; i < 256; i++) { 149521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed fTable[i] = i; 159521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 169521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 179521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 189521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkTableMaskFilter::SkTableMaskFilter(const uint8_t table[256]) { 199521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed this->setTable(table); 209521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 219521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 229521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkTableMaskFilter::~SkTableMaskFilter() {} 239521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 249521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reedvoid SkTableMaskFilter::setTable(const uint8_t table[256]) { 259521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed memcpy(fTable, table, 256); 269521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 279521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 289521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reedbool SkTableMaskFilter::filterMask(SkMask* dst, const SkMask& src, 299521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed const SkMatrix&, SkIPoint* margin) { 309521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (src.fFormat != SkMask::kA8_Format) { 319521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed return false; 329521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 339521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 349521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dst->fBounds = src.fBounds; 359521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dst->fRowBytes = SkAlign4(dst->fBounds.width()); 369521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dst->fFormat = SkMask::kA8_Format; 379521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dst->fImage = NULL; 389521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 399521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (src.fImage) { 409521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dst->fImage = SkMask::AllocImage(dst->computeImageSize()); 419521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 429521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed const uint8_t* srcP = src.fImage; 439521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed uint8_t* dstP = dst->fImage; 449521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed const uint8_t* table = fTable; 459521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed int dstWidth = dst->fBounds.width(); 469521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed int extraZeros = dst->fRowBytes - dstWidth; 479521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 489521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int y = dst->fBounds.height() - 1; y >= 0; --y) { 499521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int x = dstWidth - 1; x >= 0; --x) { 509521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dstP[x] = table[srcP[x]]; 519521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 529521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed srcP += src.fRowBytes; 539521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed // we can't just inc dstP by rowbytes, because if it has any 549521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed // padding between its width and its rowbytes, we need to zero those 559521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed // so that the bitters can read those safely if that is faster for 569521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed // them 579521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed dstP += dstWidth; 589521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int i = extraZeros - 1; i >= 0; --i) { 599521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed *dstP++ = 0; 609521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 619521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 629521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 639521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 649521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (margin) { 659521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed margin->set(0, 0); 669521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 679521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed return true; 689521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 699521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 709521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkMask::Format SkTableMaskFilter::getFormat() { 719521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed return SkMask::kA8_Format; 729521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 739521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 749521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reedvoid SkTableMaskFilter::flatten(SkFlattenableWriteBuffer& wb) { 759521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed this->INHERITED::flatten(wb); 769521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed wb.writePad(fTable, 256); 779521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 789521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 799521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkTableMaskFilter::SkTableMaskFilter(SkFlattenableReadBuffer& rb) 809521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed : INHERITED(rb) { 819521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed rb.read(fTable, 256); 829521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 839521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 849521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkFlattenable* SkTableMaskFilter::Factory(SkFlattenableReadBuffer& rb) { 859521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed return SkNEW_ARGS(SkTableMaskFilter, (rb)); 869521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 879521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 889521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike ReedSkFlattenable::Factory SkTableMaskFilter::getFactory() { 899521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed return SkTableMaskFilter::Factory; 909521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 919521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 929521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed/////////////////////////////////////////////////////////////////////////////// 939521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 949521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reedvoid SkTableMaskFilter::MakeGammaTable(uint8_t table[256], SkScalar gamma) { 959521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed const float dx = 1 / 255.0f; 964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const float g = SkScalarToFloat(gamma); 974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger float x = 0; 999521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int i = 0; i < 256; i++) { 1004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger float ee = powf(x, g) * 255; 1014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger table[i] = SkPin32(sk_float_round2int(powf(x, g) * 255), 0, 255); 1029521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed x += dx; 1039521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1049521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 1059521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 1069521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reedvoid SkTableMaskFilter::MakeClipTable(uint8_t table[256], uint8_t min, 1079521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed uint8_t max) { 1089521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (0 == max) { 1099521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed max = 1; 1109521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1119521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (min >= max) { 1129521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed min = max - 1; 1139521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1149521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkASSERT(min < max); 1159521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 1169521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkFixed scale = (1 << 16) * 255 / (max - min); 1179521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed memset(table, 0, min + 1); 1189521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (int i = min + 1; i < max; i++) { 1199521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed int value = SkFixedRound(scale * (i - min)); 1209521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkASSERT(value <= 255); 1219521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed table[i] = value; 1229521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1239521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed memset(table + max, 255, 256 - max); 1249521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 1259521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed#if 0 1269521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed int j; 1279521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (j = 0; j < 256; j++) { 1289521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed if (table[j]) { 1299521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed break; 1309521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1319521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1329521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkDebugf("%d %d start [%d]", min, max, j); 1339521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed for (; j < 256; j++) { 1349521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkDebugf(" %d", table[j]); 1359521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed } 1369521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed SkDebugf("\n\n"); 1379521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed#endif 1389521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed} 1399521ac9c669ee93f2e8ebfb4549ec64b57fe3559Mike Reed 140