/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * 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 file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
OSL_ENSURE(nStopLine >= nStartLine, "nStopLine is bigger than nStartLine (!)");
// sort global entries by Y, X once. After this, the vector // is seen as frozen. Pointers to its entries will be used in the following code.
std::sort(maLineEntries.begin(), maLineEntries.end());
// get scanlines first LineNumber as start
sal_Int32 nLineNumber(std::max(aCurrentEntry->getY(), nStartLine));
while((!aCurrentLine.empty() || aCurrentEntry != maLineEntries.end()) && (nLineNumber < nStopLine))
{ // add all entries which start at current line to current scanline while(aCurrentEntry != maLineEntries.end())
{ const sal_Int32 nCurrentLineNumber(aCurrentEntry->getY());
if(nCurrentLineNumber > nLineNumber)
{ // line is below current one, done (since array is sorted) break;
} else
{ // less or equal. Line is above or at current one. Advance it exactly to // current line const sal_uInt32 nStep(nLineNumber - nCurrentLineNumber);
if(!nStep || aCurrentEntry->decrementRasterConversionLineEntry3D(nStep))
{ // add when exactly on current line or when increment to it did not // completely consume it if(nStep)
{
aCurrentEntry->incrementRasterConversionLineEntry3D(nStep, *this);
}
aCurrentLine.push_back(&(*aCurrentEntry));
}
}
++aCurrentEntry;
}
// sort current scanline using comparator. Only X is used there // since all entries are already in one processed line. This needs to be done // every time since not only new spans may have benn added or old removed, // but incrementing may also have changed the order
std::sort(aCurrentLine.begin(), aCurrentLine.end(), lineComparator());
// process current scanline
aRasterConversionLineEntry3D = aCurrentLine.begin();
aNextLine.clear();
sal_uInt32 nPairCount(0);
// look for 2nd span if(aRasterConversionLineEntry3D != aCurrentLine.end())
{ // work on span from rPrevScanRasterConversionLineEntry3D to aRasterConversionLineEntry3D, fLineNumber is valid
processLineSpan(rPrevScanRasterConversionLineEntry3D, **aRasterConversionLineEntry3D, nLineNumber, nPairCount++);
}
// increment to next line if(rPrevScanRasterConversionLineEntry3D.decrementRasterConversionLineEntry3D(1))
{
rPrevScanRasterConversionLineEntry3D.incrementRasterConversionLineEntry3D(1, *this);
aNextLine.push_back(&rPrevScanRasterConversionLineEntry3D);
}
}
// copy back next scanline if count has changed if(aNextLine.size() != aCurrentLine.size())
{
aCurrentLine = aNextLine;
}
// if extra interpolation data is used, add it to the last created entry
RasterConversionLineEntry3D& rEntry = maLineEntries[maLineEntries.size() - 1];
if(nLineWidth > 1)
{ // this is not a hairline anymore, in most cases since it's an oversampled // hairline to get e.g. AA for Z-Buffering. Create fill geometry. if(!aStart.equal(aEnd))
{
reset();
maLineEntries.clear();
addArea(aPolygon, nullptr);
}
} else
{ // it's a hairline. Use direct RasterConversionLineEntry creation to // rasterconvert lines as similar to areas as possible to avoid Z-Fighting
sal_Int32 nYStart(fround(aStart.getY()));
sal_Int32 nYEnd(fround(aEnd.getY()));
// horizontal line, create vertical entries. These will be sorted by // X anyways, so no need to distinguish the case here
maLineEntries.emplace_back(
aStart.getX(), 0.0,
aStart.getZ() + fZBufferLineAdd, 0.0,
nYStart, 1);
maLineEntries.emplace_back(
aEnd.getX(), 0.0,
aEnd.getZ() + fZBufferLineAdd, 0.0,
nYStart, 1);
}
} else
{
reset();
maLineEntries.clear();
// non-horizontal line, create two parallel entries. These will be sorted by // X anyways, so no need to distinguish the case here
maLineEntries.emplace_back(
aStart.getX(), (aEnd.getX() - aStart.getX()) * fInvYDelta,
aStart.getZ() + fZBufferLineAdd, (aEnd.getZ() - aStart.getZ()) * fInvYDelta,
nYStart, nYDelta);
// need to choose a X-Distance for the 2nd edge which guarantees all pixels // of the line to be set. This is exactly the X-Increment for one Y-Step. // Same is true for Z, so in both cases, add one increment to them. To also // guarantee one pixel per line, add a minimum of one for X. constdouble fDistanceX(fabs(rEntry.getX().getInc()) >= 1.0 ? rEntry.getX().getInc() : 1.0);
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 und die Messung sind noch experimentell.