public void DrawString(RenderVxFormattedString renderVx, double x, double y) { float ox = canvasPainter.OriginX; float oy = canvasPainter.OriginY; //1. update some props.. //2. update current type face UpdateTypefaceAndGlyphBuilder(); Typeface typeface = _glyphPathBuilder.Typeface; //3. layout glyphs with selected layout technique //TODO: review this again, we should use pixel? float fontSizePoint = this.FontSizeInPoints; float scale = typeface.CalculateToPixelScaleFromPointSize(fontSizePoint); RenderVxGlyphPlan[] glyphPlans = renderVx.glyphList; int j = glyphPlans.Length; //--------------------------------------------------- //consider use cached glyph, to increase performance hintGlyphCollection.SetCacheInfo(typeface, fontSizePoint, this.HintTechnique); //--------------------------------------------------- for (int i = 0; i < j; ++i) { RenderVxGlyphPlan glyphPlan = glyphPlans[i]; //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- VertexStore glyphVxs; if (!hintGlyphCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out glyphVxs)) { //if not found then create new glyph vxs and cache it _glyphPathBuilder.SetHintTechnique(this.HintTechnique); _glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, fontSizePoint); //----------------------------------- _tovxs.Reset(); _glyphPathBuilder.ReadShapes(_tovxs); //TODO: review here, //float pxScale = _glyphPathBuilder.GetPixelScale(); glyphVxs = new VertexStore(); _tovxs.WriteOutput(glyphVxs, _vxsPool); // hintGlyphCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, glyphVxs); } canvasPainter.SetOrigin((float)(glyphPlan.x * scale + x), (float)(glyphPlan.y * scale + y)); canvasPainter.Fill(glyphVxs); } //restore prev origin canvasPainter.SetOrigin(ox, oy); }
public void DrawString(RenderVxFormattedString renderVx, double x, double y) { //TODO: review here float ox = _painter.OriginX; float oy = _painter.OriginY; //1. update some props.. //2. update current type face UpdateGlyphLayoutSettings(); _glyphMeshStore.SetFont(_currentTypeface, this.FontSizeInPoints); _glyphMeshStore.SimulateOblique = this.SimulateSlant; //3. layout glyphs with selected layout technique //TODO: review this again, we should use pixel? float fontSizePoint = this.FontSizeInPoints; float scale = _currentTypeface.CalculateScaleToPixelFromPointSize(fontSizePoint); RenderVxGlyphPlan[] glyphPlans = renderVx.GlyphList; int j = glyphPlans.Length; //--------------------------------------------------- //consider use cached glyph, to increase performance //GlyphPosPixelSnapKind x_snap = this.GlyphPosPixelSnapX; //GlyphPosPixelSnapKind y_snap = this.GlyphPosPixelSnapY; float g_x = 0; float g_y = 0; float baseY = (int)y; for (int i = 0; i < j; ++i) { RenderVxGlyphPlan glyphPlan = glyphPlans[i]; //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- VertexStore vxs = _glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex); g_x = (float)(glyphPlan.x * scale + x); g_y = (float)glyphPlan.y * scale; _painter.SetOrigin(g_x, g_y); _painter.Fill(vxs); } //restore prev origin _painter.SetOrigin(ox, oy); }
public static void CopyGlyphPlans(RenderVxFormattedString renderVx, GlyphPlanList glyphPlans, float scale) { int n = glyphPlans.Count; //copy var renderVxGlyphPlans = new RenderVxGlyphPlan[n]; for (int i = 0; i < n; ++i) { GlyphPlan glyphPlan = glyphPlans[i]; renderVxGlyphPlans[i] = new RenderVxGlyphPlan( glyphPlan.glyphIndex, glyphPlan.ExactX, glyphPlan.ExactY, glyphPlan.AdvanceX ); } renderVx.glyphList = renderVxGlyphPlans; }
public static void CopyGlyphPlans(RenderVxFormattedString renderVx, List <GlyphPlan> glyphPlans, float scale) { int n = glyphPlans.Count; //copy var renderVxGlyphPlans = new RenderVxGlyphPlan[n]; for (int i = 0; i < n; ++i) { GlyphPlan glyphPlan = glyphPlans[i]; renderVxGlyphPlans[i] = new RenderVxGlyphPlan( glyphPlan.glyphIndex, glyphPlan.x * scale, glyphPlan.y * scale, glyphPlan.advX * scale ); } renderVx.glyphList = renderVxGlyphPlans; }
public static void CopyGlyphPlans(RenderVxFormattedString renderVx, UnscaledGlyphPlanList glyphPlans, float scale) { int n = glyphPlans.Count; //copy var renderVxGlyphPlans = new RenderVxGlyphPlan[n]; float acc_x = 0; float acc_y = 0; float x = 0; float y = 0; float g_x = 0; float g_y = 0; for (int i = 0; i < n; ++i) { UnscaledGlyphPlan glyphPlan = glyphPlans[i]; float ngx = acc_x + (float)Math.Round(glyphPlan.OffsetX * scale); float ngy = acc_y + (float)Math.Round(glyphPlan.OffsetY * scale); //NOTE: // -glyphData.TextureXOffset => restore to original pos // -glyphData.TextureYOffset => restore to original pos //-------------------------- g_x = (float)(x + ngx); //ideal x g_y = (float)(y + ngy); float g_w = (float)Math.Round(glyphPlan.AdvanceX * scale); acc_x += g_w; //g_x = (float)Math.Round(g_x); g_y = (float)Math.Floor(g_y); renderVxGlyphPlans[i] = new RenderVxGlyphPlan( glyphPlan.glyphIndex, g_x, g_y, g_w ); } renderVx.glyphList = renderVxGlyphPlans; }
public void DrawString(RenderVxFormattedString renderVx, double x, double y) { RenderVxGlyphPlan[] glyphPlans = renderVx.glyphList; int n = glyphPlans.Length; EnsureLoadGLBmp(); //PERF: //TODO: review here, can we cache the glbmp for later use //not to create it every time float scaleFromTexture = _finalTextureScale; TextureKind textureKind = _fontAtlas.TextureKind; float g_x = 0; float g_y = 0; int baseY = (int)Math.Round(y); float scale = 1; for (int i = 0; i < n; ++i) { //PERF: //TODO: //render a set of glyph instead of one glyph per time *** RenderVxGlyphPlan glyph = glyphPlans[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.x * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x g_y = (float)((glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); 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; } } }
public void DrawString(RenderVxFormattedString renderVx, double x, double y) { RenderVxGlyphPlan[] glyphPlans = renderVx.glyphList; int n = glyphPlans.Length; EnsureLoadGLBmp(); //PERF: //TODO: review here, can we cache the glbmp for later use //not to create it every time float scaleFromTexture = _finalTextureScale; Typography.Rendering.TextureKind textureKind = simpleFontAtlas.TextureKind; float g_x = 0; float g_y = 0; int baseY = (int)Math.Round(y); float scale = 1; for (int i = 0; i < n; ++i) { //PERF: //TODO: //render a set of glyph instead of one glyph per time *** RenderVxGlyphPlan glyph = glyphPlans[i]; Typography.Rendering.TextureFontGlyphData glyphData; if (!simpleFontAtlas.TryGetGlyphDataByCodePoint(glyph.glyphIndex, out glyphData)) { continue; } //-------------------------------------- //TODO: review precise height in float //-------------------------------------- PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect); //-------------------------- GlyphPosPixelSnapKind x_snap = this.GlyphPosPixelSnapX; GlyphPosPixelSnapKind y_snap = this.GlyphPosPixelSnapY; switch (x_snap) { default: throw new NotSupportedException(); case GlyphPosPixelSnapKind.Integer: { g_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x int floor_x = (int)g_x; //round to int 0,1 if (g_x - floor_x >= (1f / 2f)) { g_x = floor_x + 1; } else { g_x = floor_x; } } break; case GlyphPosPixelSnapKind.Half: { g_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x //adjust int floor_x = (int)g_x; //round to int 0, 0.5,1.0 if (g_x - floor_x >= (2f / 3f)) { g_x = floor_x + 1; } else if (g_x - floor_x >= (1f / 3f)) { g_x = floor_x + 0.5f; } else { g_x = floor_x; } } break; case GlyphPosPixelSnapKind.None: g_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture); break; } // switch (y_snap) { default: throw new NotSupportedException(); case GlyphPosPixelSnapKind.Integer: //use baseY not y { g_y = (float)((glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); int floor_y = (int)g_y; //round to int 0,1 if (g_y - floor_y >= (1f / 2f)) { g_y = floor_y + 1; } else { g_y = floor_y; } g_y = baseY + g_y; } break; case GlyphPosPixelSnapKind.Half: //review here //use baseY not y { g_y = (float)((glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); int floor_y = (int)g_y; //round to int 0, 0.5,1.0 if (g_y - floor_y >= (2f / 3f)) { g_y = floor_y + 1; } else if (g_x - floor_y >= (1f / 3f)) { g_y = floor_y + 0.5f; } else { g_y = floor_y; } g_y = baseY + g_y; } break; case GlyphPosPixelSnapKind.None: //use Y not baseY g_y = (float)(y + (glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture); break; } switch (textureKind) { case Typography.Rendering.TextureKind.Msdf: canvas2d.DrawSubImageWithMsdf(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; case Typography.Rendering.TextureKind.AggGrayScale: canvas2d.DrawSubImage(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; case Typography.Rendering.TextureKind.AggSubPixel: canvas2d.DrawGlyphImageWithSubPixelRenderingTechnique(_glBmp, ref srcRect, g_x, g_y, scaleFromTexture); break; } //----------- //backup //switch (textureKind) //{ // case Typography.Rendering.TextureKind.Msdf: // { // canvas2d.DrawSubImageWithMsdf(_glBmp, // ref srcRect, // (float)(x + (glyph.x - glyphData.TextureXOffset) * scaleFromTexture), // -glyphData.TextureXOffset => restore to original pos // (float)(y + (glyph.y - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture),// -glyphData.TextureYOffset => restore to original pos // scaleFromTexture); // } // break; // case Typography.Rendering.TextureKind.AggGrayScale: // { // canvas2d.DrawSubImage(_glBmp, // ref srcRect, // (float)(x + (glyph.x - glyphData.TextureXOffset) * scaleFromTexture), // -glyphData.TextureXOffset => restore to original pos // (float)(y + (glyph.y - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture),// -glyphData.TextureYOffset => restore to original pos // scaleFromTexture); // } // break; // case Typography.Rendering.TextureKind.AggSubPixel: // canvas2d.DrawGlyphImageWithSubPixelRenderingTechnique(_glBmp, // ref srcRect, // (float)(x + (glyph.x - glyphData.TextureXOffset) * scaleFromTexture), // -glyphData.TextureXOffset => restore to original pos // (float)(y + (glyph.y - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture),// -glyphData.TextureYOffset => restore to original pos // scaleFromTexture); // break; //} } }