protected override void OnGLRender(object sender, EventArgs args) { _glsx.SmoothMode = SmoothMode.Smooth; _glsx.StrokeColor = PixelFarm.Drawing.Color.Blue; _glsx.ClearColorBuffer(); if (!resInit) { // msdf_bmp = LoadTexture(@"..\msdf_75.png"); //msdf_bmp = LoadTexture(@"d:\\WImageTest\\a001_x1_66.png"); msdf_bmp = DemoHelper.LoadTexture(totalImg); //msdf_bmp = LoadTexture(@"d:\\WImageTest\\a001_x1.png"); //msdf_bmp = LoadTexture(@"d:\\WImageTest\\msdf_65.png"); resInit = true; } painter.Clear(PixelFarm.Drawing.Color.White); //var f = painter.CurrentFont; //painter.DrawString("hello!", 0, 20); //canvas2d.DrawImageWithSubPixelRenderingMsdf(msdf_bmp, 200, 500, 15f); Typography.Rendering.TextureFontGlyphData glyphData; byte[] codepoint = System.Text.Encoding.UTF8.GetBytes("AB"); fontAtlas.TryGetGlyphDataByGlyphIndex(codepoint[0], out glyphData); PixelFarm.Drawing.Rectangle r = ConvToRect(glyphData.Rect); //canvas2d.DrawSubImageWithMsdf(msdf_bmp, ref r, 100, 500); _glsx.DrawSubImageWithMsdf(msdf_bmp, ref r, 100, 500); fontAtlas.TryGetGlyphDataByGlyphIndex(codepoint[1], out glyphData); PixelFarm.Drawing.Rectangle r2 = ConvToRect(glyphData.Rect); _glsx.DrawSubImageWithMsdf(msdf_bmp, ref r2, 100 + r.Width - 10, 500); //full image _glsx.DrawImage(msdf_bmp, 100, 300); SwapBuffers(); }
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; float g_x = 0; float g_y = 0; int baseY = (int)Math.Round(y); int n = glyphPlanSeq.len; int endBefore = glyphPlanSeq.startAt + n; //------------------------------------- _glsx.LoadTexture1(_glBmp); //------------------------------------- _vboBufferList.Clear(); //clear before use _indexList.Clear(); //clear before use float acc_x = 0; float acc_y = 0; for (int i = glyphPlanSeq.startAt; i < endBefore; ++i) { UnscaledGlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq); UnscaledGlyphPlan glyph = glyphPlanList[i]; Typography.Rendering.TextureFontGlyphData glyphData; if (!_fontAtlas.TryGetGlyphDataByGlyphIndex(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); float ngx = acc_x + (float)Math.Round(glyph.OffsetX * scale); float ngy = acc_y + (float)Math.Round(glyph.OffsetY * scale); //NOTE: // -glyphData.TextureXOffset => restore to original pos // -glyphData.TextureYOffset => restore to original pos //-------------------------- g_x = (float)(x + (ngx - glyphData.TextureXOffset) * scaleFromTexture); //ideal x g_y = (float)(y + (ngy - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); acc_x += (float)Math.Round(glyph.AdvanceX * scale); //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.WriteVboToList( _vboBufferList, _indexList, ref srcRect, g_x, g_y, scaleFromTexture); break; } } //------- //we create vbo first //then render _glsx.DrawGlyphImageWithSubPixelRenderingTechnique3(_vboBufferList.ToArray(), _indexList.ToArray()); }