1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "gfxRect.h"
7 
8 #include "nsMathUtils.h"
9 
10 #include "mozilla/gfx/Matrix.h"
11 
12 #include "gfxQuad.h"
13 
14 gfxQuad
TransformToQuad(const mozilla::gfx::Matrix4x4 & aMatrix) const15 gfxRect::TransformToQuad(const mozilla::gfx::Matrix4x4 &aMatrix) const
16 {
17   gfxPoint points[4];
18 
19   points[0] = TopLeft();
20   points[1] = TopRight();
21   points[2] = BottomRight();
22   points[3] = BottomLeft();
23 
24   points[0].Transform(aMatrix);
25   points[1].Transform(aMatrix);
26   points[2].Transform(aMatrix);
27   points[3].Transform(aMatrix);
28 
29   // Could this ever result in lines that intersect? I don't think so.
30   return gfxQuad(points[0], points[1], points[2], points[3]);
31 }
32 
33 static bool
WithinEpsilonOfInteger(gfxFloat aX,gfxFloat aEpsilon)34 WithinEpsilonOfInteger(gfxFloat aX, gfxFloat aEpsilon)
35 {
36     return fabs(NS_round(aX) - aX) <= fabs(aEpsilon);
37 }
38 
39 bool
WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const40 gfxRect::WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const
41 {
42     NS_ASSERTION(-0.5 < aEpsilon && aEpsilon < 0.5, "Nonsense epsilon value");
43     return (WithinEpsilonOfInteger(x, aEpsilon) &&
44             WithinEpsilonOfInteger(y, aEpsilon) &&
45             WithinEpsilonOfInteger(width, aEpsilon) &&
46             WithinEpsilonOfInteger(height, aEpsilon));
47 }
48 
49 /* Clamp r to CAIRO_COORD_MIN .. CAIRO_COORD_MAX
50  * these are to be device coordinates.
51  *
52  * Cairo is currently using 24.8 fixed point,
53  * so -2^24 .. 2^24-1 is our valid
54  */
55 
56 #define CAIRO_COORD_MAX (16777215.0)
57 #define CAIRO_COORD_MIN (-16777216.0)
58 
59 void
Condition()60 gfxRect::Condition()
61 {
62     // if either x or y is way out of bounds;
63     // note that we don't handle negative w/h here
64     if (x > CAIRO_COORD_MAX) {
65         x = CAIRO_COORD_MAX;
66         width = 0.0;
67     }
68 
69     if (y > CAIRO_COORD_MAX) {
70         y = CAIRO_COORD_MAX;
71         height = 0.0;
72     }
73 
74     if (x < CAIRO_COORD_MIN) {
75         width += x - CAIRO_COORD_MIN;
76         if (width < 0.0)
77             width = 0.0;
78         x = CAIRO_COORD_MIN;
79     }
80 
81     if (y < CAIRO_COORD_MIN) {
82         height += y - CAIRO_COORD_MIN;
83         if (height < 0.0)
84             height = 0.0;
85         y = CAIRO_COORD_MIN;
86     }
87 
88     if (x + width > CAIRO_COORD_MAX) {
89         width = CAIRO_COORD_MAX - x;
90     }
91 
92     if (y + height > CAIRO_COORD_MAX) {
93         height = CAIRO_COORD_MAX - y;
94     }
95 }
96 
97