浏览代码

refine font texture

/main
fzhangtj 6 年前
当前提交
caf0bcd5
共有 10 个文件被更改,包括 233 次插入38 次删除
  1. 4
      Assets/UIWidgets/ui/painting/canvas.cs
  2. 5
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  3. 11
      Assets/UIWidgets/ui/painting/draw_cmd.cs
  4. 2
      Assets/UIWidgets/ui/painting/picture.cs
  5. 11
      Assets/UIWidgets/ui/txt/linebreaker.cs
  6. 40
      Assets/UIWidgets/ui/txt/paragraph.cs
  7. 73
      Assets/UIWidgets/ui/txt/font_manager.cs
  8. 3
      Assets/UIWidgets/ui/txt/font_manager.cs.meta
  9. 119
      Assets/UIWidgets/ui/txt/mesh.cs
  10. 3
      Assets/UIWidgets/ui/txt/mesh.cs.meta

4
Assets/UIWidgets/ui/painting/canvas.cs


void clipRRect(RRect rrect);
void drawMesh(Mesh mesh, Material material);
void drawMesh(IMesh mesh, Material material);
}
public class RecorderCanvas : Canvas {

});
}
public void drawMesh(Mesh mesh, Material material)
public void drawMesh(IMesh mesh, Material material)
{
this._recorder.addDrawCmd(new DrawMesh() {
mesh = mesh,

5
Assets/UIWidgets/ui/painting/canvas_impl.cs


this.pushClipRRect(rect, this._transform);
}
public void drawMesh(Mesh mesh, Material material)
public void drawMesh(IMesh mesh, Material material)
Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
mesh.syncTextureUV();
Graphics.DrawMeshNow(mesh.mesh, Matrix4x4.identity);
}
private void pushClipRect(Rect clipRect, Matrix4x4 transform) {

11
Assets/UIWidgets/ui/painting/draw_cmd.cs


}
public class DrawMesh : DrawCmd {
public Mesh mesh;
public IMesh mesh;
public interface IMesh
{
void syncTextureUV();
Mesh mesh { get; }
}

2
Assets/UIWidgets/ui/painting/picture.cs


var drawClipRRect = (DrawClipRRect) drawCmd;
this.addClipRect(drawClipRRect.rrect.outerRect);
} else if (drawCmd is DrawMesh) {
var bounds = ((DrawMesh)drawCmd).mesh.bounds;
var bounds = ((DrawMesh)drawCmd).mesh.mesh.bounds;
var rect = Rect.fromLTRB(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
this.addPaintBounds(rect);

11
Assets/UIWidgets/ui/txt/linebreaker.cs


private int _spaceCount = 0;
private int tabCount = 4;
private double _lineLength;
private Font[] _styleRunFonts;
public void setup(string text, StyledRuns runs, Font[] styleRunFonts, double width, Vector2d[] characterPositions, double[] characterWidth)
public void setup(string text, StyledRuns runs, double width, Vector2d[] characterPositions, double[] characterWidth)
{
_text = text;
_runs = runs;

_styleRunFonts = styleRunFonts;
}
public List<LineInfo> getLines()

{
runIterator.nextTo(charIndex);
var run = runIterator.run;
var font = _styleRunFonts[runIterator.runIndex];
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
var style = run.style;
var charInfo = new CharacterInfo();

}
else if (_text[charIndex] == ' ')
{
font.GetCharacterInfo(_text[charIndex], out charInfo, 0, run.style.UnityFontStyle);
font.GetCharacterInfo(_text[charIndex], out charInfo, style.UnityFontSize, run.style.UnityFontStyle);
_spaceCount++;
_characterPositions[charIndex].x = offsetX;
_characterWidth[charIndex] = charInfo.advance;

else
{
font.GetCharacterInfo(_text[charIndex], out charInfo, 0, run.style.UnityFontStyle);
font.GetCharacterInfo(_text[charIndex], out charInfo, style.UnityFontSize,
run.style.UnityFontStyle);
if (_spaceCount > 0 || blockStart == charIndex)
{
_wordStart = charIndex;

40
Assets/UIWidgets/ui/txt/paragraph.cs


private double _minIntrinsicWidth;
private double _alphabeticBaseline;
private double _ideographicBaseline;
private Font[] _styleRunFonts;
private double[] _characterWidths;
private List<double> _lineHeights = new List<double>();
private bool _didExceedMaxLines;

// It is the Unicode set: [[:General_Category=Space_Separator:]-[:Line_Break=Glue:]],
// plus '\n'.
// Note: all such characters are in the BMP, so it's ok to use code units for this.
static bool isLineEndSpace(char c) {
public static bool isLineEndSpace(char c) {
return c == '\n' || c == ' ' || c == 0x1680 || (0x2000 <= c && c <= 0x200A && c != 0x2007) ||
c == 0x205F || c == 0x3000;
}

get { return _alphabeticBaseline; }
}
public double ideographicBaseline
{
get { return _ideographicBaseline; }

var run = _runs.getRun(runIndex);
if (run.start < run.end)
{
var font = _styleRunFonts[runIndex];
var mesh = generateMesh(x, y, font, run);
canvas.drawMesh(mesh, font.material);
var fontEntry = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize);
var mesh = new TextMesh(new Vector2d(x, y), _text, _characterPositions, fontEntry, run);
canvas.drawMesh(mesh, fontEntry.font.material);
}
}

_text = text;
_runs = runs;
_needsLayout = true;
_styleRunFonts = null;
}
public void setParagraphStyle(ParagraphStyle style)

_styleRunFonts = null;
}
public static void offsetCharacters(Vector2d offset, Vector2d[] characterPos, int start, int end)

_lineRanges.Clear();
_lineWidths.Clear();
_characterWidths = new double[_text.Length];
if (_styleRunFonts == null)
for (int i = 0; i < _runs.size; ++i)
_styleRunFonts = new Font[_runs.size];
for (int i = 0; i < _styleRunFonts.Length; ++i)
var run = _runs.getRun(i);
if (run.start < run.end)
var run = _runs.getRun(i);
if (run.start < run.end)
{
_styleRunFonts[i] = Font.CreateDynamicFontFromOSFont(run.style.safeFontFamily,
run.style.UnityFontSize);
_styleRunFonts[i].material.shader = textShader;
_styleRunFonts[i].RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), 0,
run.style.UnityFontStyle);
}
}
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), 0,
run.style.UnityFontStyle);
}
}
}

var run = _runs.getRun(runIndex);
if (run.start < run.end && run.start < line.end && run.end > line.start)
{
var font = _styleRunFonts[runIndex];
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
var ascent = font.ascent * (run.style.height??1.0);
var descent = (font.lineHeight - font.ascent) * (run.style.height??1.0);
if (ascent > maxAscent)

newLinePositions.Add(_text.Length);
var lineBreaker = new LineBreaker();
lineBreaker.setup(_text, _runs, _styleRunFonts, _width, _characterPositions, _characterWidths);
lineBreaker.setup(_text, _runs, _width, _characterPositions, _characterWidths);
for (var newlineIndex = 0; newlineIndex < newLinePositions.Count; ++newlineIndex)
{

var triangles = new int[_text.Length * 6];
var uv = new Vector2[_text.Length * 4];
Vector3 offset = new Vector3((float)Utils.PixelCorrectRound(x), (float)Utils.PixelCorrectRound(y), 0);
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), run.style.UnityFontSize, run.style.UnityFontStyle);
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start),
run.style.UnityFontSize, run.style.UnityFontStyle);
for (int charIndex = run.start; charIndex < run.end; ++charIndex)
{
CharacterInfo charInfo = new CharacterInfo();

73
Assets/UIWidgets/ui/txt/font_manager.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UIWidgets.ui
{
public class FontEntry
{
public readonly Font font;
private int _textureBuildVersion = 0;
public FontEntry(Font font)
{
this.font = font;
}
public int textureBuildVersion
{
get { return _textureBuildVersion; }
}
internal void onFontTextureRebuild()
{
_textureBuildVersion++;
}
}
public class FontManager
{
private List<FontEntry> _fonts = new List<FontEntry>();
public static readonly FontManager instance = new FontManager();
private FontManager()
{
Font.textureRebuilt += this.onFontTextureRebuilt;
}
public FontEntry getOrCreate(string[] names, int fontSize)
{
var founded = _fonts.Find((font) =>
(
font.font.fontSize == fontSize &&
(names == font.font.fontNames || (names != null && names.SequenceEqual(font.font.fontNames)))));
if (founded != null)
{
return founded;
}
Debug.Log(string.Format("Create new Font names={0}, size={1}", names, fontSize));
var newFont = new FontEntry(Font.CreateDynamicFontFromOSFont(names,
fontSize));
_fonts.Add(newFont);
return newFont;
}
public FontEntry getOrCreate(string name, int fontSize)
{
return getOrCreate(new []{name}, fontSize);
}
private void onFontTextureRebuilt(Font font)
{
var entry = _fonts.Find((f) => f.font == font);
if (entry != null)
{
entry.onFontTextureRebuild();
}
}
}
}

3
Assets/UIWidgets/ui/txt/font_manager.cs.meta


fileFormatVersion: 2
guid: b643b1d2b3f14560bfa4b97bfdb7422a
timeCreated: 1536220942

119
Assets/UIWidgets/ui/txt/mesh.cs


using UnityEngine;
namespace UIWidgets.ui
{
public class TextMesh: IMesh
{
private Mesh _mesh;
private FontEntry _fontEntry;
private string _text;
private StyledRuns.Run _run;
private int _textureVersion;
public TextMesh(Vector2d pos, string text, Vector2d[] _characterPositions, FontEntry fontEntry, StyledRuns.Run run)
{
_fontEntry = fontEntry;
_text = text;
this._run = run;
var vertices = new Vector3[_text.Length * 4];
var triangles = new int[_text.Length * 6];
var font = fontEntry.font;
var offset = new Vector3((float)Utils.PixelCorrectRound(pos.x), (float)Utils.PixelCorrectRound(pos.y), 0);
font.RequestCharactersInTexture(_text.Substring(_run.start, _run.end - _run.start),
_run.style.UnityFontSize, _run.style.UnityFontStyle);
for (int charIndex = _run.start; charIndex < _run.end; ++charIndex)
{
CharacterInfo charInfo = new CharacterInfo();
if (_text[charIndex] != '\n' && _text[charIndex] != '\t')
{
Debug.Assert(font.GetCharacterInfo(_text[charIndex], out charInfo, _run.style.UnityFontSize, _run.style.UnityFontStyle));
var position = _characterPositions[charIndex];
vertices[4 * charIndex + 0] = offset + new Vector3((float)(position.x + charInfo.minX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 1] = offset + new Vector3((float)(position.x + charInfo.maxX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 2] = offset + new Vector3(
(float)(position.x + charInfo.maxX), (float)(position.y - charInfo.minY), 0);
vertices[4 * charIndex + 3] = offset + new Vector3(
(float)(position.x + charInfo.minX), (float)(position.y - charInfo.minY), 0);
}
else
{
vertices[4 * charIndex + 0] = vertices[4 * charIndex + 1] =
vertices[4 * charIndex + 2] = vertices[4 * charIndex + 3] = offset;
}
triangles[6 * charIndex + 0] = 4 * charIndex + 0;
triangles[6 * charIndex + 1] = 4 * charIndex + 1;
triangles[6 * charIndex + 2] = 4 * charIndex + 2;
triangles[6 * charIndex + 3] = 4 * charIndex + 0;
triangles[6 * charIndex + 4] = 4 * charIndex + 2;
triangles[6 * charIndex + 5] = 4 * charIndex + 3;
}
var uv = getTextureUV();
var mesh = new Mesh()
{
vertices = vertices,
triangles = triangles,
uv = uv
};
var colors = new UnityEngine.Color[vertices.Length];
for (var i = 0; i < colors.Length; i++)
{
colors[i] = _run.style.UnityColor;
}
mesh.colors = colors;
_textureVersion = _fontEntry.textureBuildVersion;
_mesh = mesh;
}
public void syncTextureUV()
{
if (_fontEntry.textureBuildVersion != _textureVersion) // texture has been rebuilt, update the texture uv
{
_mesh.uv = getTextureUV();
}
}
public Mesh mesh
{
get { return _mesh; }
}
private Vector2[] getTextureUV()
{
var font = _fontEntry.font;
var uv = _mesh == null ? new Vector2[_text.Length * 4] : _mesh.uv;
for (int charIndex = _run.start; charIndex < _run.end; ++charIndex)
{
CharacterInfo charInfo = new CharacterInfo();
if (_text[charIndex] != '\n' && _text[charIndex] != '\t')
{
font.GetCharacterInfo(_text[charIndex], out charInfo, _run.style.UnityFontSize,
_run.style.UnityFontStyle);
}
if (Paragraph.isWordSpace(_text[charIndex]) || Paragraph.isLineEndSpace(_text[charIndex]) || _text[charIndex] == '\t')
{
uv[4 * charIndex + 0] = Vector2.zero;
uv[4 * charIndex + 1] = Vector2.zero;
uv[4 * charIndex + 2] = Vector2.zero;
uv[4 * charIndex + 3] = Vector2.zero;
} else
{
uv[4 * charIndex + 0] = charInfo.uvTopLeft;
uv[4 * charIndex + 1] = charInfo.uvTopRight;
uv[4 * charIndex + 2] = charInfo.uvBottomRight;
uv[4 * charIndex + 3] = charInfo.uvBottomLeft;
}
}
return uv;
}
}
}

3
Assets/UIWidgets/ui/txt/mesh.cs.meta


fileFormatVersion: 2
guid: 96ec1d4b2b7d4bf59d4b2db221323ae9
timeCreated: 1536283931
正在加载...
取消
保存