TtsSpan.java revision a896363400f09600fc2ef67b7e5ac702d110c8e9
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.text.style; 18 19import java.text.NumberFormat; 20import java.util.Locale; 21 22import android.os.Parcel; 23import android.os.PersistableBundle; 24import android.text.ParcelableSpan; 25import android.text.TextUtils; 26 27/** 28 * A span that supplies additional meta-data for the associated text intended 29 * for text-to-speech engines. If the text is being processed by a 30 * text-to-speech engine, the engine may use the data in this span in addition 31 * to or instead of its associated text. 32 * 33 * The inner classes are there for convenience and provide builders for each 34 * TtsSpan type. 35 */ 36public class TtsSpan implements ParcelableSpan { 37 private final String mType; 38 private final PersistableBundle mArgs; 39 40 /** 41 * This span type can be used to add morphosyntactic features to the text it 42 * spans over, or synthesize a something else than the spanned text. Use 43 * the argument {@link #ARG_TEXT} to set a different text. 44 * Accepts the arguments {@link #ARG_GENDER}, 45 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 46 * {@link #ARG_CASE}. 47 */ 48 public static final String TYPE_TEXT = "android.type.text"; 49 50 /** 51 * The text associated with this span is a cardinal. Must include the 52 * number to be synthesized with {@link #ARG_NUMBER}. 53 * Also accepts the arguments {@link #ARG_GENDER}, 54 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 55 * {@link #ARG_CASE}. 56 */ 57 public static final String TYPE_CARDINAL = "android.type.cardinal"; 58 59 /** 60 * The text associated with this span is an ordinal. Must include the 61 * number to be synthesized with {@link #ARG_NUMBER}. 62 * Also accepts the arguments {@link #ARG_GENDER}, 63 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 64 * {@link #ARG_CASE}. 65 */ 66 public static final String TYPE_ORDINAL = "android.type.ordinal"; 67 68 /** 69 * The text associated with this span is a decimal number. Must include the 70 * number to be synthesized with {@link #ARG_INTEGER_PART} and 71 * {@link #ARG_FRACTIONAL_PART}. 72 * Also accepts the arguments {@link #ARG_GENDER}, 73 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 74 * {@link #ARG_CASE}. 75 */ 76 public static final String TYPE_DECIMAL = "android.type.decimal"; 77 78 /** 79 * The text associated with this span is a fractional number. Must include 80 * the number to be synthesized with {@link #ARG_NUMERATOR} and 81 * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional 82 * Also accepts the arguments {@link #ARG_GENDER}, 83 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 84 * {@link #ARG_CASE}. 85 */ 86 public static final String TYPE_FRACTION = "android.type.fraction"; 87 88 /** 89 * The text associated with this span is a measure, consisting of a number 90 * and a unit. The number can be a cardinal, decimal or a fraction. Set the 91 * number with the same arguments as {@link #TYPE_CARDINAL}, 92 * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be 93 * specified with {@link #ARG_UNIT}. 94 * Also accepts the arguments {@link #ARG_GENDER}, 95 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 96 * {@link #ARG_CASE}. 97 */ 98 public static final String TYPE_MEASURE = "android.type.measure"; 99 100 /** 101 * The text associated with this span is a time, consisting of a number of 102 * hours and minutes, specified with {@link #ARG_HOURS} and 103 * {@link #ARG_MINUTES}. 104 * Also accepts the arguments {@link #ARG_GENDER}, 105 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 106 * {@link #ARG_CASE}. 107 */ 108 public static final String TYPE_TIME = "android.type.time"; 109 110 /** 111 * The text associated with this span is a date. All arguments are optional, 112 * but at least one has to be provided: {@link #ARG_WEEKDAY}, 113 * {@link #ARG_DAY}, {@link #ARG_MONTH} and {@link #ARG_YEAR}. 114 * Also accepts the arguments {@link #ARG_GENDER}, 115 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 116 * {@link #ARG_CASE}. 117 */ 118 public static final String TYPE_DATE = "android.type.date"; 119 120 /** 121 * The text associated with this span is a telephone number. The argument 122 * {@link #ARG_NUMBER_PART} is required. {@link #ARG_COUNTRY_CODE} and 123 * {@link #ARG_EXTENSION} are optional. 124 * Also accepts the arguments {@link #ARG_GENDER}, 125 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 126 * {@link #ARG_CASE}. 127 */ 128 public static final String TYPE_TELEPHONE = "android.type.telephone"; 129 130 131 /** 132 * The text associated with this span is a URI (can be used for URLs and 133 * email addresses). The full schema for URLs, which email addresses can 134 * effectively be seen as a subset of, is: 135 * protocol://username:password@domain:port/path?query_string#fragment_id 136 * Hence populating just username and domain will read as an email address. 137 * All arguments are optional, but at least one has to be provided: 138 * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD}, 139 * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH}, 140 * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}. 141 * Also accepts the arguments {@link #ARG_GENDER}, 142 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 143 * {@link #ARG_CASE}. 144 */ 145 public static final String TYPE_ELECTRONIC = "android.type.electronic"; 146 147 /** 148 * The text associated with this span is a series of digits that have to be 149 * read sequentially. {@link #ARG_DIGITS} is required. 150 * Also accepts the arguments {@link #ARG_GENDER}, 151 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 152 * {@link #ARG_CASE}. 153 */ 154 public static final String TYPE_DIGITS = "android.type.digits"; 155 156 /** 157 * The text associated with this span is a series of characters that have to 158 * be read verbatim. The engine will attempt to ready out any character like 159 * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required. 160 * Also accepts the arguments {@link #ARG_GENDER}, 161 * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and 162 * {@link #ARG_CASE}. 163 */ 164 public static final String TYPE_VERBATIM = "android.type.verbatim"; 165 166 /** 167 * String argument supplying gender information. Can be any of 168 * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and 169 * {@link #GENDER_FEMALE}. 170 */ 171 public static final String ARG_GENDER = "android.arg.gender"; 172 173 public static final String GENDER_NEUTRAL = "android.neutral"; 174 public static final String GENDER_MALE = "android.male"; 175 public static final String GENDER_FEMALE = "android.female"; 176 177 /** 178 * String argument supplying animacy information. Can be 179 * {@link #ANIMACY_ANIMATE} or 180 * {@link #ANIMACY_INANIMATE} 181 */ 182 public static final String ARG_ANIMACY = "android.arg.animacy"; 183 184 public static final String ANIMACY_ANIMATE = "android.animate"; 185 public static final String ANIMACY_INANIMATE = "android.inanimate"; 186 187 /** 188 * String argument supplying multiplicity information. Can be any of 189 * {@link #MULTIPLICITY_SINGLE}, 190 * {@link #MULTIPLICITY_DUAL} and 191 * {@link #MULTIPLICITY_PLURAL} 192 */ 193 public static final String ARG_MULTIPLICITY = "android.arg.multiplicity"; 194 195 public static final String MULTIPLICITY_SINGLE = "android.single"; 196 public static final String MULTIPLICITY_DUAL = "android.dual"; 197 public static final String MULTIPLICITY_PLURAL = "android.plural"; 198 199 /** 200 * String argument supplying case information. Can be any of 201 * {@link #CASE_NOMINATIVE}, {@link #CASE_ACCUSATIVE}, 202 * {@link #CASE_DATIVE}, {@link #CASE_ABLATIVE}, 203 * {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE}, 204 * {@link #CASE_LOCATIVE} and 205 * {@link #CASE_INSTRUMENTAL} 206 */ 207 public static final String ARG_CASE = "android.arg.case"; 208 209 public static final String CASE_NOMINATIVE = "android.nomative"; 210 public static final String CASE_ACCUSATIVE = "android.accusative"; 211 public static final String CASE_DATIVE = "android.dative"; 212 public static final String CASE_ABLATIVE = "android.ablative"; 213 public static final String CASE_GENITIVE = "android.genitive"; 214 public static final String CASE_VOCATIVE = "android.vocative"; 215 public static final String CASE_LOCATIVE = "android.locative"; 216 public static final String CASE_INSTRUMENTAL = "android.instrumental"; 217 218 /** 219 * String supplying the text to be synthesized. The synthesizer is free 220 * to decide how to interpret the text. 221 * Can be used with {@link #TYPE_TEXT}. 222 */ 223 public static final String ARG_TEXT = "android.arg.text"; 224 225 /** 226 * Argument used to specify a whole number. The value can be a string of 227 * digits of any size optionally prefixed with a - or +. 228 * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}. 229 */ 230 public static final String ARG_NUMBER = "android.arg.number"; 231 232 /** 233 * Argument used to specify the integer part of a decimal or fraction. The 234 * value can be a string of digits of any size optionally prefixed with 235 * a - or +. 236 * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}. 237 */ 238 public static final String ARG_INTEGER_PART = "android.arg.integer_part"; 239 240 /** 241 * Argument used to specify the fractional part of a decimal. The value can 242 * be a string of digits of any size. 243 * Can be used with {@link #TYPE_DECIMAL}. 244 */ 245 public static final String ARG_FRACTIONAL_PART = 246 "android.arg.fractional_part"; 247 248 /** 249 * Argument used to specify the numerator of a fraction. The value can be a 250 * string of digits of any size optionally prefixed with a - or +. 251 * Can be used with {@link #TYPE_FRACTION}. 252 */ 253 public static final String ARG_NUMERATOR = "android.arg.numerator"; 254 255 /** 256 * Argument used to specify the denominator of a fraction. The value can be 257 * a string of digits of any size optionally prefixed with a + or -. 258 * Can be used with {@link #TYPE_FRACTION}. 259 */ 260 public static final String ARG_DENOMINATOR = "android.arg.denominator"; 261 262 /** 263 * Argument used to specify the unit of a measure. The unit should always be 264 * specified in English singular form. Prefixes may be used. Engines will do 265 * their best to pronounce them correctly in the language used. Engines are 266 * expected to at least support the most common ones like 'meter', 'second', 267 * 'degree celcius' and 'degree fahrenheit' with some common prefixes like 268 * 'milli' and 'kilo'. 269 * Can be used with {@link #TYPE_MEASURE}. 270 */ 271 public static final String ARG_UNIT = "android.arg.unit"; 272 273 /** 274 * Argument used to specify the hours of a time. The hours should be 275 * provided as an integer in the range from 0 up to and including 24. 276 * Can be used with {@link #TYPE_TIME}. 277 */ 278 public static final String ARG_HOURS = "android.arg.hours"; 279 280 /** 281 * Argument used to specify the minutes of a time. The hours should be 282 * provided as an integer in the range from 0 up to and including 59. 283 * Can be used with {@link #TYPE_TIME}. 284 */ 285 public static final String ARG_MINUTES = "android.arg.minutes"; 286 287 /** 288 * Argument used to specify the weekday of a date. The value should be 289 * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY}, 290 * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY}, 291 * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY}, 292 * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}. 293 * Can be used with {@link #TYPE_DATE}. 294 */ 295 public static final String ARG_WEEKDAY = "android.arg.weekday"; 296 297 public static final int WEEKDAY_SUNDAY = 1; 298 public static final int WEEKDAY_MONDAY = 2; 299 public static final int WEEKDAY_TUESDAY = 3; 300 public static final int WEEKDAY_WEDNESDAY = 4; 301 public static final int WEEKDAY_THURSDAY = 5; 302 public static final int WEEKDAY_FRIDAY = 6; 303 public static final int WEEKDAY_SATURDAY = 7; 304 305 /** 306 * Argument used to specify the day of the month of a date. The value should 307 * be provided as an integer in the range from 1 up to and including 31. 308 * Can be used with {@link #TYPE_DATE}. 309 */ 310 public static final String ARG_DAY = "android.arg.day"; 311 312 /** 313 * Argument used to specify the month of a date. The value should be 314 * provided as an integer and can be any of {@link #MONTH_JANUARY}, 315 * {@link #MONTH_FEBRUARY}, {@link #MONTH_MARCH}, {@link #MONTH_APRIL}, 316 * {@link #MONTH_MAY}, {@link #MONTH_JUNE}, {@link #MONTH_JULY}, 317 * {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER}, {@link #MONTH_OCTOBER}, 318 * {@link #MONTH_NOVEMBER} and {@link #MONTH_DECEMBER}. 319 * Can be used with {@link #TYPE_DATE}. 320 */ 321 public static final String ARG_MONTH = "android.arg.month"; 322 323 public static final int MONTH_JANUARY = 0; 324 public static final int MONTH_FEBRUARY = 1; 325 public static final int MONTH_MARCH = 2; 326 public static final int MONTH_APRIL = 3; 327 public static final int MONTH_MAY = 4; 328 public static final int MONTH_JUNE = 5; 329 public static final int MONTH_JULY = 6; 330 public static final int MONTH_AUGUST = 7; 331 public static final int MONTH_SEPTEMBER = 8; 332 public static final int MONTH_OCTOBER = 9; 333 public static final int MONTH_NOVEMBER = 10; 334 public static final int MONTH_DECEMBER = 11; 335 336 /** 337 * Argument used to specify the year of a date. The value should be provided 338 * as a positive integer. 339 * Can be used with {@link #TYPE_DATE}. 340 */ 341 public static final String ARG_YEAR = "android.arg.year"; 342 343 /** 344 * Argument used to specify the country code of a telephone number. Can be 345 * a string of digits. 346 * Can be used with {@link #TYPE_TELEPHONE}. 347 */ 348 public static final String ARG_COUNTRY_CODE = "android.arg.country_code"; 349 350 /** 351 * Argument used to specify the main number part of a telephone number. Can 352 * be a string of digits where the different parts of the telephone number 353 * can be separated with a space, '-', '/' or '.'. 354 * Can be used with {@link #TYPE_TELEPHONE}. 355 */ 356 public static final String ARG_NUMBER_PART = "android.arg.number_part"; 357 358 /** 359 * Argument used to specify the extension part of a telephone number. Can be 360 * a string of digits. 361 * Can be used with {@link #TYPE_TELEPHONE}. 362 */ 363 public static final String ARG_EXTENSION = "android.arg.extension"; 364 365 /** 366 * Argument used to specify the protocol of a URI. Examples are 'http' and 367 * 'ftp'. 368 * Can be used with {@link #TYPE_ELECTRONIC}. 369 */ 370 public static final String ARG_PROTOCOL = "android.arg.protocol"; 371 372 /** 373 * Argument used to specify the username part of a URI. Should be set as a 374 * string. 375 * Can be used with {@link #TYPE_ELECTRONIC}. 376 */ 377 public static final String ARG_USERNAME = "android.arg.username"; 378 379 /** 380 * Argument used to specify the password part of a URI. Should be set as a 381 * string. 382 * Can be used with {@link #TYPE_ELECTRONIC}. 383 */ 384 public static final String ARG_PASSWORD = "android.arg.password"; 385 386 /** 387 * Argument used to specify the domain part of a URI. For example are 388 * 'source.android.com'. 389 * Can be used with {@link #TYPE_ELECTRONIC}. 390 */ 391 public static final String ARG_DOMAIN = "android.arg.domain"; 392 393 /** 394 * Argument used to specify the port number of a URI. Should be specified as 395 * an integer. 396 * Can be used with {@link #TYPE_ELECTRONIC}. 397 */ 398 public static final String ARG_PORT = "android.arg.port"; 399 400 /** 401 * Argument used to specify the path part of a URI. For example 402 * 'source/index.html'. 403 * Can be used with {@link #TYPE_ELECTRONIC}. 404 */ 405 public static final String ARG_PATH = "android.arg.path"; 406 407 /** 408 * Argument used to specify the query string of a URI. For example 409 * 'arg=value&argtwo=value'. 410 * Can be used with {@link #TYPE_ELECTRONIC}. 411 */ 412 public static final String ARG_QUERY_STRING = "android.arg.query_string"; 413 414 /** 415 * Argument used to specify the fragment id of a URI. Should be specified as 416 * a string. 417 * Can be used with {@link #TYPE_ELECTRONIC}. 418 */ 419 public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id"; 420 421 /** 422 * Argument used to specify a string of digits. 423 * Can be used with {@link #TYPE_DIGITS}. 424 */ 425 public static final String ARG_DIGITS = "android.arg.digits"; 426 427 /** 428 * Argument used to specify a string where the characters are read verbatim, 429 * except whitespace. 430 * Can be used with {@link #TYPE_VERBATIM}. 431 */ 432 public static final String ARG_VERBATIM = "android.arg.verbatim"; 433 434 public TtsSpan(String type, PersistableBundle args) { 435 mType = type; 436 mArgs = args; 437 } 438 439 public TtsSpan(Parcel src) { 440 mType = src.readString(); 441 mArgs = src.readPersistableBundle(); 442 } 443 444 /** 445 * Returns the type. 446 * @return The type of this instance. 447 */ 448 public String getType() { 449 return mType; 450 } 451 452 /** 453 * Returns a bundle of the arguments set. 454 * @return The bundle of the arguments set. 455 */ 456 public PersistableBundle getArgs() { 457 return mArgs; 458 } 459 460 @Override 461 public int describeContents() { 462 return 0; 463 } 464 465 @Override 466 public void writeToParcel(Parcel dest, int flags) { 467 dest.writeString(mType); 468 dest.writePersistableBundle(mArgs); 469 } 470 471 @Override 472 public int getSpanTypeId() { 473 return TextUtils.TTS_SPAN; 474 } 475 476 /** 477 * A simple builder for TtsSpans. 478 * This builder can be used directly, but the more specific subclasses of 479 * this builder like {@link TtsSpan.TextBuilder} and 480 * {@link TtsSpan.CardinalBuilder} are likely more useful. 481 * 482 * This class uses generics so methods from this class can return instances 483 * of its child classes, resulting in a fluent API (CRTP pattern). 484 */ 485 public static abstract class Builder<C extends Builder<C>> { 486 // Holds the type of this class. 487 private final String mType; 488 489 // Holds the arguments of this class. It only stores objects of type 490 // String, Integer and Long. 491 private PersistableBundle mArgs = new PersistableBundle(); 492 493 public Builder(String type) { 494 mType = type; 495 } 496 497 /** 498 * Returns a TtsSpan built from the parameters set by the setter 499 * methods. 500 * @return A TtsSpan built with parameters of this builder. 501 */ 502 public TtsSpan build() { 503 return new TtsSpan(mType, mArgs); 504 } 505 506 /** 507 * Sets an argument to a string value. 508 * @param arg The argument name. 509 * @param value The value the argument should be set to. 510 * @return This instance. 511 */ 512 @SuppressWarnings("unchecked") 513 public C setStringArgument(String arg, String value) { 514 mArgs.putString(arg, value); 515 return (C) this; 516 } 517 518 /** 519 * Sets an argument to an int value. 520 * @param arg The argument name. 521 * @param value The value the argument should be set to. 522 */ 523 @SuppressWarnings("unchecked") 524 public C setIntArgument(String arg, int value) { 525 mArgs.putInt(arg, value); 526 return (C) this; 527 } 528 529 /** 530 * Sets an argument to a long value. 531 * @param arg The argument name. 532 * @param value The value the argument should be set to. 533 */ 534 @SuppressWarnings("unchecked") 535 public C setLongArgument(String arg, long value) { 536 mArgs.putLong(arg, value); 537 return (C) this; 538 } 539 } 540 541 /** 542 * A builder for TtsSpans, has setters for morphosyntactic features. 543 * This builder can be used directly, but the more specific subclasses of 544 * this builder like {@link TtsSpan.TextBuilder} and 545 * {@link TtsSpan.CardinalBuilder} are likely more useful. 546 */ 547 public static class SemioticClassBuilder<C extends SemioticClassBuilder<C>> 548 extends Builder<C> { 549 550 public SemioticClassBuilder(String type) { 551 super(type); 552 } 553 554 /** 555 * Sets the gender information for this instance. 556 * @param gender Can any of {@link TtsSpan#GENDER_NEUTRAL}, 557 * {@link TtsSpan#GENDER_MALE} and {@link TtsSpan#GENDER_FEMALE}. 558 * @return This instance. 559 */ 560 public C setGender(String gender) { 561 return setStringArgument(TtsSpan.ARG_GENDER, gender); 562 } 563 564 /** 565 * Sets the animacy information for this instance. 566 * @param animacy Can be any of {@link TtsSpan#ANIMACY_ANIMATE} and 567 * {@link TtsSpan#ANIMACY_INANIMATE}. 568 * @return This instance. 569 */ 570 public C setAnimacy(String animacy) { 571 return setStringArgument(TtsSpan.ARG_ANIMACY, animacy); 572 } 573 574 /** 575 * Sets the multiplicity information for this instance. 576 * @param multiplicity Can be any of 577 * {@link TtsSpan#MULTIPLICITY_SINGLE}, 578 * {@link TtsSpan#MULTIPLICITY_DUAL} and 579 * {@link TtsSpan#MULTIPLICITY_PLURAL}. 580 * @return This instance. 581 */ 582 public C setMultiplicity(String multiplicity) { 583 return setStringArgument(TtsSpan.ARG_MULTIPLICITY, multiplicity); 584 } 585 586 /** 587 * Sets the grammatical case information for this instance. 588 * @param grammaticalCase Can be any of {@link TtsSpan#CASE_NOMINATIVE}, 589 * {@link TtsSpan#CASE_ACCUSATIVE}, {@link TtsSpan#CASE_DATIVE}, 590 * {@link TtsSpan#CASE_ABLATIVE}, {@link TtsSpan#CASE_GENITIVE}, 591 * {@link TtsSpan#CASE_VOCATIVE}, {@link TtsSpan#CASE_LOCATIVE} and 592 * {@link TtsSpan#CASE_INSTRUMENTAL}. 593 * @return This instance. 594 */ 595 public C setCase(String grammaticalCase) { 596 return setStringArgument(TtsSpan.ARG_CASE, grammaticalCase); 597 } 598 } 599 600 /** 601 * A builder for TtsSpans of type {@link TtsSpan #TYPE_TEXT}. 602 */ 603 public static class TextBuilder extends SemioticClassBuilder<TextBuilder> { 604 605 /** 606 * Creates a builder for a TtsSpan of type {@link TtsSpan#TYPE_TEXT}. 607 */ 608 public TextBuilder() { 609 super(TtsSpan.TYPE_TEXT); 610 } 611 612 /** 613 * Creates a TtsSpan of type {@link TtsSpan#TYPE_TEXT} and sets the 614 * {@link TtsSpan#ARG_TEXT} argument. 615 * @param text The text to be synthesized. 616 * @see #setText(String) 617 */ 618 public TextBuilder(String text) { 619 this(); 620 setText(text); 621 } 622 623 /** 624 * Sets the {@link TtsSpan#ARG_TEXT} argument, the text to be 625 * synthesized. 626 * @param text The string that will be synthesized. 627 * @return This instance. 628 */ 629 public TextBuilder setText(String text) { 630 return setStringArgument(TtsSpan.ARG_TEXT, text); 631 } 632 } 633 634 /** 635 * A builder for TtsSpans of type {@link TtsSpan #TYPE_CARDINAL}. 636 */ 637 public static class CardinalBuilder 638 extends SemioticClassBuilder<CardinalBuilder> { 639 640 /** 641 * Creates a builder for a TtsSpan of type 642 * {@link TtsSpan#TYPE_CARDINAL}. 643 */ 644 public CardinalBuilder() { 645 super(TtsSpan.TYPE_CARDINAL); 646 } 647 648 /** 649 * Creates a TtsSpan of type {@link TtsSpan#TYPE_CARDINAL} and sets the 650 * {@link TtsSpan#ARG_NUMBER} argument. 651 * @param number The number to synthesize. 652 * @see #setNumber(long) 653 */ 654 public CardinalBuilder(long number) { 655 this(); 656 setNumber(number); 657 } 658 659 /** 660 * Creates a TtsSpan of type {@link TtsSpan#TYPE_CARDINAL} and sets the 661 * {@link TtsSpan#ARG_NUMBER} argument. 662 * @param number The number to synthesize. 663 * @see #setNumber(String) 664 */ 665 public CardinalBuilder(String number) { 666 this(); 667 setNumber(number); 668 } 669 670 /** 671 * Convenience method that converts the number to a String and set it to 672 * the value for {@link TtsSpan#ARG_NUMBER}. 673 * @param number The number that will be synthesized. 674 * @return This instance. 675 */ 676 public CardinalBuilder setNumber(long number) { 677 return setNumber(String.valueOf(number)); 678 } 679 680 /** 681 * Sets the {@link TtsSpan#ARG_NUMBER} argument. 682 * @param number A non-empty string of digits with an optional 683 * leading + or -. 684 * @return This instance. 685 */ 686 public CardinalBuilder setNumber(String number) { 687 return setStringArgument(TtsSpan.ARG_NUMBER, number); 688 } 689 } 690 691 /** 692 * A builder for TtsSpans of type {@link TtsSpan#TYPE_ORDINAL}. 693 */ 694 public static class OrdinalBuilder 695 extends SemioticClassBuilder<OrdinalBuilder> { 696 697 /** 698 * Creates a builder for a TtsSpan of type {@link TtsSpan#TYPE_ORDINAL}. 699 */ 700 public OrdinalBuilder() { 701 super(TtsSpan.TYPE_ORDINAL); 702 } 703 704 /** 705 * Creates a TtsSpan of type {@link TtsSpan#TYPE_ORDINAL} and sets the 706 * {@link TtsSpan#ARG_NUMBER} argument. 707 * @param number The ordinal number to synthesize. 708 * @see #setNumber(long) 709 */ 710 public OrdinalBuilder(long number) { 711 this(); 712 setNumber(number); 713 } 714 715 /** 716 * Creates a TtsSpan of type {@link TtsSpan#TYPE_ORDINAL} and sets the 717 * {@link TtsSpan#ARG_NUMBER} argument. 718 * @param number The number to synthesize. 719 * @see #setNumber(String) 720 */ 721 public OrdinalBuilder(String number) { 722 this(); 723 setNumber(number); 724 } 725 726 /** 727 * Convenience method that converts the number to a String and sets it 728 * to the value for {@link TtsSpan#ARG_NUMBER}. 729 * @param number The ordinal number that will be synthesized. 730 * @return This instance. 731 */ 732 public OrdinalBuilder setNumber(long number) { 733 return setNumber(String.valueOf(number)); 734 } 735 736 /** 737 * Sets the {@link TtsSpan#ARG_NUMBER} argument. 738 * @param number A non-empty string of digits with an optional 739 * leading + or -. 740 * @return This instance. 741 */ 742 public OrdinalBuilder setNumber(String number) { 743 return setStringArgument(TtsSpan.ARG_NUMBER, number); 744 } 745 } 746 747 /** 748 * A builder for TtsSpans of type {@link TtsSpan#TYPE_DECIMAL}. 749 */ 750 public static class DecimalBuilder 751 extends SemioticClassBuilder<DecimalBuilder> { 752 753 /** 754 * Creates a builder for a TtsSpan of type {@link TtsSpan#TYPE_DECIMAL}. 755 */ 756 public DecimalBuilder() { 757 super(TtsSpan.TYPE_DECIMAL); 758 } 759 760 /** 761 * Creates a TtsSpan of type {@link TtsSpan#TYPE_DECIMAL} and sets the 762 * {@link TtsSpan#ARG_INTEGER_PART} and 763 * {@link TtsSpan#ARG_FRACTIONAL_PART} arguments. 764 * @see {@link #setArgumentsFromDouble(double, int, int) 765 */ 766 public DecimalBuilder(double number, 767 int minimumFractionDigits, 768 int maximumFractionDigits) { 769 this(); 770 setArgumentsFromDouble(number, 771 minimumFractionDigits, 772 maximumFractionDigits); 773 } 774 775 /** 776 * Creates a TtsSpan of type {@link TtsSpan#TYPE_DECIMAL} and sets the 777 * {@link TtsSpan#ARG_INTEGER_PART} and 778 * {@link TtsSpan#ARG_FRACTIONAL_PART} arguments. 779 */ 780 public DecimalBuilder(String integerPart, String fractionalPart) { 781 this(); 782 setIntegerPart(integerPart); 783 setFractionalPart(fractionalPart); 784 } 785 786 /** 787 * Convenience method takes a double and a maximum number of fractional 788 * digits, it sets the {@link TtsSpan#ARG_INTEGER_PART} and 789 * {@link TtsSpan#ARG_FRACTIONAL_PART} arguments. 790 * @param number The number to be synthesized. 791 * @param minimumFractionDigits The minimum number of fraction digits 792 * that are pronounced. 793 * @param maximumFractionDigits The maximum number of fraction digits 794 * that are pronounced. If maximumFractionDigits < 795 * minimumFractionDigits then minimumFractionDigits will be assumed 796 * to be equal to maximumFractionDigits. 797 * @return This instance. 798 */ 799 public DecimalBuilder setArgumentsFromDouble( 800 double number, 801 int minimumFractionDigits, 802 int maximumFractionDigits) { 803 // Format double. 804 NumberFormat formatter = NumberFormat.getInstance(Locale.US); 805 formatter.setMinimumFractionDigits(maximumFractionDigits); 806 formatter.setMaximumFractionDigits(maximumFractionDigits); 807 formatter.setGroupingUsed(false); 808 String str = formatter.format(number); 809 810 // Split at decimal point. 811 int i = str.indexOf('.'); 812 if (i >= 0) { 813 setIntegerPart(str.substring(0, i)); 814 setFractionalPart(str.substring(i + 1)); 815 } else { 816 setIntegerPart(str); 817 } 818 return this; 819 } 820 821 /** 822 * Convenience method that converts the number to a String and sets it 823 * to the value for {@link TtsSpan#ARG_INTEGER_PART}. 824 * @param integerPart The integer part of the decimal. 825 * @return This instance. 826 */ 827 public DecimalBuilder setIntegerPart(long integerPart) { 828 return setIntegerPart(String.valueOf(integerPart)); 829 } 830 831 /** 832 * Sets the {@link TtsSpan#ARG_INTEGER_PART} argument. 833 * @param integerPart A non-empty string of digits with an optional 834 * leading + or -. 835 * @return This instance. 836 */ 837 public DecimalBuilder setIntegerPart(String integerPart) { 838 return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart); 839 } 840 841 /** 842 * Sets the {@link TtsSpan#ARG_FRACTIONAL_PART} argument. 843 * @param fractionalPart A non-empty string of digits. 844 * @return This instance. 845 */ 846 public DecimalBuilder setFractionalPart(String fractionalPart) { 847 return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART, 848 fractionalPart); 849 } 850 } 851 852 /** 853 * A builder for TtsSpans of type {@link TtsSpan#TYPE_FRACTION}. 854 */ 855 public static class FractionBuilder 856 extends SemioticClassBuilder<FractionBuilder> { 857 858 /** 859 * Creates a builder for a TtsSpan of type 860 * {@link TtsSpan#TYPE_FRACTION}. 861 */ 862 public FractionBuilder() { 863 super(TtsSpan.TYPE_FRACTION); 864 } 865 866 /** 867 * Creates a TtsSpan of type {@link TtsSpan#TYPE_FRACTION} and sets the 868 * {@link TtsSpan#ARG_INTEGER_PART}, {@link TtsSpan#ARG_NUMERATOR}, and 869 * {@link TtsSpan#ARG_DENOMINATOR} arguments. 870 */ 871 public FractionBuilder(long integerPart, 872 long numerator, 873 long denominator) { 874 this(); 875 setIntegerPart(integerPart); 876 setNumerator(numerator); 877 setDenominator(denominator); 878 } 879 880 881 /** 882 * Convenience method that converts the integer to a String and sets the 883 * argument {@link TtsSpan#ARG_NUMBER}. 884 * @param integerPart The integer part. 885 * @return This instance. 886 */ 887 public FractionBuilder setIntegerPart(long integerPart) { 888 return setIntegerPart(String.valueOf(integerPart)); 889 } 890 891 /** 892 * Sets the {@link TtsSpan#ARG_INTEGER_PART} argument. 893 * @param integerPart A non-empty string of digits with an optional 894 * leading + or -. 895 * @return This instance. 896 */ 897 public FractionBuilder setIntegerPart(String integerPart) { 898 return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart); 899 } 900 901 /** 902 * Convenience method that converts the numerator to a String and sets 903 * the argument {@link TtsSpan#ARG_NUMERATOR}. 904 * @param numerator The numerator. 905 * @return This instance. 906 */ 907 public FractionBuilder setNumerator(long numerator) { 908 return setNumerator(String.valueOf(numerator)); 909 } 910 911 /** 912 * Sets the {@link TtsSpan#ARG_NUMERATOR} argument. 913 * @param numerator A non-empty string of digits with an optional 914 * leading + or -. 915 * @return This instance. 916 */ 917 public FractionBuilder setNumerator(String numerator) { 918 return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator); 919 } 920 921 /** 922 * Convenience method that converts the denominator to a String and sets 923 * the argument {@link TtsSpan#ARG_DENOMINATOR}. 924 * @param denominator The denominator. 925 * @return This instance. 926 */ 927 public FractionBuilder setDenominator(long denominator) { 928 return setDenominator(String.valueOf(denominator)); 929 } 930 931 /** 932 * Sets the {@link TtsSpan#ARG_DENOMINATOR} argument. 933 * @param denominator A non-empty string of digits with an optional 934 * leading + or -. 935 * @return This instance. 936 */ 937 public FractionBuilder setDenominator(String denominator) { 938 return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator); 939 } 940 } 941} 942