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