use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getItalicBounds.
public Rectangle2D getItalicBounds() {
float left = Float.MAX_VALUE, right = -Float.MAX_VALUE;
float top = Float.MAX_VALUE, bottom = -Float.MAX_VALUE;
for (int i = 0, n = 0; i < fComponents.length; i++, n += 2) {
TextLineComponent tlc = fComponents[getComponentLogicalIndex(i)];
Rectangle2D tlcBounds = tlc.getItalicBounds();
float x = locs[n];
float y = locs[n + 1];
left = Math.min(left, x + (float) tlcBounds.getX());
right = Math.max(right, x + (float) tlcBounds.getMaxX());
top = Math.min(top, y + (float) tlcBounds.getY());
bottom = Math.max(bottom, y + (float) tlcBounds.getMaxY());
}
return new Rectangle2D.Float(left, top, right - left, bottom - top);
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getJustifiedLine.
/*
* create a new line with characters between charStart and charLimit
* justified using the provided width and ratio.
*/
public TextLine getJustifiedLine(float justificationWidth, float justifyRatio, int justStart, int justLimit) {
TextLineComponent[] newComponents = new TextLineComponent[fComponents.length];
System.arraycopy(fComponents, 0, newComponents, 0, fComponents.length);
float leftHang = 0;
float adv = 0;
float justifyDelta = 0;
boolean rejustify = false;
do {
adv = getAdvanceBetween(newComponents, 0, characterCount());
// all characters outside the justification range must be in the base direction
// of the layout, otherwise justification makes no sense.
float justifyAdvance = getAdvanceBetween(newComponents, justStart, justLimit);
// get the actual justification delta
justifyDelta = (justificationWidth - justifyAdvance) * justifyRatio;
// generate an array of GlyphJustificationInfo records to pass to
// the justifier. Array is visually ordered.
// get positions that each component will be using
int[] infoPositions = new int[newComponents.length];
int infoCount = 0;
for (int visIndex = 0; visIndex < newComponents.length; visIndex++) {
int logIndex = getComponentLogicalIndex(visIndex);
infoPositions[logIndex] = infoCount;
infoCount += newComponents[logIndex].getNumJustificationInfos();
}
GlyphJustificationInfo[] infos = new GlyphJustificationInfo[infoCount];
// get justification infos
int compStart = 0;
for (int i = 0; i < newComponents.length; i++) {
TextLineComponent comp = newComponents[i];
int compLength = comp.getNumCharacters();
int compLimit = compStart + compLength;
if (compLimit > justStart) {
int rangeMin = Math.max(0, justStart - compStart);
int rangeMax = Math.min(compLength, justLimit - compStart);
comp.getJustificationInfos(infos, infoPositions[i], rangeMin, rangeMax);
if (compLimit >= justLimit) {
break;
}
}
}
// records are visually ordered, and contiguous, so start and end are
// simply the places where we didn't fetch records
int infoStart = 0;
int infoLimit = infoCount;
while (infoStart < infoLimit && infos[infoStart] == null) {
++infoStart;
}
while (infoLimit > infoStart && infos[infoLimit - 1] == null) {
--infoLimit;
}
// invoke justifier on the records
TextJustifier justifier = new TextJustifier(infos, infoStart, infoLimit);
float[] deltas = justifier.justify(justifyDelta);
boolean canRejustify = rejustify == false;
boolean wantRejustify = false;
boolean[] flags = new boolean[1];
// apply justification deltas
compStart = 0;
for (int i = 0; i < newComponents.length; i++) {
TextLineComponent comp = newComponents[i];
int compLength = comp.getNumCharacters();
int compLimit = compStart + compLength;
if (compLimit > justStart) {
int rangeMin = Math.max(0, justStart - compStart);
int rangeMax = Math.min(compLength, justLimit - compStart);
newComponents[i] = comp.applyJustificationDeltas(deltas, infoPositions[i] * 2, flags);
wantRejustify |= flags[0];
if (compLimit >= justLimit) {
break;
}
}
}
// only make two passes
rejustify = wantRejustify && !rejustify;
} while (rejustify);
return new TextLine(frc, newComponents, fBaselineOffsets, fChars, fCharsStart, fCharsLimit, fCharLogicalOrder, fCharLevels, fIsDirectionLTR);
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method createComponentsOnRun.
/**
* Returns an array in logical order of the TextLineComponents on
* the text in the given range, with the given attributes.
*/
public static TextLineComponent[] createComponentsOnRun(int runStart, int runLimit, char[] chars, int[] charsLtoV, byte[] levels, TextLabelFactory factory, Font font, CoreMetrics cm, FontRenderContext frc, Decoration decorator, TextLineComponent[] components, int numComponents) {
int pos = runStart;
do {
// <= displayLimit
int chunkLimit = firstVisualChunk(charsLtoV, levels, pos, runLimit);
do {
int startPos = pos;
int lmCount;
if (cm == null) {
LineMetrics lineMetrics = font.getLineMetrics(chars, startPos, chunkLimit, frc);
cm = CoreMetrics.get(lineMetrics);
lmCount = lineMetrics.getNumChars();
} else {
lmCount = (chunkLimit - startPos);
}
TextLineComponent nextComponent = factory.createExtended(font, cm, decorator, startPos, startPos + lmCount);
++numComponents;
if (numComponents >= components.length) {
components = expandArray(components);
}
components[numComponents - 1] = nextComponent;
pos += lmCount;
} while (pos < chunkLimit);
} while (pos < runLimit);
return components;
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getPixelBounds.
public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
Rectangle result = null;
// for each component
if (frc != null && frc.equals(this.frc)) {
frc = null;
}
// only cache integral locations with the default frc, this is a bit strict
int ix = (int) Math.floor(x);
int iy = (int) Math.floor(y);
float rx = x - ix;
float ry = y - iy;
boolean canCache = frc == null && rx == 0 && ry == 0;
if (canCache && pixelBounds != null) {
result = new Rectangle(pixelBounds);
result.x += ix;
result.y += iy;
return result;
}
if (isSimple) {
// all glyphvectors with no decorations, no layout path
for (int i = 0, n = 0; i < fComponents.length; i++, n += 2) {
TextLineComponent tlc = fComponents[getComponentLogicalIndex(i)];
Rectangle pb = tlc.getPixelBounds(frc, locs[n] + rx, locs[n + 1] + ry);
if (!pb.isEmpty()) {
if (result == null) {
result = pb;
} else {
result.add(pb);
}
}
}
if (result == null) {
result = new Rectangle(0, 0, 0, 0);
}
} else {
// draw and test
final int MARGIN = 3;
Rectangle2D r2d = getVisualBounds();
if (lp != null) {
r2d = lp.mapShape(r2d).getBounds();
}
Rectangle bounds = r2d.getBounds();
BufferedImage im = new BufferedImage(bounds.width + MARGIN * 2, bounds.height + MARGIN * 2, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = im.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, im.getWidth(), im.getHeight());
g2d.setColor(Color.BLACK);
draw(g2d, rx + MARGIN - bounds.x, ry + MARGIN - bounds.y);
result = computePixelBounds(im);
result.x -= MARGIN - bounds.x;
result.y -= MARGIN - bounds.y;
}
if (canCache) {
pixelBounds = new Rectangle(result);
}
result.x += ix;
result.y += iy;
return result;
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getAdvanceBetween.
// return the sum of the advances of text between the logical start and limit
public static float getAdvanceBetween(TextLineComponent[] components, int start, int limit) {
float advance = 0;
int tlcStart = 0;
for (int i = 0; i < components.length; i++) {
TextLineComponent comp = components[i];
int tlcLength = comp.getNumCharacters();
int tlcLimit = tlcStart + tlcLength;
if (tlcLimit > start) {
int measureStart = Math.max(0, start - tlcStart);
int measureLimit = Math.min(tlcLength, limit - tlcStart);
advance += comp.getAdvanceBetween(measureStart, measureLimit);
if (tlcLimit >= limit) {
break;
}
}
tlcStart = tlcLimit;
}
return advance;
}
Aggregations