public void DrawString(char[] text, int startAt, int len, double x, double y) { if (this.UseSubPixelRendering) { //1. clear prev drawing result _aggPainter.Clear(Drawing.Color.FromArgb(0, 0, 0, 0)); //aggPainter.Clear(Drawing.Color.White); //aggPainter.Clear(Drawing.Color.FromArgb(0, 0, 0, 0)); //2. print text span into Agg Canvas _vxsTextPrinter.DrawString(text, startAt, len, 0, 0); //3.copy to gl bitmap //byte[] buffer = PixelFarm.Agg.ActualImage.GetBuffer(_actualImage); //------------------------------------------------------ GLBitmap glBmp = new GLBitmap(_actualImage); glBmp.IsInvert = false; //TODO: review font height if (StartDrawOnLeftTop) { y -= _vxsTextPrinter.FontLineSpacingPx; } _glsx.DrawGlyphImageWithSubPixelRenderingTechnique(glBmp, (float)x, (float)y); glBmp.Dispose(); } else { //1. clear prev drawing result _aggPainter.Clear(Drawing.Color.White); _aggPainter.StrokeColor = Color.Black; //2. print text span into Agg Canvas _vxsTextPrinter.StartDrawOnLeftTop = false; float dyOffset = _vxsTextPrinter.FontDescedingPx; _vxsTextPrinter.DrawString(text, startAt, len, 0, -dyOffset); //------------------------------------------------------ //debug save image from agg's buffer #if DEBUG //actualImage.dbugSaveToPngFile("d:\\WImageTest\\aa1.png"); #endif //------------------------------------------------------ //3.copy to gl bitmap //byte[] buffer = PixelFarm.Agg.ActualImage.GetBuffer(_actualImage); //------------------------------------------------------ //debug save image from agg's buffer //------------------------------------------------------ //GLBitmap glBmp = new GLBitmap(bmpWidth, bmpHeight, buffer, true); GLBitmap glBmp = new GLBitmap(_actualImage); glBmp.IsInvert = false; //TODO: review font height //if (StartDrawOnLeftTop) //{ y += _vxsTextPrinter.FontLineSpacingPx; //} _glsx.DrawGlyphImage(glBmp, (float)x, (float)y + dyOffset); glBmp.Dispose(); } }
public void DrawString(char[] buffer, int startAt, int len, double x, double y) { _glsx.FontFillColor = painter.FontFillColor; int j = buffer.Length; //create temp buffer span that describe the part of a whole char buffer TextBufferSpan textBufferSpan = new TextBufferSpan(buffer, startAt, len); //ask text service to parse user input char buffer and create a glyph-plan-sequence (list of glyph-plan) //with specific request font GlyphPlanSequence glyphPlanSeq = _textServices.CreateGlyphPlanSeq(ref textBufferSpan, font); float scale = _fontAtlas.TargetTextureScale; int recommendLineSpacing = _fontAtlas.OriginalRecommendLineSpacing; //-------------------------- //TODO: //if (x,y) is left top //we need to adjust y again y -= ((_fontAtlas.OriginalRecommendLineSpacing) * scale); EnsureLoadGLBmp(); // float scaleFromTexture = _finalTextureScale; TextureKind textureKind = _fontAtlas.TextureKind; //-------------------------- //TODO: review render steps //NOTE: // -glyphData.TextureXOffset => restore to original pos // -glyphData.TextureYOffset => restore to original pos // ideal_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture); // ideal_y = (float)(y + (glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); //-------------------------- float g_x = 0; float g_y = 0; int baseY = (int)Math.Round(y); int n = glyphPlanSeq.len; int endBefore = glyphPlanSeq.startAt + n; for (int i = glyphPlanSeq.startAt; i < endBefore; ++i) { GlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq); GlyphPlan glyph = glyphPlanList[i]; Typography.Rendering.TextureFontGlyphData glyphData; if (!_fontAtlas.TryGetGlyphDataByCodePoint(glyph.glyphIndex, out glyphData)) { //if no glyph data, we should render a missing glyph *** continue; } //-------------------------------------- //TODO: review precise height in float //-------------------------------------- PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect); g_x = (float)(x + (glyph.ExactX * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x g_y = (float)(y + (glyph.ExactY * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); //for sharp glyph //we adjust g_x,g_y to integer value g_x = (float)Math.Round(g_x); g_y = (float)Math.Floor(g_y); switch (textureKind) { case TextureKind.Msdf: _glsx.DrawSubImageWithMsdf(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; case TextureKind.StencilGreyScale: //stencil gray scale with fill-color _glsx.DrawGlyphImageWithStecil(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; case TextureKind.Bitmap: _glsx.DrawSubImage(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; case TextureKind.StencilLcdEffect: _glsx.DrawGlyphImageWithSubPixelRenderingTechnique(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; } } }