protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { if (this.imageBinder != null) { switch (imageBinder.State) { case ImageBinderState.Loaded: { canvas.DrawImage(imageBinder.Image, new RectangleF(0, 0, this.Width, this.Height)); } break; case ImageBinderState.Unload: { if (this.imageBinder.HasLazyFunc) { this.imageBinder.LazyLoadImage(); } } break; } } else { //when no image //canvasPage.FillRectangle(BackColor, updateArea._left, updateArea._top, updateArea.Width, updateArea.Height); } #if DEBUG //canvasPage.dbug_DrawCrossRect(PixelFarm.Drawing.Color.Black, // new Rectangle(0, 0, this.Width, this.Height)); #endif }
public override void InvalidateRootArea(Rectangle r) { Rectangle rect = r; this.RootGfx.InvalidateGraphicArea( RootGfx.TopWindowRenderBox, ref rect); }
static void RootInvalidateGraphicArea(RenderElement re, ref Rectangle rect) { //1. re.propFlags &= ~RenderElementConst.IS_GRAPHIC_VALID; //2. re.rootGfx.InvalidateGraphicArea(re, ref rect); }
//========================================================= /// <summary> /// push clip area relative to (0,0) of current CssBox /// </summary> /// <param name="w"></param> /// <param name="h"></param> /// <returns></returns> internal bool PushLocalClipArea(float w, float h) { //return true; //store lastest clip this.latestClip = canvas.CurrentClipRect; clipStacks.Push(this.latestClip); ////make new clip global Rectangle intersectResult = Rectangle.Intersect( latestClip, new Rectangle(0, 0, (int)w, (int)h)); this.latestClip = intersectResult; #if DEBUG if (this.dbugEnableLogRecord) { canvas.DrawRectangle(Color.DeepPink, intersectResult.X, intersectResult.Y, intersectResult.Width, intersectResult.Height); logRecords.Add(new string('>', dbugIndentLevel) + dbugIndentLevel.ToString() + " clip[" + intersectResult + "] "); } #endif canvas.SetClipRect(intersectResult); return !intersectResult.IsEmpty; }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { // canvas.FillRectangle(Color.White, 0, 0, this.Width, this.Height); if (needUpdate) { //default bg => transparent !, //gfx2d.Clear(ColorRGBA.White);//if want opaque bg ReleaseUnmanagedResources(); if (bmp != null) { bmp.Dispose(); } this.bmp = this.actualImage;// new Bitmap(this.Width, this.Height, this.actualImage.GetBuffer(), false); // canvas.Platform.CreatePlatformBitmap(this.Width, this.Height, this.actualImage.GetBuffer(), false); Image.SetCacheInnerImage(bmp, null); needUpdate = false; } //canvas.FillRectangle(this.BackColor, 0, 0, this.Width, this.Height); if (bmp != null) { canvas.DrawImage(this.bmp, new RectangleF(0, 0, this.Width, this.Height)); } //--------------------- #if DEBUG //canvasPage.dbug_DrawCrossRect(PixelFarm.Drawing.Color.Black, // new Rectangle(0, 0, this.Width, this.Height)); #endif }
protected override void OnGLRender(object sender, EventArgs args) { _pcx.SmoothMode = SmoothMode.Smooth; _pcx.StrokeColor = PixelFarm.Drawing.Color.Blue; _pcx.ClearColorBuffer(); if (!_resInit) { _msdf_bmp = DemoHelper.LoadTexture(_fontAtlas.MainBitmap); _resInit = true; } _painter.Clear(PixelFarm.Drawing.Color.White); _fontAtlas.TryGetItem(_glyphIndex_0, out AtlasItem glyphData); PixelFarm.Drawing.Rectangle r = new PixelFarm.Drawing.Rectangle(glyphData.Left, glyphData.Top, glyphData.Width, glyphData.Height); _pcx.DrawSubImageWithMsdf(_msdf_bmp, ref r, 100, 40); _fontAtlas.TryGetItem(_glyphIndex_1, out glyphData); PixelFarm.Drawing.Rectangle r2 = new PixelFarm.Drawing.Rectangle(glyphData.Left, glyphData.Top, glyphData.Width, glyphData.Height); _pcx.DrawSubImageWithMsdf(_msdf_bmp, ref r2, 100 + r.Width, 40); //full image _pcx.DrawImage(_msdf_bmp, 0, 100); SwapBuffers(); }
public sealed override void CustomDrawToThisCanvas(Canvas canvas, Rectangle updateArea) { canvas.OffsetCanvasOrigin(-myviewportX, -myviewportY); updateArea.Offset(myviewportX, myviewportY); this.DrawBoxContent(canvas, updateArea); canvas.OffsetCanvasOrigin(myviewportX, myviewportY); updateArea.Offset(-myviewportX, -myviewportY); }
public void PaintToOutputWindowFullMode() { Rectangle rect = new Rectangle(0, 0, rootGraphic.Width, rootGraphic.Height); rootGraphic.InvalidateGraphicArea( rootGraphic.TopWindowRenderBox, ref rect); this.PaintToOutputWindow(); }
public void UnBind() { //clear this.canvas = null; this.htmlContainer = null; this.clipStacks.Clear(); this.latestClip = new Rectangle(0, 0, CssBoxConstConfig.BOX_MAX_RIGHT, CssBoxConstConfig.BOX_MAX_BOTTOM); }
public static void InvalidateGraphicLocalArea(RenderElement re, Rectangle localArea) { if (localArea.Height == 0 || localArea.Width == 0) { return; } RootInvalidateGraphicArea(re, ref localArea); }
public override void CustomDrawToThisCanvas(Canvas canvas, Rectangle updateArea) { if (this.textBuffer != null) { var prevColor = canvas.CurrentTextColor; canvas.CurrentTextColor = textColor; canvas.DrawText(this.textBuffer, this.X, this.Y); canvas.CurrentTextColor = prevColor; } }
public void dbug_HighlightMeNow(Rectangle rect) { using (System.Drawing.Pen mpen = new System.Drawing.Pen(System.Drawing.Brushes.White, 2)) using (System.Drawing.Graphics g = this.dbugCreateGraphics()) { System.Drawing.Rectangle r = rect.ToRect(); g.DrawRectangle(mpen, r); g.DrawLine(mpen, new System.Drawing.Point(r.X, r.Y), new System.Drawing.Point(r.Right, r.Bottom)); g.DrawLine(mpen, new System.Drawing.Point(r.X, r.Bottom), new System.Drawing.Point(r.Right, r.Y)); } }
public void InvalidateGraphicBounds(Rectangle totalBounds) { propFlags &= ~RenderElementConst.IS_GRAPHIC_VALID; var parent = this.ParentRenderElement; //start at parent **** //--------------------------------------- if (parent == null) { return; } this.rootGfx.InvalidateGraphicArea(parent, ref totalBounds); }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { myHtmlCont.CheckDocUpdate(); var painter = PainterStock.GetSharedPainter(this.myHtmlCont, canvas); painter.SetViewportSize(this.Width, this.Height); #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif myHtmlCont.PerformPaint(painter); PainterStock.ReleaseSharedPainter(painter); }
/// <summary> /// Draw the background image of the given box in the given rectangle.<br/> /// Handle background-repeat and background-position values. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="box">the box to draw its background image</param> /// <param name="imageLoadHandler">the handler that loads image to draw</param> /// <param name="rectangle">the rectangle to draw image in</param> public static void DrawBackgroundImage(Canvas g, CssBox box, ImageBinder imageBinder, RectangleF rectangle) { var image = imageBinder.Image; //temporary comment image scale code var imgSize = image.Size; //new Size(imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Width : imageLoadHandler.Rectangle.Width, // imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Height : imageLoadHandler.Rectangle.Height); // get the location by BackgroundPosition value var location = GetLocation(box.BackgroundPositionX, box.BackgroundPositionY, rectangle, imgSize); //var srcRect = imageLoadHandler.Rectangle == Rectangle.Empty // ? new Rectangle(0, 0, imgSize.Width, imgSize.Height) // : new Rectangle(imageLoadHandler.Rectangle.Left, imageLoadHandler.Rectangle.Top, imgSize.Width, imgSize.Height); var srcRect = new Rectangle(0, 0, image.Width, image.Height); // initial image destination rectangle var destRect = new Rectangle(location, imgSize); // need to clip so repeated image will be cut on rectangle var prevClip = g.CurrentClipRect; PixelFarm.Drawing.Rectangle copyRect = new PixelFarm.Drawing.Rectangle( (int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height); copyRect.Intersect(prevClip); g.SetClipRect(copyRect); switch (box.BackgroundRepeat) { case CssBackgroundRepeat.NoRepeat: g.DrawImage(image, new RectangleF(location, imgSize), new RectangleF(0, 0, image.Width, image.Height)); break; case CssBackgroundRepeat.RepeatX: DrawRepeatX(g, image, rectangle, srcRect, destRect, imgSize); break; case CssBackgroundRepeat.RepeatY: DrawRepeatY(g, image, rectangle, srcRect, destRect, imgSize); break; default: DrawRepeat(g, image, rectangle, srcRect, destRect, imgSize); break; } g.SetClipRect(prevClip); }
public virtual void InvalidateGraphics(Rectangle clientArea) { //bubble up to parent //clientArea => area relative to this element //adjust to //adjust client area var parentBox = this.ParentBox; if (parentBox != null) { clientArea.Offset((int)this.LocalX, (int)this.LocalY); parentBox.InvalidateGraphics(clientArea); } }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { var enterFont = canvas.CurrentFont; canvas.CurrentFont = this.CurrentTextSpanStyle.FontInfo; if (vscrollableSurface != null) { vscrollableSurface.DrawToThisPage(canvas, updateArea); } //1. bg if (BackgroundColor.A > 0) { //canvas.FillRectangle(BackgroundColor, 0, 0, updateArea.Width, updateArea.Height); canvas.FillRectangle(BackgroundColor, 0, 0, this.Width, this.Height); } //2. sub ground if (internalTextLayerController.SelectionRange != null) { internalTextLayerController.SelectionRange.Draw(canvas, updateArea); } //3. each layer if (vscrollableSurface != null) { vscrollableSurface.DrawToThisPage(canvas, updateArea); } else { this.textLayer.DrawChildContent(canvas, updateArea); if (this.HasDefaultLayer) { this.DrawDefaultLayer(canvas, ref updateArea); } } #if DEBUG //for debug canvas.FillRectangle(Color.Red, 0, 0, 5, 5); #endif //4. caret if (this.stateShowCaret) { Point textManCaretPos = internalTextLayerController.CaretPos; this.myCaret.DrawCaret(canvas, textManCaretPos.X, textManCaretPos.Y); } else { } canvas.CurrentFont = enterFont; }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { //draw this ... var penwidth = canvas.StrokeWidth; int borderWidth = 5; int halfBorder = borderWidth / 2; canvas.StrokeWidth = borderWidth; canvas.DrawRectangle( Color.OrangeRed, halfBorder, halfBorder, this.Width - borderWidth, this.Height - borderWidth); canvas.StrokeWidth = penwidth; }
public bool InvalidateGraphics() { propFlags &= ~RenderElementConst.IS_GRAPHIC_VALID; if ((uiLayoutFlags & RenderElementConst.LY_SUSPEND_GRAPHIC) != 0) { #if DEBUG dbugVRoot.dbug_PushInvalidateMsg(RootGraphic.dbugMsg_BLOCKED, this); #endif return false; } Rectangle rect = new Rectangle(0, 0, b_width, b_height); RootInvalidateGraphicArea(this, ref rect); return true;//TODO: review this }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { #if DEBUG if (this.dbugBreak) { } #endif //sample bg //canvas.FillRectangle(BackColor, updateArea.Left, updateArea.Top, updateArea.Width, updateArea.Height); canvas.FillRectangle(BackColor, 0, 0, this.Width, this.Height); this.DrawDefaultLayer(canvas, ref updateArea); #if DEBUG //canvas.dbug_DrawCrossRect(PixelFarm.Drawing.Color.Black, // new Rectangle(0, 0, this.Width, this.Height)); //canvas.dbug_DrawCrossRect(PixelFarm.Drawing.Color.Black, // new Rectangle(updateArea.Left, updateArea.Top, updateArea.Width, updateArea.Height)); #endif }
public SelectionRange( CssBoxHitChain startChain, CssBoxHitChain endChain, IFonts ifonts) { if (IsOnTheSameLine(startChain, endChain)) { //on the same line if (endChain.RootGlobalX < startChain.RootGlobalX) { //swap var tmp = endChain; endChain = startChain; startChain = tmp; } } else { //across line if (endChain.RootGlobalY < startChain.RootGlobalY) { //swap var tmp = endChain; endChain = startChain; startChain = tmp; } } //1. this.SetupStartHitPoint(startChain, ifonts); //2. if (this.startHitHostLine == null) { this.isValid = false; return; } this.SetupEndHitPoint(startChain, endChain, ifonts); this.snapSelectionArea = this.GetSelectionRectArea(); }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { //if (this.image != null) //{ // canvas.DrawImage(this.image, // new RectangleF(0, 0, this.Width, this.Height)); //} //else //{ //when no image //--------------------- // canvas.FillRectangle(Color.White, 0, 0, this.Width, this.Height); if (needUpdate) { //default bg => transparent !, //gfx2d.Clear(ColorRGBA.White);//if want opaque bg ReleaseUnmanagedResources(); int j = sprites.Count; for (int i = 0; i < j; ++i) { sprites[i].OnDraw(gfx2d); } //this.bmp = new Bitmap(this.Width, this.Height, this.actualImage.GetBuffer(), true); needUpdate = false; } canvas.DrawImage(actualImage, new RectangleF(0, 0, this.Width, this.Height)); //--------------------- //copy data from actual image to canvas //} #if DEBUG //canvasPage.dbug_DrawCrossRect(PixelFarm.Drawing.Color.Black, // new Rectangle(0, 0, this.Width, this.Height)); #endif }
public override void DrawChildContent(Canvas canvasPage, Rectangle updateArea) { if ((layerFlags & IS_LAYER_HIDDEN) != 0) { return; } this.BeginDrawingChildContent(); foreach (RenderElement child in this.GetDrawingIter()) { if (child.IntersectsWith(ref updateArea)) { int x = child.X; int y = child.Y; canvasPage.OffsetCanvasOrigin(x, y); updateArea.Offset(-x, -y); child.DrawToThisCanvas(canvasPage, updateArea); canvasPage.OffsetCanvasOrigin(-x, -y); updateArea.Offset(x, y); } } this.FinishDrawingChildContent(); }
static void ResizeTargetWithSnapToGridWhenDragRelease(UIControllerBox controllerBox, UIMouseEventArgs e) { ////sample move with snap to grid //Point pos = controllerBox.Position; //int newX = pos.X + e.XDiff; //int newY = pos.Y + e.YDiff; ////snap to gridsize =5; ////find nearest snap x //int gridSize = 5; //float halfGrid = (float)gridSize / 2f; //int nearestX = (int)((newX + halfGrid) / gridSize) * gridSize; //int nearestY = (int)((newY + halfGrid) / gridSize) * gridSize; //int xdiff = nearestX - pos.X; //if (xdiff == 0) //{ // return; //} //controllerBox.SetSize(controllerBox.Width + xdiff, controllerBox.Height); var targetBox = controllerBox.TargetBox; if (targetBox != null) { int diffX = 0, diffY = 0; var targetBoxLocation = targetBox.GetGlobalLocation(); diffX = controllerBox.Left - targetBoxLocation.X; diffY = controllerBox.Top - targetBoxLocation.Y; //move target box too var newRect = new Rectangle(targetBox.Left + diffX + 5, targetBox.Top + diffY + 5, controllerBox.Width - 10, controllerBox.Height - 10); controllerBox.DesignBoardModule.HistoryRecordDzElementNewBounds( controllerBox.TargetBox, controllerBox.beginRect, newRect); controllerBox.beginRect = newRect; targetBox.SetBounds(newRect.Left, newRect.Top, newRect.Width, newRect.Height); } }
protected override void OnMouseUp(UIMouseEventArgs e) { //create commadn history and add? var newBeginPoint = new Point(this.TargetBox.Left, this.TargetBox.Top); this.DesignBoardModule.HistoryRecordDzElementNewPosition( this.TargetBox, new Point(this.beginRect.Left, this.beginRect.Top), newBeginPoint); this.beginRect = new Rectangle(newBeginPoint.X, newBeginPoint.Y, this.TargetBox.Width, this.TargetBox.Height); base.OnMouseUp(e); }
public UIDragHitCollection(List<UIElement> hitList, Rectangle hitArea) { this.hitArea = hitArea; this.hitList = hitList; }
public void DrawString(char[] buffer, int startAt, int len, double x, double y) { int j = buffer.Length; //resolve font from painter? glyphPlans.Clear(); _glyphLayout.Layout(_typeface, buffer, startAt, len, glyphPlans); float scale = _typeface.CalculateToPixelScaleFromPointSize(font.SizeInPoints); //-------------------------- //TODO: //if (x,y) is left top //we need to adjust y again y -= (_typeface.Ascender - _typeface.Descender + _typeface.LineGap) * scale; int n = glyphPlans.Count; EnsureLoadGLBmp(); // float scaleFromTexture = _finalTextureScale; Typography.Rendering.TextureKind textureKind = simpleFontAtlas.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); //-------------------------- GlyphPosPixelSnapKind x_snap = this.GlyphPosPixelSnapX; GlyphPosPixelSnapKind y_snap = this.GlyphPosPixelSnapY; float g_x = 0; float g_y = 0; int baseY = (int)Math.Round(y); for (int i = 0; i < n; ++i) { GlyphPlan 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); 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; } } }
public void PrepareStringForRenderVx(RenderVxFormattedString renderVx, char[] buffer, int startAt, int len) { 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 float x = 0; float y = 0; y -= ((recommendLineSpacing) * scale); renderVx.RecommmendLineSpacing = (int)(recommendLineSpacing * scale); // 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; //*** _glsx.SetAssociatedTextureInfo(_glBmp); // vboBufferList2.Clear(); indexList2.Clear(); 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( vboBufferList2, indexList2, ref srcRect, g_x, g_y, scaleFromTexture); break; } } //--------- DrawingGL.GLRenderVxFormattedString renderVxFormattedString = (DrawingGL.GLRenderVxFormattedString)renderVx; renderVxFormattedString.IndexArray = indexList2.ToArray(); renderVxFormattedString.VertexCoords = vboBufferList2.ToArray(); renderVxFormattedString.VertexCount = indexList2.Count; }
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; //} } }
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()); }
protected override void DrawBoxContent(Canvas canvas, Rectangle updateArea) { canvas.FillRectangle(Color.White, 0, 0, this.Width, this.Height); this.DrawDefaultLayer(canvas, ref updateArea); }
public override void InvalidateGraphics(Rectangle clientArea) { //send to container element this.containerElement.InvalidateGraphicBounds(clientArea); }
public static unsafe extern bool ExtTextOut(IntPtr hdc, int x, int y, uint fuOptions, Rectangle* lpRect, char[] charBuffer, int cbCount, object arrayOfSpaceValues);
public abstract void DrawChildContent(Canvas canvasPage, Rectangle updateArea);
public void InvalidateGraphicArea(RenderElement fromElement, ref Rectangle elemClientRect) { //total bounds = total bounds at level if (this.IsInRenderPhase) { return; } //-------------------------------------- //bubble up ,find global rect coord //and then merge to accumulate rect //int globalX = 0; //int globalY = 0; Point globalPoint = new Point(); bool isBubbleUp = false; #if DEBUG int dbug_ncount = 0; dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> :" + elemClientRect.ToString()); #endif do { if (!fromElement.Visible) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "EARLY-RET: "); #endif return; } else if (fromElement.BlockGraphicUpdateBubble) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED2: "); #endif return; } //--------------------------------------------------------------------- #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> "); #endif globalPoint.Offset(fromElement.X, fromElement.Y); //globalX += fromElement.BubbleUpX; //globalY += fromElement.BubbleUpY; if (fromElement.MayHasViewport && isBubbleUp) { //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (fromElement.HasDoubleScrollableSurface) { //container.VisualScrollableSurface.WindowRootNotifyInvalidArea(elementClientRect); } Rectangle elementRect = fromElement.RectBounds; elementRect.Offset(fromElement.ViewportX, fromElement.ViewportY); elemClientRect.Intersect(elementRect); globalPoint.X = -fromElement.ViewportX; globalPoint.Y = -fromElement.ViewportY; //globalX = -fromElement.ViewportX; //globalY = -fromElement.ViewportY; } if (fromElement.IsTopWindow) { break; } else { #if DEBUG if (fromElement.dbugParentVisualElement == null) { dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED3: "); } #endif var parentLink = fromElement.MyParentLink; if (parentLink == null) { return; } parentLink.AdjustLocation(ref globalPoint); //move up fromElement = parentLink.ParentRenderElement;// fromElement.ParentRenderElement; if (fromElement == null) { return; } } isBubbleUp = true; } while (true); #if DEBUG var dbugMyroot = this; if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { while (dbug_ncount > 0) { dbugMyroot.dbugGraphicInvalidateTracer.PopElement(); dbug_ncount--; } } #endif //---------------------------------------- //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (elemClientRect.Top > this.Height || elemClientRect.Left > this.Width || elemClientRect.Bottom < 0 || elemClientRect.Right < 0) { //no intersect with #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ZERO-EEX"); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif return; } //-------------------------------------------------------------------------------------------------- if (!hasAccumRect) { accumulateInvalidRect = elemClientRect; hasAccumRect = true; } else { accumulateInvalidRect = Rectangle.Union(accumulateInvalidRect, elemClientRect); } #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { string state_str = "ACC: "; if (this.dbugNeedContentArrangement || this.dbugNeedReCalculateContentSize) { state_str = "!!" + state_str; } dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ACC: " + accumulateInvalidRect.ToString()); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif }
public static void CreateCanvasControlOnExistingControl( Control landingControl, int xpos, int ypos, int w, int h, InnerViewportKind internalViewportKind, out GraphicsViewRoot view_root) { //1. init InitWinform(); IInstalledTypefaceProvider fontLoader = YourImplementation.CommonTextServiceSetup.FontLoader; //2. switch (internalViewportKind) { default: //gdi, gdi on gles break; case InnerViewportKind.PureAgg: case InnerViewportKind.AggOnGLES: case InnerViewportKind.GLES: { var openFontTextService = new Typography.Text.OpenFontTextService(); openFontTextService.SvgBmpBuilder = PaintLab.SvgBuilderHelper.ParseAndRenderSvg; PixelFarm.Drawing.GLES2.GLES2Platform.TextService = openFontTextService; Typography.Text.GlobalTextService.TxtClient = openFontTextService.CreateNewServiceClient(); } break; } PixelFarm.Drawing.WinGdi.WinGdiPlusPlatform.SetInstalledTypefaceProvider(fontLoader); //--------------------------------------------------------------------------- //3. root graphics PixelFarm.Drawing.Rectangle screenClientAreaRect = Conv.ToRect(Screen.PrimaryScreen.WorkingArea); w = screenClientAreaRect.Width; h = screenClientAreaRect.Height; MyRootGraphic myRootGfx = new MyRootGraphic(w, h); //4. create event bridge that will bridge from native window event to root graphics AbstractTopWindowBridge bridge = GetTopWindowBridge(internalViewportKind, myRootGfx, myRootGfx.TopWinEventPortal); //5. actualWinUI is platform specific var actualWinUI = new LayoutFarm.UI.MyWinFormsControl(); actualWinUI.Size = new System.Drawing.Size(w, h); landingControl.Controls.Add(actualWinUI); //so we create abstraction of actual UI IGpuOpenGLSurfaceView viewAbstraction = actualWinUI.CreateWindowWrapper(bridge); var viewRoot = view_root = new GraphicsViewRoot( screenClientAreaRect.Width, screenClientAreaRect.Height); view_root.InitRootGraphics( myRootGfx, myRootGfx.TopWinEventPortal, internalViewportKind, viewAbstraction, bridge); //TODO: review here again myRootGfx.SetDrawboardReqDelegate(view_root.GetDrawBoard); //------ //TODO: review here view_root.SetBounds(xpos, ypos, screenClientAreaRect.Width, screenClientAreaRect.Height); // Form ownerForm = landingControl.FindForm(); if (ownerForm != null) { ownerForm.FormClosing += (s, e) => { //TODO: review here viewRoot.Close(); }; } }
public void DrawString(char[] buffer, double x, double y) { int j = buffer.Length; int buffsize = j * 2; //resolve font from painter? ActualFont fontImp = ff.GetFontAtPointsSize(font.SizeInPoints); var tt = (Typography.OpenFont.Typeface)ff.GetInternalTypeface(); List <GlyphPlan> glyphPlans = new List <GlyphPlan>(); _glyphLayout.Layout(tt, font.SizeInPoints, buffer, glyphPlans); // //un-test version //ActualFont fontImp = nativeFontStore.GetResolvedNativeFont(painter.CurrentFont); //if (properGlyphs == null) //{ // properGlyphs = new ProperGlyph[buffsize]; // TextShapingService.GetGlyphPos(fontImp, buffer, 0, buffsize, properGlyphs); //} //TODO: implement msdf texture //double xpos = x; //for (int i = 0; i < buffsize; ++i) //{ // uint codepoint = properGlyphs[i].codepoint; // if (codepoint == 0) // { // break; // } // //------------------------------------------------------------- // FontGlyph glyph = fontImp.GetGlyphByIndex(codepoint); // //glyph image32 // //------------------------------------------------------------- // GLBitmap bmp = new GLBitmap(new LazyAggBitmapBufferProvider(glyph.glyphImage32)); // var left = glyph.glyphMatrix.img_horiBearingX; // this.canvas2d.DrawImage(bmp, // (float)(xpos + (left >> 6)), // (float)(y + (glyph.glyphMatrix.bboxYmin >> 6))); // int w = (glyph.glyphMatrix.advanceX) >> 6; // xpos += (w); // bmp.Dispose(); //temp here // //------------------------------------------------------------- //} //------------------------------------- //msdf texture version double xpos = x; int n = glyphPlans.Count; Typography.Rendering.GlyphImage glyphImage = simpleFontAtlas.TotalGlyph; GLBitmap glBmp = new GLBitmap(glyphImage.Width, glyphImage.Height, glyphImage.GetImageBuffer(), false); float c_x = (float)x; float c_y = (float)y; //int left = ((int)(glyph.glyphMatrix.img_horiBearingX * scale) >> 6); int left = 0; //float baseline = c_y - 24;//eg line height= 24 //create a list float baseline = c_y - 24;//eg line height= 24 //create a list bool isFlipY = canvas2d.FlipY; if (!isFlipY) { canvas2d.FlipY = true; } for (int i = 0; i < n; ++i) { GlyphPlan glyph = glyphPlans[i]; Typography.Rendering.TextureFontGlyphData glyphData; if (!simpleFontAtlas.GetRectByCodePoint(glyph.glyphIndex, out glyphData)) { //Rectangle r = glyphData.Rect; //float x_min = glyphData.BBoxXMin / 64; ////draw each glyph at specific position ////_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); //_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); ////c_x += r.Width - 10; //c_x += (glyphData.AdvanceX / 64); continue; } //found PixelFarm.Drawing.Rectangle r = ConvToRect(glyphData.Rect); //test draw full msdf gen img //canvas2d.DrawImage(glBmp, c_x + left, (float)(baseline + ((int)(glyphData.ImgHeight)))); canvas2d.DrawSubImageWithMsdf(glBmp, ref r, c_x + left, (float)(baseline + ((int)(glyphData.ImgHeight))), 1.0f); c_x += glyph.advX; } canvas2d.FlipY = isFlipY; glBmp.Dispose(); //temp here //draw with texture printer *** //char[] chars = text.ToCharArray(); //int j = chars.Length; //int buffsize = j * 2; ////get kerning list ////get actual font for this canvas //TextureFont currentFont = _currentTextureFont; //SimpleFontAtlas fontAtlas = currentFont.FontAtlas; //ProperGlyph[] properGlyphs = new ProperGlyph[buffsize]; //TextShapingService.GetGlyphPos(currentFont, chars, 0, buffsize, properGlyphs); //GLBitmap glBmp = (GLBitmap)currentFont.GLBmp; //if (glBmp == null) //{ // //create glbmp // GlyphImage glyphImage = fontAtlas.TotalGlyph; // int[] buffer = glyphImage.GetImageBuffer(); // glBmp = new GLBitmap(glyphImage.Width, glyphImage.Height, buffer, false); //} ////int j = chars.Length; //// //float c_x = (float)x; //float c_y = (float)y; ////TODO: review here *** ////----------------- ////1. layout each glyph before render *** //// //float baseline = c_y - 24;//eg line height= 24 //create a list ////-------------- //List<float> coords = new List<float>(); //float scale = 1f; //for (int i = 0; i < buffsize; ++i) //{ // ProperGlyph glyph1 = properGlyphs[i]; // uint codepoint = properGlyphs[i].codepoint; // if (codepoint == 0) // { // break; // } // //-------------------------------- // //if (codepoint == 1173 && i > 1) // //{ // // //check prev code point // // codepoint = 1168; // //} // //-------------------------------- // TextureFontGlyphData glyphData; // if (!fontAtlas.GetRectByCodePoint((int)codepoint, out glyphData)) // { // //Rectangle r = glyphData.Rect; // //float x_min = glyphData.BBoxXMin / 64; // ////draw each glyph at specific position // ////_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); // //_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); // ////c_x += r.Width - 10; // //c_x += (glyphData.AdvanceX / 64); // continue; // } // FontGlyph glyph = currentFont.GetGlyphByIndex(codepoint); // int left = ((int)(glyph.glyphMatrix.img_horiBearingX * scale) >> 6); // Rectangle r = glyphData.Rect; // int adjustX = 0; // int bboxYMin = glyph.glyphMatrix.bboxYmin >> 6; // if (bboxYMin > 1 || bboxYMin < -1) // { // // adjustX = 3; // } // //scale down 0.8; // //_canvas.DrawSubImageWithMsdf(glBmp, ref r, adjustX + c_x + left, // // (float)(baseline + ((int)(glyphData.ImgHeight + glyph.glyphMatrix.bboxYmin) >> 6)), 1.1f); // coords.Add(r.Left); // coords.Add(r.Top); // coords.Add(r.Width); // coords.Add(r.Height); // //------------------------- // coords.Add(adjustX + c_x + left); // //coords.Add(baseline + ((int)((glyphData.ImgHeight + glyph.glyphMatrix.bboxYmin) * scale) >> 6)); // coords.Add(baseline + ((int)((glyphData.ImgHeight + glyphData.BBoxYMin) * scale) >> 6)); // //int w = (int)(glyph.glyphMatrix.advanceX * scale) >> 6; // int w = (int)(glyph.horiz_adv_x * scale) >> 6; // c_x += w; //} //_canvas.DrawSubImageWithMsdf(glBmp, coords.ToArray(), scale); //----------------------- //public override void DrawString(string text, double x, double y) //{ // char[] chars = text.ToCharArray(); // int j = chars.Length; // int buffsize = j * 2; // //get kerning list // TextureFont currentFont = this.CurrentFont as TextureFont; // SimpleFontAtlas fontAtlas = currentFont.FontAtlas; // ProperGlyph[] properGlyphs = new ProperGlyph[buffsize]; // currentFont.GetGlyphPos(chars, 0, buffsize, properGlyphs); // GLBitmap glBmp = currentFont.GLBmp; // if (glBmp == null) // { // //create glbmp // GlyphImage glyphImage = fontAtlas.TotalGlyph; // int[] buffer = glyphImage.GetImageBuffer(); // glBmp = new GLBitmap(glyphImage.Width, glyphImage.Height, buffer, false); // } // //int j = chars.Length; // // // float c_x = (float)x; // float c_y = (float)y; // //TODO: review here // //----------------- // //1. layout each glyph before render *** // float baseline = c_y - 24;//eg line height= 24 // //create a list // for (int i = 0; i < buffsize; ++i) // { // ProperGlyph glyph1 = properGlyphs[i]; // uint codepoint = properGlyphs[i].codepoint; // if (codepoint == 0) // { // break; // } // if (codepoint == 1173 && i > 1) // { // //check prev code point // codepoint = 1168; // } // TextureFontGlyphData glyphData; // if (!fontAtlas.GetRect((int)codepoint, out glyphData)) // { // //Rectangle r = glyphData.Rect; // //float x_min = glyphData.BBoxXMin / 64; // ////draw each glyph at specific position // ////_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); // //_canvas.DrawSubImageWithMsdf(glBmp, ref r, c_x + x_min, (float)(baseline + r.Height)); // ////c_x += r.Width - 10; // //c_x += (glyphData.AdvanceX / 64); // continue; // } // //------------------------------------------------------------- // //FontGlyph glyph = this.currentFont.GetGlyphByIndex(codepoint); // FontGlyph glyph = currentFont.GetGlyphByIndex(codepoint); // int left = (glyph.glyphMatrix.img_horiBearingX >> 6); // Rectangle r = glyphData.Rect; // int adjustX = 0; // int bboxYMin = glyph.glyphMatrix.bboxYmin >> 6; // if (bboxYMin > 1 || bboxYMin < -1) // { // // adjustX = 3; // } // //scale down 0.8; // _canvas.DrawSubImageWithMsdf(glBmp, ref r, adjustX + c_x + left, // (float)(baseline + ((int)(glyphData.ImgHeight + glyph.glyphMatrix.bboxYmin) >> 6)), 1.1f); // int w = (glyph.glyphMatrix.advanceX) >> 6; // c_x += (w); // } //} // public override void DrawString(string text, double x, double y) // { // ////in this version we draw string to image // ////and the write the image back to gl surface // //_winGfx.Clear(System.Drawing.Color.White); // //_winGfx.DrawString(text, _winFont, _winGfxBrush, 0, 0); // ////_winGfxBackBmp.Save("d:\\WImageTest\\a00123.png"); // //System.Drawing.SizeF textAreaSize = _winGfx.MeasureString(text, _winFont); // //var bmpData = _winGfxBackBmp.LockBits(new System.Drawing.Rectangle(0, 0, _winGfxBackBmp.Width, _winGfxBackBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, _winGfxBackBmp.PixelFormat); // //int width = (int)textAreaSize.Width; // //int height = (int)textAreaSize.Height; // //ActualImage actualImg = new ActualImage(width, height, Agg.Image.PixelFormat.ARGB32); // ////------------------------------------------------------ // ////copy bmp from specific bmp area // ////and convert to GLBmp // //int stride = bmpData.Stride; // //byte[] buffer = actualImg.GetBuffer(); // //unsafe // //{ // // byte* header = (byte*)bmpData.Scan0; // // fixed (byte* dest0 = &buffer[0]) // // { // // byte* dest = dest0; // // byte* rowHead = header; // // int rowLen = width * 4; // // for (int h = 0; h < height; ++h) // // { // // header = rowHead; // // for (int n = 0; n < rowLen;) // // { // // //move next // // *(dest + 0) = *(header + 0); // // *(dest + 1) = *(header + 1); // // *(dest + 2) = *(header + 2); // // *(dest + 3) = *(header + 3); // // header += 4; // // dest += 4; // // n += 4; // // } // // //finish one row // // rowHead += stride; // // } // // } // //} // //_winGfxBackBmp.UnlockBits(bmpData); // ////------------------------------------------------------ // //GLBitmap glBmp = new GLBitmap(width, height, buffer, false); // //_canvas.DrawImageWithWhiteTransparent(glBmp, (float)x, (float)y); // //glBmp.Dispose(); // } }