use std::cell::Cell;
use typed_arena_nomut::Arena;
#[cfg(debug_assertions)]
use crate::aarasterizer::AssertActiveList;
use crate::aarasterizer::CEdge;
use crate::nullable_ref::Ref;
use crate::types::*;
pub const c_nShift: INT = 3;
pub const c_nShiftSize: INT = 8;
pub const c_nShiftSizeSquared: INT = c_nShiftSize * c_nShiftSize;
pub const c_nHalfShiftSize: INT = 4;
pub const c_nShiftMask: INT = 7;
pub const c_rInvShiftSize: f32 = 1.0/8.0;
pub const c_antiAliasMode: MilAntiAliasMode = MilAntiAliasMode::EightByEight;
pub struct CCoverageInterval<'a>
{
pub m_pNext: Cell<Ref<'a, CCoverageInterval<'a>>>, pub m_nPixelX: Cell<INT>, pub m_nCoverage: Cell<INT>, }
impl<'a> Default for CCoverageInterval<'a> {
fn default() -> Self {
Self { m_pNext: Cell::new(unsafe { Ref::null() } ), m_nPixelX: Default::default(), m_nCoverage: Default::default() }
}
}
#[cfg(debug_assertions)]
const INTERVAL_BUFFER_NUMBER: usize = 8;
#[cfg(not(debug_assertions))]
const INTERVAL_BUFFER_NUMBER: usize = 32;
struct CCoverageIntervalBuffer<'a>
{
m_pNext: Cell<Option<& 'a CCoverageIntervalBuffer<'a>>>,
m_interval: [CCoverageInterval<'a>; INTERVAL_BUFFER_NUMBER],
}
impl<'a> Default for CCoverageIntervalBuffer<'a> {
fn default() -> Self {
Self { m_pNext: Cell::new(None), m_interval: Default::default() }
}
}
pub struct CCoverageBuffer<'a>
{
pub m_pIntervalStart: Cell<Ref<'a, CCoverageInterval<'a>>>,
m_pIntervalNew: Cell<Ref<'a, CCoverageInterval<'a>>>,
interval_new_index: Cell<usize>,
m_pIntervalEndMinus4: Cell<Ref<'a, CCoverageInterval<'a>>>,
m_pIntervalLast: Cell<Ref<'a, CCoverageInterval<'a>>>,
m_pIntervalBufferBuiltin: CCoverageIntervalBuffer<'a>,
m_pIntervalBufferCurrent: Cell<Ref<'a, CCoverageIntervalBuffer<'a>>>,
arena: Arena<CCoverageIntervalBuffer<'a>>
}
impl<'a> Default for CCoverageBuffer<'a> {
fn default() -> Self {
Self {
m_pIntervalStart: Cell::new(unsafe { Ref::null() }),
m_pIntervalNew: Cell::new(unsafe { Ref::null() }),
m_pIntervalEndMinus4: Cell::new(unsafe { Ref::null() }),
m_pIntervalLast: Cell::new(unsafe { Ref::null() }),
m_pIntervalBufferBuiltin: Default::default(),
m_pIntervalBufferCurrent: unsafe { Cell::new(Ref::null()) },
arena: Arena::new(),
interval_new_index: Cell::new(0),
}
}
}
impl<'a> CCoverageBuffer<'a> {
pub fn AddInterval(&'a self, nSubpixelXLeft: INT, nSubpixelXRight: INT) -> HRESULT
{
let hr: HRESULT = S_OK;
let mut nPixelXNext: INT;
let nPixelXLeft: INT;
let nPixelXRight: INT;
let nCoverageLeft: INT; let nCoverageRight: INT;
let mut pInterval = self.m_pIntervalStart.get();
let mut pIntervalNew = self.m_pIntervalNew.get();
let mut interval_new_index = self.interval_new_index.get();
let mut pIntervalEndMinus4 = self.m_pIntervalEndMinus4.get();
if (pIntervalNew >= pIntervalEndMinus4)
{
IFC!(self.Grow(&mut pIntervalNew, &mut pIntervalEndMinus4, &mut interval_new_index));
}
debug_assert!(nSubpixelXLeft < nSubpixelXRight);
nPixelXLeft = nSubpixelXLeft >> c_nShift;
nPixelXRight = nSubpixelXRight >> c_nShift;
if self.m_pIntervalLast.get().m_nPixelX.get() < nPixelXLeft {
pInterval = self.m_pIntervalLast.get();
}
loop {
let nextInterval = pInterval.m_pNext.get();
nPixelXNext = nextInterval.m_nPixelX.get();
if !(nPixelXNext < nPixelXLeft) { break }
pInterval = nextInterval;
}
self.m_pIntervalLast.set(pInterval);
if (nPixelXNext != nPixelXLeft)
{
pIntervalNew.m_nPixelX.set(nPixelXLeft);
pIntervalNew.m_nCoverage.set(pInterval.m_nCoverage.get());
pIntervalNew.m_pNext.set(pInterval.m_pNext.get());
pInterval.m_pNext.set(pIntervalNew);
pInterval = pIntervalNew;
interval_new_index += 1;
pIntervalNew = Ref::new(&Ref::get_ref(self.m_pIntervalBufferCurrent.get()).m_interval[interval_new_index])
}
else
{
pInterval = (*pInterval).m_pNext.get();
}
nCoverageLeft = c_nShiftSize - (nSubpixelXLeft & c_nShiftMask);
debug_assert!(nCoverageLeft > 0);
if ((nCoverageLeft < c_nShiftSize || (nPixelXLeft == nPixelXRight))
&& nPixelXLeft + 1 != pInterval.m_pNext.get().m_nPixelX.get())
{
pIntervalNew.m_nPixelX.set(nPixelXLeft + 1);
pIntervalNew.m_nCoverage.set(pInterval.m_nCoverage.get());
pIntervalNew.m_pNext.set(pInterval.m_pNext.get());
pInterval.m_pNext.set(pIntervalNew);
interval_new_index += 1;
pIntervalNew = Ref::new(&Ref::get_ref(self.m_pIntervalBufferCurrent.get()).m_interval[interval_new_index])
}
if (nPixelXLeft == nPixelXRight)
{
pInterval.m_nCoverage.set(pInterval.m_nCoverage.get() + nSubpixelXRight - nSubpixelXLeft);
debug_assert!(pInterval.m_nCoverage.get() <= c_nShiftSize*c_nShiftSize);
self.interval_new_index.set(interval_new_index);
self.m_pIntervalNew.set(pIntervalNew);
return hr;
}
pInterval.m_nCoverage.set(pInterval.m_nCoverage.get() + nCoverageLeft);
debug_assert!(pInterval.m_nCoverage.get() <= c_nShiftSize*c_nShiftSize);
loop {
let nextInterval = pInterval.m_pNext.get();
(nPixelXNext = nextInterval.m_nPixelX.get());
if !(nPixelXNext < nPixelXRight) {
break;
}
pInterval = nextInterval;
pInterval.m_nCoverage.set(pInterval.m_nCoverage.get() + c_nShiftSize);
debug_assert!(pInterval.m_nCoverage.get() <= c_nShiftSize*c_nShiftSize);
}
self.m_pIntervalLast.set(pInterval);
if (nPixelXNext != nPixelXRight)
{
pIntervalNew.m_nPixelX.set(nPixelXRight);
pIntervalNew.m_nCoverage.set(pInterval.m_nCoverage.get() - c_nShiftSize);
pIntervalNew.m_pNext.set(pInterval.m_pNext.get());
pInterval.m_pNext.set(pIntervalNew);
pInterval = pIntervalNew;
interval_new_index += 1;
pIntervalNew = Ref::new(&Ref::get_ref(self.m_pIntervalBufferCurrent.get()).m_interval[interval_new_index])
}
else
{
pInterval = pInterval.m_pNext.get();
}
nCoverageRight = nSubpixelXRight & c_nShiftMask;
if (nCoverageRight > 0)
{
if (nPixelXRight + 1 != (*(*pInterval).m_pNext.get()).m_nPixelX.get())
{
pIntervalNew.m_nPixelX.set(nPixelXRight + 1);
pIntervalNew.m_nCoverage.set(pInterval.m_nCoverage.get());
pIntervalNew.m_pNext.set(pInterval.m_pNext.get());
pInterval.m_pNext.set(pIntervalNew);
interval_new_index += 1;
pIntervalNew = Ref::new(&Ref::get_ref(self.m_pIntervalBufferCurrent.get()).m_interval[interval_new_index])
}
pInterval.m_nCoverage.set((*pInterval).m_nCoverage.get() + nCoverageRight);
debug_assert!(pInterval.m_nCoverage.get() <= c_nShiftSize*c_nShiftSize);
}
self.interval_new_index.set(interval_new_index);
self.m_pIntervalNew.set(pIntervalNew);
return hr;
}
pub fn FillEdgesAlternating(&'a self,
pEdgeActiveList: Ref<CEdge>,
nSubpixelYCurrent: INT
) -> HRESULT
{
let hr: HRESULT = S_OK;
let mut pEdgeStart: Ref<CEdge> = (*pEdgeActiveList).Next.get();
let mut pEdgeEnd: Ref<CEdge>;
let mut nSubpixelXLeft: INT;
let mut nSubpixelXRight: INT;
ASSERTACTIVELIST!(pEdgeActiveList, nSubpixelYCurrent);
while (pEdgeStart.X.get() != INT::MAX)
{
pEdgeEnd = pEdgeStart.Next.get();
(nSubpixelXLeft = pEdgeStart.X.get());
if (nSubpixelXLeft != pEdgeEnd.X.get())
{
while ({(nSubpixelXRight = pEdgeEnd.X.get()); pEdgeEnd.X == pEdgeEnd.Next.get().X})
{
pEdgeEnd = pEdgeEnd.Next.get().Next.get();
}
debug_assert!((nSubpixelXLeft < nSubpixelXRight) && (nSubpixelXRight < INT::MAX));
IFC!(self.AddInterval(nSubpixelXLeft, nSubpixelXRight));
}
pEdgeStart = pEdgeEnd.Next.get();
}
return hr
}
pub fn FillEdgesWinding(&'a self,
pEdgeActiveList: Ref<CEdge>,
nSubpixelYCurrent: INT
) -> HRESULT
{
let hr: HRESULT = S_OK;
let mut pEdgeStart: Ref<CEdge> = pEdgeActiveList.Next.get();
let mut pEdgeEnd: Ref<CEdge>;
let mut nSubpixelXLeft: INT;
let mut nSubpixelXRight: INT;
let mut nWindingValue: INT;
ASSERTACTIVELIST!(pEdgeActiveList, nSubpixelYCurrent);
while (pEdgeStart.X.get() != INT::MAX)
{
pEdgeEnd = pEdgeStart.Next.get();
nWindingValue = pEdgeStart.WindingDirection;
while ({nWindingValue += pEdgeEnd.WindingDirection; nWindingValue != 0})
{
pEdgeEnd = pEdgeEnd.Next.get();
}
debug_assert!(pEdgeEnd.X.get() != INT::MAX);
if ({nSubpixelXLeft = pEdgeStart.X.get(); nSubpixelXLeft != pEdgeEnd.X.get()})
{
while ({nSubpixelXRight = pEdgeEnd.X.get(); nSubpixelXRight == pEdgeEnd.Next.get().X.get()})
{
pEdgeStart = pEdgeEnd.Next.get();
pEdgeEnd = pEdgeStart.Next.get();
nWindingValue = pEdgeStart.WindingDirection;
while ({nWindingValue += pEdgeEnd.WindingDirection; nWindingValue != 0})
{
pEdgeEnd = pEdgeEnd.Next.get();
}
}
debug_assert!((nSubpixelXLeft < nSubpixelXRight) && (nSubpixelXRight < INT::MAX));
IFC!(self.AddInterval(nSubpixelXLeft, nSubpixelXRight));
}
pEdgeStart = pEdgeEnd.Next.get();
}
return hr;}
pub fn Initialize(&'a self)
{
self.m_pIntervalBufferBuiltin.m_interval[0].m_nPixelX.set(INT::MIN);
self.m_pIntervalBufferBuiltin.m_interval[0].m_nCoverage.set(0);
self.m_pIntervalBufferBuiltin.m_interval[0].m_pNext.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[1]));
self.m_pIntervalBufferBuiltin.m_interval[1].m_nPixelX.set(INT::MAX);
self.m_pIntervalBufferBuiltin.m_interval[1].m_nCoverage.set(0xdeadbeef);
self.m_pIntervalBufferBuiltin.m_interval[1].m_pNext.set(unsafe { Ref::null() });
self.m_pIntervalBufferBuiltin.m_pNext.set(None);
self.m_pIntervalBufferCurrent.set(Ref::new(&self.m_pIntervalBufferBuiltin));
self.m_pIntervalStart.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[0]));
self.m_pIntervalNew.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[2]));
self.interval_new_index.set(2);
self.m_pIntervalEndMinus4.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[INTERVAL_BUFFER_NUMBER - 4]));
self.m_pIntervalLast.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[1]));
}
pub fn Destroy(&mut self)
{
}
pub fn Reset(&'a self)
{
self.m_pIntervalBufferBuiltin.m_interval[0].m_pNext.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[1]));
self.m_pIntervalBufferCurrent.set(Ref::new(&self.m_pIntervalBufferBuiltin));
self.m_pIntervalNew.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[2]));
self.interval_new_index.set(2);
self.m_pIntervalEndMinus4.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[INTERVAL_BUFFER_NUMBER - 4]));
self.m_pIntervalLast.set(Ref::new(&self.m_pIntervalBufferBuiltin.m_interval[1]));
}
fn Grow(&'a self,
ppIntervalNew: &mut Ref<'a, CCoverageInterval<'a>>,
ppIntervalEndMinus4: &mut Ref<'a, CCoverageInterval<'a>>,
interval_new_index: &mut usize
) -> HRESULT
{
let hr: HRESULT = S_OK;
let pIntervalBufferNew = (*self.m_pIntervalBufferCurrent.get()).m_pNext.get();
let pIntervalBufferNew = pIntervalBufferNew.unwrap_or_else(||
{
let pIntervalBufferNew = self.arena.alloc(Default::default());
(*pIntervalBufferNew).m_pNext.set(None);
(*self.m_pIntervalBufferCurrent.get()).m_pNext.set(Some(pIntervalBufferNew));
pIntervalBufferNew
});
self.m_pIntervalBufferCurrent.set(Ref::new(pIntervalBufferNew));
self.m_pIntervalNew.set(Ref::new(&(*pIntervalBufferNew).m_interval[2]));
self.interval_new_index.set(2);
self.m_pIntervalEndMinus4.set(Ref::new(&(*pIntervalBufferNew).m_interval[INTERVAL_BUFFER_NUMBER - 4]));
*ppIntervalNew = self.m_pIntervalNew.get();
*ppIntervalEndMinus4 = self.m_pIntervalEndMinus4.get();
*interval_new_index = 2;
return hr;
}
}