如何控制drawstring时的字符间距?如何旋转字体? 1、drawstring 的字符间距如何控制?类似GDI时代的SetTextCharacterExtra功能,只需控制字符间距即可,无需考虑行间间距。2、如何使用旋转字体,即如何在不旋转画布的情况下,输出旋转的字体? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1自定义FONT 设置宽度。2。也是自定义字体。c++基础的书籍里有正好楼主所要的东西。 http://hi.baidu.com/helmsman88/blog/item/0b8ffbcdf8a70f1801e928be.html 将整句拆成一个个文字进行绘制,绘制时控制X坐标即可.如果你是怕旋转了画布绘制出的旋转字体会影响整体角度的话,可以在每次旋转画布并绘制后重新恢复原来的画布角度.可在绘制前先保存graphics状态,然后旋转绘制,绘制后恢复这个状态. 可在绘制前先保存graphics状态,然后旋转绘制,绘制后恢复这个状态. 使用 GDI 绘制有间距的文本在.netFramework中Graphics.DrawString方法提供了基本的文本绘制功能。然而,这个方法本身缺乏对字符格式的控制能力,例如不支持多数文本处理器支持的字符间距(大概微软认为不会有人编写基于.NET的文本处理器)。这个问题最简单的解决方法是将整个字符串“化整为零”,一个字符一个字符的按照指定间距画出来。然而这样做会产生大量的临时字符串,而且有巨大的PInvoke代价。那有没有其他的方法呢?答案是肯定的——GDI 底层提供了GdipDrawDriverString方法,允许我们对单个字符的输出位置进行控制。遗憾的是也许因为这个方法太底层了,所以在.NETFramework中并没有针对它的封装。(顺便说一下,Office从OfficeXP开始就使用GDI 作为绘图引擎,象Visio中的文本绘制就使用了GdipDrawDriverString) 软件开发网 下面是对GdipDrawDriverString的简单封装(GdiplusMethods.cs): 软件开发网usingSystem;usingSystem.Drawing.Drawing2D;usingSystem.Reflection;usingSystem.Runtime.InteropServices; http://www.mscto.comnamespaceSystem.Drawing{///<summary>///SummarydescriptionforGdiplusMethods.///</summary>publicclassGdiplusMethods{privateGdiplusMethods(){} privateenumDriverStringOptions{CmapLookup=1,Vertical=2,Advance=4,LimitSubpixel=8,} publicstaticvoidDrawDriverString(Graphicsgraphics,stringtext,Fontfont,Brushbrush,PointF[]positions){DrawDriverString(graphics,text,font,brush,positions,null);} publicstaticvoidDrawDriverString(Graphicsgraphics,stringtext,Fontfont,Brushbrush,PointF[]positions,Matrixmatrix){if(graphics==null)thrownewArgumentNullException("graphics");if(text==null)thrownewArgumentNullException("text");if(font==null)thrownewArgumentNullException("font");if(brush==null)thrownewArgumentNullException("brush");if(positions==null)thrownewArgumentNullException("positions"); //GethGraphicsFieldInfofield=typeof(Graphics).GetField("nativeGraphics",BindingFlags.Instance|BindingFlags.NonPublic);IntPtrhGraphics=(IntPtr)field.GetValue(graphics); //GethFontfield=typeof(Font).GetField("nativeFont",BindingFlags.Instance|BindingFlags.NonPublic);IntPtrhFont=(IntPtr)field.GetValue(font); http://www.mscto.com//GethBrushfield=typeof(Brush).GetField("nativeBrush",BindingFlags.Instance|BindingFlags.NonPublic);IntPtrhBrush=(IntPtr)field.GetValue(brush); //GethMatrixIntPtrhMatrix=IntPtr.Zero;if(matrix!=null){field=typeof(Matrix).GetField("nativeMatrix",BindingFlags.Instance|BindingFlags.NonPublic);hMatrix=(IntPtr)field.GetValue(matrix);}intresult=GdipDrawDriverString(hGraphics,text,text.Length,hFont,hBrush,positions,(int)DriverStringOptions.CmapLookup,hMatrix);} [DllImport("Gdiplus.dll",CharSet=CharSet.Unicode)]internalexternstaticintGdipMeasureDriverString(IntPtrgraphics,stringtext,intlength,IntPtrfont,PointF[]positions,intflags,IntPtrmatrix,refRectangleFbounds); [DllImport("Gdiplus.dll",CharSet=CharSet.Unicode)]internalexternstaticintGdipDrawDriverString(IntPtrgraphics,stringtext,intlength,IntPtrfont,IntPtrbrush,PointF[]positions,intflags,IntPtrmatrix);}} 下面我们来试验一下:新建一个窗体,在OnPaint事件里加入如下代码: protectedoverridevoidOnPaint(PaintEventArgse){base.OnPaint(e); http://www.mscto.comGraphicsg=e.Graphics;g.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;Brushbrush=newSolidBrush(Color.Red);Fontfont=newFont("宋体",12.0f); strings="Test中文オンエア版";SizeFsize=g.MeasureString(s,font,int.MaxValue); PointF[]positions=newPointF[s.Length];for(inti=0;i<s.Length;i )positions[i]=newPointF(i*40 20,size.Height); GdiplusMethods.DrawDriverString(g,s,font,brush,positions);} http://www.mscto.com 在这里,我们使用PointF[]positions这个数组来控制字符的输出位置。需要注意的是坐标指的是字符的左下角,而不是左上角(计算机科学家和数学家使用不同的坐标系)。 有趣的是,如果我们把字体从“宋体”改为英文字体,如“Arial”,那么非英文字母将显示成一个框。这是因为GdipDrawDriverString就像它的名字暗示的那样,它直接使用指定字体绘制文本而不做其他处理。而GdipDrawString则会对文本进行分析,例如如果我们使用一个英文字体绘制中文字,则GdipDrawString会在内部创建一个中文字体(通常是宋体)然后使用这个字体进行绘制(这个分析和匹配过程是相当复杂的,并且没有任何文档记载)。 再顶一下,有没有简单的解决办法?DrawDriverString的办法我知道 为什么会有这个错误啊!!System.Windows.Forms.TextBox并不包含“AppendText”的定义 如何:EBCDIC编码文本转换为ASII编码 本人想用C#做一个信息抓取系统,想在新浪网上抓取新闻。前提是我已经在新浪网上已登陆的。请问应该怎么实现? c#解决方案如何调用其他解决方案?? 如何跟据不同的数据源在页面上用不同的控件来显示 设置outlook附件 请问C#怎么样才能入门的快一点 关于多个控件的ID能否编数组 TreeView的问题 axWindowsMediaPlayer1的问题 项目架设问题 请大家帮忙!!!VS2008 总是空白页 为什么?
2。也是自定义字体。c++基础的书籍里有正好楼主所要的东西。
在.netFramework中Graphics.DrawString方法提供了基本的文本绘制功能。然而,这个方法本身缺乏对字符格式的控制能力,例如不支持多数文本处理器支持的字符间距(大概微软认为不会有人编写基于.NET的文本处理器)。这个问题最简单的解决方法是将整个字符串“化整为零”,一个字符一个字符的按照指定间距画出来。然而这样做会产生大量的临时字符串,而且有巨大的PInvoke代价。那有没有其他的方法呢?答案是肯定的——GDI 底层提供了GdipDrawDriverString方法,允许我们对单个字符的输出位置进行控制。遗憾的是也许因为这个方法太底层了,所以在.NETFramework中并没有针对它的封装。(顺便说一下,Office从OfficeXP开始就使用GDI 作为绘图引擎,象Visio中的文本绘制就使用了GdipDrawDriverString) 软件开发网 下面是对GdipDrawDriverString的简单封装(GdiplusMethods.cs): 软件开发网usingSystem;
usingSystem.Drawing.Drawing2D;
usingSystem.Reflection;
usingSystem.Runtime.InteropServices; http://www.mscto.comnamespaceSystem.Drawing
{
///<summary>
///SummarydescriptionforGdiplusMethods.
///</summary>
publicclassGdiplusMethods
{
privateGdiplusMethods(){} privateenumDriverStringOptions
{
CmapLookup=1,
Vertical=2,
Advance=4,
LimitSubpixel=8,
} publicstaticvoidDrawDriverString(Graphicsgraphics,stringtext,
Fontfont,Brushbrush,PointF[]positions)
{
DrawDriverString(graphics,text,font,brush,positions,null);
} publicstaticvoidDrawDriverString(Graphicsgraphics,stringtext,
Fontfont,Brushbrush,PointF[]positions,Matrixmatrix)
{
if(graphics==null)
thrownewArgumentNullException("graphics");
if(text==null)
thrownewArgumentNullException("text");
if(font==null)
thrownewArgumentNullException("font");
if(brush==null)
thrownewArgumentNullException("brush");
if(positions==null)
thrownewArgumentNullException("positions");
//GethGraphics
FieldInfofield=typeof(Graphics).GetField("nativeGraphics",
BindingFlags.Instance|BindingFlags.NonPublic);
IntPtrhGraphics=(IntPtr)field.GetValue(graphics); //GethFont
field=typeof(Font).GetField("nativeFont",
BindingFlags.Instance|BindingFlags.NonPublic);
IntPtrhFont=(IntPtr)field.GetValue(font); http://www.mscto.com
//GethBrush
field=typeof(Brush).GetField("nativeBrush",
BindingFlags.Instance|BindingFlags.NonPublic);
IntPtrhBrush=(IntPtr)field.GetValue(brush);
//GethMatrix
IntPtrhMatrix=IntPtr.Zero;
if(matrix!=null)
{
field=typeof(Matrix).GetField("nativeMatrix",
BindingFlags.Instance|BindingFlags.NonPublic);
hMatrix=(IntPtr)field.GetValue(matrix);
}intresult=GdipDrawDriverString(hGraphics,text,text.Length,
hFont,hBrush,positions,(int)DriverStringOptions.CmapLookup,hMatrix);
} [DllImport("Gdiplus.dll",CharSet=CharSet.Unicode)]
internalexternstaticintGdipMeasureDriverString(IntPtrgraphics,
stringtext,intlength,IntPtrfont,PointF[]positions,
intflags,IntPtrmatrix,refRectangleFbounds);
[DllImport("Gdiplus.dll",CharSet=CharSet.Unicode)]
internalexternstaticintGdipDrawDriverString(IntPtrgraphics,
stringtext,intlength,IntPtrfont,IntPtrbrush,
PointF[]positions,intflags,IntPtrmatrix);
}
} 下面我们来试验一下:新建一个窗体,在OnPaint事件里加入如下代码:
protectedoverridevoidOnPaint(PaintEventArgse)
{
base.OnPaint(e); http://www.mscto.comGraphicsg=e.Graphics;
g.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;
Brushbrush=newSolidBrush(Color.Red);
Fontfont=newFont("宋体",12.0f); strings="Test中文オンエア版";
SizeFsize=g.MeasureString(s,font,int.MaxValue); PointF[]positions=newPointF[s.Length];
for(inti=0;i<s.Length;i )
positions[i]=newPointF(i*40 20,size.Height);
GdiplusMethods.DrawDriverString(g,s,font,brush,positions);
} http://www.mscto.com 在这里,我们使用PointF[]positions这个数组来控制字符的输出位置。需要注意的是坐标指的是字符的左下角,而不是左上角(计算机科学家和数学家使用不同的坐标系)。 有趣的是,如果我们把字体从“宋体”改为英文字体,如“Arial”,那么非英文字母将显示成一个框。这是因为GdipDrawDriverString就像它的名字暗示的那样,它直接使用指定字体绘制文本而不做其他处理。而GdipDrawString则会对文本进行分析,例如如果我们使用一个英文字体绘制中文字,则GdipDrawString会在内部创建一个中文字体(通常是宋体)然后使用这个字体进行绘制(这个分析和匹配过程是相当复杂的,并且没有任何文档记载)。