11cab2921ab279367f8206cdadc9259d12e603548Derek 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. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUnitMappers.h" 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkDiscreteMapper::SkDiscreteMapper(int segments) { 1135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (segments < 2) { 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSegments = 0; 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = 0; 1435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } else { 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (segments > 0xFFFF) { 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project segments = 0xFFFF; 1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSegments = segments; 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = SK_Fract1 / (segments - 1); 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergeruint16_t SkDiscreteMapper::mapUnit16(uint16_t input) { 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed x = input * fSegments >> 16; 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = x * fScale >> 14; 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += x << 15 >> 31; // map 0x10000 to 0xFFFF 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkToU16(x); 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDiscreteMapper::SkDiscreteMapper(SkFlattenableReadBuffer& rb) 3135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : SkUnitMapper(rb) { 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fSegments = rb.readU32(); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = rb.readU32(); 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable::Factory SkDiscreteMapper::getFactory() { 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return Create; 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable* SkDiscreteMapper::Create(SkFlattenableReadBuffer& rb) { 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkDiscreteMapper, (rb)); 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkDiscreteMapper::flatten(SkFlattenableWriteBuffer& wb) { 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->INHERITED::flatten(wb); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project wb.write32(fSegments); 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project wb.write32(fScale); 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint16_t SkCosineMapper::mapUnit16(uint16_t input) 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /* we want to call cosine(input * pi/2) treating input as [0...1) 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project however, the straight multitply would overflow 32bits since input is 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16bits and pi/2 is 17bits, so we shift down our pi const before we mul 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed rads = (unsigned)(input * (SK_FixedPI >> 2)) >> 15; 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed x = SkFixedCos(rads); 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += x << 15 >> 31; // map 0x10000 to 0xFFFF 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkToU16(x); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkCosineMapper::SkCosineMapper(SkFlattenableReadBuffer& rb) 6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : SkUnitMapper(rb) {} 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable::Factory SkCosineMapper::getFactory() { 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return Create; 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkFlattenable* SkCosineMapper::Create(SkFlattenableReadBuffer& rb) { 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkCosineMapper, (rb)); 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 76