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