2362N/A * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * Need to account for the rare case when (eg) repainting damaged 0N/A * areas results in the drawing location being negative, in which 0N/A * case (int) rounding always goes towards zero. We need to always 0N/A * round down instead, so that we paint at the correct position. 0N/A * We only call "floor" when value is < 0 (ie rarely). 0N/A * Storing the result of (eg) (x+ginfo->topLeftX) benchmarks is more 0N/A * expensive than repeating the calculation as we do here. 0N/A * "floor" shows up as a significant cost in app-level microbenchmarks. 0N/A * This macro avoids calling it on positive values, instead using an 0N/A if ((r)<0) (l) = ((
int)
floor(r));
else (l) = ((
int)(r))
0N/A /* Add 0.5 to x and y and then use floor (or an equivalent operation) 0N/A * to round down the glyph positions to integral pixel positions. 0N/A /* copy image data into this array at x/y locations */ 0N/A/* since the AA and non-AA loop functions share a common method 0N/A * signature, can call both through this common function since 0N/A * there's no difference except for the inner loop. 0N/A * This could be a macro but there's enough of those already. 0N/A * Class: sun_java2d_loops_DrawGlyphList 0N/A * Method: DrawGlyphList 0N/A * Class: sun_java2d_loops_DrawGlyphListAA 0N/A * Method: DrawGlyphListAA 0N/A * Class: sun_java2d_loops_DrawGlyphListLCD 0N/A * Method: DrawGlyphListLCD 0N/A * LCD text utilises a filter which spreads energy to adjacent subpixels. 0N/A * So we add 3 bytes (one whole pixel) of padding at the start of every row 0N/A * to hold energy from the very leftmost sub-pixel. 0N/A * This is to the left of the intended glyph image position so LCD text also 0N/A * adjusts the top-left X position of the padded image one pixel to the left 0N/A * so a glyph image is drawn in the same place it would be if the padding 0N/A * So in the glyph cache for LCD text the first two bytes of every row are 0N/A * We make use of this to be able to adjust the rendering position of the 0N/A * text when the client specifies a fractional metrics sub-pixel positioning 0N/A * So the first 6 bytes in a cache row looks like : 0N/A * 00 are the always zero bytes 0N/A * Ex is extra energy spread from the glyph into the left padding pixel. 0N/A * Gn are the RGB component bytes of the first pixel of the glyph image 0N/A * For an RGB display G0 is the red component, etc. 0N/A * If a glyph is drawn at X=12 then the G0 G1 G2 pixel is placed at that 0N/A * position : ie G0 is drawn in the first sub-pixel at X=12 0N/A * PIXEL POS 11 11 11 12 12 12 13 13 13 0N/A * SUBPX POS 0 1 2 0 1 2 0 1 2 0N/A * If a sub-pixel rounded glyph position is calculated as being X=12.33 - 0N/A * ie 12 and one-third pixels, we want the result to look like this : 0N/A * PIXEL POS 11 11 11 12 12 12 13 13 13 0N/A * SUBPX POS 0 1 2 0 1 2 0 1 2 0N/A * ie the G0 byte is moved one sub-pixel to the right. 0N/A * To do this we need to make two adjustments : 0N/A * - set start of scan row to start+2, ie index past the two zero bytes 0N/A * ie we don't need the 00 00 bytes at all any more. Rendering start X 0N/A * can skip over those. 0N/A * Lets look at the final case : 0N/A * If a sub-pixel rounded glyph position is calculated as being X=12.67 - 0N/A * ie 12 and two-third pixels, we want the result to look like this : 0N/A * PIXEL POS 11 11 11 12 12 12 13 13 13 0N/A * SUBPX POS 0 1 2 0 1 2 0 1 2 0N/A * ie the G0 byte is moved two sub-pixels to the right, so that the image 0N/A * To do this we need to make these two adjustments : 0N/A * - set start of scan row to start+1, ie index past the first zero byte 0N/A * In this case the second of the 00 bytes is used as a no-op on the first 0N/A * red sub-pixel position. 0N/A * The final adjustment needed to make all this work is note that if 0N/A * we moved the start of row one or two bytes in we will go one or two bytes 0N/A * past the end of the row. So the glyph cache needs to have 2 bytes of 0N/A * zero padding at the end of each row. This is the extra memory cost to 0N/A * accommodate this algorithm. 0N/A * The resulting text is perhaps fractionally better in overall perception 0N/A * than rounding to the whole pixel grid, as a few issues arise. 0N/A * * the improvement in inter-glyph spacing as well as being limited 0N/A * to 1/3 pixel resolution, is also limited because the glyphs were hinted 0N/A * so they fit to the whole pixel grid. It may be worthwhile to pursue 0N/A * disabling x-axis gridfitting. 0N/A * * an LCD display may have gaps between the pixels that are greater 0N/A * than the subpixels. Thus for thin stemmed fonts, if the shift causes 0N/A * the "heart" of a stem to span whole pixels it may appear more diffuse - 0N/A * less sharp. Eliminating hinting would probably not make this worse - in 0N/A * effect we have already doing that here. But it would improve the spacing. 0N/A * * perhaps contradicting the above point in some ways, more diffuse glyphs 0N/A * are better at reducing colour fringing, but what appears to be more 0N/A * colour fringing in this FM case is more likely attributable to a greater 0N/A * likelihood for glyphs to abutt. In integer metrics or even whole pixel 0N/A * rendered fractional metrics, there's typically more space between the 0N/A * glyphs. Perhaps disabling X-axis grid-fitting will help with that. 0N/A /* The position of the start of the text is adjusted up so 0N/A * that we can round it to an integral pixel position for a 0N/A * bitmap glyph or non-subpixel positioning, and round it to an 0N/A * integral subpixel position for that case, hence 0.5/3 = 0.166667 0N/A * Presently subPixPos means FM, and FM disables embedded bitmaps 0N/A * Therefore if subPixPos is true we should never get embedded bitmaps 0N/A * and the glyphlist will be homogenous. This test and the position 0N/A * adjustments will need to be per glyph once this case becomes 0N/A * Also set subPixPos=false if detect a B&W bitmap as we only 0N/A * need to test that on a per glyph basis once the list becomes 0N/A /* rowBytes==width tests if its a B&W or LCD glyph */ 0N/A * Subpixel positioning may be requested for LCD text. 0N/A * Subpixel positioning can take place only in the direction in 0N/A * which the subpixels increase the resolution. 0N/A * So this is useful for the typical case of vertical stripes 0N/A * increasing the resolution in the direction of the glyph 0N/A * advances - ie typical horizontally laid out text. 0N/A * If the subpixel stripes are horizontal, subpixel positioning 0N/A * can take place only in the vertical direction, which isn't 0N/A * as useful - you would have to be drawing rotated text on 0N/A * a display which actually had that organisation. A pretty 0N/A * unlikely combination. 0N/A * So this is supported only for vertical stripes which 0N/A * increase the horizontal resolution. 0N/A * If in this case the client also rotates the text then there 0N/A * will still be some benefit for small rotations. For 90 degree 0N/A * rotation there's no horizontal advance and less benefit 0N/A * from the subpixel rendering too. 0N/A * The test for width==rowBytes detects the case where the glyph 0N/A * is a B&W image obtained from an embedded bitmap. In that 0N/A * case we cannot apply sub-pixel positioning so ignore it. 0N/A * This is handled on a per glyph basis. 0N/A /* Calculate the fractional pixel position - ie the subpixel 0N/A * position within the RGB/BGR triple. We are rounding to 0N/A * the nearest, even though we just do (int) since at the 0N/A * start of the loop the position was already adjusted by 0N/A * 0.5 (sub)pixels to get rounding. 0N/A * Thus the "fractional" position will be 0, 1 or 2. 0N/A * eg 0->0.32 is 0, 0.33->0.66 is 1, > 0.66->0.99 is 2. 0N/A * We can use an (int) cast here since the floor operation 0N/A * above guarantees us that the value is positive. 0N/A /* frac rounded down to zero, so this is equivalent 0N/A * to no sub-pixel positioning. 0N/A /* In this case we need to adjust both the position at 0N/A * which the glyph will be positioned by one pixel to the 0N/A * left and adjust the position in the glyph image row 0N/A * from which to extract the data 0N/A * Every glyph image row has 2 bytes padding 0N/A * on the right to account for this. 0N/A /* copy image data into this array at x/y locations */ 0N/A/* LCD text needs to go through a gamma (contrast) adjustment. 0N/A * Gamma is constrained to the range 1.0->2.2 with a quantization of 0N/A * 0.01 (more than good enough). Representing as an integer with that 0N/A * precision yields a range 100->250 thus we need to store up to 151 LUTs 0N/A * We allocate the actual LUTs on an as needed basis. Typically zero or 0N/A * one is what will be needed. 0N/A * Colour component values are in the range 0.0->1.0 represented as an integer 0N/A * in the range 0->255 (ie in a byte). It is assumed that even if we have 5 0N/A * bit colour components these are presented mapped on to 8 bit components. 0N/A * lcdGammaLUT references LUTs which convert linear colour components 0N/A * to a gamma adjusted space, and 0N/A * lcdInvGammaLUT references LUTs which convert gamma adjusted colour 0N/A * components to a linear space. 0N/A for (i=0;i<
256;i++) {
0N/A for (i=
1;i<
255;i++) {
0N/A double val = ((
double)i)/
255.0;
0N/A for (i=0;i<
256;i++) {
0N/A if ((i+
1) %
8 == 0) {
0N/A printf(
"UInt8 defaultInvGammaLUT[256] = {\n");
0N/A for (i=0;i<
256;i++) {
0N/A if ((i+
1) %
8 == 0) {
0N/A/* These tables are generated for a Gamma adjustment of 1.4 */ 0N/A /* 0 */ 0,
4,
7,
10,
13,
15,
17,
19,
0N/A /* 8 */ 21,
23,
25,
27,
28,
30,
32,
33,
0N/A /* 16 */ 35,
36,
38,
39,
41,
42,
44,
45,
0N/A /* 24 */ 47,
48,
49,
51,
52,
53,
55,
56,
0N/A /* 32 */ 57,
59,
60,
61,
62,
64,
65,
66,
0N/A /* 40 */ 67,
69,
70,
71,
72,
73,
75,
76,
0N/A /* 48 */ 77,
78,
79,
80,
81,
83,
84,
85,
0N/A /* 56 */ 86,
87,
88,
89,
90,
91,
92,
93,
0N/A /* 64 */ 94,
96,
97,
98,
99,
100,
101,
102,
0N/A /* 72 */ 103,
104,
105,
106,
107,
108,
109,
110,
0N/A /* 80 */ 111,
112,
113,
114,
115,
116,
117,
118,
0N/A /* 88 */ 119,
120,
121,
122,
123,
124,
125,
125,
0N/A /* 96 */ 126,
127,
128,
129,
130,
131,
132,
133,
0N/A /* 104 */ 134,
135,
136,
137,
138,
138,
139,
140,
0N/A /* 112 */ 141,
142,
143,
144,
145,
146,
147,
147,
0N/A /* 120 */ 148,
149,
150,
151,
152,
153,
154,
154,
0N/A /* 128 */ 155,
156,
157,
158,
159,
160,
161,
161,
0N/A /* 136 */ 162,
163,
164,
165,
166,
167,
167,
168,
0N/A /* 144 */ 169,
170,
171,
172,
172,
173,
174,
175,
0N/A /* 152 */ 176,
177,
177,
178,
179,
180,
181,
181,
0N/A /* 160 */ 182,
183,
184,
185,
186,
186,
187,
188,
0N/A /* 168 */ 189,
190,
190,
191,
192,
193,
194,
194,
0N/A /* 176 */ 195,
196,
197,
198,
198,
199,
200,
201,
0N/A /* 184 */ 201,
202,
203,
204,
205,
205,
206,
207,
0N/A /* 192 */ 208,
208,
209,
210,
211,
212,
212,
213,
0N/A /* 200 */ 214,
215,
215,
216,
217,
218,
218,
219,
0N/A /* 208 */ 220,
221,
221,
222,
223,
224,
224,
225,
0N/A /* 216 */ 226,
227,
227,
228,
229,
230,
230,
231,
0N/A /* 224 */ 232,
233,
233,
234,
235,
236,
236,
237,
0N/A /* 232 */ 238,
239,
239,
240,
241,
242,
242,
243,
0N/A /* 240 */ 244,
244,
245,
246,
247,
247,
248,
249,
0N/A /* 248 */ 249,
250,
251,
252,
252,
253,
254,
255,
0N/A /* 0 */ 0, 0, 0, 0, 0,
1,
1,
1,
0N/A /* 8 */ 2,
2,
2,
3,
3,
3,
4,
4,
0N/A /* 16 */ 5,
5,
6,
6,
7,
7,
8,
8,
0N/A /* 24 */ 9,
9,
10,
10,
11,
12,
12,
13,
0N/A /* 32 */ 13,
14,
15,
15,
16,
17,
17,
18,
0N/A /* 40 */ 19,
19,
20,
21,
21,
22,
23,
23,
0N/A /* 48 */ 24,
25,
26,
26,
27,
28,
29,
29,
0N/A /* 56 */ 30,
31,
32,
32,
33,
34,
35,
36,
0N/A /* 64 */ 36,
37,
38,
39,
40,
40,
41,
42,
0N/A /* 72 */ 43,
44,
45,
45,
46,
47,
48,
49,
0N/A /* 80 */ 50,
51,
52,
52,
53,
54,
55,
56,
0N/A /* 88 */ 57,
58,
59,
60,
61,
62,
63,
64,
0N/A /* 96 */ 64,
65,
66,
67,
68,
69,
70,
71,
0N/A /* 104 */ 72,
73,
74,
75,
76,
77,
78,
79,
0N/A /* 112 */ 80,
81,
82,
83,
84,
85,
86,
87,
0N/A /* 120 */ 88,
89,
90,
91,
92,
93,
95,
96,
0N/A /* 128 */ 97,
98,
99,
100,
101,
102,
103,
104,
0N/A /* 136 */ 105,
106,
107,
109,
110,
111,
112,
113,
0N/A /* 144 */ 114,
115,
116,
117,
119,
120,
121,
122,
0N/A /* 152 */ 123,
124,
125,
127,
128,
129,
130,
131,
0N/A /* 160 */ 132,
133,
135,
136,
137,
138,
139,
140,
0N/A /* 168 */ 142,
143,
144,
145,
146,
148,
149,
150,
0N/A /* 176 */ 151,
152,
154,
155,
156,
157,
159,
160,
0N/A /* 184 */ 161,
162,
163,
165,
166,
167,
168,
170,
0N/A /* 192 */ 171,
172,
173,
175,
176,
177,
178,
180,
0N/A /* 200 */ 181,
182,
184,
185,
186,
187,
189,
190,
0N/A /* 208 */ 191,
193,
194,
195,
196,
198,
199,
200,
0N/A /* 216 */ 202,
203,
204,
206,
207,
208,
210,
211,
0N/A /* 224 */ 212,
214,
215,
216,
218,
219,
220,
222,
0N/A /* 232 */ 223,
224,
226,
227,
228,
230,
231,
232,
0N/A /* 240 */ 234,
235,
236,
238,
239,
241,
242,
243,
0N/A /* 248 */ 245,
246,
248,
249,
250,
252,
253,
255,
0N/A/* Since our default is 140, here we can populate that from pre-calculated 0N/A * data, it needs only 512 bytes - plus a few more of overhead - and saves 0N/A * about that many intrinsic function calls plus other FP calculations. 0N/A/* printDefaultTables(140); */