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