在Windows上打印PDF时,我需要根据文本中的字符选择字体。
我想使用iTextSharp FontSelector,但我希望粗体和普通字体的正确字体可能不同。但字体选择器没有粗体参数。
我不太了解中文字体,但我认为simsun.ttc中没有粗体字体,simhei.ttf可以选择粗体字体(如果我错了,请纠正我)。我应该为粗体选择不同的字体吗?怎么样?
const int fontSizeforSelector = 12;
static Font Arial;
static Font SimplifiedArabic;
static Font Andalus;
static Font TraditionalArabic;
static Font Tahoma;
static Font Simpo;
static Font Batang;
static Font Simsun;
static Font ArialUni;
static Font Simpbdo;
static Font Simhei;
static iTextSharp.text.pdf.FontSelector _fontSelector = new iTextSharp.text.pdf.FontSelector();
static MyFontSelector()
{
string winDir = Environment.GetEnvironmentVariable("WINDIR");//!-!
if (winDir.IsNullOrEmpty())
winDir = GetWindowsDirectory();
string fontDir = winDir + "\\Fonts\\";//!-!
Arial = TryCreateFont(fontDir, "arial.ttf");
SimplifiedArabic = TryCreateFont(fontDir,"simpo.ttf");
Andalus = TryCreateFont(fontDir,"andlso.ttf");
TraditionalArabic = TryCreateFont(fontDir,"trado.ttf");
Tahoma = TryCreateFontEmbedded(fontDir, "tahoma.ttf");
Simpo = TryCreateFontEmbedded(fontDir, "simpo.ttc");//!-!
Batang = TryCreateFontEmbedded(fontDir, "batang.ttc");//!-!
Simsun = TryCreateFontEmbedded(fontDir, "simsun.ttc,1");//!-!
ArialUni = TryCreateFontEmbedded(fontDir, "arialuni.ttf");//!-!
Simpbdo = TryCreateFontEmbedded(fontDir, "simpbdo.ttf");//!-!
Simhei = TryCreateFontEmbedded(fontDir, "simhei.ttf");//!-!
//http://stackoverflow.com/questions/16415074/detecting-cjk-characters-in-a-string-c/16429065#16429065
//http://www.computarat.com/files/java/Test9.java
if (Arial != null)
_fontSelector.AddFont(Arial);
if (SimplifiedArabic != null)
_fontSelector.AddFont(SimplifiedArabic);
if (Andalus != null)
_fontSelector.AddFont(Andalus);
if (SimplifiedArabic != null)
_fontSelector.AddFont(SimplifiedArabic);
if (TraditionalArabic != null)
_fontSelector.AddFont(TraditionalArabic);
if (Tahoma != null)
_fontSelector.AddFont(Tahoma);
if (Batang != null)
_fontSelector.AddFont(Batang);
if (Simsun != null)
_fontSelector.AddFont(Simsun);
if (ArialUni != null)
_fontSelector.AddFont(ArialUni);
if (Simpbdo != null)
_fontSelector.AddFont(Simpbdo);
if (Simhei != null)
_fontSelector.AddFont(Simhei);
}
private static Font TryCreateFont(string fontDir, string file)
{
try
{
return FontFactory.GetFont(fontDir + file, BaseFont.IDENTITY_H, fontSizeforSelector);
}
catch(Exception ex)
{
Trace.WriteLine(ex);
}
return null;
}
private static Font TryCreateFontEmbedded(string fontDir, string file)
{
try
{
return FontFactory.GetFont(fontDir + file, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
return null;
}
public static iTextSharp.text.pdf.FontSelector FontSelector
{
get
{
return _fontSelector;
}
}
public static BaseFont GetBaseFont(string text)
{
Phrase phrase = _fontSelector.Process(text);
return phrase.Font.GetCalculatedBaseFont(true);
}
答案 0 :(得分:1)
我的答案分为两部分:
我的答案的第1部分:
通常没有任何粗体版本的中文字体,因此如果您需要中文字体为粗体,则应使用中文文本更改Chunk
的渲染模式以模仿粗体字体
例如,如果您的Chunk
对象chunk
包含普通字体的文字,您可以这样做,使其粗体看起来像是粗体:
chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
这在我的书的SayPeace示例中得到了证明。默认情况下,字形是填充颜色的形状。为了使它们看起来更粗体,我们改变渲染模式,使它们不仅仅被填充,而且还被抚摸。
我的回答第2部分:
您正在使用Phrase
创建FontSelector
。此phrase
对象将是具有不同字体的Chunk
个对象的集合。奇怪的是你问phrase
对象的字体,因为这只返回一种字体,而短语中的不同块可以有不同的字体。
如果我是你,我将获得phrase
的不同块,检查用于每个块的字体,在必要时更改文本呈现模式,并使用这些块创建一个新短语。