<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WPF 探索 Skia 的豎排文本渲染的字符高度

      如果只考慮字符和字符之間密集的進行排列,那只需使用 GetGlyphWidths 方法獲取字符的字墨尺寸范圍即可。如以下代碼所示,從 SKFont 獲取字墨尺寸范圍

                  using var paint = new SKPaint();
                  paint.Color = SKColors.Blue;
                  paint.Style = SKPaintStyle.Fill;
                  paint.IsAntialias = true;
      
                  using var typeface = SKFontManager.Default.MatchFamily("微軟雅黑");
                  using var skFont = new SKFont(typeface, 30);
      
                  var text = "pi一二一中文雅黑對齊";
      
                  var glyphList = new ushort[text.Length];
                  skFont.GetGlyphs(text, glyphList);
                  var widthList = new float[glyphList.Length];
                  var boundsList = new SKRect[glyphList.Length];
                  skFont.GetGlyphWidths(glyphList, widthList, boundsList, paint);
      

      以上獲取的 boundsList 就是對應的每個字符的在 WPF 概念里面的 字墨尺寸范圍 接近的值。這里需要說明的是 WPF 采用的是 DirectWrite 進行渲染,和 Skia 獲取的數值上有所偏差,好在對于微軟雅黑來說,只是小數點之后的誤差而已

      在 Skia 里面,傳入 DrawText 里面的點坐標指的是字符的 baseline 基線坐標,而不是左上角坐標

      默認情況下渲染的字符高度,直接等于字高度是可以的,能夠實現一個字緊接一個字的效果。盡管這樣會讓字過于緊湊,如以下示意圖

      對應的代碼如下

                  var positionList = new SKPoint[text.Length];
                  var y = 0f;
                  for (int i = 0; i < text.Length; i++)
                  {
                      var height = boundsList[i].Height;
                      var charHeight = height;
                      var top = boundsList[i].Top;
      
                      paint.Color = SKColors.Blue.WithAlpha(0xC5);
                      paint.Style = SKPaintStyle.Stroke;
      
                      positionList[i] = new SKPoint(boundsList[i].Left, y + -top);
                      y += charHeight;
                  }
      
                  SKTextBlob skTextBlob = SKTextBlob.CreatePositioned(text, skFont, positionList.AsSpan());
                  skCanvas.DrawText(skTextBlob, 0, 0, paint);
      

      實現的效果十分緊湊的字符排版效果,如此的直排豎排垂直分布排版界面效果如下

      以上代碼放在 githubgitee 上,可以使用如下命令行拉取代碼。我整個代碼倉庫比較龐大,使用以下命令行可以進行部分拉取,拉取速度比較快

      先創建一個空文件夾,接著使用命令行 cd 命令進入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

      git init
      git remote add origin https://gitee.com/lindexi/lindexi_gd.git
      git pull origin d77e52470f55cc00d556dea1c873a1ec5ce61f22
      

      以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令行繼續輸入以下代碼,將 gitee 源換成 github 源進行拉取代碼。如果依然拉取不到代碼,可以發郵件向我要代碼

      git remote remove origin
      git remote add origin https://github.com/lindexi/lindexi_gd.git
      git pull origin d77e52470f55cc00d556dea1c873a1ec5ce61f22
      

      獲取代碼之后,進入 SkiaSharp/DihealereniRakallfairko 文件夾,即可獲取到源代碼

      以上的豎排效果只能說是有效果,但整體效果不好。為了實現更好的豎排效果,自然可以想到的就是加上字符邊距,如 https://gitee.com/lindexi/lindexi_gd/blob/0d200a22b3829188a9abb6f967f96a7341f75b5c/LightTextEditorPlus/LightTextEditorPlus.Skia/Platform/SkiaCharInfoMeasurer.cs#L275-277https://github.com/lindexi/lindexi_gd/blob/0d200a22b3829188a9abb6f967f96a7341f75b5c/LightTextEditorPlus/LightTextEditorPlus.Skia/Platform/SkiaCharInfoMeasurer.cs#L275-L277 文本庫的補丁代碼所示

      if (!isHorizontal)
      {
          // 豎排情況下,不要讓字間距過大
          const int margin = 6;
          height = renderBounds.Height + margin;
      }
      

      自然來說,這個間距是好的。但不足之處至于這是一個魔法值,沒有什么理由

      一個自然的方法是引入 baseline(Ascent)來作為間距,如下圖所示

      引入 baseline(Ascent)來作為間距,即以上代碼的 margin 換成了 space 值

      space = Ascent - Top
      

      于是此時的渲染高度計算公式如下

      RenderHeight = height + space
      = 字高度+空隙
      

      為了讓字不緊湊,就需要使用至少為 baseline(Ascent) 的間距距離。盡管理論上使用 Top 就足夠了,但 Top 過于緊湊。引入 baseline 之后,就會因為 Top 和 baseline 之間的差距,引入了 space 高度的空隙。于是引入 baseline 之后的渲染高度就應該是 height 字高加上空隙

      更改代碼,引入 baseline 作為 margin 的代碼如下

                  var positionList = new SKPoint[text.Length];
                  var y = 0f;
                  for (int i = 0; i < text.Length; i++)
                  {
                      var height = boundsList[i].Height;
                      var charHeight = height;
                      var top = boundsList[i].Top;
      
                      var space = baseline + top;
                      charHeight = height + space; // 字高度加空隙等于渲染高度
      
                      paint.Color = SKColors.Blue.WithAlpha(0xC5);
                      paint.Style = SKPaintStyle.Stroke;
      
                      positionList[i] = new SKPoint(boundsList[i].Left, y + baseline);
                      y += charHeight;
                  }
      
                  SKTextBlob skTextBlob = SKTextBlob.CreatePositioned(text, skFont, positionList.AsSpan());
      
                  paint.Style = SKPaintStyle.Fill;
                  paint.Color = SKColors.Blue;
                  skCanvas.DrawText(skTextBlob, 0, 0, paint);
      

      運行之后的界面效果如下

      是不是看起來有些奇怪?試試將每個外接邊框也輸出出來,代碼如下

                      var height = boundsList[i].Height;
                      var charHeight = height;
                      var top = boundsList[i].Top;
      
                      var space = baseline + top;
                      charHeight = height + space; // 字高度加空隙等于渲染高度
      
                      paint.Color = SKColors.Blue.WithAlpha(0xC5);
                      paint.Style = SKPaintStyle.Stroke;
      
                      skCanvas.DrawRect(boundsList[i].Left, y, boundsList[i].Width, charHeight, paint);
      
                      positionList[i] = new SKPoint(boundsList[i].Left, y + baseline);
                      y += charHeight;
      

      運行的效果如下圖,從下圖一下就可以看出來,漢字“一”明顯過于偏下

      只引入 baseline 依然還是不夠的,為了能夠在豎排過程中,讓一些漢字,如“一”進行垂直方向的居中,這里不會直接從 baseline 開始畫,而是取 (baseline-space/2) 開始畫,確保畫出來的效果如下所示

      核心實現代碼如下

                  var positionList = new SKPoint[text.Length];
                  var y = 0f;
                  for (int i = 0; i < text.Length; i++)
                  {
                      var height = boundsList[i].Height;
                      var charHeight = height;
                      var top = boundsList[i].Top;
      
                      var space = baseline + top;
                      charHeight = height + space; // 字高度加空隙等于渲染高度
      
                      paint.Color = SKColors.Blue.WithAlpha(0xC5);
                      paint.Style = SKPaintStyle.Stroke;
      
                      skCanvas.DrawRect(boundsList[i].Left, y, boundsList[i].Width, charHeight, paint);
      
                      positionList[i] = new SKPoint(boundsList[i].Left, y + baseline - space / 2);
                      y += charHeight;
                  }
      

      畫出來的界面效果如下

      去掉調試邊框之后的效果如下

      如此看起來垂直方向就十分正常了。以上優化修改的代碼放在 githubgitee 上,可以使用如下命令行拉取代碼。我整個代碼倉庫比較龐大,使用以下命令行可以進行部分拉取,拉取速度比較快

      先創建一個空文件夾,接著使用命令行 cd 命令進入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

      git init
      git remote add origin https://gitee.com/lindexi/lindexi_gd.git
      git pull origin 0223eda53dae64ded4aa99a0a4506b6c89af207e
      

      以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令行繼續輸入以下代碼,將 gitee 源換成 github 源進行拉取代碼。如果依然拉取不到代碼,可以發郵件向我要代碼

      git remote remove origin
      git remote add origin https://github.com/lindexi/lindexi_gd.git
      git pull origin 0223eda53dae64ded4aa99a0a4506b6c89af207e
      

      獲取代碼之后,進入 SkiaSharp/RebeduryaiNarjargeka 文件夾,即可獲取到源代碼

      更多技術博客,請參閱 博客導航

      posted @ 2025-04-09 07:28  lindexi  閱讀(179)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲自拍偷拍福利小视频| 波多野结衣久久一区二区| 静乐县| 国产人妻人伦精品婷婷| 99热门精品一区二区三区无码| 黑人巨大粗物挺进了少妇| 国产精品成人午夜久久| 东京热一精品无码av| 最近中文字幕免费手机版| 色综合天天综合网国产人| 丰满少妇被猛烈进入av久久| 国产精品亚洲二区在线看| 国产极品美女高潮无套| 在线观看成人永久免费网站| 国产精品国产三级在线专区| 亚洲综合av一区二区三区| 久久精品国产亚洲av天海翼| 国产成a人片在线观看视频下载 | 欧洲精品码一区二区三区| 国产视频有码字幕一区二区| 精品无码人妻一区二区三区| 国产精品午夜福利免费看| 国产精品论一区二区三区| 狠狠综合久久综合88亚洲| 国产一区二区不卡91| 国产内射性高湖| 俺也来俺也去俺也射| 国内自拍视频在线一区| 久久国产免费观看精品3| 中文字幕乱码中文乱码毛片 | 一本色道婷婷久久欧美| 亚洲av一本二本三本| 国产在线不卡精品网站| 国产成人高清亚洲综合| 亚洲精品一区二区三区色| 精品一区二区三区少妇蜜臀| 成人免费A级毛片无码网站入口| 亚洲色大成网站www看下面| 青河县| 色婷婷日日躁夜夜躁| 一二三三免费观看视频|