gecko-dev/layout/painting/DashedCornerFinder.h
Ehsan Akhgari aca985efab Bug 1318805 - Move the code for the Web Painting module to layout/painting; r=mattwoodrow
This will help make it clearer that this code lives in a different
module for contributors.


--HG--
rename : layout/base/ActiveLayerTracker.cpp => layout/painting/ActiveLayerTracker.cpp
rename : layout/base/ActiveLayerTracker.h => layout/painting/ActiveLayerTracker.h
rename : layout/base/BorderCache.h => layout/painting/BorderCache.h
rename : layout/base/BorderConsts.h => layout/painting/BorderConsts.h
rename : layout/base/DashedCornerFinder.cpp => layout/painting/DashedCornerFinder.cpp
rename : layout/base/DashedCornerFinder.h => layout/painting/DashedCornerFinder.h
rename : layout/base/DisplayItemClip.cpp => layout/painting/DisplayItemClip.cpp
rename : layout/base/DisplayItemClip.h => layout/painting/DisplayItemClip.h
rename : layout/base/DisplayItemScrollClip.cpp => layout/painting/DisplayItemScrollClip.cpp
rename : layout/base/DisplayItemScrollClip.h => layout/painting/DisplayItemScrollClip.h
rename : layout/base/DisplayListClipState.cpp => layout/painting/DisplayListClipState.cpp
rename : layout/base/DisplayListClipState.h => layout/painting/DisplayListClipState.h
rename : layout/base/DottedCornerFinder.cpp => layout/painting/DottedCornerFinder.cpp
rename : layout/base/DottedCornerFinder.h => layout/painting/DottedCornerFinder.h
rename : layout/base/FrameLayerBuilder.cpp => layout/painting/FrameLayerBuilder.cpp
rename : layout/base/FrameLayerBuilder.h => layout/painting/FrameLayerBuilder.h
rename : layout/base/LayerState.h => layout/painting/LayerState.h
rename : layout/base/MaskLayerImageCache.cpp => layout/painting/MaskLayerImageCache.cpp
rename : layout/base/MaskLayerImageCache.h => layout/painting/MaskLayerImageCache.h
rename : layout/base/PaintTracker.cpp => layout/painting/PaintTracker.cpp
rename : layout/base/PaintTracker.h => layout/painting/PaintTracker.h
rename : layout/base/nsCSSRendering.cpp => layout/painting/nsCSSRendering.cpp
rename : layout/base/nsCSSRendering.h => layout/painting/nsCSSRendering.h
rename : layout/base/nsCSSRenderingBorders.cpp => layout/painting/nsCSSRenderingBorders.cpp
rename : layout/base/nsCSSRenderingBorders.h => layout/painting/nsCSSRenderingBorders.h
rename : layout/base/nsDisplayItemTypes.h => layout/painting/nsDisplayItemTypes.h
rename : layout/base/nsDisplayItemTypesList.h => layout/painting/nsDisplayItemTypesList.h
rename : layout/base/nsDisplayList.cpp => layout/painting/nsDisplayList.cpp
rename : layout/base/nsDisplayList.h => layout/painting/nsDisplayList.h
rename : layout/base/nsDisplayListInvalidation.cpp => layout/painting/nsDisplayListInvalidation.cpp
rename : layout/base/nsDisplayListInvalidation.h => layout/painting/nsDisplayListInvalidation.h
2016-11-21 20:01:15 -05:00

278 lines
9.5 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#ifndef mozilla_DashedCornerFinder_h_
#define mozilla_DashedCornerFinder_h_
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/BezierUtils.h"
namespace mozilla {
// Calculate {OuterT_i, InnerT_i} for each 1 < i < n, that
// (OuterL_i + InnerL_i) / 2 == dashLength * (W_i + W_{i-1}) / 2
// where
// OuterP_i: OuterCurve(OuterT_i)
// InnerP_i: InnerCurve(OuterT_i)
// OuterL_i: Elliptic arc length between OuterP_i - OuterP_{i-1}
// InnerL_i: Elliptic arc length between InnerP_i - InnerP_{i-1}
// W_i = |OuterP_i - InnerP_i|
// 1.0 < dashLength < 3.0
//
// OuterP_1 OuterP_0
// _+__-----------+ OuterCurve
// OuterP_2 __---- | OuterL_1 |
// __+--- | |
// __--- | OuterL_2 | |
// OuterP_3 _-- | | W_1 | W_0
// _+ | | |
// / \ W_2 | | |
// / \ | | InnerL_1 |
// | \ | InnerL_2|____-------+ InnerCurve
// | \ |____----+ InnerP_0
// | . \ __---+ InnerP_1
// | \ / InnerP_2
// | . /+ InnerP_3
// | |
// | . |
// | |
// | |
// | |
// OuterP_{n-1} +--------+ InnerP_{n-1}
// | |
// | |
// | |
// | |
// | |
// OuterP_n +--------+ InnerP_n
//
// Returns region with [OuterCurve((OuterT_{2j} + OuterT_{2j-1}) / 2),
// OuterCurve((OuterT_{2j} + OuterT_{2j-1}) / 2),
// InnerCurve((OuterT_{2j} + OuterT_{2j+1}) / 2),
// InnerCurve((OuterT_{2j} + OuterT_{2j+1}) / 2)],
// to start and end with half segment.
//
// _+__----+------+ OuterCurve
// _+---- | |######|
// __+---#| | |######|
// _+---##|####| | |######|
// _-- |#####|#####| | |#####|
// _+ |#####|#####| | |#####|
// / \ |#####|####| | |#####|
// / \ |####|#####| | |#####|
// | \ |####|####| |____-+-----+ InnerCurve
// | \ |####|____+---+
// | . \ __+---+
// | \ /
// | . /+
// | |
// | . |
// | |
// | |
// | |
// +--------+
// | |
// | |
// +--------+
// |########|
// |########|
// +--------+
class DashedCornerFinder
{
typedef mozilla::gfx::Bezier Bezier;
typedef mozilla::gfx::Float Float;
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Size Size;
public:
struct Result
{
// Control points for the outer curve and the inner curve.
//
// outerSectionBezier
// |
// v _+ 3
// ___---#|
// 0 +---#######|
// |###########|
// |###########|
// |##########|
// |##########|
// |#########|
// |#####____+ 3
// 0 +----
// ^
// |
// innerSectionBezier
Bezier outerSectionBezier;
Bezier innerSectionBezier;
Result(const Bezier& aOuterSectionBezier,
const Bezier& aInnerSectionBezier)
: outerSectionBezier(aOuterSectionBezier),
innerSectionBezier(aInnerSectionBezier)
{}
};
// aCornerDim.width
// |<----------------->|
// | |
// --+-------------___---+--
// ^ | __-- | ^
// | | _- | |
// | | / | | aBorderWidthH
// | | / | |
// | | | | v
// | | | __--+--
// aCornerDim.height | || _-
// | || /
// | | /
// | | |
// | | |
// | | |
// | | |
// v | |
// --+---------+
// | |
// |<------->|
// aBorderWidthV
DashedCornerFinder(const Bezier& aOuterBezier, const Bezier& aInnerBezier,
Float aBorderWidthH, Float aBorderWidthV,
const Size& aCornerDim);
bool HasMore(void) const;
Result Next(void);
private:
static const size_t MAX_LOOP = 32;
// Bezier control points for the outer curve and the inner curve.
//
// ___---+ outer curve
// __-- |
// _- |
// / |
// / |
// | |
// | __--+ inner curve
// | _-
// | /
// | /
// | |
// | |
// | |
// | |
// | |
// +---------+
Bezier mOuterBezier;
Bezier mInnerBezier;
Point mLastOuterP;
Point mLastInnerP;
Float mLastOuterT;
Float mLastInnerT;
// Length for each segment, ratio of the border width at that point.
Float mBestDashLength;
// If one of border-widths is 0, do not calculate mBestDashLength, and draw
// segments until it reaches the other side or exceeds mMaxCount.
bool mHasZeroBorderWidth;
bool mHasMore;
// The maximum number of segments.
size_t mMaxCount;
enum {
// radius.width
// |<----------------->|
// | |
// --+-------------___---+--
// ^ | __-- | ^
// | | _- | |
// | | / + | top-width
// | | / | |
// | | | | v
// | | | __--+--
// radius.height | || _-
// | || /
// | | /
// | | |
// | | |
// | | |
// | | |
// v | |
// --+----+----+
// | |
// |<------->|
// left-width
// * top-width == left-width
// * radius.width == radius.height
// * top-width < radius.width * 2
//
// Split the perfect circle's arc into 2n segments, each segment's length is
// top-width * dashLength. Then split the inner curve and the outer curve
// with same angles.
//
// radius.width
// |<---------------------->|
// | | v
// --+------------------------+--
// ^ | | | top-width / 2
// | | perfect | |
// | | circle's ___---+--
// | | arc __-+ | ^
// | | | _- | |
// radius.height | | | + | +--
// | | | / \ | |
// | | | | \ | |
// | | | | \ | |
// | | +->| \ | |
// | | +---__ \ | |
// | | | --__ \ | |
// | | | ---__ \ | |
// v | | --_\||
// --+----+----+--------------+
// | | |
// |<-->| |
// left-width / 2
PERFECT,
// Other cases.
//
// Split the outer curve and the inner curve into 2n segments, each segment
// satisfies following:
// (OuterL_i + InnerL_i) / 2 == dashLength * (W_i + W_{i-1}) / 2
OTHER
} mType;
size_t mI;
size_t mCount;
// Determine mType from parameters.
void DetermineType(Float aBorderWidthH, Float aBorderWidthV);
// Reset calculation.
void Reset(void);
// Find next segment.
Float FindNext(Float dashLength);
// Find mBestDashLength for parameters.
void FindBestDashLength(Float aMinBorderWidth, Float aMaxBorderWidth,
Float aMinBorderRadius, Float aMaxBorderRadius);
// Fill corner with dashes with given dash length, and return the number of
// segments and last segment's dash length.
bool GetCountAndLastDashLength(Float aDashLength,
size_t* aCount, Float* aActualDashLength);
};
} // namespace mozilla
#endif /* mozilla_DashedCornerFinder_h_ */