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/native/sun/java2d/x11/X11TextRenderer_md.c
32288 views
1
/*
2
* Copyright (c) 2001, 2005, 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
#include "GlyphImageRef.h"
27
28
#ifdef HEADLESS
29
#include "SurfaceData.h"
30
#else
31
#include "X11SurfaceData.h"
32
#include "GraphicsPrimitiveMgr.h"
33
#endif /* !HEADLESS */
34
#include <jlong.h>
35
36
#define TEXT_BM_WIDTH 1024
37
#define TEXT_BM_HEIGHT 32
38
39
#ifndef HEADLESS
40
41
static jboolean checkPixmap(JNIEnv *env, AwtGraphicsConfigDataPtr cData)
42
{
43
XImage *img;
44
int image_size;
45
Window root;
46
47
if (cData->monoImage == NULL) {
48
img = XCreateImage(awt_display, NULL, 1, XYBitmap, 0, 0,
49
TEXT_BM_WIDTH, TEXT_BM_HEIGHT, 32, 0);
50
if (img != NULL) {
51
image_size = img->bytes_per_line * TEXT_BM_HEIGHT;
52
// assert(BM_W and BM_H are not large enough to overflow);
53
img->data = (char *) malloc(image_size);
54
if (img->data == NULL) {
55
XFree(img);
56
} else {
57
// Force same bit/byte ordering
58
img->bitmap_bit_order = img->byte_order;
59
cData->monoImage = img;
60
}
61
}
62
if (cData->monoImage == NULL) {
63
JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmap for text");
64
return JNI_FALSE;
65
}
66
}
67
if (cData->monoPixmap == 0 ||
68
cData->monoPixmapGC == NULL ||
69
cData->monoPixmapWidth != TEXT_BM_WIDTH ||
70
cData->monoPixmapHeight != TEXT_BM_HEIGHT)
71
{
72
if (cData->monoPixmap != 0) {
73
XFreePixmap(awt_display, cData->monoPixmap);
74
cData->monoPixmap = 0;
75
}
76
if (cData->monoPixmapGC != NULL) {
77
XFreeGC(awt_display, cData->monoPixmapGC);
78
cData->monoPixmapGC = 0;
79
}
80
root = RootWindow(awt_display, cData->awt_visInfo.screen);
81
cData->monoPixmap = XCreatePixmap(awt_display, root,
82
TEXT_BM_WIDTH, TEXT_BM_HEIGHT, 1);
83
if (cData->monoPixmap == 0) {
84
JNU_ThrowOutOfMemoryError(env, "Cannot allocate pixmap for text");
85
return JNI_FALSE;
86
}
87
cData->monoPixmapGC = XCreateGC(awt_display, cData->monoPixmap,
88
0, NULL);
89
if (cData->monoPixmapGC == NULL) {
90
XFreePixmap(awt_display, cData->monoPixmap);
91
cData->monoPixmap = 0;
92
JNU_ThrowOutOfMemoryError(env, "Cannot allocate pixmap for text");
93
return JNI_FALSE;
94
}
95
XSetForeground(awt_display, cData->monoPixmapGC, 1);
96
XSetBackground(awt_display, cData->monoPixmapGC, 0);
97
cData->monoPixmapWidth = TEXT_BM_WIDTH;
98
cData->monoPixmapHeight = TEXT_BM_HEIGHT;
99
}
100
return JNI_TRUE;
101
}
102
103
static void FillBitmap(XImage *theImage,
104
ImageRef *glyphs, jint totalGlyphs,
105
jint clipLeft, jint clipTop,
106
jint clipRight, jint clipBottom)
107
{
108
int glyphCounter;
109
int scan = theImage->bytes_per_line;
110
int y, left, top, right, bottom, width, height;
111
jubyte *pPix;
112
const jubyte *pixels;
113
unsigned int rowBytes;
114
115
pPix = (jubyte *) theImage->data;
116
glyphCounter = ((clipRight - clipLeft) + 7) >> 3;
117
for (y = clipTop; y < clipBottom; y++) {
118
memset(pPix, 0, glyphCounter);
119
pPix += scan;
120
}
121
122
for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
123
pixels = (const jubyte *)glyphs[glyphCounter].pixels;
124
if (!pixels) {
125
continue;
126
}
127
rowBytes = glyphs[glyphCounter].width;
128
left = glyphs[glyphCounter].x;
129
top = glyphs[glyphCounter].y;
130
width = glyphs[glyphCounter].width;
131
height = glyphs[glyphCounter].height;
132
133
/* if any clipping required, modify parameters now */
134
right = left + width;
135
bottom = top + height;
136
if (left < clipLeft) {
137
pixels += clipLeft - left;
138
left = clipLeft;
139
}
140
if (top < clipTop) {
141
pixels += (clipTop - top) * rowBytes;
142
top = clipTop;
143
}
144
if (right > clipRight) {
145
right = clipRight;
146
}
147
if (bottom > clipBottom) {
148
bottom = clipBottom;
149
}
150
if (right <= left || bottom <= top) {
151
continue;
152
}
153
width = right - left;
154
height = bottom - top;
155
top -= clipTop;
156
left -= clipLeft;
157
pPix = ((jubyte *) theImage->data) + (left >> 3) + (intptr_t) top * scan;
158
left &= 0x07;
159
if (theImage->bitmap_bit_order == MSBFirst) {
160
left = 0x80 >> left;
161
do {
162
int x = 0, bx = 0;
163
int pix = pPix[0];
164
int bit = left;
165
do {
166
if (bit == 0) {
167
pPix[bx] = (jubyte) pix;
168
pix = pPix[++bx];
169
bit = 0x80;
170
}
171
if (pixels[x]) {
172
pix |= bit;
173
}
174
bit >>= 1;
175
} while (++x < width);
176
pPix[bx] = (jubyte) pix;
177
pPix += scan;
178
pixels += rowBytes;
179
} while (--height > 0);
180
} else {
181
left = 1 << left;
182
do {
183
int x = 0, bx = 0;
184
int pix = pPix[0];
185
int bit = left;
186
do {
187
if ((bit >> 8) != 0) {
188
pPix[bx] = (jubyte) pix;
189
pix = pPix[++bx];
190
bit = 1;
191
}
192
if (pixels[x]) {
193
pix |= bit;
194
}
195
bit <<= 1;
196
} while (++x < width);
197
pPix[bx] = (jubyte) pix;
198
pPix += scan;
199
pixels += rowBytes;
200
} while (--height > 0);
201
}
202
}
203
}
204
#endif /* !HEADLESS */
205
206
JNIEXPORT void JNICALL
207
AWTDrawGlyphList(JNIEnv *env, jobject xtr,
208
jlong dstData, jlong gc,
209
SurfaceDataBounds *bounds, ImageRef *glyphs, jint totalGlyphs)
210
{
211
#ifndef HEADLESS
212
GC xgc, theGC;
213
XImage *theImage;
214
Pixmap thePixmap;
215
XGCValues xgcv;
216
int scan, screen;
217
AwtGraphicsConfigDataPtr cData;
218
X11SDOps *xsdo = (X11SDOps *)jlong_to_ptr(dstData);
219
jint cx1, cy1, cx2, cy2;
220
221
if (xsdo == NULL) {
222
return;
223
}
224
225
xgc = (GC)gc;
226
if (xgc == NULL) {
227
return;
228
}
229
230
screen = xsdo->configData->awt_visInfo.screen;
231
cData = getDefaultConfig(screen);
232
if (!checkPixmap(env, cData)) {
233
return;
234
}
235
theImage = cData->monoImage;
236
thePixmap = cData->monoPixmap;
237
theGC = cData->monoPixmapGC;
238
239
scan = theImage->bytes_per_line;
240
241
xgcv.fill_style = FillStippled;
242
xgcv.stipple = thePixmap;
243
xgcv.ts_x_origin = bounds->x1;
244
xgcv.ts_y_origin = bounds->y1;
245
XChangeGC(awt_display, xgc,
246
GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin,
247
&xgcv);
248
249
cy1 = bounds->y1;
250
while (cy1 < bounds->y2) {
251
cy2 = cy1 + TEXT_BM_HEIGHT;
252
if (cy2 > bounds->y2) cy2 = bounds->y2;
253
254
cx1 = bounds->x1;
255
while (cx1 < bounds->x2) {
256
cx2 = cx1 + TEXT_BM_WIDTH;
257
if (cx2 > bounds->x2) cx2 = bounds->x2;
258
259
FillBitmap(theImage,
260
glyphs,
261
totalGlyphs,
262
cx1, cy1, cx2, cy2);
263
264
// NOTE: Since we are tiling around by BM_W, BM_H offsets
265
// and thePixmap is BM_W x BM_H, we do not have to move
266
// the TSOrigin at each step since the stipple repeats
267
// every BM_W, BM_H units
268
XPutImage(awt_display, thePixmap, theGC, theImage,
269
0, 0, 0, 0, cx2 - cx1, cy2 - cy1);
270
/* MGA on Linux doesn't pick up the new stipple image data,
271
* probably because it caches the image as a hardware pixmap
272
* and doesn't update it when the pixmap image data is changed.
273
* So if the loop is executed more than once, update the GC
274
* which triggers the required behaviour. This extra XChangeGC
275
* call only happens on large or rotated text so isn't a
276
* significant new overhead..
277
* This code needs to execute on a Solaris client too, in case
278
* we are remote displaying to a MGA.
279
*/
280
if (cy1 != bounds->y1 || cx1 != bounds->x1) {
281
XChangeGC(awt_display, xgc, GCStipple, &xgcv);
282
}
283
284
XFillRectangle(awt_display, xsdo->drawable, xgc,
285
cx1, cy1, cx2 - cx1, cy2 - cy1);
286
287
cx1 = cx2;
288
}
289
290
cy1 = cy2;
291
}
292
XSetFillStyle(awt_display, xgc, FillSolid);
293
294
X11SD_DirectRenderNotify(env, xsdo);
295
#endif /* !HEADLESS */
296
}
297
298