1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 *   - Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 *
11 *   - Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 *   - Neither the name of Oracle nor the names of its
16 *     contributors may be used to endorse or promote products derived
17 *     from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * This source code is provided to illustrate the usage of a given feature
34 * or technique and has been deliberately simplified. Additional steps
35 * required for a production-quality application, such as security checks,
36 * input validation and proper error handling, might not be present in
37 * this sample code.
38 */
39
40
41/*
42 * (C) Copyright IBM Corp. 2003, All Rights Reserved.
43 * This technology is protected by multiple US and International
44 * patents. This notice and attribution to IBM may not be removed.
45 */
46
47package j2dbench.tests.text;
48
49import java.awt.Font;
50import java.awt.font.FontRenderContext;
51import java.awt.font.GlyphVector;
52import java.awt.font.TextLayout;
53import java.text.AttributedCharacterIterator;
54import java.text.AttributedString;
55import java.text.Bidi;
56import java.text.CharacterIterator;
57import java.util.Map;
58
59import j2dbench.Group;
60import j2dbench.Result;
61import j2dbench.TestEnvironment;
62
63public abstract class TextConstructionTests extends TextTests {
64    static Group constructroot;
65    static Group constructtestroot;
66
67    public static void init() {
68      // don't even bother with this at all if we don't have Java2 APIs.
69      if (hasGraphics2D) {
70        constructroot = new Group(textroot, "construction", "Construction Benchmarks");
71        constructtestroot = new Group(constructroot, "tests", "Construction Tests");
72
73        new GVFromFontString();
74        new GVFromFontChars();
75        new GVFromFontCI();
76        new GVFromFontGlyphs();
77        new GVFromFontLayout();
78        //  new GVClone(); // not public API!
79
80        new TLFromFont();
81        new TLFromMap();
82        /*
83        new TLFromACI();
84        new TLClone();
85        new TLJustify();
86        new TLFromLBM();
87        */
88      }
89    }
90
91    public TextConstructionTests(Group parent, String nodeName, String description) {
92        super(parent, nodeName, description);
93    }
94
95    public static class TCContext extends G2DContext {
96        char[] chars1;
97        CharacterIterator ci;
98        GlyphVector gv;
99        int[] glyphs;
100        int flags;
101
102        public void init(TestEnvironment env, Result results) {
103            super.init(env, results);
104
105            chars1 = new char[chars.length + 2];
106            System.arraycopy(chars, 0, chars1, 1, chars.length);
107            ci = new ArrayCI(chars1, 1, chars.length);
108            gv = font.createGlyphVector(frc, text);
109            glyphs = gv.getGlyphCodes(0, gv.getNumGlyphs(), null);
110            flags = Bidi.requiresBidi(chars, 0, chars.length)
111                ? Font.LAYOUT_LEFT_TO_RIGHT
112                : Font.LAYOUT_RIGHT_TO_LEFT;
113        }
114    }
115
116    public Context createContext() {
117        return new TCContext();
118    }
119
120    public static class GVFromFontString extends TextConstructionTests {
121        public GVFromFontString() {
122            super(constructtestroot, "gvfromfontstring", "Call Font.createGlyphVector(FRC, String)");
123        }
124
125        public void runTest(Object ctx, int numReps) {
126            TCContext tcctx = (TCContext)ctx;
127            final Font font = tcctx.font;
128            final String text = tcctx.text;
129            final FontRenderContext frc = tcctx.frc;
130            GlyphVector gv;
131            do {
132                gv = font.createGlyphVector(frc, text);
133            } while (--numReps >= 0);
134        }
135    }
136
137    public static class GVFromFontChars extends TextConstructionTests {
138        public GVFromFontChars() {
139            super(constructtestroot, "gvfromfontchars", "Call Font.createGlyphVector(FRC, char[])");
140        }
141
142        public void runTest(Object ctx, int numReps) {
143            TCContext tcctx = (TCContext)ctx;
144            final Font font = tcctx.font;
145            final char[] chars = tcctx.chars;
146            final FontRenderContext frc = tcctx.frc;
147            GlyphVector gv;
148            do {
149                gv = font.createGlyphVector(frc, chars);
150            } while (--numReps >= 0);
151        }
152    }
153
154    public static class GVFromFontCI extends TextConstructionTests {
155        public GVFromFontCI() {
156            super(constructtestroot, "gvfromfontci", "Call Font.createGlyphVector(FRC, CharacterIterator)");
157        }
158
159        public void runTest(Object ctx, int numReps) {
160            TCContext tcctx = (TCContext)ctx;
161            final Font font = tcctx.font;
162            final CharacterIterator ci = tcctx.ci;
163            final FontRenderContext frc = tcctx.frc;
164            GlyphVector gv;
165            do {
166                gv = font.createGlyphVector(frc, ci);
167            } while (--numReps >= 0);
168        }
169    }
170
171    public static class GVFromFontGlyphs extends TextConstructionTests {
172        public GVFromFontGlyphs() {
173            super(constructtestroot, "gvfromfontglyphs", "Call Font.createGlyphVector(FRC, int[])");
174        }
175
176        public void runTest(Object ctx, int numReps) {
177            TCContext tcctx = (TCContext)ctx;
178            final Font font = tcctx.font;
179            final int[] glyphs = tcctx.glyphs;
180            final FontRenderContext frc = tcctx.frc;
181            GlyphVector gv;
182            do {
183                gv = font.createGlyphVector(frc, glyphs);
184            } while (--numReps >= 0);
185        }
186    }
187
188    public static class GVFromFontLayout extends TextConstructionTests {
189        public GVFromFontLayout() {
190            super(constructtestroot, "gvfromfontlayout", "Call Font.layoutGlyphVector(...)");
191        }
192
193        public void runTest(Object ctx, int numReps) {
194            TCContext tcctx = (TCContext)ctx;
195            final Font font = tcctx.font;
196            final char[] chars = tcctx.chars1;
197            final int start = 1;
198            final int limit = chars.length - 1;
199            final FontRenderContext frc = tcctx.frc;
200            final int flags = tcctx.flags;
201            GlyphVector gv;
202            do {
203                gv = font.layoutGlyphVector(frc, chars, start, limit, flags);
204            } while (--numReps >= 0);
205        }
206    }
207
208    /*
209     * my bad, clone is not public in GlyphVector!
210
211    public static class GVClone extends TextConstructionTests {
212        public GVClone() {
213            super(constructtestroot, "gvclone", "Call GV.clone");
214        }
215
216        public void runTest(Object ctx, int numReps) {
217            TCContext tcctx = (TCContext)ctx;
218            final GlyphVector origGV = tcctx.gv;
219            GlyphVector gv;
220            do {
221                gv = (GlyphVector)origGV.clone();
222            } while (--numReps >= 0);
223        }
224    }
225    */
226
227    public static class TLFromFont extends TextConstructionTests {
228        public TLFromFont() {
229            super(constructtestroot, "tlfromfont", "TextLayout(String, Font, FRC)");
230        }
231
232        public void runTest(Object ctx, int numReps) {
233            TCContext tcctx = (TCContext)ctx;
234            final Font font = tcctx.font;
235            final String text = tcctx.text;
236            final FontRenderContext frc = tcctx.frc;
237            TextLayout tl;
238            do {
239                tl = new TextLayout(text, font, frc);
240            } while (--numReps >= 0);
241        }
242    }
243
244    public static class TLMapContext extends G2DContext {
245        Map map;
246
247        public void init(TestEnvironment env, Result results) {
248            super.init(env, results);
249
250            map = (Map)env.getModifier(tlmapList);
251        }
252
253    }
254
255    public static class TLFromMap extends TextConstructionTests {
256        public TLFromMap() {
257            super(constructtestroot, "tlfrommap", "TextLayout(String, Map, FRC)");
258        }
259
260        public Context createContext() {
261            return new TLMapContext();
262        }
263
264        public void runTest(Object ctx, int numReps) {
265            TLMapContext tlmctx = (TLMapContext)ctx;
266            final String text = tlmctx.text;
267            final FontRenderContext frc = tlmctx.frc;
268            final Map map = tlmctx.map;
269            TextLayout tl;
270            do {
271                tl = new TextLayout(text, map, frc);
272            } while (--numReps >= 0);
273        }
274    }
275
276    public static class ACIContext extends G2DContext {
277        AttributedCharacterIterator aci;
278
279        public void init(TestEnvironment env, Result results) {
280            super.init(env, results);
281
282            AttributedString astr = new AttributedString(text);
283
284        }
285    }
286
287    public class TLFromACI extends TextConstructionTests {
288        public TLFromACI() {
289            super(constructtestroot, "tlfromaci", "TextLayout(ACI, FRC)");
290        }
291
292        public void runTest(Object ctx, int numReps) {
293            TCContext tcctx = (TCContext)ctx;
294            final Font font = tcctx.font;
295            final String text = tcctx.text;
296            final FontRenderContext frc = tcctx.frc;
297            TextLayout tl;
298            do {
299                tl = new TextLayout(text, font, frc);
300            } while (--numReps >= 0);
301        }
302    }
303
304    public class TLClone extends TextConstructionTests {
305        public TLClone() {
306            super(constructtestroot, "tlclone", "call TextLayout.clone()");
307        }
308
309        public void runTest(Object ctx, int numReps) {
310            TCContext tcctx = (TCContext)ctx;
311            final Font font = tcctx.font;
312            final String text = tcctx.text;
313            final FontRenderContext frc = tcctx.frc;
314            TextLayout tl;
315            do {
316                tl = new TextLayout(text, font, frc);
317            } while (--numReps >= 0);
318        }
319    }
320
321    public class TLJustify extends TextConstructionTests {
322        public TLJustify() {
323            super(constructtestroot, "tljustify", "call TextLayout.getJustifiedLayout(...)");
324        }
325
326        public void runTest(Object ctx, int numReps) {
327            TCContext tcctx = (TCContext)ctx;
328            final Font font = tcctx.font;
329            final String text = tcctx.text;
330            final FontRenderContext frc = tcctx.frc;
331            TextLayout tl;
332            do {
333                tl = new TextLayout(text, font, frc);
334            } while (--numReps >= 0);
335        }
336    }
337
338    public class TLFromLBM extends TextConstructionTests {
339        public TLFromLBM() {
340            super(constructtestroot, "tlfromlbm", "call LineBreakMeasurer.next()");
341        }
342
343        public void runTest(Object ctx, int numReps) {
344            TCContext tcctx = (TCContext)ctx;
345            final Font font = tcctx.font;
346            final String text = tcctx.text;
347            final FontRenderContext frc = tcctx.frc;
348            TextLayout tl;
349            do {
350                tl = new TextLayout(text, font, frc);
351            } while (--numReps >= 0);
352        }
353    }
354
355    public static final class ArrayCI implements CharacterIterator {
356        char[] chars;
357        int off;
358        int max;
359        int pos;
360
361        ArrayCI(char[] chars, int off, int len) {
362            if (off < 0 || len < 0 || (len > 0 && (chars == null || chars.length - off < len))) {
363                throw new InternalError("bad ArrayCI params");
364            }
365            this.chars = chars;
366            this.off = off;
367            this.max = off + len;
368            this.pos = off;
369        }
370
371    /**
372     * Sets the position to getBeginIndex() and returns the character at that
373     * position.
374     * @return the first character in the text, or DONE if the text is empty
375     * @see #getBeginIndex()
376     */
377        public char first() {
378            if (max > off) {
379                return chars[pos = off];
380            }
381            return DONE;
382        }
383
384    /**
385     * Sets the position to getEndIndex()-1 (getEndIndex() if the text is empty)
386     * and returns the character at that position.
387     * @return the last character in the text, or DONE if the text is empty
388     * @see #getEndIndex()
389     */
390        public char last() {
391            if (max > off) {
392                return chars[pos = max - 1];
393            }
394            pos = max;
395            return DONE;
396        }
397
398    /**
399     * Gets the character at the current position (as returned by getIndex()).
400     * @return the character at the current position or DONE if the current
401     * position is off the end of the text.
402     * @see #getIndex()
403     */
404        public char current() {
405            return pos == max ? DONE : chars[pos];
406        }
407
408
409    /**
410     * Increments the iterator's index by one and returns the character
411     * at the new index.  If the resulting index is greater or equal
412     * to getEndIndex(), the current index is reset to getEndIndex() and
413     * a value of DONE is returned.
414     * @return the character at the new position or DONE if the new
415     * position is off the end of the text range.
416     */
417        public char next() {
418            if (++pos < max) {
419                return chars[pos];
420            }
421            pos = max;
422            return DONE;
423        }
424
425
426    /**
427     * Decrements the iterator's index by one and returns the character
428     * at the new index. If the current index is getBeginIndex(), the index
429     * remains at getBeginIndex() and a value of DONE is returned.
430     * @return the character at the new position or DONE if the current
431     * position is equal to getBeginIndex().
432     */
433        public char previous() {
434            if (--pos >= off) {
435                return chars[pos];
436            }
437            pos = off;
438            return DONE;
439        }
440
441    /**
442     * Sets the position to the specified position in the text and returns that
443     * character.
444     * @param position the position within the text.  Valid values range from
445     * getBeginIndex() to getEndIndex().  An IllegalArgumentException is thrown
446     * if an invalid value is supplied.
447     * @return the character at the specified position or DONE if the specified position is equal to getEndIndex()
448     */
449        public char setIndex(int position) {
450            if (position < off || position > max) {
451                throw new IllegalArgumentException("pos: " + position + " off: " + off + " len: " + (max - off));
452            }
453            return ((pos = position) < max) ? chars[position] : DONE;
454        }
455
456    /**
457     * Returns the start index of the text.
458     * @return the index at which the text begins.
459     */
460        public int getBeginIndex() {
461            return off;
462        }
463
464    /**
465     * Returns the end index of the text.  This index is the index of the first
466     * character following the end of the text.
467     * @return the index after the last character in the text
468     */
469        public int getEndIndex() {
470            return max;
471        }
472
473    /**
474     * Returns the current index.
475     * @return the current index.
476     */
477        public int getIndex() {
478            return pos;
479        }
480
481    /**
482     * Create a copy of this iterator
483     * @return A copy of this
484     */
485        public Object clone() {
486            try {
487                return super.clone();
488            }
489            catch (Exception e) {
490                return new InternalError();
491            }
492        }
493    }
494}
495