You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NativeTextPainter.java 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.svg;
  19. import java.awt.Graphics2D;
  20. import java.io.IOException;
  21. import java.text.AttributedCharacterIterator;
  22. import java.util.List;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.apache.batik.gvt.renderer.StrokingTextPainter;
  26. import org.apache.batik.gvt.text.TextSpanLayout;
  27. import org.apache.fop.fonts.Font;
  28. import org.apache.fop.fonts.FontInfo;
  29. import org.apache.fop.util.CharUtilities;
  30. /**
  31. * Abstract base class for text painters that use specialized text commands native to an output
  32. * format to render text.
  33. */
  34. public abstract class NativeTextPainter extends StrokingTextPainter {
  35. /** the logger for this class */
  36. protected Log log = LogFactory.getLog(NativeTextPainter.class);
  37. /** the font collection */
  38. protected final FontInfo fontInfo;
  39. /**
  40. * Creates a new instance.
  41. * @param fontInfo the font collection
  42. */
  43. public NativeTextPainter(FontInfo fontInfo) {
  44. this.fontInfo = fontInfo;
  45. }
  46. /**
  47. * Indicates whether the given {@link Graphics2D} instance if compatible with this text painter
  48. * implementation.
  49. * @param g2d the instance to check
  50. * @return true if the instance is compatible.
  51. */
  52. protected abstract boolean isSupported(Graphics2D g2d);
  53. /**
  54. * Paints a single text run.
  55. * @param textRun the text run
  56. * @param g2d the target Graphics2D instance
  57. * @throws IOException if an I/O error occurs while rendering the text
  58. */
  59. protected abstract void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException;
  60. /** {@inheritDoc} */
  61. @Override
  62. protected void paintTextRuns(List textRuns, Graphics2D g2d) {
  63. if (log.isTraceEnabled()) {
  64. log.trace("paintTextRuns: count = " + textRuns.size());
  65. }
  66. if (!isSupported(g2d)) {
  67. super.paintTextRuns(textRuns, g2d);
  68. return;
  69. }
  70. for (int i = 0; i < textRuns.size(); i++) {
  71. TextRun textRun = (TextRun)textRuns.get(i);
  72. try {
  73. paintTextRun(textRun, g2d);
  74. } catch (IOException ioe) {
  75. //No other possibility than to use a RuntimeException
  76. throw new RuntimeException(ioe);
  77. }
  78. }
  79. }
  80. /**
  81. * Finds an array of suitable fonts for a given AttributedCharacterIterator.
  82. * @param aci the character iterator
  83. * @return the array of fonts
  84. */
  85. protected Font[] findFonts(AttributedCharacterIterator aci) {
  86. Font[] fonts = ACIUtils.findFontsForBatikACI(aci, fontInfo);
  87. return fonts;
  88. }
  89. /**
  90. * Collects all characters from an {@link AttributedCharacterIterator}.
  91. * @param runaci the character iterator
  92. * @return the characters
  93. */
  94. protected CharSequence collectCharacters(AttributedCharacterIterator runaci) {
  95. StringBuffer chars = new StringBuffer();
  96. for (runaci.first(); runaci.getIndex() < runaci.getEndIndex();) {
  97. chars.append(runaci.current());
  98. runaci.next();
  99. }
  100. return chars;
  101. }
  102. /**
  103. * @param runaci an attributed character iterator
  104. * @param layout a text span layout
  105. */
  106. protected final void logTextRun(AttributedCharacterIterator runaci, TextSpanLayout layout) {
  107. if (log.isTraceEnabled()) {
  108. int charCount = runaci.getEndIndex() - runaci.getBeginIndex();
  109. log.trace("================================================");
  110. log.trace("New text run:");
  111. log.trace("char count: " + charCount);
  112. log.trace("range: "
  113. + runaci.getBeginIndex() + " - " + runaci.getEndIndex());
  114. log.trace("glyph count: " + layout.getGlyphCount()); //=getNumGlyphs()
  115. }
  116. }
  117. /**
  118. * @param ch a character
  119. * @param layout a text span layout
  120. * @param index an index
  121. * @param visibleChar visible character flag
  122. */
  123. protected final void logCharacter(char ch, TextSpanLayout layout, int index,
  124. boolean visibleChar) {
  125. if (log.isTraceEnabled()) {
  126. log.trace("glyph " + index
  127. + " -> " + layout.getGlyphIndex(index) + " => " + ch);
  128. if (CharUtilities.isAnySpace(ch) && ch != 32) {
  129. log.trace("Space found: " + Integer.toHexString(ch));
  130. } else if (ch == CharUtilities.ZERO_WIDTH_JOINER) {
  131. log.trace("ZWJ found: " + Integer.toHexString(ch));
  132. } else if (ch == CharUtilities.SOFT_HYPHEN) {
  133. log.trace("Soft hyphen found: " + Integer.toHexString(ch));
  134. }
  135. if (!visibleChar) {
  136. log.trace("Invisible glyph found: " + Integer.toHexString(ch));
  137. }
  138. }
  139. }
  140. }