gecko-dev/gfx/2d/PathRecording.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

225 строки
6.8 KiB
C++
Исходник Обычный вид История

/* -*- 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/. */
#include "PathRecording.h"
#include "DrawEventRecorder.h"
#include "RecordedEventImpl.h"
namespace mozilla {
namespace gfx {
#define NEXT_PARAMS(_type) \
const _type params = *reinterpret_cast<const _type*>(nextByte); \
nextByte += sizeof(_type);
using namespace std;
bool PathOps::StreamToSink(PathSink& aPathSink) const {
if (mPathData.empty()) {
return true;
}
const uint8_t* nextByte = mPathData.data();
const uint8_t* end = nextByte + mPathData.size();
while (nextByte < end) {
const OpType opType = *reinterpret_cast<const OpType*>(nextByte);
nextByte += sizeof(OpType);
switch (opType) {
case OpType::OP_MOVETO: {
NEXT_PARAMS(Point)
aPathSink.MoveTo(params);
break;
}
case OpType::OP_LINETO: {
NEXT_PARAMS(Point)
aPathSink.LineTo(params);
break;
}
case OpType::OP_BEZIERTO: {
NEXT_PARAMS(ThreePoints)
aPathSink.BezierTo(params.p1, params.p2, params.p3);
break;
}
case OpType::OP_QUADRATICBEZIERTO: {
NEXT_PARAMS(TwoPoints)
aPathSink.QuadraticBezierTo(params.p1, params.p2);
break;
}
case OpType::OP_ARC: {
NEXT_PARAMS(ArcParams)
aPathSink.Arc(params.origin, params.radius, params.startAngle,
params.endAngle, params.antiClockwise);
break;
}
case OpType::OP_CLOSE:
aPathSink.Close();
break;
default:
return false;
}
}
return true;
}
PathOps PathOps::TransformedCopy(const Matrix& aTransform) const {
PathOps newPathOps;
const uint8_t* nextByte = mPathData.data();
const uint8_t* end = nextByte + mPathData.size();
while (nextByte < end) {
const OpType opType = *reinterpret_cast<const OpType*>(nextByte);
nextByte += sizeof(OpType);
switch (opType) {
case OpType::OP_MOVETO: {
NEXT_PARAMS(Point)
newPathOps.MoveTo(aTransform.TransformPoint(params));
break;
}
case OpType::OP_LINETO: {
NEXT_PARAMS(Point)
newPathOps.LineTo(aTransform.TransformPoint(params));
break;
}
case OpType::OP_BEZIERTO: {
NEXT_PARAMS(ThreePoints)
newPathOps.BezierTo(aTransform.TransformPoint(params.p1),
aTransform.TransformPoint(params.p2),
aTransform.TransformPoint(params.p3));
break;
}
case OpType::OP_QUADRATICBEZIERTO: {
NEXT_PARAMS(TwoPoints)
newPathOps.QuadraticBezierTo(aTransform.TransformPoint(params.p1),
aTransform.TransformPoint(params.p2));
break;
}
case OpType::OP_ARC: {
NEXT_PARAMS(ArcParams)
ArcToBezier(&newPathOps, params.origin,
gfx::Size(params.radius, params.radius), params.startAngle,
params.endAngle, params.antiClockwise, 0.0f, aTransform);
break;
}
case OpType::OP_CLOSE:
newPathOps.Close();
break;
default:
MOZ_CRASH("We control mOpTypes, so this should never happen.");
}
}
return newPathOps;
}
#undef NEXT_PARAMS
size_t PathOps::NumberOfOps() const {
size_t size = 0;
const uint8_t* nextByte = mPathData.data();
const uint8_t* end = nextByte + mPathData.size();
while (nextByte < end) {
size++;
const OpType opType = *reinterpret_cast<const OpType*>(nextByte);
nextByte += sizeof(OpType);
switch (opType) {
case OpType::OP_MOVETO:
nextByte += sizeof(Point);
break;
case OpType::OP_LINETO:
nextByte += sizeof(Point);
break;
case OpType::OP_BEZIERTO:
nextByte += sizeof(ThreePoints);
break;
case OpType::OP_QUADRATICBEZIERTO:
nextByte += sizeof(TwoPoints);
break;
case OpType::OP_ARC:
nextByte += sizeof(ArcParams);
break;
case OpType::OP_CLOSE:
break;
default:
MOZ_CRASH("We control mOpTypes, so this should never happen.");
}
}
return size;
}
void PathBuilderRecording::MoveTo(const Point& aPoint) {
mPathOps.MoveTo(aPoint);
mPathBuilder->MoveTo(aPoint);
}
void PathBuilderRecording::LineTo(const Point& aPoint) {
mPathOps.LineTo(aPoint);
mPathBuilder->LineTo(aPoint);
}
void PathBuilderRecording::BezierTo(const Point& aCP1, const Point& aCP2,
const Point& aCP3) {
mPathOps.BezierTo(aCP1, aCP2, aCP3);
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
}
void PathBuilderRecording::QuadraticBezierTo(const Point& aCP1,
const Point& aCP2) {
mPathOps.QuadraticBezierTo(aCP1, aCP2);
mPathBuilder->QuadraticBezierTo(aCP1, aCP2);
}
void PathBuilderRecording::Close() {
mPathOps.Close();
mPathBuilder->Close();
}
void PathBuilderRecording::Arc(const Point& aOrigin, float aRadius,
float aStartAngle, float aEndAngle,
bool aAntiClockwise) {
mPathOps.Arc(aOrigin, aRadius, aStartAngle, aEndAngle, aAntiClockwise);
mPathBuilder->Arc(aOrigin, aRadius, aStartAngle, aEndAngle, aAntiClockwise);
}
already_AddRefed<Path> PathBuilderRecording::Finish() {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<Path> path = mPathBuilder->Finish();
return MakeAndAddRef<PathRecording>(path, std::move(mPathOps), mFillRule,
mCurrentPoint, mBeginPoint);
}
PathRecording::~PathRecording() {
for (size_t i = 0; i < mStoredRecorders.size(); i++) {
mStoredRecorders[i]->RemoveStoredObject(this);
mStoredRecorders[i]->RecordEvent(RecordedPathDestruction(this));
}
}
already_AddRefed<PathBuilder> PathRecording::CopyToBuilder(
FillRule aFillRule) const {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PathBuilder> pathBuilder = mPath->CopyToBuilder(aFillRule);
RefPtr<PathBuilderRecording> recording =
new PathBuilderRecording(pathBuilder, mPathOps, aFillRule);
recording->SetCurrentPoint(mCurrentPoint);
recording->SetBeginPoint(mBeginPoint);
return recording.forget();
}
already_AddRefed<PathBuilder> PathRecording::TransformedCopyToBuilder(
const Matrix& aTransform, FillRule aFillRule) const {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PathBuilder> pathBuilder =
mPath->TransformedCopyToBuilder(aTransform, aFillRule);
RefPtr<PathBuilderRecording> recording = new PathBuilderRecording(
pathBuilder, mPathOps.TransformedCopy(aTransform), aFillRule);
recording->SetCurrentPoint(aTransform.TransformPoint(mCurrentPoint));
recording->SetBeginPoint(aTransform.TransformPoint(mBeginPoint));
return recording.forget();
}
} // namespace gfx
} // namespace mozilla