Transform.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Region.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/pixelflinger/ggl_fixed.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Transform.h"
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTransform::Transform()
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mType(0)
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.reset();
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTransform::Transform(const Transform&  other)
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mTransform(other.mTransform), mType(other.mType)
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTransform::~Transform() {
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTransform Transform::operator * (const Transform& rhs) const
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (LIKELY(mType == 0))
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return rhs;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Transform r(*this);
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.mTransform.preConcat(rhs.mTransform);
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.mType |= rhs.mType;
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return r;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat Transform::operator [] (int i) const
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    float r = 0;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch(i) {
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] );  break;
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] );   break;
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] );   break;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] );  break;
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return r;
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint8_t Transform::type() const
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(mType & 0x80000000)) {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mType = mTransform.getType();
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return uint8_t(mType & 0xFF);
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Transform::transformed() const {
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return type() > SkMatrix::kTranslate_Mask;
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint Transform::tx() const {
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return SkScalarRound( mTransform[SkMatrix::kMTransX] );
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint Transform::ty() const {
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return SkScalarRound( mTransform[SkMatrix::kMTransY] );
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Transform::reset() {
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.reset();
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mType = 0;
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Transform::set( float xx, float xy,
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                     float yx, float yy)
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mType |= 0x80000000;
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Transform::set(int tx, int ty)
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tx | ty) {
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mType |= SkMatrix::kTranslate_Mask;
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransform.set(SkMatrix::kMTransX, 0);
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransform.set(SkMatrix::kMTransY, 0);
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mType &= ~SkMatrix::kTranslate_Mask;
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Transform::transform(GLfixed* point, int x, int y) const
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SkPoint s;
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    point[0] = SkScalarToFixed(s.fX);
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    point[1] = SkScalarToFixed(s.fY);
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect Transform::makeBounds(int w, int h) const
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Rect r;
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SkRect d, s;
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.mapRect(&d, s);
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.left   = SkScalarRound( d.fLeft );
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.top    = SkScalarRound( d.fTop );
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.right  = SkScalarRound( d.fRight );
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.bottom = SkScalarRound( d.fBottom );
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return r;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect Transform::transform(const Rect& bounds) const
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Rect r;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SkRect d, s;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s.set(  SkIntToScalar( bounds.left ),
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            SkIntToScalar( bounds.top ),
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            SkIntToScalar( bounds.right ),
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            SkIntToScalar( bounds.bottom ));
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransform.mapRect(&d, s);
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.left   = SkScalarRound( d.fLeft );
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.top    = SkScalarRound( d.fTop );
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.right  = SkScalarRound( d.fRight );
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    r.bottom = SkScalarRound( d.fBottom );
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return r;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion Transform::transform(const Region& reg) const
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region out;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(transformed())) {
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (LIKELY(preserveRects())) {
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Rect r;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Region::iterator iterator(reg);
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            while (iterator.iterate(&r)) {
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.orSelf(transform(r));
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.set(transform(reg.bounds()));
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out = reg.translate(tx(), ty());
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return out;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint32_t Transform::getOrientation() const
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (UNLIKELY(transformed())) {
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkScalar a = mTransform[SkMatrix::kMScaleX];
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkScalar b = mTransform[SkMatrix::kMSkewX];
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkScalar c = mTransform[SkMatrix::kMSkewY];
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkScalar d = mTransform[SkMatrix::kMScaleY];
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (b==0 && c==0 && a && d) {
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (a<0)    flags |= FLIP_H;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (d<0)    flags |= FLIP_V;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else if (b && c && a==0 && d==0) {
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            flags |= ROT_90;
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (b>0)    flags |= FLIP_H;
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c<0)    flags |= FLIP_V;
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            flags = 0x80000000;
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return flags;
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Transform::preserveRects() const
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mTransform.rectStaysRect();
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
205