/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This class exists as a wrapper for ID2D1SimplifiedGeometry sink, it allows // a geometry to be duplicated into a geometry sink, while removing the final // figure end and thus allowing a figure that was implicitly closed to be // continued. class OpeningGeometrySink : public ID2D1SimplifiedGeometrySink { public: explicit OpeningGeometrySink(ID2D1SimplifiedGeometrySink* aSink)
: mSink(aSink), mNeedsFigureEnded(false) {}
// This function is special - it's the reason this class exists. // It needs to intercept the very last endfigure. So that a user can // continue writing to this sink as if they never stopped.
STDMETHOD_(void, EndFigure)(D2D1_FIGURE_END aEnd) { if (aEnd == D2D1_FIGURE_END_CLOSED) { return mSink->EndFigure(aEnd);
} else {
mNeedsFigureEnded = true;
}
}
// We want aEndAngle to come numerically after aStartAngle when taking into // account the sweep direction so that our calculation of the arcSize below // (large or small) works. Float sweepDirection = aAntiClockwise ? -1.0f : 1.0f;
Float arcSweepLeft = (aEndAngle - aStartAngle) * sweepDirection; if (arcSweepLeft < 0) { // This calculation moves aStartAngle by a multiple of 2*Pi so that it is // the closest it can be to aEndAngle and still be numerically before // aEndAngle when taking into account sweepDirection.
arcSweepLeft = Float(2.0f * M_PI) + fmodf(arcSweepLeft, Float(2.0f * M_PI));
aStartAngle = aEndAngle - arcSweepLeft * sweepDirection;
}
// XXX - Workaround for now, D2D does not appear to do the desired thing when // the angle sweeps a complete circle. bool fullCircle = false; if (aEndAngle - aStartAngle >= 1.9999 * M_PI) {
fullCircle = true;
aEndAngle = Float(aStartAngle + M_PI * 1.9999);
} elseif (aStartAngle - aEndAngle >= 1.9999 * M_PI) {
fullCircle = true;
aStartAngle = Float(aEndAngle + M_PI * 1.9999);
}
// if startPoint and endPoint of our circle are too close there are D2D issues // with drawing the circle as a single arc constFloat kEpsilon = 1e-5f; if (!fullCircle || (std::abs(startPoint.x - endPoint.x) +
std::abs(startPoint.y - endPoint.y) >
kEpsilon)) { if (aAntiClockwise) { if (aStartAngle - aEndAngle > M_PI) {
arcSize = D2D1_ARC_SIZE_LARGE;
}
} else { if (aEndAngle - aStartAngle > M_PI) {
arcSize = D2D1_ARC_SIZE_LARGE;
}
}
mSink->AddArc(D2D1::ArcSegment(D2DPoint(endPoint),
D2D1::SizeF(aRadius, aRadius), 0.0f,
direction, arcSize));
} else { // our first workaround attempt didn't work, so instead draw the circle as // two half-circles Float midAngle = aEndAngle > aStartAngle ? Float(aStartAngle + M_PI)
: Float(aEndAngle + M_PI);
Point midPoint;
midPoint.x = aOrigin.x + aRadius * cosf(midAngle);
midPoint.y = aOrigin.y + aRadius * sinf(midAngle);
// if the adjusted endPoint computed above is used here and endPoint != // startPoint then this half of the circle won't render...
mSink->AddArc(D2D1::ArcSegment(D2DPoint(startPoint),
D2D1::SizeF(aRadius, aRadius), 0.0f,
direction, arcSize));
}
if (FAILED(hr)) {
gfxWarning() << "Failed to stream D2D path to sink. Code: " << hexa(hr); return;
}
}
bool PathD2D::ContainsPoint(const Point& aPoint, const Matrix& aTransform) const { if (!aTransform.Determinant()) { // If the transform is not invertible, then don't consider point inside. returnfalse;
}
bool PathD2D::StrokeContainsPoint(const StrokeOptions& aStrokeOptions, const Point& aPoint, const Matrix& aTransform) const { if (!aTransform.Determinant()) { // If the transform is not invertible, then don't consider point inside. returnfalse;
}
Rect bounds = ToRect(d2dBounds); if (FAILED(hr) || !bounds.IsFinite()) {
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr); return Rect();
}
Rect bounds = ToRect(d2dBounds); if (FAILED(hr) || !bounds.IsFinite()) {
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr); return Rect();
}
return bounds;
}
} // namespace gfx
} // namespace mozilla
¤ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.