使用Apache POI HSLFSlide.draw时默认的日语字体是什么? [英] What is the default Japanese font when using Apache POI HSLFSlide.draw?

查看:104
本文介绍了使用Apache POI HSLFSlide.draw时默认的日语字体是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Apache POI将pptx幻灯片转换为图像.在pptx幻灯片中,我有GE Inspira字体的日语文本,该文本在我的系统中不可用(注释掉ge.registerFont(font)以进行模拟).生成的图像以默认字体(请参见此处)显示日语文本.那是什么字体,默认字体在哪里设置?

I am using Apache POI to convert pptx slide to image. In the pptx slide, I have Japanese text in GE Inspira font that is not available in my system (comment out ge.registerFont(font) to simulate that). The generated image shows the Japanese text in a default font (see image here). What font is that and where is this default font set?

注册字体时,日语文本显示为框(请参见此处图片).这是因为GE Inspira字体不支持日语字符.有没有一种方法可以强制POI对日语文本使用默认字体?

When I register the font, the Japanese text appears as boxes (see image here). This is because GE Inspira font does not support Japanese characters. Is there a way to force POI to use the default font for Japanese text?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;

public class UnicodePPT {
    public static void main(String[] args) throws Exception {
        // create a sample pptx
        XMLSlideShow ss = new XMLSlideShow();
        Dimension pgsize = ss.getPageSize();

        XSLFSlide slide = ss.createSlide();
        XSLFTextBox tb = slide.createTextBox();
        // tb.setShapeType(XSLFShapeType.HEART);
        int shapeSize = 150;
        tb.setAnchor(new Rectangle((int)(pgsize.getWidth() / 2 - shapeSize / 2), (int)(pgsize.getHeight()
                / 2
                - shapeSize
                / 2), shapeSize, shapeSize));
        tb.setLineWidth(2);
        tb.setLineColor(Color.BLACK);
        XSLFTextParagraph par = tb.addNewTextParagraph();
        tb.setVerticalAlignment(VerticalAlignment.DISTRIBUTED);
        par.setTextAlign(TextAlign.CENTER);
        XSLFTextRun run = par.addNewTextRun();
        run.setText("ゴミ箱");
        run.setFontFamily("GE Inspira");
        run.setFontSize(12.0);

        // set the font
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        InputStream is = new FileInputStream("src/test/resources/GEInspRg.TTF");
        Font font = Font.createFont(Font.TRUETYPE_FONT, is);
        is.close();
        ge.registerFont(font);

        // render it
        double zoom = 2; // magnify it by 2
        AffineTransform at = new AffineTransform();
        at.setToScale(zoom, zoom);

        BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width * zoom),
                (int)Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = img.createGraphics();
        graphics.setTransform(at);
        graphics.setPaint(Color.white);
        graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
        slide.draw(graphics);

        FileOutputStream fos = new FileOutputStream("src/test/resources/unicodeppt.png");
        javax.imageio.ImageIO.write(img, "png", fos);
        fos.close();
    }
}

推荐答案

如注释中所述,Inspira GE字体不是unicode字体,因此需要回退.如果未指定特定的后备字体,请字体.将使用SANS_SERIF .对于像SANS_SERIF这样的逻辑字体,有java内部的后备配置.不幸的是,自动添加的 Lucida字体不支持中文(简体),中文(繁体),日语和韩语.

As mentioned in the comments, the Inspira GE font is not an unicode font, therefore a fallback is needed. If no specific fallback font is specified, Font.SANS_SERIF will be used. For the logical fonts like SANS_SERIF there is java internal fallback configuration. Unfortunately the automatically added Lucida fonts do not support Chinese (Simplified), Chinese (Traditional), Japanese, and Korean.

因此,您应该提供unicode字体,例如 Mona Code2000 Arial Unicode MS -呈现提示的形式提供. Map<String,String>的形式,其中key是原始字体系列,而value是替代字体.您还可以指定"*"作为键,以捕获所有字体.在FONT_FALLBACK旁边,还有一个FONT_MAP提示来映射所有出现的内容,即不仅是丢失的字形.

So you should provide a unicode font, e.g. Mona, Code2000 and Arial Unicode MS are a good picks - wikipedia has also good collection. The mapping is provided as POI-specific rendering hint in the form of Map<String,String>, where the key is original font family and value the substitution font. You can also specify "*" as a key, to catch-all fonts. Beside the FONT_FALLBACK, there's also a FONT_MAP hint to map all the occurrences, i.e. not only the missing glyphs.

这将在POI 3.16-beta2(ETA 2017年2月)中提供,或者您暂时使用

This will be available in POI 3.16-beta2 (ETA February 2017) or you temporarily use the trunk - another option is to provide your own DrawTextParagraph via a customized DrawFactory

要找出答案,如果您的字体能够呈现chars/glpyhs,则需要在 Windows字符映射工具或其他字体工具,例如 FontForge ,然后检查 unicode块中是否有字形.

To find out, if your font is capable of rendering your chars/glpyhs, you need to open it in the Windows character map tool or some other font tool like FontForge and check if there's a glyph at the unicode block.

@Test
public void unicodeRendering() throws Exception {
    // create a sample pptx
    XMLSlideShow ss = createSamplePPT();
    Dimension pgsize = ss.getPageSize();

    // set the font
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    for (String s : new String[]{"GEInspRg.ttf","mona.ttf"}) {
        Font font = Font.createFont(Font.TRUETYPE_FONT, new File(s));
        ge.registerFont(font);
    }
    Map<String,String> fallbackMap = new HashMap<String,String>();
    fallbackMap.put("GE Inspira", "Mona");

    // render it
    double zoom = 2; // magnify it by 2
    AffineTransform at = new AffineTransform();
    at.setToScale(zoom, zoom);

    BufferedImage img = new BufferedImage((int)Math.ceil(pgsize.width * zoom),
            (int)Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics = img.createGraphics();
    graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
    graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

    graphics.setTransform(at);
    graphics.setPaint(Color.white);
    graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
    ss.getSlides().get(0).draw(graphics);

    javax.imageio.ImageIO.write(img, "png", new File("unicodeppt.png"));

    ss.close();
}

private XMLSlideShow createSamplePPT() {
    XMLSlideShow ss = new XMLSlideShow();
    Dimension pgsize = ss.getPageSize();

    XSLFSlide slide = ss.createSlide();
    XSLFTextBox tb = slide.createTextBox();
    // tb.setShapeType(XSLFShapeType.HEART);
    int shapeSize = 150;
    tb.setAnchor(new Rectangle((int)(pgsize.getWidth() / 2 - shapeSize / 2),
            (int)(pgsize.getHeight() / 2 - shapeSize / 2), shapeSize, shapeSize));
    tb.setLineWidth(2);
    tb.setLineColor(Color.BLACK);
    XSLFTextParagraph par = tb.addNewTextParagraph();
    tb.setVerticalAlignment(VerticalAlignment.DISTRIBUTED);
    par.setTextAlign(TextAlign.CENTER);
    XSLFTextRun run = par.addNewTextRun();
    run.setText("unicode ->\u30B4\u30DF\u7BB1<-");
    run.setFontFamily("GE Inspira");
    run.setFontSize(12.0);
    return ss;
}

这篇关于使用Apache POI HSLFSlide.draw时默认的日语字体是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆