コード例 #1
0
        public void DrawString(char[] text, int startAt, int len, 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);

            _outputGlyphPlans.Clear();
            _glyphLayout.Layout(typeface, text, startAt, len, _outputGlyphPlans);
            //4. render each glyph
            int j = _outputGlyphPlans.Count;

            //---------------------------------------------------
            //consider use cached glyph, to increase performance
            hintGlyphCollection.SetCacheInfo(typeface, fontSizePoint, this.HintTechnique);
            //---------------------------------------------------
            for (int i = 0; i < j; ++i)
            {
                GlyphPlan glyphPlan = _outputGlyphPlans[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);
        }
コード例 #2
0
        public void PrepareStringForRenderVx(RenderVxFormattedString renderVx, char[] text, int startAt, int len)
        {
            //1. update some props..
            //2. update current type face
            UpdateTypefaceAndGlyphBuilder();
            Typeface typeface = _currentTypeface;// _glyphPathBuilder.Typeface;

            _glyphLayout.Typeface = typeface;
            _glyphLayout.Layout(text, startAt, len);
            //
            //3. scale from design unit to specific font size
            _outputGlyphPlans.Clear();
            _pxScaleEngine.Layout(_glyphLayout.ResultUnscaledGlyphPositions, _outputGlyphPlans);
            TextPrinterHelper.CopyGlyphPlans(renderVx, _outputGlyphPlans, this._currentFontSizePxScale);
        }
コード例 #3
0
 public static void GenerateGlyphPlans(this GlyphLayout glyphLayout,
                                       char[] textBuffer,
                                       int startAt,
                                       int len,
                                       UnscaledGlyphPlanList list)
 {
     //generate glyph plan based on its current setting
     glyphLayout.Layout(textBuffer, startAt, len);
     ReadOutput(glyphLayout, list);
 }
コード例 #4
0
        public virtual void GenerateGlyphPlan(
            char[] textBuffer,
            int startAt,
            int len,
            IUnscaledGlyphPlanList unscaledGlyphPlan)
        {
            GlyphLayout glyphLayout = this.GlyphLayoutMan;

            glyphLayout.Layout(textBuffer, startAt, len);
            glyphLayout.GenerateUnscaledGlyphPlans(unscaledGlyphPlan);
        }
コード例 #5
0
ファイル: TextPrinter.cs プロジェクト: tmstar/fork-typography
        public MeasuredStringBox Measure(char[] textBuffer, int startAt, int len)
        {
            glyphLayout.Typeface = this.CurrentTypeFace;
            float pxscale = CurrentTypeFace.CalculateScaleToPixelFromPointSize(this.FontSizeInPoints);

            glyphLayout.Layout(textBuffer, startAt, len);

            _reusableGlyphPlanList.Clear();
            IGlyphPositions glyphPositions = glyphLayout.ResultUnscaledGlyphPositions;

            GlyphLayoutExtensions.GenerateGlyphPlan(glyphLayout.ResultUnscaledGlyphPositions,
                                                    pxscale,
                                                    false, _reusableGlyphPlanList);
            return(new MeasuredStringBox(
                       _reusableGlyphPlanList.AccumAdvanceX * pxscale,
                       CurrentTypeFace.Ascender * pxscale,
                       CurrentTypeFace.Descender * pxscale,
                       CurrentTypeFace.LineGap * pxscale,
                       Typography.OpenFont.Extensions.TypefaceExtensions.CalculateRecommendLineSpacing(CurrentTypeFace) * pxscale));
        }
コード例 #6
0
        public override void DrawString(char[] textBuffer, int startAt, int len, float x, float y)
        {
            _reusableUnscaledGlyphPlanList.Clear();
            //1. unscale layout, in design unit
            _glyphLayout.Layout(textBuffer, startAt, len);
            _glyphLayout.GenerateUnscaledGlyphPlans(_reusableUnscaledGlyphPlanList);

            //draw from the glyph plan seq

            DrawFromGlyphPlans(
                new GlyphPlanSequence(_reusableUnscaledGlyphPlanList),
                x, y);
        }
コード例 #7
0
        }         // End Sub DrawFromGlyphPlans

        public override void DrawString(char[] textBuffer, int startAt, int len, float x, float y)
        {
            this.TargetGraphics.SetTextAndFont(new string(textBuffer), this.Typeface.Name, this.FontSizeInPoints);
            this.TargetGraphics.OpenGroup();

            _reusableUnscaledGlyphPlanList.Clear();
            //1. unscale layout, in design unit
            _glyphLayout.Layout(textBuffer, startAt, len);
            _glyphLayout.GenerateUnscaledGlyphPlans(_reusableUnscaledGlyphPlanList);

            //draw from the glyph plan seq
            DrawFromGlyphPlans(new GlyphPlanSequence(_reusableUnscaledGlyphPlanList), x, y);

            this.TargetGraphics.CloseGroup();
        } // End Sub DrawString
コード例 #8
0
        public void PrepareStringForRenderVx(RenderVxFormattedString renderVx, char[] text, int startAt, int len)
        {
            //1. update some props..
            //2. update current type face
            UpdateTypefaceAndGlyphBuilder();
            Typeface typeface = _currentTypeface;// _glyphPathBuilder.Typeface;
            //3. layout glyphs with selected layout technique
            //TODO: review this again, we should use pixel?

            float pxscale = typeface.CalculateToPixelScaleFromPointSize(FontSizeInPoints);

            _outputGlyphPlans.Clear();
            _glyphLayout.Layout(typeface, text, startAt, len, _outputGlyphPlans);
            TextPrinterHelper.CopyGlyphPlans(renderVx, _outputGlyphPlans, pxscale);
        }
コード例 #9
0
        public virtual void GenerateGlyphPlan(
            char[] textBuffer,
            int startAt,
            int len,
            GlyphPlanList outputGlyphPlanList,
            List <UserCodePointToGlyphIndex> charToGlyphMapList)
        {
            GlyphLayout glyphLayout = this.GlyphLayoutMan;

            glyphLayout.Layout(textBuffer, startAt, len);

            GlyphLayoutExtensions.GenerateGlyphPlans(
                glyphLayout.ResultUnscaledGlyphPositions,
                this.Typeface.CalculateScaleToPixelFromPointSize(this.FontSizeInPoints),
                false, outputGlyphPlanList);
        }
コード例 #10
0
        GlyphPlanSequence CreateGlyphPlanSeq(GlyphLayout glyphLayout, TextBuffer buffer, int startAt, int len)
        {
            GlyphPlanList planList  = GlyphPlanBuffer.UnsafeGetGlyphPlanList(_glyphPlanBuffer);
            int           pre_count = planList.Count;

            glyphLayout.Typeface   = _typeface;
            glyphLayout.ScriptLang = _scLang;
            glyphLayout.Layout(
                TextBuffer.UnsafeGetCharBuffer(buffer),
                startAt,
                len);


            int post_count = planList.Count;

            return(new GlyphPlanSequence(_glyphPlanBuffer, pre_count, post_count - pre_count));
        }
コード例 #11
0
        public GlyphPlanSequence GetUnscaledGlyphPlanSequence(
            GlyphLayout glyphLayout,
            TextBuffer buffer, int start, int seqLen)
        {
            //UNSCALED VERSION
            //use current typeface + scriptlang
            int seqHashValue = CalculateHash(buffer, start, seqLen);

            //this func get the raw char from buffer
            //and create glyph list
            //check if we have the string cache in specific value
            //---------
            if (seqLen > _glyphPlanSeqSet.MaxCacheLen)
            {
                //layout string is too long to be cache
                //it need to split into small buffer
            }

            GlyphPlanSequence      planSeq = GlyphPlanSequence.Empty;
            GlyphPlanSeqCollection seqCol  = _glyphPlanSeqSet.GetSeqCollectionOrCreateIfNotExist(seqLen);

            if (!seqCol.TryGetCacheGlyphPlanSeq(seqHashValue, out planSeq))
            {
                //create a new one if we don't has a cache
                //1. layout
                glyphLayout.Layout(
                    buffer.UnsafeGetInternalBuffer(),
                    start,
                    seqLen);

                int pre_count = _reusableGlyphPlanList.Count;
                //create glyph-plan ( UnScaled version) and add it to planList

                glyphLayout.GenerateUnscaledGlyphPlans(_reusableGlyphPlanList);

                int post_count = _reusableGlyphPlanList.Count;
                planSeq = new GlyphPlanSequence(_reusableGlyphPlanList, pre_count, post_count - pre_count);
                //
                seqCol.Register(seqHashValue, planSeq);
            }
            return(planSeq);
        }
コード例 #12
0
        List <ushort> inputGlyphs = new List <ushort>(); //not thread safe***
        public void Print(Typeface typeface, float size, char[] str, List <GlyphPlan> glyphPlanBuffer)
        {
            //1. layout
            _glyphLayout.Layout(typeface, size, str, glyphPlanBuffer);
            var glyphPathBuilder = new MyGlyphPathBuilder(typeface);
            int j = glyphPlanBuffer.Count;

            float pxScale = typeface.CalculateFromPointToPixelScale(size);

            for (int i = 0; i < j; ++i)
            {
                GlyphPlan glyphPlan = glyphPlanBuffer[i];
                //-----------------------------------
                //check if we static vxs/bmp for this glyph
                //if not, create and cache
                //-----------------------------------
                glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, size);
                //-----------------------------------
                var vxsBuilder = new GlyphPathBuilderVxs();
                glyphPathBuilder.ReadShapes(vxsBuilder);
                glyphPlan.vxs = vxsBuilder.GetVxs(pxScale);
            }
        }
コード例 #13
0
        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;
                }
            }
        }
コード例 #14
0
        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();
            //        }
        }
コード例 #15
0
        private void button3_Click(object sender, EventArgs e)
        {
            //it should be faster if we use 'mesh' cache
            //instead of read-transform it every time like code above(button2_click)

            LoadFont();

            float font_size_in_Point = 20;

            _glyphMeshStore.SetFont(_latinModernMathFont, font_size_in_Point);//20= font size
            _glyphMeshStore.FlipGlyphUpward = true;

            float px_scale = _latinModernMathFont.CalculateScaleToPixelFromPointSize(font_size_in_Point);

            using (Tools.BorrowAggPainter(_memBmp, out var p))
            {
                p.Clear(PixelFarm.Drawing.Color.White);

                float prevX = p.OriginX;
                float prevY = p.OriginY;


                int line_left = 10;
                int line_top  = 50;

                p.SetOrigin(line_left, line_top);//*** test

                //draw reference point
                p.FillRect(0, 0, 5, 5, PixelFarm.Drawing.Color.Red);

                char[] test_str    = "‽_x‾".ToCharArray();
                int    inline_left = 0;
                int    inline_top  = 0;

                //----------
                GlyphLayout glyphLayout = new GlyphLayout();
                glyphLayout.ScriptLang = new ScriptLang("math");
                glyphLayout.Typeface   = _latinModernMathFont;


                //temp fix for some typeface

                glyphLayout.SetGlyphIndexNotFoundHandler((glyph_layout, codepoint, next_codepoint) =>
                {
                    switch (codepoint)
                    {
                    //overline unicode
                    case 8254: return(2246);    //overline-combine, this will break into 3 parts in math layout process
                    }
                    return(0);
                });


                //
                glyphLayout.Layout(test_str, 0, test_str.Length);

                List <UnscaledGlyphPlan> glyphPlans = new List <UnscaledGlyphPlan>();

                foreach (UnscaledGlyphPlan glypyPlan in glyphLayout.GetUnscaledGlyphPlanIter())
                {
                    glyphPlans.Add(glypyPlan);
                }
                //--------
                for (int i = 0; i < glyphPlans.Count; ++i)
                {
                    //ushort glyphIndex = _latinModernMathFont.GetGlyphIndex((int)test_str[i]);
                    ////do some glyph-substitution
                    //ushort advW = _latinModernMathFont.GetAdvanceWidth((int)test_str[i]);//unscale glyph width
                    //now scale it to specific font size

                    UnscaledGlyphPlan glyphPlan = glyphPlans[i];
                    int         advW_s          = (int)System.Math.Round(px_scale * glyphPlan.AdvanceX);
                    VertexStore v1 = _glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex);
                    p.SetOrigin(line_left + inline_left, line_top + inline_top);
                    p.Fill(v1, PixelFarm.Drawing.Color.Black);
                    inline_left += advW_s;//move
                }
                //restore
                p.SetOrigin(prevX, prevY);
            }

            //-----------
            CopyBitmapToScreen();
        }
コード例 #16
0
        void Issue118(PaintEventArgs e)
        {
            Text = "Issue 118 Demo";
            const string s = "0123456789";
            const float  z = 80;
            const bool   f = true;
            var          m = GetType().Assembly;
            var          t = new OpenFontReader().Read
                                 (m.GetManifestResourceStream
                                     (Array.Find(m.GetManifestResourceNames(), n => n.EndsWith("otf"))));

            t.UpdateAllCffGlyphBounds();
            var c = t.CalculateScaleToPixelFromPointSize(z);
            var l = new GlyphLayout {
                Typeface = t
            };
            var q = new GlyphLayout {
                Typeface = t
            };

            l.Layout(s.ToCharArray(), 0, s.Length);
            var        p = l.ResultUnscaledGlyphPositions;
            var        b = new B(t);
            var        r = new SampleWinForms.GlyphTranslatorToGdiPath();
            var        h = Pens.Black.Brush;
            var        u = Pens.Blue;
            var        v = Pens.Red;
            const bool _ = true;
            var        j = true;

            using (var g = e.Graphics)
            {
                if (f)
                {
                    g.ScaleTransform(1, -1);
                    g.TranslateTransform(0, -Height / 2);
                }
                for (var i = 0; i < s.Length; i++, j ^= true)
                {
                    var o = q.LayoutAndMeasureString(new[] { s[i] }, 0, 1, z);
                    var n = p.GetGlyph(i, out var x, out var y, out var w);
                    var a = g.Save();
                    var d = t.GetGlyphByIndex(n).Bounds;
                    var k = R.FromLTRB(d.XMin * c, d.YMin * c, d.XMax * c, d.YMax * c);
                    g.TranslateTransform(x * c, y * c);
                    b.Build(s[i], z);
                    b.ReadShapes(r);
                    r.ResultGraphicsPath.CloseFigure();
                    g.FillPath(h, r.ResultGraphicsPath);
                    if (_ || j)
                    {
                        g.DrawRectangle(u, 0, 0, o.width, o.ascending - o.descending);
                    }
                    if (_ || !j)
                    {
                        g.DrawRectangle(v, k.X, k.Y, k.Width, k.Height);
                    }
                    g.Restore(a);
                    g.TranslateTransform(w * c, 0);
                }

                g.ResetTransform();
                g.DrawString("Blue = LayoutAndMeasureString, Red = Glyph.Bounds", Font, h, 0, 0);
            }
        }