public void RemoveWordStrip(GLRenderVxFormattedString vx) { _wordStrips.Remove(vx); if (_full && _wordStrips.Count == 0) { Cleared?.Invoke(this); } }
/// <summary> /// get current wordplate if there is avilable space, or create new one /// </summary> /// <param name="fmtPlate"></param> /// <returns></returns> public WordPlate GetWordPlate(GLRenderVxFormattedString fmtPlate) { if (_latestPlate != null && _latestPlate.HasAvailableSpace(fmtPlate)) { return(_latestPlate); } return(GetNewWordPlate()); }
public void DrawString(GLRenderVxFormattedString renderVx, double x, double y) { _pcx.LoadTexture(_glBmp); _pcx.FontFillColor = _painter.FontFillColor; DrawingGL.GLRenderVxFormattedString renderVxString1 = (DrawingGL.GLRenderVxFormattedString)renderVx; DrawingGL.VertexBufferObject vbo = renderVxString1.GetVbo(); vbo.Bind(); _pcx.DrawGlyphImageWithSubPixelRenderingTechnique4_FromLoadedVBO(renderVxString1.IndexArrayCount, (float)x, (float)y); vbo.UnBind(); }
public override RenderVxFormattedString CreateRenderVx(string textspan) { char[] buffer = textspan.ToCharArray(); var renderVxFmtStr = new GLRenderVxFormattedString(buffer); if (_textPrinter != null) { _textPrinter.PrepareStringForRenderVx(renderVxFmtStr, buffer, 0, buffer.Length); } return(renderVxFmtStr); }
public void DrawString(GLBitmap glBmp, GLRenderVxFormattedString renderVx, double x, double y) { _pcx.FontFillColor = _painter.FontFillColor; //for sharp edge glyph _pcx.DrawGlyphImageWithSubPixelRenderingTechnique4_FromVBO( glBmp, renderVx.GetVbo(), renderVx.IndexArrayCount, (float)Math.Round(x), (float)Math.Floor(y)); }
public bool HasAvailableSpace(GLRenderVxFormattedString renderVxFormattedString) { //check if we have avaliable space for this? float width = renderVxFormattedString.Width; float previewY = _currentY; #if DEBUG float previewX = _currentX; #endif if (_currentX + width > _plateWidth) { //move to newline previewY += _currentLineHeightMax + INTERLINE_SPACE; } return(previewY + renderVxFormattedString.SpanHeight < _plateHeight); }
public void PrepareStringForRenderVx(GLRenderVxFormattedString renderVxFormattedString, char[] buffer, int startAt, int len) { int top = 0; //simulate top int left = 0; //simulate left _vboBuilder.Clear(); _vboBuilder.SetTextureInfo(_glBmp.Width, _glBmp.Height, _glBmp.IsYFlipped, _pcx.OriginKind); //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 px_scale = _px_scale; //-------------------------- TextureKind textureKind = _fontAtlas.TextureKind; float g_left = 0; float g_top = 0; int baseLine = (int)Math.Round((float)top + _font.AscentInPixels); int bottom = (int)Math.Round((float)top + _font.AscentInPixels - _font.DescentInPixels); float acc_x = 0; //local accumulate x float acc_y = 0; //local accumulate y int seqLen = glyphPlanSeq.Count; for (int i = 0; i < seqLen; ++i) { UnscaledGlyphPlan glyph = glyphPlanSeq[i]; Typography.Rendering.TextureGlyphMapData glyphData; if (!_fontAtlas.TryGetGlyphMapData(glyph.glyphIndex, out glyphData)) { //if no glyph data, we should render a missing glyph *** continue; } //-------------------------------------- //TODO: review precise height in float //-------------------------------------- //paint src rect //temp fix, glyph texture img is not flipped //but the associate info is flipped => so //we need remap exact Y from the image Rectangle srcRect = new Rectangle(glyphData.Left, _glBmp.Height - (glyphData.Top + glyphData.Height), glyphData.Width, glyphData.Height); //offset length from 'base-line' float x_offset = acc_x + (float)Math.Round(glyph.OffsetX * px_scale - glyphData.TextureXOffset); float y_offset = acc_y + (float)Math.Round(glyph.OffsetY * px_scale - glyphData.TextureYOffset) + srcRect.Height; //*** //NOTE: // -glyphData.TextureXOffset => restore to original pos // -glyphData.TextureYOffset => restore to original pos //-------------------------- g_left = (float)(left + x_offset); g_top = (float)(bottom - y_offset); //*** acc_x += (float)Math.Round(glyph.AdvanceX * px_scale); //g_x = (float)Math.Round(g_x); //*** g_top = (float)Math.Floor(g_top);//adjust to integer num *** // _vboBuilder.WriteVboToList(ref srcRect, g_left, g_top); } //--- //copy vbo result and store into renderVx float[] vertexList = _vboBuilder._buffer.ToArray(); ushort[] indexList = _vboBuilder._indexList.ToArray(); //--- renderVxFormattedString.IndexArrayCount = _vboBuilder._indexList.Count; renderVxFormattedString.IndexArray = _vboBuilder._indexList.ToArray(); renderVxFormattedString.VertexCoords = _vboBuilder._buffer.ToArray(); _vboBuilder.Clear(); }
public bool CreateWordStrip(GLPainter painter, GLRenderVxFormattedString renderVxFormattedString) { //-------------- //create stencil text buffer //we use white glyphs on black bg //-------------- if (!_isInitBg) { //by default, we init bg to black for stencil buffer _isInitBg = true; painter.Clear(Color.Black); } float width = renderVxFormattedString.Width; if (_currentX + width > _plateWidth) { //move to newline _currentY += _currentLineHeightMax + INTERLINE_SPACE;//interspace =4 px _currentX = 0; //new line _currentLineHeightMax = (int)Math.Ceiling(renderVxFormattedString.SpanHeight); } //on current line //check available height if (_currentY + renderVxFormattedString.SpanHeight > _plateHeight) { _full = true; return(false); } //---------------------------------- if (renderVxFormattedString.SpanHeight > _currentLineHeightMax) { _currentLineHeightMax = (int)Math.Ceiling(renderVxFormattedString.SpanHeight); } Color prevColor = painter.FontFillColor; Color prevTextBgHint = painter.TextBgColorHint; bool prevPreparingWordStrip = painter.PreparingWordStrip; GlyphTexturePrinterDrawingTechnique prevTextDrawing = painter.TextPrinterDrawingTechnique; painter.TextBgColorHint = Color.Black; painter.FontFillColor = Color.White; painter.PreparingWordStrip = true; renderVxFormattedString.UseWithWordPlate = false; GLBitmapGlyphTextPrinter textPrinter = (GLBitmapGlyphTextPrinter)painter.TextPrinter; switch (renderVxFormattedString.GlyphMixMode) { case GLRenderVxFormattedStringGlyphMixMode.OnlyColorGlyphs: { //TODO: review this option again //optional painter.TextPrinterDrawingTechnique = GlyphTexturePrinterDrawingTechnique.Copy; Rectangle currentClip = painter.ClipBox; painter.SetClipBox(_currentX, _currentY, (int)(_currentX + width), _currentY + _currentLineHeightMax); painter.Clear(Color.Transparent); painter.SetClipBox(currentClip.Left, currentClip.Top, currentClip.Right, currentClip.Bottom); //restore } break; } //use special mode of the GLBitmapGlyphTextPrinter //----------- textPrinter.WordPlateCreatingMode = true; //turn on platemode textPrinter.DrawString(renderVxFormattedString, _currentX, _currentY); textPrinter.WordPlateCreatingMode = false; //switch back //----------- renderVxFormattedString.UseWithWordPlate = true; //restore painter.FontFillColor = prevColor; //restore painter.TextBgColorHint = prevTextBgHint; //restore painter.PreparingWordStrip = prevPreparingWordStrip; painter.TextPrinterDrawingTechnique = prevTextDrawing; //restore //in this case we can dispose vbo inside renderVx //(we can recreate that vbo later) renderVxFormattedString.DisposeVbo(); renderVxFormattedString.OwnerPlate = this; renderVxFormattedString.WordPlateLeft = (ushort)_currentX; renderVxFormattedString.WordPlateTop = (ushort)_currentY; renderVxFormattedString.UseWithWordPlate = true; #if DEBUG dbugUsedCount++; #endif _wordStrips.Add(renderVxFormattedString, true); //-------- _currentX += (int)Math.Ceiling(renderVxFormattedString.Width) + INTERWORD_SPACE; //interspace x 1px #if DEBUG //dbugSaveBackBuffer("dbug_test1.png"); #endif return(true); }