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.

DrawFontManagerDefault.java 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.sl.draw;
  20. import java.awt.Font;
  21. import java.awt.Graphics2D;
  22. import java.awt.GraphicsEnvironment;
  23. import java.util.Arrays;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.TreeSet;
  27. import org.apache.poi.common.usermodel.fonts.FontCharset;
  28. import org.apache.poi.common.usermodel.fonts.FontInfo;
  29. import org.apache.poi.sl.draw.Drawable.DrawableHint;
  30. import org.apache.poi.util.StringUtil;
  31. /**
  32. * Manages fonts when rendering slides.
  33. *
  34. * Use this class to handle unknown / missing fonts or to substitute fonts
  35. */
  36. public class DrawFontManagerDefault implements DrawFontManager {
  37. protected final Set<String> knownSymbolFonts = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
  38. public DrawFontManagerDefault() {
  39. knownSymbolFonts.add("Wingdings");
  40. knownSymbolFonts.add("Symbol");
  41. // knownSymbolFonts.add("Monotype Sorts");
  42. }
  43. @Override
  44. public FontInfo getMappedFont(Graphics2D graphics, FontInfo fontInfo) {
  45. return getFontWithFallback(graphics, Drawable.FONT_MAP, fontInfo);
  46. }
  47. @Override
  48. public FontInfo getFallbackFont(Graphics2D graphics, FontInfo fontInfo) {
  49. FontInfo fi = getFontWithFallback(graphics, Drawable.FONT_FALLBACK, fontInfo);
  50. if (fi == null) {
  51. fi = new DrawFontInfo(Font.SANS_SERIF);
  52. }
  53. return fi;
  54. }
  55. /**
  56. * Symbol fonts like "Wingdings" or "Symbol" have glyphs mapped to a Unicode private use range via the Java font loader,
  57. * although a system font viewer might show you the glyphs in the ASCII range.
  58. * This maps the chars of the text string to the corresponding private use range chars.
  59. *
  60. * @param graphics the used graphics context
  61. * @param fontInfo the font info
  62. * @param text the input string
  63. *
  64. * @return the mapped string, typically consists of chars in the range of 0xf000 to 0xf0ff
  65. *
  66. * @since POI 4.0.0
  67. */
  68. @Override
  69. public String mapFontCharset(Graphics2D graphics, FontInfo fontInfo, String text) {
  70. if (fontInfo == null || text == null || text.isEmpty()) {
  71. return text;
  72. }
  73. String typeface = fontInfo.getTypeface();
  74. if (fontInfo.getCharset() == FontCharset.SYMBOL || knownSymbolFonts.contains(typeface)) {
  75. int[] cps = text.codePoints().map(DrawFontManagerDefault::mapSymbolChar).toArray();
  76. String ret = new String(cps, 0, cps.length);
  77. String[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
  78. boolean hasFont = Arrays.asList(allFonts).contains(typeface);
  79. return hasFont ? ret : StringUtil.mapMsCodepointString(ret);
  80. }
  81. return text;
  82. }
  83. @Override
  84. public Font createAWTFont(Graphics2D graphics, FontInfo fontInfo, double fontSize, boolean bold, boolean italic) {
  85. int style = (bold ? Font.BOLD : 0) | (italic ? Font.ITALIC : 0);
  86. Font font = new Font(fontInfo.getTypeface(), style, 12);
  87. if (Font.DIALOG.equals(font.getFamily())) {
  88. // SansSerif is a better choice than Dialog
  89. font = new Font(Font.SANS_SERIF, style, 12);
  90. }
  91. return font.deriveFont((float)fontSize);
  92. }
  93. private FontInfo getFontWithFallback(Graphics2D graphics, DrawableHint hint, FontInfo fontInfo) {
  94. @SuppressWarnings("unchecked")
  95. Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(hint);
  96. if (fontMap == null) {
  97. return fontInfo;
  98. }
  99. String f = (fontInfo != null) ? fontInfo.getTypeface() : null;
  100. String mappedTypeface = null;
  101. if (fontMap.containsKey(f)) {
  102. mappedTypeface = fontMap.get(f);
  103. } else if (fontMap.containsKey("*")) {
  104. mappedTypeface = fontMap.get("*");
  105. }
  106. return (mappedTypeface != null) ? new DrawFontInfo(mappedTypeface) : fontInfo;
  107. }
  108. private static int mapSymbolChar(int cp) {
  109. return ((0x20 <= cp && cp <= 0x7f) || (0xa0 <= cp && cp <= 0xff)) ? cp | 0xf000 : cp;
  110. }
  111. }