ext.plantuml.com.ctreber.acearth.scanbit.ScanBuf Maven / Gradle / Ivy
Show all versions of plantuml-gplv2 Show documentation
// THIS FILE HAS BEEN GENERATED BY A PREPROCESSOR.
/* +=======================================================================
* |
* | PlantUML : a free UML diagram generator
* |
* +=======================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/liberapay (only 1€ per month!)
* https://plantuml.com/paypal
*
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License V2.
*
* THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
* LICENSE ("AGREEMENT"). [GNU General Public License V2]
*
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
*
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* PlantUML can occasionally display sponsored or advertising messages. Those
* messages are usually generated on welcome or error images and never on
* functional diagrams.
* See https://plantuml.com/professional if you want to remove them
*
* Images (whatever their format : PNG, SVG, EPS...) generated by running PlantUML
* are owned by the author of their corresponding sources code (that is, their
* textual description in PlantUML language). Those images are not covered by
* this GPL v2 license.
*
* The generated images can then be used without any reference to the GPL v2 license.
* It is not even necessary to stipulate that they have been generated with PlantUML,
* although this will be appreciated by the PlantUML team.
*
* There is an exception : if the textual description in PlantUML language is also covered
* by any license, then the generated images are logically covered
* by the very same license.
*
* This is the IGY distribution (Install GraphViz by Yourself).
* You have to install GraphViz and to setup the GRAPHVIZ_DOT environment variable
* (see https://plantuml.com/graphviz-dot )
*
* Icons provided by OpenIconic : https://useiconic.com/open
* Archimate sprites provided by Archi : http://www.archimatetool.com
* Stdlib AWS provided by https://github.com/milo-minderbinder/AWS-PlantUML
* Stdlib Icons provided https://github.com/tupadr3/plantuml-icon-font-sprites
* ASCIIMathML (c) Peter Jipsen http://www.chapman.edu/~jipsen
* ASCIIMathML (c) David Lippman http://www.pierce.ctc.edu/dlippman
* CafeUndZopfli ported by Eugene Klyuchnikov https://github.com/eustas/CafeUndZopfli
* Brotli (c) by the Brotli Authors https://github.com/google/brotli
* Themes (c) by Brett Schwarz https://github.com/bschwarz/puml-themes
* Twemoji (c) by Twitter at https://twemoji.twitter.com/
*
*/
package ext.plantuml.com.ctreber.acearth.scanbit;
import java.util.ArrayList;
import java.util.List;
import ext.plantuml.com.ctreber.aclib.sort.CTSort;
import ext.plantuml.com.ctreber.aclib.sort.QuickSort;
/**
* For each line, the scanbuffer (= a raster divice) records the points hit
* I.e., line 5 (y=5) contains the values 2, 6, 40, and 46 (these line have
* been crossed). The values always come as pairs because we're dealing with
* polygons, which have a left and a right side which consists of a line.
* The points in between two values painted as filled.
*
*
© 2002 Christian Treber, [email protected]
* @author Christian Treber, [email protected]
*
*/
class ScanBuf
{
private List[] fScanbuf;
private int fLineMin;
private int fLineMax;
private final int fLines;
private final int fPoints;
private boolean fScanBufsAdded;
/**
*
Create a list for each line.
*
* @param pLines Number of lines aka screen height.
* @param pPoints Number of points per line aka screen width.
*/
public ScanBuf(int pLines, int pPoints)
{
fLines = pLines;
fPoints = pPoints;
fLineMin = Integer.MAX_VALUE;
fLineMax = Integer.MIN_VALUE;
fScanBufsAdded = false;
fScanbuf = new ArrayList[fLines];
for(int i = 0; i < fScanbuf.length; i++)
{
fScanbuf[i] = new ArrayList();
}
}
/**
*
Add a line to the generateScanBits buffer.
*/
public void addLine(double pXFrom, double pYFrom, double pXTo, double pYTo)
{
int lYFrom;
int lYTo;
// Do some rounding (but not in the way we expect it), limit values
if(pYFrom < pYTo)
{
// Round lYFrom (but .5 is handled oddly)
// 1.5001 - 2.5 -> 1.0001 - 2.0 -> 2
lYFrom = (int)Math.ceil(pYFrom - 0.5);
// Round lYTo, substract 1
// 1.5 - 2.4999 -> 1.0 - 1.9999 -> 1
lYTo = (int)Math.floor(pYTo - 0.5);
/**
* I don't know if this is intended, but in Java 3 == 3.001 is false
* (the left arg is converted to double), so the expr is true only when
* pYTo - 0.5 is exactly lYTo
*/
if(lYTo == pYTo - 0.5)
{
lYTo--;
}
} else
{
lYFrom = (int)Math.ceil(pYTo - 0.5);
lYTo = (int)Math.floor(pYFrom - 0.5);
if(lYTo == pYFrom - 0.5)
{
lYTo--;
}
}
// Limit y to size of image
if(lYFrom < 0)
{
lYFrom = 0;
}
if(lYTo >= fLines)
{
lYTo = fLines - 1;
}
if(lYFrom > lYTo)
{
// No lines crossed.
return;
}
// Note min/max settings so far
if(lYFrom < fLineMin)
{
fLineMin = lYFrom;
}
if(lYTo > fLineMax)
{
fLineMax = lYTo;
}
// todo Curious: What happens if yFrom and yTo are equal? Shit? Or can't they be?
double lDx = (pXTo - pXFrom) / (pYTo - pYFrom);
double lX = pXFrom + lDx * ((lYFrom + 0.5) - pYFrom);
// Record the x value for every line (y).
for(int lLineNo = lYFrom; lLineNo <= lYTo; lLineNo++)
{
fScanbuf[lLineNo].add(Double.valueOf(lX));
lX += lDx;
}
fScanBufsAdded = true;
}
public boolean containsPoints()
{
return fScanBufsAdded;
}
/**
*
For each line, for each x value pair in line, create one ScanBit.
*/
public List getScanbits(int pCurveType)
{
final List fScanBits = new ArrayList();
// For each generateScanBits line containing points
for(int lLineNo = fLineMin; lLineNo <= fLineMax; lLineNo++)
{
// Sort so that lowest x values come first.
Double[] lScanLine = (Double[])fScanbuf[lLineNo].toArray(new Double[0]);
CTSort lSort = new QuickSort();
lSort.sort(lScanLine);
// The length will be divisible by 2 because we render closed polyons,
// so every generateScanBits line is crossed twice (left and right edge of polygon,
// no intersections allowed!).
for(int n = 0; n < lScanLine.length; n += 2)
{
// Round lLineFrom (but .5 is handled oddly)
// 1.5001 - 2.5 -> 1.0001 - 2.0 -> 2
int lXLo = (int)Math.ceil(lScanLine[n] - 0.5);
// Round lLineTo, substract 1
// 1.5 - 2.4999 -> 1.0 - 1.9999 -> 1
int lXHi = (int)Math.floor(lScanLine[n + 1] - 0.5);
// Limit low and high x to image dimensions
if(lXLo < 0)
{
lXLo = 0;
}
if(lXHi >= fPoints)
{
lXHi = fPoints - 1;
}
if(lXLo <= lXHi)
{
/**
* Shouldn't that always be true since we sorted? "Yes", BUT the
* rounding might create lo 3.6 -> 4.0 and hi 3.7 -> 3.0
*/
fScanBits.add(new ScanBit(lLineNo, lXLo, lXHi, pCurveType));
}
}
}
return fScanBits;
}
public int getYMax()
{
return fLineMax;
}
public int getYMin()
{
return fLineMin;
}
}