Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/font/XRTextRenderer.java
32287 views
1
/*
2
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.font;
27
28
import sun.awt.*;
29
import sun.java2d.SunGraphics2D;
30
import sun.java2d.pipe.GlyphListPipe;
31
import sun.java2d.xr.*;
32
33
/**
34
* A delegate pipe of SG2D for drawing any text to a XRender surface
35
*
36
* @author Clemens Eisserer
37
*/
38
public class XRTextRenderer extends GlyphListPipe {
39
// Workarround for a bug in libXrender.
40
// In case the number of glyphs of an ELT is a multiple of 254,
41
// a few garbage bytes are sent to the XServer causing hangs.
42
static final int MAX_ELT_GLYPH_COUNT = 253;
43
44
XRGlyphCache glyphCache;
45
XRCompositeManager maskBuffer;
46
XRBackend backend;
47
48
GrowableEltArray eltList;
49
50
public XRTextRenderer(XRCompositeManager buffer) {
51
glyphCache = new XRGlyphCache(buffer);
52
maskBuffer = buffer;
53
backend = buffer.getBackend();
54
eltList = new GrowableEltArray(64);
55
}
56
57
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
58
if (gl.getNumGlyphs() == 0) {
59
return;
60
}
61
62
try {
63
SunToolkit.awtLock();
64
65
XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
66
x11sd.validateAsDestination(null, sg2d.getCompClip());
67
x11sd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform, sg2d.paint, sg2d);
68
69
float advX = gl.getX();
70
float advY = gl.getY();
71
int oldPosX = 0, oldPosY = 0;
72
73
if (gl.isSubPixPos()) {
74
advX += 0.1666667f;
75
advY += 0.1666667f;
76
} else {
77
advX += 0.5f;
78
advY += 0.5f;
79
}
80
81
XRGlyphCacheEntry[] cachedGlyphs = glyphCache.cacheGlyphs(gl);
82
boolean containsLCDGlyphs = false;
83
int activeGlyphSet = cachedGlyphs[0].getGlyphSet();
84
85
int eltIndex = -1;
86
gl.getBounds();
87
float[] positions = gl.getPositions();
88
for (int i = 0; i < gl.getNumGlyphs(); i++) {
89
gl.setGlyphIndex(i);
90
XRGlyphCacheEntry cacheEntry = cachedGlyphs[i];
91
if (cacheEntry == null) {
92
continue;
93
}
94
95
eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
96
int glyphSet = cacheEntry.getGlyphSet();
97
98
containsLCDGlyphs |= (glyphSet == glyphCache.lcdGlyphSet);
99
100
int posX = 0, posY = 0;
101
if (gl.usePositions()
102
|| cacheEntry.getXAdvance() != ((float) cacheEntry.getXOff())
103
|| cacheEntry.getYAdvance() != ((float) cacheEntry.getYOff())
104
|| glyphSet != activeGlyphSet
105
|| eltIndex < 0
106
|| eltList.getCharCnt(eltIndex) == MAX_ELT_GLYPH_COUNT) {
107
108
eltIndex = eltList.getNextIndex();
109
eltList.setCharCnt(eltIndex, 1);
110
activeGlyphSet = glyphSet;
111
eltList.setGlyphSet(eltIndex, glyphSet);
112
113
if (gl.usePositions()) {
114
// In this case advX only stores rounding errors
115
float x = positions[i * 2] + advX;
116
float y = positions[i * 2 + 1] + advY;
117
posX = (int) Math.floor(x);
118
posY = (int) Math.floor(y);
119
advX -= cacheEntry.getXOff();
120
advY -= cacheEntry.getYOff();
121
} else {
122
/*
123
* Calculate next glyph's position in the case of
124
* relative positioning. In XRender we can only position
125
* glyphs using integer coordinates, therefor we sum all
126
* the advances up as float, and convert them to integer
127
* later. This way rounding-error can be corrected, and
128
* is required to be consistent with the software loops.
129
*/
130
posX = (int) Math.floor(advX);
131
posY = (int) Math.floor(advY);
132
133
// Advance of ELT = difference between stored relative
134
// positioning information and required float.
135
advX += (cacheEntry.getXAdvance() - cacheEntry.getXOff());
136
advY += (cacheEntry.getYAdvance() - cacheEntry.getYOff());
137
}
138
139
// Offset of the current glyph is the difference
140
// to the last glyph and this one
141
eltList.setXOff(eltIndex, (posX - oldPosX));
142
eltList.setYOff(eltIndex, (posY - oldPosY));
143
144
oldPosX = posX;
145
oldPosY = posY;
146
147
} else {
148
eltList.setCharCnt(eltIndex, eltList.getCharCnt(eltIndex) + 1);
149
}
150
}
151
152
int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8;
153
maskBuffer.compositeText(x11sd, (int) gl.getX(), (int) gl.getY(), 0, maskFormat, eltList);
154
155
eltList.clear();
156
} finally {
157
SunToolkit.awtUnlock();
158
}
159
}
160
}
161
162