浏览代码

fix format & load font

/siyaoH-1.17-PlatformMessage
siyao 4 年前
当前提交
720be903
共有 27 个文件被更改,包括 4280 次插入1523 次删除
  1. 2
      Samples/UIWidgetsSamples_2019_4/Assets/TextTest.unity
  2. 395
      com.unity.uiwidgets/Runtime/ui2/text.cs
  3. 37
      engine/Build.bee.cs
  4. 13
      engine/README.md
  5. 6
      engine/src/TestLoadICU.cpp
  6. 8
      engine/src/engine.cc
  7. 202
      engine/src/lib/ui/txt/asset_manager_font_provider.cc
  8. 100
      engine/src/lib/ui/txt/asset_manager_font_provider.h
  9. 206
      engine/src/lib/ui/txt/font_collection.cc
  10. 33
      engine/src/lib/ui/txt/font_collection.h
  11. 157
      engine/src/lib/ui/txt/icu_util.cc
  12. 12
      engine/src/lib/ui/txt/icu_util.h
  13. 399
      engine/src/lib/ui/txt/paragraph.cc
  14. 76
      engine/src/lib/ui/txt/paragraph.h
  15. 880
      engine/src/lib/ui/txt/paragraph_builder.cc
  16. 88
      engine/src/lib/ui/txt/paragraph_builder.h
  17. 1
      engine/src/render_api.h
  18. 10
      engine/src/render_api_d3d11.cc
  19. 18
      engine/src/shell/common/shell.cc
  20. 3
      engine/src/shell/platform/unity/uiwidgets_panel.cc
  21. 186
      Samples/UIWidgetsSamples_2019_4/Assets/TextTest.cs
  22. 825
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Ranchers-Regular.ttf
  23. 1001
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-BlackItalic.ttf
  24. 1001
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-Italic.ttf
  25. 124
      Samples/UIWidgetsSamples_2019_4/Assets/Behavior1.cs
  26. 20
      engine/src/lib/ui/txt/utils.h

2
Samples/UIWidgetsSamples_2019_4/Assets/TextTest.unity


m_GameObject: {fileID: 847097468}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d51be63934ecb58489023ddfb123b3ad, type: 3}
m_Script: {fileID: 11500000, guid: db61290d6ca38264995f5749021d562c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}

395
com.unity.uiwidgets/Runtime/ui2/text.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using UnityEngine;
using RSG;
using Unity.UIWidgets.async2;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.ui2 {

}
}
public class Utils {
public partial class ui_ {
public static void SetFloat(List<byte> data, int offSet, float value) {
var bytes = BitConverter.GetBytes(value);
data[offSet] = bytes[0];

TextDecoration decoration,
Color decorationColor,
TextDecorationStyle? decorationStyle,
double? decorationThickness,
float? decorationThickness,
double? fontSize,
double? letterSpacing,
double? wordSpacing,
double? height,
float? fontSize,
float? letterSpacing,
float? wordSpacing,
float? height,
Locale locale,
Paint background,
Paint foreground,

TextDirection? textDirection,
int? maxLines,
String fontFamily,
double? fontSize,
double? height,
float? fontSize,
float? height,
TextHeightBehavior textHeightBehavior,
FontWeight fontWeight,
FontStyle? fontStyle,

internal static List<byte> _encodeStrut(
String fontFamily,
List<String> fontFamilyFallback,
double fontSize,
double height,
double leading,
float fontSize,
float height,
float leading,
FontWeight fontWeight,
FontStyle fontStyle,
bool forceStrutHeight) {

return data.GetRange(0, byteCount);
}
public Promise loadFontFromList(int[] list, string fontFamily = null) {
var completer = new Promise(true);
GCHandle completerHandle = GCHandle.Alloc(completer);
loadFontFromList(list, _toImageCallback, (IntPtr) completerHandle, fontFamily);
return completer;
public static unsafe Future loadFontFromList(byte[] list, string fontFamily = null) {
return ui_._futurize((_Callback<object> callback) => {
// var completer = new Promise(true);
GCHandle completerHandle = GCHandle.Alloc(callback);
fixed (byte* listPtr = list) {
LoadFontFromList(listPtr, list.Length, _loadFontCallback, (IntPtr) completerHandle, fontFamily);
}
return null;
});
static void _toImageCallback(IntPtr callbackHandle) {
static void _loadFontCallback(IntPtr callbackHandle) {
var completer = (Promise) completerHandle.Target;
var callback = (_Callback<object>) completerHandle.Target;
try {
callback(new object());
}
catch (Exception ex) {
Debug.LogException(ex);
}
}
static byte[] _fontChangeMessage =

unsafe {
Window window = new Window();
window.onPlatformMessage?.Invoke("flutter/system", _fontChangeMessage,
window.onPlatformMessage?.Invoke("uiwidgets/system", _fontChangeMessage,
(byte[] dataIn) => { });
}
}

[DllImport(NativeBindings.dllName)]
static extern IntPtr loadFontFromList(int[] list, _loadFontFromListCallback callback, IntPtr callbackHandle,
static extern unsafe void LoadFontFromList(byte* list, int size, _loadFontFromListCallback callback,
IntPtr callbackHandle,
string fontFamily);
public struct Float32List {

TextDecoration decoration = null,
Color decorationColor = null,
TextDecorationStyle? decorationStyle = null,
double? decorationThickness = null,
float? decorationThickness = null,
double? fontSize = null,
double? letterSpacing = null,
double? wordSpacing = null,
double? height = null,
float? fontSize = null,
float? letterSpacing = null,
float? wordSpacing = null,
float? height = null,
Locale locale = null,
Paint background = null,
Paint foreground = null,

// "Cannot provide both a color and a foreground\n"+
// "The color argument is just a shorthand for \"foreground: Paint()..color = color\"."
);
_encoded = Utils._encodeTextStyle(
_encoded = ui_._encodeTextStyle(
color,
decoration,
decorationColor,

public readonly List<int> _encoded;
public readonly String _fontFamily;
public readonly List<String> _fontFamilyFallback;
public readonly double? _fontSize;
public readonly double? _letterSpacing;
public readonly double? _wordSpacing;
public readonly double? _height;
public readonly double? _decorationThickness;
public readonly float? _fontSize;
public readonly float? _letterSpacing;
public readonly float? _wordSpacing;
public readonly float? _height;
public readonly float? _decorationThickness;
public readonly Locale _locale;
public readonly Paint _background;
public readonly Paint _foreground;

&& textStyle._locale == _locale
&& textStyle._background == _background
&& textStyle._foreground == _foreground
&& Utils._listEquals<int>(textStyle._encoded, _encoded)
&& Utils._listEquals<Shadow>(textStyle._shadows, _shadows)
&& Utils._listEquals<String>(textStyle._fontFamilyFallback, _fontFamilyFallback)
&& Utils._listEquals<FontFeature>(textStyle._fontFeatures, _fontFeatures);
&& ui_._listEquals<int>(textStyle._encoded, _encoded)
&& ui_._listEquals<Shadow>(textStyle._shadows, _shadows)
&& ui_._listEquals<String>(textStyle._fontFamilyFallback, _fontFamilyFallback)
&& ui_._listEquals<FontFeature>(textStyle._fontFeatures, _fontFeatures);
}
public override int GetHashCode() {

TextDirection? textDirection = null,
int? maxLines = null,
String fontFamily = null,
double? fontSize = null,
double? height = null,
float? fontSize = null,
float? height = null,
TextHeightBehavior textHeightBehavior = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,

) {
_encoded = Utils._encodeParagraphStyle(
_encoded = ui_._encodeParagraphStyle(
textAlign,
textDirection,
maxLines,

public readonly List<int> _encoded;
public readonly String _fontFamily;
public readonly double? _fontSize;
public readonly double? _height;
public readonly float? _fontSize;
public readonly float? _height;
public readonly StrutStyle _strutStyle;
public readonly String _ellipsis;
public readonly Locale _locale;

&& otherParagraph._strutStyle == _strutStyle
&& otherParagraph._ellipsis == _ellipsis
&& otherParagraph._locale == _locale
&& Utils._listEquals<int>(otherParagraph._encoded, _encoded);
&& ui_._listEquals<int>(otherParagraph._encoded, _encoded);
}
public override int GetHashCode() {

public StrutStyle(
String fontFamily,
List<String> fontFamilyFallback,
double fontSize,
double height,
double leading,
float fontSize,
float height,
float leading,
_encoded = Utils._encodeStrut(
_encoded = ui_._encodeStrut(
fontFamily,
fontFamilyFallback,
fontSize,

return obj is StrutStyle other
&& other._fontFamily == _fontFamily
&& Utils._listEquals<String>(other._fontFamilyFallback, _fontFamilyFallback)
&& Utils._listEquals<byte>(other._encoded, _encoded);
&& ui_._listEquals<String>(other._fontFamilyFallback, _fontFamilyFallback)
&& ui_._listEquals<byte>(other._encoded, _encoded);
}
public override int GetHashCode() {

public class TextBox {
public TextBox(
double left,
double top,
double right,
double bottom,
float left,
float top,
float right,
float bottom,
TextDirection direction) {
this.left = left;
this.top = top;

}
public static TextBox fromLTRBD(
double left,
double top,
double right,
double bottom,
float left,
float top,
float right,
float bottom,
public readonly double left;
public readonly float left;
public readonly double top;
public readonly float top;
public readonly double right;
public readonly float right;
public readonly double bottom;
public readonly float bottom;
double start {
float start {
double end {
float end {
get { return (direction == TextDirection.ltr) ? right : left; }
}

}
public class ParagraphConstraints {
public ParagraphConstraints(double width) {
public ParagraphConstraints(float width) {
public readonly double width;
public readonly float width;
public override bool Equals(object obj) {
return obj is ui.ParagraphConstraints other && other.width == width;

public class LineMetrics {
public LineMetrics(
bool hardBreak,
double ascent,
double descent,
double unscaledAscent,
double height,
double width,
double left,
double baseline,
float ascent,
float descent,
float unscaledAscent,
float height,
float width,
float left,
float baseline,
int lineNumber) {
this.hardBreak = hardBreak;
this.ascent = ascent;

public readonly bool hardBreak;
public readonly double ascent;
public readonly float ascent;
public readonly double descent;
public readonly float descent;
public readonly double unscaledAscent;
public readonly float unscaledAscent;
public readonly double height;
public readonly float height;
public readonly double width;
public readonly float width;
public readonly double left;
public readonly float left;
public readonly double baseline;
public readonly float baseline;
public readonly int lineNumber;

}
[DllImport(NativeBindings.dllName)]
static extern double Paragraph_width(IntPtr ptr);
static extern float Paragraph_width(IntPtr ptr);
static extern double Paragraph_height(IntPtr ptr);
static extern float Paragraph_height(IntPtr ptr);
static extern double Paragraph_longestLine(IntPtr ptr);
static extern float Paragraph_longestLine(IntPtr ptr);
static extern double Paragraph_minIntrinsicWidth(IntPtr ptr);
static extern float Paragraph_minIntrinsicWidth(IntPtr ptr);
static extern double Paragraph_maxIntrinsicWidth(IntPtr ptr);
static extern float Paragraph_maxIntrinsicWidth(IntPtr ptr);
static extern double Paragraph_alphabeticBaseline(IntPtr ptr);
static extern float Paragraph_alphabeticBaseline(IntPtr ptr);
static extern double Paragraph_ideographicBaseline(IntPtr ptr);
static extern float Paragraph_ideographicBaseline(IntPtr ptr);
static extern void Paragraph_layout(IntPtr ptr, double width);
static extern void Paragraph_layout(IntPtr ptr, float width);
static extern Utils.Float32List Paragraph_getRectsForRange(IntPtr ptr, int start, int end, int boxHeightStyle,
static extern int Paragraph_getRectsForRangeSize(IntPtr ptr, int start, int end,
int boxHeightStyle,
static extern Utils.Float32List Paragraph_getRectsForPlaceholders(IntPtr ptr);
static extern unsafe void Paragraph_getRectsForRange(IntPtr ptr, float* data, int start, int end,
int boxHeightStyle,
int boxWidthStyle);
[DllImport(NativeBindings.dllName)]
static extern unsafe int Paragraph_getRectsForPlaceholdersSize(IntPtr ptr);
[DllImport(NativeBindings.dllName)]
static extern unsafe void Paragraph_getRectsForPlaceholders(IntPtr ptr, float* data);
[DllImport(NativeBindings.dllName)]
static extern unsafe void Paragraph_getPositionForOffset(IntPtr ptr, float dx, float dy, int* encodedPtr);
static extern List<int> Paragraph_getPositionForOffset(IntPtr ptr, double dx, double dy);
static extern unsafe void Paragraph_getWordBoundary(IntPtr ptr, int offset, int* boundaryPtr);
static extern List<int> Paragraph_getWordBoundary(IntPtr ptr, int offset);
static extern unsafe void Paragraph_getLineBoundary(IntPtr ptr, int offset, int* boundaryPtr);
static extern List<int> Paragraph_getLineBoundary(IntPtr ptr, int offset);
static extern void Paragraph_paint(IntPtr ptr, IntPtr canvas, float x, float y);
static extern void Paragraph_paint(IntPtr ptr, IntPtr canvas, double x, double y);
static extern int Paragraph_computeLineMetricsSize(IntPtr ptr);
static extern Utils.Float32List Paragraph_computeLineMetrics(IntPtr ptr);
static extern unsafe void Paragraph_computeLineMetrics(IntPtr ptr, float* data);
void _layout(double width) => Paragraph_layout(_ptr, width);
void _layout(float width) => Paragraph_layout(_ptr, width);
List<TextBox> _decodeTextBoxes(Utils.Float32List encoded) {
int count = encoded.Length / 5;
List<TextBox> _decodeTextBoxes(float[] encoded, int size) {
int count = size / 5;
encoded.data[position++],
encoded.data[position++],
encoded.data[position++],
encoded.data[position++],
(TextDirection) encoded.data[position++]
encoded[position++],
encoded[position++],
encoded[position++],
encoded[position++],
(TextDirection) encoded[position++]
));
}
}

public double width() {
protected override void DisposePtr(IntPtr ptr) {
Paragraph_dispose(ptr);
}
public float width() {
public double height() {
public float height() {
public double longestLine() {
public float longestLine() {
public double minIntrinsicWidth() {
public float minIntrinsicWidth() {
public double maxIntrinsicWidth() {
public float maxIntrinsicWidth() {
public double alphabeticBaseline() {
public float alphabeticBaseline() {
public double ideographicBaseline() {
public float ideographicBaseline() {
return Paragraph_ideographicBaseline(_ptr);
}

public List<TextBox> getBoxesForRange(int start, int end, BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight,
public unsafe List<TextBox> getBoxesForRange(int start, int end,
BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight,
return _decodeTextBoxes(_getBoxesForRange(start, end, (int) boxHeightStyle, (int) boxWidthStyle));
int size = Paragraph_getRectsForRangeSize(_ptr, start, end, (int) boxHeightStyle, (int) boxWidthStyle);
float[] data = new float[size];
fixed (float* dataPtr = data) {
_getBoxesForRange(dataPtr, start, end, (int) boxHeightStyle, (int) boxWidthStyle);
}
return _decodeTextBoxes(data, size);
Utils.Float32List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle) =>
Paragraph_getRectsForRange(_ptr, start, end, boxHeightStyle, boxWidthStyle);
unsafe void _getBoxesForRange(float* data, int start, int end, int boxHeightStyle, int boxWidthStyle) =>
Paragraph_getRectsForRange(_ptr, data, start, end, boxHeightStyle, boxWidthStyle);
public unsafe List<TextBox> getBoxesForPlaceholders() {
int size = Paragraph_getRectsForPlaceholdersSize(_ptr);
float[] data = new float[size];
fixed (float* dataPtr = data) {
_getBoxesForPlaceholders(dataPtr);
}
public List<TextBox> getBoxesForPlaceholders() {
return _decodeTextBoxes(_getBoxesForPlaceholders());
return _decodeTextBoxes(data, size);
Utils.Float32List _getBoxesForPlaceholders() => Paragraph_getRectsForPlaceholders(_ptr);
unsafe void _getBoxesForPlaceholders(float* data) => Paragraph_getRectsForPlaceholders(_ptr, data);
public unsafe TextPosition getPositionForOffset(Offset offset) {
int[] encoded = new int[2];
fixed (int* encodedPtr = encoded) {
_getPositionForOffset(offset.dx, offset.dy, encodedPtr);
}
public TextPosition getPositionForOffset(Offset offset) {
List<int> encoded = _getPositionForOffset(offset.dx, offset.dy);
List<int> _getPositionForOffset(double dx, double dy) => Paragraph_getPositionForOffset(_ptr, dx, dy);
unsafe void _getPositionForOffset(float dx, float dy, int* encodedPtr) =>
Paragraph_getPositionForOffset(_ptr, dx, dy, encodedPtr);
public TextRange getWordBoundary(TextPosition position) {
List<int> boundary = _getWordBoundary(position.offset);
public unsafe TextRange getWordBoundary(TextPosition position) {
int[] boundary = new int[2];
fixed (int* boundaryPtr = boundary) {
_getWordBoundary(position.offset, boundaryPtr);
}
List<int> _getWordBoundary(int offset) => Paragraph_getWordBoundary(_ptr, offset);
unsafe void _getWordBoundary(int offset, int* boundaryPtr) =>
Paragraph_getWordBoundary(_ptr, offset, boundaryPtr);
public unsafe TextRange getLineBoundary(TextPosition position) {
int[] boundary = new int[2];
fixed (int* boundaryPtr = boundary) {
_getLineBoundary(position.offset, boundaryPtr);
}
public TextRange getLineBoundary(TextPosition position) {
List<int> boundary = _getLineBoundary(position.offset);
List<int> _getLineBoundary(int offset) => Paragraph_getLineBoundary(_ptr, offset);
unsafe void _getLineBoundary(int offset, int* boundaryPtr) =>
Paragraph_getLineBoundary(_ptr, offset, boundaryPtr);
public void _paint(Canvas canvas, double x, double y) {
public void _paint(Canvas canvas, float x, float y) {
public List<LineMetrics> computeLineMetrics() {
Utils.Float32List encoded = _computeLineMetrics();
int count = encoded.Length / 9;
public unsafe List<LineMetrics> computeLineMetrics() {
int size = Paragraph_computeLineMetricsSize(_ptr);
float[] data = new float[size];
fixed (float* dataPtr = data) {
_computeLineMetrics(dataPtr);
}
int count = size / 9;
int position = 0;
List<LineMetrics> metrics = new List<LineMetrics>();

hardBreak: encoded.data[position++] != 0,
ascent: encoded.data[position++],
descent: encoded.data[position++],
unscaledAscent: encoded.data[position++],
height: encoded.data[position++],
width: encoded.data[position++],
left: encoded.data[position++],
baseline: encoded.data[position++],
lineNumber: (int) encoded.data[position++]
hardBreak: data[position++] != 0,
ascent: data[position++],
descent: data[position++],
unscaledAscent: data[position++],
height: data[position++],
width: data[position++],
left: data[position++],
baseline: data[position++],
lineNumber: (int) data[position++]
));
}
}

Utils.Float32List _computeLineMetrics() => Paragraph_computeLineMetrics(_ptr);
protected override void DisposePtr(IntPtr ptr) {
Paragraph_dispose(ptr);
}
unsafe void _computeLineMetrics(float* data) => Paragraph_computeLineMetrics(_ptr, data);
}
public class ParagraphBuilder : NativeWrapper {

string fontFamily,
[In] string[] structFontFamily,
int structFontFamilySize,
double fontSize,
double height,
float fontSize,
float height,
[MarshalAs(UnmanagedType.LPWStr)] string ellipsis,
string locale);

int encodedSize,
[In] string[] fontFamilies,
int fontFamiliesSize,
double? fontSize,
double? letterSpacing,
double? wordSpacing,
double? height,
double? decorationThickness,
float fontSize,
float letterSpacing,
float wordSpacing,
float height,
float decorationThickness,
string locale,
IntPtr* backgroundObjects,
byte[] backgroundData,

float baselineOffset, int baseline);
[DllImport(NativeBindings.dllName)]
static extern IntPtr ParagraphBuilder_build(IntPtr ptr /*, IntPtr outParagraph*/);
static extern IntPtr ParagraphBuilder_build(IntPtr ptr);
[DllImport(NativeBindings.dllName)]
static extern void ParagraphBuilder_dispose(IntPtr ptr);

byte[] structData,
string fontFamily,
string[] structFontFamily,
double fontSize,
double height,
float fontSize,
float height,
string ellipsis,
string locale
) => ParagraphBuilder_constructor(

locale
);
protected override void DisposePtr(IntPtr ptr) {
ParagraphBuilder_dispose(ptr);
}
public int placeholderCount {
get { return _placeholderCount; }
}

public List<double> placeholderScales {
public List<float> placeholderScales {
List<double> _placeholderScales = new List<double>();
List<float> _placeholderScales = new List<float>();
public void pushStyle(TextStyle style) {
List<String> fullFontFamilies = new List<string>();

unsafe void _pushStyle(
int[] encoded,
string[] fontFamilies,
double? fontSize,
double? letterSpacing,
double? wordSpacing,
double? height,
double? decorationThickness,
float? fontSize,
float? letterSpacing,
float? wordSpacing,
float? height,
float? decorationThickness,
string locale,
IntPtr[] backgroundObjects,
byte[] backgroundData,

encoded.Length,
fontFamilies,
fontFamilies.Length,
fontSize,
letterSpacing,
wordSpacing,
height,
decorationThickness,
fontSize.GetValueOrDefault(0),
letterSpacing.GetValueOrDefault(0),
wordSpacing.GetValueOrDefault(0),
height.GetValueOrDefault(0),
decorationThickness.GetValueOrDefault(0),
locale,
backgroundObjectsPtr,
backgroundData,

return paragraph;
}
IntPtr _build( /*IntPtr outParagraph*/) => ParagraphBuilder_build(_ptr /*, outParagraph*/);
protected override void DisposePtr(IntPtr ptr) {
ParagraphBuilder_dispose(ptr);
}
IntPtr _build() => ParagraphBuilder_build(_ptr);
}
}

37
engine/Build.bee.cs


"src/lib/ui/compositing/scene_builder.cc",
"src/lib/ui/compositing/scene_builder.h",
"src/lib/ui/txt/utils.h",
"src/lib/ui/txt/icu_util.h",
"src/lib/ui/txt/icu_util.cc",
"src/lib/ui/txt/asset_manager_font_provider.cc",

builtNP.DeployTo("../Samples/UIWidgetsSamples_2019_4/Assets/Plugins/x86_64");
}
//CopyTool.Instance().Setup(new NPath("../Samples/UIWidgetsSamples_2019_4/Assets/Plugins/x86_64").Combine("icudtl.dat"), new NPath("").Combine(skiaRoot, "third_party/externals/icu/common/icudtl.dat"));
//
// var npAndroid = new NativeProgram("libUIWidgets")
// {
// Sources =
// {
// "src/engine.cc",
// "src/platform_base.h",
// "src/render_api.cc",
// "src/render_api.h",
// "src/render_api_vulkan.cc",
// "src/render_api_opengles.cc",
// },
// OutputName = {c => $"libUIWidgets{(c.CodeGen == CodeGen.Debug ? "_d" : "")}"},
// };
//
// npAndroid.Defines.Add("SUPPORT_VULKAN");
// npAndroid.CompilerSettings().Add(c => c.WithCppLanguageVersion(CppLanguageVersion.Cpp17));
// npAndroid.IncludeDirectories.Add("third_party");
//
// SetupSkiaAndroid(npAndroid);
//
// var androidToolchain = ToolChain.Store.Android().r19().Arm64();
//
// foreach (var codegen in codegens)
// {
// var config = new NativeProgramConfiguration(codegen, androidToolchain, lump: true);
//
// // var builtNP = npAndroid.SetupSpecificConfiguration(config, androidToolchain.DynamicLibraryFormat)
// // .DeployTo("build_android_arm64");
// //
// // builtNP.DeployTo("../Samples/UIWidgetsSamples_2019_4/Assets/Plugins/Android/arm64");
// // builtNP.DeployTo("../Samples/UIWidgetsSamples_2019_4/BuildAndroid/unityLibrary/src/main/jniLibs/arm64-v8a/");
// }
CopyTool.Instance().Setup(new NPath("../Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/").Combine("icudtl.dat"), new NPath("").Combine(skiaRoot, "out/Debug/icudtl.dat"));
return np;
}

13
engine/README.md


## How to Build Engine
```
bee
```
## Set ICU Data Enviroment Varaible
cmd
```
set UIWIDGETS_ICUDATA=<SKIA_ROOT>/out/Debug/icudtl.dat
```
powershell
```
$env:UIWIDGETS_ICUDATA="$env:SKIA_ROOT/out/Debug/icudtl.dat"
```
Unity Editor need to run with those environment variables set.
```

6
engine/src/TestLoadICU.cpp


return end ? std::string(path, end - path) : std::string();
}
static bool inited = false;
if (inited) {
return true;
}
static bool good = false;
static std::once_flag flag;
std::call_once(flag, []() {

}
}
});
inited = good;
return good;
}

8
engine/src/engine.cc


s_CurrentAPI->Draw();
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API DrawParagraph(uiwidgets::Paragraph* paragraph) {
if (s_CurrentAPI == NULL) {
return;
}
s_CurrentAPI->Draw2(paragraph);
}
static void UNITY_INTERFACE_API OnRenderEvent(int eventID) {
// Unknown / unsupported graphics device type? Do nothing
if (s_CurrentAPI == NULL) {

202
engine/src/lib/ui/txt/asset_manager_font_provider.cc


// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include "lib/ui/txt/asset_manager_font_provider.h"
#include "asset_manager_font_provider.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "include/core/SkData.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
namespace {
namespace {
void MappingReleaseProc(const void* ptr, void* context) {
delete reinterpret_cast<fml::Mapping*>(context);
}
void MappingReleaseProc(const void* ptr, void* context) {
delete reinterpret_cast<fml::Mapping*>(context);
}
} // anonymous namespace
} // anonymous namespace
AssetManagerFontProvider::AssetManagerFontProvider(
std::shared_ptr<AssetManager> asset_manager)
: asset_manager_(asset_manager) {}
AssetManagerFontProvider::AssetManagerFontProvider(
std::shared_ptr<AssetManager> asset_manager)
: asset_manager_(asset_manager) {}
AssetManagerFontProvider::~AssetManagerFontProvider() = default;
AssetManagerFontProvider::~AssetManagerFontProvider() = default;
// |FontAssetProvider|
size_t AssetManagerFontProvider::GetFamilyCount() const {
return family_names_.size();
}
// |FontAssetProvider|
size_t AssetManagerFontProvider::GetFamilyCount() const {
return family_names_.size();
}
// |FontAssetProvider|
std::string AssetManagerFontProvider::GetFamilyName(int index) const {
FML_DCHECK(index >= 0 && static_cast<size_t>(index) < family_names_.size());
return family_names_[index];
}
// |FontAssetProvider|
std::string AssetManagerFontProvider::GetFamilyName(int index) const {
FML_DCHECK(index >= 0 && static_cast<size_t>(index) < family_names_.size());
return family_names_[index];
}
// |FontAssetProvider|
SkFontStyleSet* AssetManagerFontProvider::MatchFamily(
const std::string& family_name) {
auto found = registered_families_.find(CanonicalFamilyName(family_name));
if (found == registered_families_.end()) {
return nullptr;
}
sk_sp<SkFontStyleSet> font_style_set = found->second;
return font_style_set.release();
}
// |FontAssetProvider|
SkFontStyleSet* AssetManagerFontProvider::MatchFamily(
const std::string& family_name) {
auto found = registered_families_.find(CanonicalFamilyName(family_name));
if (found == registered_families_.end()) {
return nullptr;
}
sk_sp<SkFontStyleSet> font_style_set = found->second;
return font_style_set.release();
}
void AssetManagerFontProvider::RegisterAsset(std::string family_name,
std::string asset) {
std::string canonical_name = CanonicalFamilyName(family_name);
auto family_it = registered_families_.find(canonical_name);
void AssetManagerFontProvider::RegisterAsset(std::string family_name,
std::string asset) {
std::string canonical_name = CanonicalFamilyName(family_name);
auto family_it = registered_families_.find(canonical_name);
if (family_it == registered_families_.end()) {
family_names_.push_back(family_name);
auto value = std::make_pair(
canonical_name,
sk_make_sp<AssetManagerFontStyleSet>(asset_manager_, family_name));
family_it = registered_families_.emplace(value).first;
}
if (family_it == registered_families_.end()) {
family_names_.push_back(family_name);
auto value = std::make_pair(
canonical_name,
sk_make_sp<AssetManagerFontStyleSet>(asset_manager_, family_name));
family_it = registered_families_.emplace(value).first;
}
family_it->second->registerAsset(asset);
}
family_it->second->registerAsset(asset);
}
AssetManagerFontStyleSet::AssetManagerFontStyleSet(
std::shared_ptr<AssetManager> asset_manager,
std::string family_name)
: asset_manager_(asset_manager), family_name_(family_name) {}
AssetManagerFontStyleSet::AssetManagerFontStyleSet(
std::shared_ptr<AssetManager> asset_manager, std::string family_name)
: asset_manager_(asset_manager), family_name_(family_name) {}
AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;
AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;
void AssetManagerFontStyleSet::registerAsset(std::string asset) {
assets_.emplace_back(asset);
}
void AssetManagerFontStyleSet::registerAsset(std::string asset) {
assets_.emplace_back(asset);
}
int AssetManagerFontStyleSet::count() {
return assets_.size();
}
int AssetManagerFontStyleSet::count() { return assets_.size(); }
void AssetManagerFontStyleSet::getStyle(int index,
SkFontStyle* style,
SkString* name) {
FML_DCHECK(index < static_cast<int>(assets_.size()));
if (style) {
sk_sp<SkTypeface> typeface(createTypeface(index));
if (typeface) {
*style = typeface->fontStyle();
}
}
if (name) {
*name = family_name_.c_str();
}
void AssetManagerFontStyleSet::getStyle(int index, SkFontStyle* style,
SkString* name) {
FML_DCHECK(index < static_cast<int>(assets_.size()));
if (style) {
sk_sp<SkTypeface> typeface(createTypeface(index));
if (typeface) {
*style = typeface->fontStyle();
}
if (name) {
*name = family_name_.c_str();
}
}
SkTypeface* AssetManagerFontStyleSet::createTypeface(int i) {
size_t index = i;
if (index >= assets_.size())
return nullptr;
SkTypeface* AssetManagerFontStyleSet::createTypeface(int i) {
size_t index = i;
if (index >= assets_.size()) return nullptr;
TypefaceAsset& asset = assets_[index];
if (!asset.typeface) {
std::unique_ptr<fml::Mapping> asset_mapping =
asset_manager_->GetAsMapping(asset.asset);
if (asset_mapping == nullptr) {
return nullptr;
}
TypefaceAsset& asset = assets_[index];
if (!asset.typeface) {
std::unique_ptr<fml::Mapping> asset_mapping =
asset_manager_->GetAsMapping(asset.asset);
if (asset_mapping == nullptr) {
return nullptr;
}
fml::Mapping* asset_mapping_ptr = asset_mapping.release();
sk_sp<SkData> asset_data = SkData::MakeWithProc(
asset_mapping_ptr->GetMapping(), asset_mapping_ptr->GetSize(),
MappingReleaseProc, asset_mapping_ptr);
std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(asset_data);
fml::Mapping* asset_mapping_ptr = asset_mapping.release();
sk_sp<SkData> asset_data = SkData::MakeWithProc(
asset_mapping_ptr->GetMapping(), asset_mapping_ptr->GetSize(),
MappingReleaseProc, asset_mapping_ptr);
std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(asset_data);
// Ownership of the stream is transferred.
asset.typeface = SkTypeface::MakeFromStream(std::move(stream));
if (!asset.typeface)
return nullptr;
}
// Ownership of the stream is transferred.
asset.typeface = SkTypeface::MakeFromStream(std::move(stream));
if (!asset.typeface) return nullptr;
}
return SkRef(asset.typeface.get());
}
return SkRef(asset.typeface.get());
}
SkTypeface* AssetManagerFontStyleSet::matchStyle(const SkFontStyle& pattern) {
return matchStyleCSS3(pattern);
}
SkTypeface* AssetManagerFontStyleSet::matchStyle(const SkFontStyle& pattern) {
return matchStyleCSS3(pattern);
}
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(std::string a)
: asset(std::move(a)) {}
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(std::string a)
: asset(std::move(a)) {}
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(
const AssetManagerFontStyleSet::TypefaceAsset& other) = default;
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(
const AssetManagerFontStyleSet::TypefaceAsset& other) = default;
AssetManagerFontStyleSet::TypefaceAsset::~TypefaceAsset() = default;
AssetManagerFontStyleSet::TypefaceAsset::~TypefaceAsset() = default;
} // namespace flutter
} // namespace uiwidgets

100
engine/src/lib/ui/txt/asset_manager_font_provider.h


#pragma once
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_LIB_UI_TEXT_ASSET_MANAGER_FONT_PROVIDER_H_
#define FLUTTER_LIB_UI_TEXT_ASSET_MANAGER_FONT_PROVIDER_H_
#include <memory>
#include <string>

namespace uiwidgets {
class AssetManagerFontStyleSet : public SkFontStyleSet {
public:
AssetManagerFontStyleSet(std::shared_ptr<AssetManager> asset_manager,
std::string family_name);
~AssetManagerFontStyleSet() override;
class AssetManagerFontStyleSet : public SkFontStyleSet {
public:
AssetManagerFontStyleSet(std::shared_ptr<AssetManager> asset_manager,
std::string family_name);
void registerAsset(std::string asset);
~AssetManagerFontStyleSet() override;
// |SkFontStyleSet|
int count() override;
void registerAsset(std::string asset);
// |SkFontStyleSet|
void getStyle(int index, SkFontStyle*, SkString* style) override;
// |SkFontStyleSet|
int count() override;
// |SkFontStyleSet|
SkTypeface* createTypeface(int index) override;
// |SkFontStyleSet|
void getStyle(int index, SkFontStyle*, SkString* style) override;
// |SkFontStyleSet|
SkTypeface* matchStyle(const SkFontStyle& pattern) override;
// |SkFontStyleSet|
SkTypeface* createTypeface(int index) override;
private:
std::shared_ptr<AssetManager> asset_manager_;
std::string family_name_;
// |SkFontStyleSet|
SkTypeface* matchStyle(const SkFontStyle& pattern) override;
struct TypefaceAsset {
TypefaceAsset(std::string a);
private:
std::shared_ptr<AssetManager> asset_manager_;
std::string family_name_;
TypefaceAsset(const TypefaceAsset& other);
struct TypefaceAsset {
TypefaceAsset(std::string a);
~TypefaceAsset();
TypefaceAsset(const TypefaceAsset& other);
std::string asset;
sk_sp<SkTypeface> typeface;
};
std::vector<TypefaceAsset> assets_;
~TypefaceAsset();
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontStyleSet);
};
std::string asset;
sk_sp<SkTypeface> typeface;
};
std::vector<TypefaceAsset> assets_;
class AssetManagerFontProvider : public txt::FontAssetProvider {
public:
AssetManagerFontProvider(std::shared_ptr<AssetManager> asset_manager);
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontStyleSet);
};
~AssetManagerFontProvider() override;
class AssetManagerFontProvider : public txt::FontAssetProvider {
public:
AssetManagerFontProvider(std::shared_ptr<AssetManager> asset_manager);
void RegisterAsset(std::string family_name, std::string asset);
~AssetManagerFontProvider() override;
// |FontAssetProvider|
size_t GetFamilyCount() const override;
void RegisterAsset(std::string family_name, std::string asset);
// |FontAssetProvider|
std::string GetFamilyName(int index) const override;
// |FontAssetProvider|
size_t GetFamilyCount() const override;
// |FontAssetProvider|
SkFontStyleSet* MatchFamily(const std::string& family_name) override;
// |FontAssetProvider|
std::string GetFamilyName(int index) const override;
private:
std::shared_ptr<AssetManager> asset_manager_;
std::unordered_map<std::string, sk_sp<AssetManagerFontStyleSet>>
registered_families_;
std::vector<std::string> family_names_;
// |FontAssetProvider|
SkFontStyleSet* MatchFamily(const std::string& family_name) override;
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontProvider);
};
private:
std::shared_ptr<AssetManager> asset_manager_;
std::unordered_map<std::string, sk_sp<AssetManagerFontStyleSet>>
registered_families_;
std::vector<std::string> family_names_;
} // namespace flutter
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontProvider);
};
#endif // FLUTTER_LIB_UI_TEXT_ASSET_MANAGER_FONT_PROVIDER_H_
} // namespace uiwidgets

206
engine/src/lib/ui/txt/font_collection.cc


#include "lib/ui/txt/font_collection.h"
#pragma once
#include "font_collection.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "lib/ui/ui_mono_state.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace {
typedef void (*LoadFontCallback)(Mono_Handle callback_handle);
namespace {
UIWIDGETS_API(void)
LoadFontFromList(uint8_t* font_data, int size,
LoadFontCallback loadFontCallback, Mono_Handle callbackHandle,
char* family_name) {
FontCollection& font_collection =
UIMonoState::Current()->window()->client()->GetFontCollection();
font_collection.LoadFontFromList(font_data, size, family_name);
loadFontCallback(callbackHandle);
}
/* void LoadFontFromList(tonic::Uint8List& font_data,
Dart_Handle callback,
std::string family_name) {
FontCollection& font_collection =
UIDartState::Current()->window()->client()->GetFontCollection();
font_collection.LoadFontFromList(font_data.data(), font_data.num_elements(),
family_name);
font_data.Release();
tonic::DartInvoke(callback, { tonic::ToDart(0) });
}*/
} // namespace
//void _LoadFontFromList(Dart_NativeArguments args) {
// UIDartState::ThrowIfUIOperationsProhibited();
// tonic::DartCallStatic(LoadFontFromList, args);
//}
FontCollection::FontCollection()
: collection_(std::make_shared<txt::FontCollection>()) {
dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
collection_->SetDynamicFontManager(dynamic_font_manager_);
}
} // namespace
FontCollection::~FontCollection() {
collection_.reset();
SkGraphics::PurgeFontCache();
}
FontCollection::FontCollection()
: collection_(std::make_shared<txt::FontCollection>()) {
dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
collection_->SetDynamicFontManager(dynamic_font_manager_);
}
std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}
FontCollection::~FontCollection() {
collection_.reset();
SkGraphics::PurgeFontCache();
}
void FontCollection::SetupDefaultFontManager() {
collection_->SetupDefaultFontManager();
}
void FontCollection::RegisterFonts(
std::shared_ptr<AssetManager> asset_manager) {
std::unique_ptr<fml::Mapping> manifest_mapping =
asset_manager->GetAsMapping("FontManifest.json");
if (manifest_mapping == nullptr) {
FML_DLOG(WARNING) << "Could not find the font manifest in the asset store.";
return;
}
std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}
void FontCollection::SetupDefaultFontManager() {
collection_->SetupDefaultFontManager();
}
void FontCollection::RegisterFonts(
std::shared_ptr<AssetManager> asset_manager) {
std::unique_ptr<fml::Mapping> manifest_mapping =
asset_manager->GetAsMapping("FontManifest.json");
if (manifest_mapping == nullptr) {
FML_DLOG(WARNING) << "Could not find the font manifest in the asset store.";
return;
}
rapidjson::Document document;
static_assert(sizeof(decltype(document)::Ch) == sizeof(uint8_t), "");
document.Parse(reinterpret_cast<const decltype(document)::Ch*>(
manifest_mapping->GetMapping()),
manifest_mapping->GetSize());
if (document.HasParseError()) {
FML_DLOG(WARNING) << "Error parsing the font manifest in the asset store.";
return;
}
rapidjson::Document document;
static_assert(sizeof(decltype(document)::Ch) == sizeof(uint8_t), "");
document.Parse(reinterpret_cast<const decltype(document)::Ch*>(
manifest_mapping->GetMapping()),
manifest_mapping->GetSize());
// Structure described in https://flutter.io/custom-fonts/
if (document.HasParseError()) {
FML_DLOG(WARNING) << "Error parsing the font manifest in the asset store.";
return;
}
if (!document.IsArray()) {
return;
}
// Structure described in https://flutter.io/custom-fonts/
auto font_provider =
std::make_unique<AssetManagerFontProvider>(asset_manager);
if (!document.IsArray()) {
return;
}
for (const auto& family : document.GetArray()) {
auto family_name = family.FindMember("family");
if (family_name == family.MemberEnd() || !family_name->value.IsString()) {
continue;
}
auto font_provider =
std::make_unique<AssetManagerFontProvider>(asset_manager);
auto family_fonts = family.FindMember("fonts");
if (family_fonts == family.MemberEnd() || !family_fonts->value.IsArray()) {
continue;
}
for (const auto& family : document.GetArray()) {
auto family_name = family.FindMember("family");
if (family_name == family.MemberEnd() || !family_name->value.IsString()) {
continue;
}
for (const auto& family_font : family_fonts->value.GetArray()) {
if (!family_font.IsObject()) {
continue;
}
auto family_fonts = family.FindMember("fonts");
if (family_fonts == family.MemberEnd() || !family_fonts->value.IsArray()) {
continue;
}
auto font_asset = family_font.FindMember("asset");
if (font_asset == family_font.MemberEnd() ||
!font_asset->value.IsString()) {
continue;
}
for (const auto& family_font : family_fonts->value.GetArray()) {
if (!family_font.IsObject()) {
continue;
}
// TODO: Handle weights and styles.
font_provider->RegisterAsset(family_name->value.GetString(),
font_asset->value.GetString());
}
}
auto font_asset = family_font.FindMember("asset");
if (font_asset == family_font.MemberEnd() ||
!font_asset->value.IsString()) {
continue;
}
collection_->SetAssetFontManager(
sk_make_sp<txt::AssetFontManager>(std::move(font_provider)));
// TODO: Handle weights and styles.
font_provider->RegisterAsset(family_name->value.GetString(),
font_asset->value.GetString());
}
void FontCollection::LoadFontFromList(const uint8_t* font_data,
int length,
std::string family_name) {
std::unique_ptr<SkStreamAsset> font_stream =
std::make_unique<SkMemoryStream>(font_data, length, true);
sk_sp<SkTypeface> typeface =
SkTypeface::MakeFromStream(std::move(font_stream));
txt::TypefaceFontAssetProvider& font_provider =
dynamic_font_manager_->font_provider();
if (family_name.empty()) {
font_provider.RegisterTypeface(typeface);
}
else {
font_provider.RegisterTypeface(typeface, family_name);
}
collection_->ClearFontFamilyCache();
}
collection_->SetAssetFontManager(
sk_make_sp<txt::AssetFontManager>(std::move(font_provider)));
}
void FontCollection::LoadFontFromList(const uint8_t* font_data, int length,
std::string family_name) {
std::unique_ptr<SkStreamAsset> font_stream =
std::make_unique<SkMemoryStream>(font_data, length, true);
sk_sp<SkTypeface> typeface =
SkTypeface::MakeFromStream(std::move(font_stream));
txt::TypefaceFontAssetProvider& font_provider =
dynamic_font_manager_->font_provider();
if (family_name.empty()) {
font_provider.RegisterTypeface(typeface);
} else {
font_provider.RegisterTypeface(typeface, family_name);
}
collection_->ClearFontFamilyCache();
}
} // namespace flutter
} // namespace uiwidgets

33
engine/src/lib/ui/txt/font_collection.h


namespace uiwidgets {
class FontCollection {
public:
FontCollection();
class FontCollection {
public:
FontCollection();
~FontCollection();
~FontCollection();
//static void RegisterNatives(tonic::DartLibraryNatives* natives);
std::shared_ptr<txt::FontCollection> GetFontCollection() const;
std::shared_ptr<txt::FontCollection> GetFontCollection() const;
void SetupDefaultFontManager();
void SetupDefaultFontManager();
void RegisterFonts(std::shared_ptr<AssetManager> asset_manager);
void RegisterFonts(std::shared_ptr<AssetManager> asset_manager);
void LoadFontFromList(const uint8_t* font_data, int length,
std::string family_name);
void LoadFontFromList(const uint8_t* font_data,
int length,
std::string family_name);
private:
std::shared_ptr<txt::FontCollection> collection_;
sk_sp<txt::DynamicFontManager> dynamic_font_manager_;
private:
std::shared_ptr<txt::FontCollection> collection_;
sk_sp<txt::DynamicFontManager> dynamic_font_manager_;
FML_DISALLOW_COPY_AND_ASSIGN(FontCollection);
};
FML_DISALLOW_COPY_AND_ASSIGN(FontCollection);
};
} // namespace flutter
} // namespace uiwidgets

157
engine/src/lib/ui/txt/icu_util.cc


#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "unicode/udata.h"
namespace fml {
namespace icu2 {
namespace uiwidgets {
namespace icu {
class ICUContext {
public:
ICUContext(const std::string& icu_data_path) : valid_(false) {
valid_ = SetupMapping(icu_data_path) && SetupICU();
}
class ICUContext {
public:
ICUContext(const std::string& icu_data_path) : valid_(false) {
valid_ = SetupMapping(icu_data_path) && SetupICU();
}
ICUContext(std::unique_ptr<Mapping> mapping) : mapping_(std::move(mapping)) {
valid_ = SetupICU();
}
ICUContext(std::unique_ptr<fml::Mapping> mapping)
: mapping_(std::move(mapping)) {
valid_ = SetupICU();
}
~ICUContext() = default;
~ICUContext() = default;
bool SetupMapping(const std::string& icu_data_path) {
auto fd =
fml::OpenFile(icu_data_path.c_str(), false, fml::FilePermission::kRead);
bool SetupMapping(const std::string& icu_data_path) {
auto fd =
fml::OpenFile(icu_data_path.c_str(), false, fml::FilePermission::kRead);
if (!fd.is_valid()) {
auto directory = fml::paths::GetExecutableDirectoryPath();
if (!fd.is_valid()) {
auto directory = fml::paths::GetExecutableDirectoryPath();
if (!directory.first) {
return false;
}
if (!directory.first) {
return false;
}
std::string path_relative_to_executable =
paths::JoinPaths({ directory.second, icu_data_path });
std::string path_relative_to_executable =
fml::paths::JoinPaths({directory.second, icu_data_path});
fd = fml::OpenFile(path_relative_to_executable.c_str(), false,
fml::FilePermission::kRead);
}
fd = fml::OpenFile(path_relative_to_executable.c_str(), false,
fml::FilePermission::kRead);
}
if (!fd.is_valid()) {
return false;
}
if (!fd.is_valid()) {
return false;
}
std::initializer_list<FileMapping::Protection> protection = {
fml::FileMapping::Protection::kRead };
std::initializer_list<fml::FileMapping::Protection> protection = {
fml::FileMapping::Protection::kRead};
auto file_mapping =
std::make_unique<FileMapping>(fd, std::move(protection));
auto file_mapping =
std::make_unique<fml::FileMapping>(fd, std::move(protection));
if (file_mapping->GetSize() != 0) {
mapping_ = std::move(file_mapping);
return true;
}
if (file_mapping->GetSize() != 0) {
mapping_ = std::move(file_mapping);
return true;
}
return false;
}
return false;
}
bool SetupICU() {
if (GetSize() == 0) {
return false;
}
bool SetupICU() {
if (GetSize() == 0) {
return false;
}
UErrorCode err_code = U_ZERO_ERROR;
udata_setCommonData(GetMapping(), &err_code);
return (err_code == U_ZERO_ERROR);
//return true;
}
UErrorCode err_code = U_ZERO_ERROR;
udata_setCommonData(GetMapping(), &err_code);
return (err_code == U_ZERO_ERROR);
// return true;
}
const uint8_t* GetMapping() const {
return mapping_ ? mapping_->GetMapping() : nullptr;
}
const uint8_t* GetMapping() const {
return mapping_ ? mapping_->GetMapping() : nullptr;
}
size_t GetSize() const { return mapping_ ? mapping_->GetSize() : 0; }
size_t GetSize() const { return mapping_ ? mapping_->GetSize() : 0; }
bool IsValid() const { return valid_; }
bool IsValid() const { return valid_; }
private:
bool valid_;
std::unique_ptr<Mapping> mapping_;
private:
bool valid_;
std::unique_ptr<fml::Mapping> mapping_;
FML_DISALLOW_COPY_AND_ASSIGN(ICUContext);
};
FML_DISALLOW_COPY_AND_ASSIGN(ICUContext);
};
void InitializeICUOnce(const std::string& icu_data_path) {
static ICUContext* context = new ICUContext(icu_data_path);
FML_CHECK(context->IsValid())
<< "Must be able to initialize the ICU context. Tried: " << icu_data_path;
}
void InitializeICUOnce(const std::string& icu_data_path) {
static ICUContext* context = new ICUContext(icu_data_path);
FML_CHECK(context->IsValid())
<< "Must be able to initialize the ICU context. Tried: " << icu_data_path;
}
std::once_flag g_icu_init_flag;
void InitializeICU(const std::string& icu_data_path) {
std::call_once(g_icu_init_flag,
[&icu_data_path]() { InitializeICUOnce(icu_data_path); });
}
std::once_flag g_icu_init_flag;
void InitializeICU(const std::string& icu_data_path) {
std::call_once(g_icu_init_flag,
[&icu_data_path]() { InitializeICUOnce(icu_data_path); });
}
void InitializeICUFromMappingOnce(std::unique_ptr<Mapping> mapping) {
static ICUContext* context = new ICUContext(std::move(mapping));
FML_CHECK(context->IsValid())
<< "Unable to initialize the ICU context from a mapping.";
}
void InitializeICUFromMappingOnce(std::unique_ptr<fml::Mapping> mapping) {
static ICUContext* context = new ICUContext(std::move(mapping));
FML_CHECK(context->IsValid())
<< "Unable to initialize the ICU context from a mapping.";
}
void InitializeICUFromMapping(std::unique_ptr<Mapping> mapping) {
std::call_once(g_icu_init_flag, [mapping = std::move(mapping)]() mutable {
InitializeICUFromMappingOnce(std::move(mapping));
});
}
void InitializeICUFromMapping(std::unique_ptr<fml::Mapping> mapping) {
std::call_once(g_icu_init_flag, [mapping = std::move(mapping)]() mutable {
InitializeICUFromMappingOnce(std::move(mapping));
});
}
}
}
} // namespace icu
} // namespace uiwidgets

12
engine/src/lib/ui/txt/icu_util.h


#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"
namespace fml {
namespace icu2 {
namespace uiwidgets {
namespace icu {
void InitializeICU(const std::string& icu_data_path = "");
void InitializeICU(const std::string& icu_data_path = "");
void InitializeICUFromMapping(std::unique_ptr<Mapping> mapping);
void InitializeICUFromMapping(std::unique_ptr<fml::Mapping> mapping);
}
}
} // namespace icu
} // namespace uiwidgets

399
engine/src/lib/ui/txt/paragraph.cc


#include "lib/ui/ui_mono_state.h"
#include "utils.h"
#include <flutter\third_party\txt\src\txt\paragraph.h>
#include "flutter/third_party/txt/src/txt/paragraph.h"
#include "lib/ui/ui_mono_state.h"
Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraph(std::move(paragraph)) {}
Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraph(std::move(paragraph)) {}
Paragraph::~Paragraph() = default;
Paragraph::~Paragraph() = default;
size_t Paragraph::GetAllocationSize() {
// We don't have an accurate accounting of the paragraph's memory consumption,
// so return a fixed size to indicate that its impact is more than the size
// of the Paragraph class.
return 2000;
}
size_t Paragraph::GetAllocationSize() {
// We don't have an accurate accounting of the paragraph's memory consumption,
// so return a fixed size to indicate that its impact is more than the size
// of the Paragraph class.
return 2000;
}
double Paragraph::width() {
return m_paragraph->GetMaxWidth();
}
float Paragraph::width() { return m_paragraph->GetMaxWidth(); }
double Paragraph::height() {
return m_paragraph->GetHeight();
}
float Paragraph::height() { return m_paragraph->GetHeight(); }
double Paragraph::longestLine() {
return m_paragraph->GetLongestLine();
}
float Paragraph::longestLine() { return m_paragraph->GetLongestLine(); }
double Paragraph::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
float Paragraph::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
double Paragraph::maxIntrinsicWidth() {
return m_paragraph->GetMaxIntrinsicWidth();
}
float Paragraph::maxIntrinsicWidth() {
return m_paragraph->GetMaxIntrinsicWidth();
}
double Paragraph::alphabeticBaseline() {
return m_paragraph->GetAlphabeticBaseline();
}
float Paragraph::alphabeticBaseline() {
return m_paragraph->GetAlphabeticBaseline();
}
double Paragraph::ideographicBaseline() {
return m_paragraph->GetIdeographicBaseline();
}
float Paragraph::ideographicBaseline() {
return m_paragraph->GetIdeographicBaseline();
}
bool Paragraph::didExceedMaxLines() {
return m_paragraph->DidExceedMaxLines();
}
bool Paragraph::didExceedMaxLines() { return m_paragraph->DidExceedMaxLines(); }
void Paragraph::layout(double width) {
m_paragraph->Layout(width);
}
void Paragraph::layout(float width) { m_paragraph->Layout(width); }
void Paragraph::paint(Canvas * canvas, double x, double y) {
SkCanvas* sk_canvas = canvas->canvas();
if (!sk_canvas)
return;
m_paragraph->Paint(sk_canvas, x, y);
}
void Paragraph::paint(Canvas* canvas, float x, float y) {
SkCanvas* sk_canvas = canvas->canvas();
if (!sk_canvas) return;
m_paragraph->Paint(sk_canvas, x, y);
}
static Float32List EncodeTextBoxes(
const std::vector<txt::Paragraph::TextBox> & boxes) {
// Layout:
// First value is the number of values.
// Then there are boxes.size() groups of 5 which are LTRBD, where D is the
// text direction index.
Float32List result = {
new float[boxes.size() * 5],
boxes.size() * 5
};
static void EncodeTextBoxes(const std::vector<txt::Paragraph::TextBox>& boxes,
float* result) {
// Layout:
// First value is the number of values.
// Then there are boxes.size() groups of 5 which are LTRBD, where D is the
// text direction index.
unsigned long position = 0;
for (unsigned long i = 0; i < boxes.size(); i++) {
const txt::Paragraph::TextBox& box = boxes[i];
result.data[position++] = box.rect.fLeft;
result.data[position++] = box.rect.fTop;
result.data[position++] = box.rect.fRight;
result.data[position++] = box.rect.fBottom;
result.data[position++] = static_cast<float>(box.direction);
}
return result;
}
unsigned long position = 0;
for (unsigned long i = 0; i < boxes.size(); i++) {
const txt::Paragraph::TextBox& box = boxes[i];
result[position++] = box.rect.fLeft;
result[position++] = box.rect.fTop;
result[position++] = box.rect.fRight;
result[position++] = box.rect.fBottom;
result[position++] = static_cast<float>(box.direction);
}
}
Float32List Paragraph::getRectsForRange(unsigned start,
unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle) {
std::vector<txt::Paragraph::TextBox> boxes = m_paragraph->GetRectsForRange(
start, end, static_cast<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
return EncodeTextBoxes(boxes);
}
int Paragraph::getRectsForRangeSize(unsigned start, unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle) {
std::vector<txt::Paragraph::TextBox> boxes = m_paragraph->GetRectsForRange(
start, end, static_cast<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
return boxes.size() * 5;
}
Float32List Paragraph::getRectsForPlaceholders() {
std::vector<txt::Paragraph::TextBox> boxes =
m_paragraph->GetRectsForPlaceholders();
return EncodeTextBoxes(boxes);
void Paragraph::getRectsForRange(float* data, unsigned start, unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle) {
std::vector<txt::Paragraph::TextBox> boxes = m_paragraph->GetRectsForRange(
start, end, static_cast<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
EncodeTextBoxes(boxes, data);
}
int Paragraph::getRectsForPlaceholdersSize() {
std::vector<txt::Paragraph::TextBox> boxes =
m_paragraph->GetRectsForPlaceholders();
return boxes.size() * 5;
}
void Paragraph::getRectsForPlaceholders(float* data) {
std::vector<txt::Paragraph::TextBox> boxes =
m_paragraph->GetRectsForPlaceholders();
return EncodeTextBoxes(boxes, data);
}
void Paragraph::getPositionForOffset(float dx, float dy, int* offset) {
txt::Paragraph::PositionWithAffinity pos =
m_paragraph->GetGlyphPositionAtCoordinate(dx, dy);
offset[0] = pos.position;
offset[1] = static_cast<int>(pos.affinity);
}
void Paragraph::getWordBoundary(unsigned offset, int* boundaryPtr) {
txt::Paragraph::Range<size_t> point = m_paragraph->GetWordBoundary(offset);
boundaryPtr[0] = point.start;
boundaryPtr[1] = point.end;
}
void Paragraph::getLineBoundary(unsigned offset, int* boundaryPtr) {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
int line_start = -1;
int line_end = -1;
for (txt::LineMetrics& line : metrics) {
if (offset >= line.start_index && offset <= line.end_index) {
line_start = line.start_index;
line_end = line.end_index;
break;
}
boundaryPtr[0] = line_start;
boundaryPtr[1] = line_end;
}
SizeTList Paragraph::getPositionForOffset(double dx, double dy) {
SizeTList result = {
new size_t[2],
2
};
txt::Paragraph::PositionWithAffinity pos =
m_paragraph->GetGlyphPositionAtCoordinate(dx, dy);
result.data[0] = pos.position;
result.data[1] = static_cast<int>(pos.affinity);
return result;
}
int Paragraph::computeLineMetricsSize() {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
// Layout:
// boxes.size() groups of 9 which are the line metrics
// properties
return metrics.size() * 9;
}
void Paragraph::computeLineMetrics(float* result) {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
SizeTList Paragraph::getWordBoundary(unsigned offset) {
txt::Paragraph::Range<size_t> point = m_paragraph->GetWordBoundary(offset);
SizeTList result = {
new size_t[2],
2
};
result.data[0] = point.start;
result.data[1] = point.end;
return result;
}
// Layout:
// boxes.size() groups of 9 which are the line metrics
// properties
unsigned long position = 0;
for (unsigned long i = 0; i < metrics.size(); i++) {
const txt::LineMetrics& line = metrics[i];
result[position++] = static_cast<float>(line.hard_break);
result[position++] = line.ascent;
result[position++] = line.descent;
result[position++] = line.unscaled_ascent;
// We add then round to get the height. The
// definition of height here is different
// than the one in LibTxt.
result[position++] = round(line.ascent + line.descent);
result[position++] = line.width;
result[position++] = line.left;
result[position++] = line.baseline;
result[position++] = static_cast<float>(line.line_number);
}
}
SizeTList Paragraph::getLineBoundary(unsigned offset) {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
int line_start = -1;
int line_end = -1;
for (txt::LineMetrics& line : metrics) {
if (offset >= line.start_index && offset <= line.end_index) {
line_start = line.start_index;
line_end = line.end_index;
break;
}
}
SizeTList result = {
new size_t[2],
2
};
result.data[0] = line_start;
result.data[1] = line_end;
return result;
}
UIWIDGETS_API(float) Paragraph_width(Paragraph* ptr) { return ptr->width(); }
Float32List Paragraph::computeLineMetrics() {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
UIWIDGETS_API(float) Paragraph_height(Paragraph* ptr) { return ptr->height(); }
// Layout:
// boxes.size() groups of 9 which are the line metrics
// properties
Float32List result = {
new float[metrics.size() * 9],
2
};
unsigned long position = 0;
for (unsigned long i = 0; i < metrics.size(); i++) {
const txt::LineMetrics& line = metrics[i];
result.data[position++] = static_cast<double>(line.hard_break);
result.data[position++] = line.ascent;
result.data[position++] = line.descent;
result.data[position++] = line.unscaled_ascent;
// We add then round to get the height. The
// definition of height here is different
// than the one in LibTxt.
result.data[position++] = round(line.ascent + line.descent);
result.data[position++] = line.width;
result.data[position++] = line.left;
result.data[position++] = line.baseline;
result.data[position++] = static_cast<double>(line.line_number);
}
UIWIDGETS_API(float) Paragraph_longestLine(Paragraph* ptr) {
return ptr->longestLine();
}
return result;
}
UIWIDGETS_API(float) Paragraph_minIntrinsicWidth(Paragraph* ptr) {
return ptr->minIntrinsicWidth();
}
UIWIDGETS_API(double) Paragraph_width(Paragraph* ptr) {
return ptr->width();
}
UIWIDGETS_API(float) Paragraph_maxIntrinsicWidth(Paragraph* ptr) {
return ptr->maxIntrinsicWidth();
}
UIWIDGETS_API(double) Paragraph_height(Paragraph* ptr) {
return ptr->height();
}
UIWIDGETS_API(float) Paragraph_alphabeticBaseline(Paragraph* ptr) {
return ptr->alphabeticBaseline();
}
UIWIDGETS_API(double) Paragraph_longestLine(Paragraph* ptr) {
return ptr->longestLine();
}
UIWIDGETS_API(float) Paragraph_ideographicBaseline(Paragraph* ptr) {
return ptr->ideographicBaseline();
}
UIWIDGETS_API(double) Paragraph_minIntrinsicWidth(Paragraph* ptr) {
return ptr->minIntrinsicWidth();
}
UIWIDGETS_API(bool) Paragraph_didExceedMaxLines(Paragraph* ptr) {
return ptr->didExceedMaxLines();
}
UIWIDGETS_API(double) Paragraph_maxIntrinsicWidth(Paragraph* ptr) {
return ptr->maxIntrinsicWidth();
}
UIWIDGETS_API(void) Paragraph_layout(Paragraph* ptr, float width) {
ptr->layout(width);
}
UIWIDGETS_API(double) Paragraph_alphabeticBaseline(Paragraph* ptr) {
return ptr->alphabeticBaseline();
}
UIWIDGETS_API(int)
Paragraph_getRectsForRangeSize(Paragraph* ptr, int start, int end,
int boxHeightStyle, int boxWidthStyle) {
return ptr->getRectsForRangeSize(start, end, boxHeightStyle, boxWidthStyle);
}
UIWIDGETS_API(double) Paragraph_ideographicBaseline(Paragraph* ptr) {
return ptr->ideographicBaseline();
}
UIWIDGETS_API(void)
Paragraph_getRectsForRange(Paragraph* ptr, float* data, int start, int end,
int boxHeightStyle, int boxWidthStyle) {
ptr->getRectsForRange(data, start, end, boxHeightStyle, boxWidthStyle);
}
UIWIDGETS_API(bool) Paragraph_didExceedMaxLines(Paragraph* ptr) {
return ptr->didExceedMaxLines();
}
UIWIDGETS_API(int)
Paragraph_getRectsForPlaceholdersSize(Paragraph* ptr) {
return ptr->getRectsForPlaceholdersSize();
}
UIWIDGETS_API(void) Paragraph_layout(Paragraph* ptr, double width) {
ptr->layout(width);
}
UIWIDGETS_API(void)
Paragraph_getRectsForPlaceholders(Paragraph* ptr, float* data) {
ptr->getRectsForPlaceholders(data);
}
UIWIDGETS_API(Float32List) Paragraph_getRectsForRange(Paragraph* ptr, int start, int end, int boxHeightStyle, int boxWidthStyle) {
return ptr->getRectsForRange(start, end, boxHeightStyle, boxWidthStyle);
}
UIWIDGETS_API(void)
Paragraph_getPositionForOffset(Paragraph* ptr, float dx, float dy,
int* offset) {
return ptr->getPositionForOffset(dx, dy, offset);
}
UIWIDGETS_API(Float32List) Paragraph_getRectsForPlaceholders(Paragraph* ptr) {
return ptr->getRectsForPlaceholders();
}
UIWIDGETS_API(SizeTList) Paragraph_getPositionForOffset(Paragraph* ptr, double dx, double dy) {
return ptr->getPositionForOffset(dx, dy);
}
UIWIDGETS_API(void)
Paragraph_getWordBoundary(Paragraph* ptr, int offset, int* boundaryPtr) {
ptr->getWordBoundary(offset, boundaryPtr);
}
UIWIDGETS_API(SizeTList) Paragraph_getWordBoundary(Paragraph* ptr, int offset) {
return ptr->getWordBoundary(offset);
}
UIWIDGETS_API(void)
Paragraph_getLineBoundary(Paragraph* ptr, int offset, int* boundaryPtr) {
ptr->getLineBoundary(offset, boundaryPtr);
}
UIWIDGETS_API(SizeTList) Paragraph_getLineBoundary(Paragraph* ptr, int offset) {
return ptr->getLineBoundary(offset);
}
UIWIDGETS_API(void)
Paragraph_paint(Paragraph* ptr, Canvas* canvas, float x, float y) {
ptr->paint(canvas, x, y);
}
UIWIDGETS_API(void) Paragraph_paint(Paragraph* ptr, Canvas* canvas, double x, double y) {
ptr->paint(canvas, x, y);
}
UIWIDGETS_API(int) Paragraph_computeLineMetricsSize(Paragraph* ptr) {
return ptr->computeLineMetricsSize();
}
UIWIDGETS_API(Float32List) Paragraph_computeLineMetrics(Paragraph* ptr) {
return ptr->computeLineMetrics();
}
UIWIDGETS_API(void) Paragraph_computeLineMetrics(Paragraph* ptr, float* data) {
ptr->computeLineMetrics(data);
}
UIWIDGETS_API(void) Paragraph_dispose(Paragraph* ptr) {
ptr->Release();
}
}
UIWIDGETS_API(void) Paragraph_dispose(Paragraph* ptr) { ptr->Release(); }
} // namespace uiwidgets

76
engine/src/lib/ui/txt/paragraph.h


#pragma once
#include <flutter/fml/memory/ref_counted.h>
#include <src\lib\ui\painting\canvas.h>
#include <flutter\third_party\txt\src\txt\paragraph.h>
#include "utils.h"
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/third_party/txt/src/txt/paragraph.h"
#include "src/lib/ui/painting/canvas.h"
class Paragraph : public fml::RefCountedThreadSafe<Paragraph> {
FML_FRIEND_MAKE_REF_COUNTED(Paragraph);
class Paragraph : public fml::RefCountedThreadSafe<Paragraph> {
FML_FRIEND_MAKE_REF_COUNTED(Paragraph);
public:
static fml::RefPtr<Paragraph> Create();
static fml::RefPtr<Paragraph> Create(std::unique_ptr<txt::Paragraph> txt_paragraph) {
return fml::MakeRefCounted<Paragraph>(std::move(txt_paragraph));
}
public:
static fml::RefPtr<Paragraph> Create();
~Paragraph();
static fml::RefPtr<Paragraph> Create(
std::unique_ptr<txt::Paragraph> txt_paragraph) {
return fml::MakeRefCounted<Paragraph>(std::move(txt_paragraph));
}
~Paragraph();
double width();
double height();
double longestLine();
double minIntrinsicWidth();
double maxIntrinsicWidth();
double alphabeticBaseline();
double ideographicBaseline();
bool didExceedMaxLines();
float width();
float height();
float longestLine();
float minIntrinsicWidth();
float maxIntrinsicWidth();
float alphabeticBaseline();
float ideographicBaseline();
bool didExceedMaxLines();
void layout(double width);
void paint(Canvas* canvas, double x, double y);
void layout(float width);
void paint(Canvas* canvas, float x, float y);
Float32List getRectsForRange(unsigned start,
unsigned end,
unsigned boxHeightStyle,
unsigned boxWidthStyle);
Float32List getRectsForPlaceholders();
SizeTList getPositionForOffset(double dx, double dy);
SizeTList getWordBoundary(unsigned offset);
SizeTList getLineBoundary(unsigned offset);
Float32List computeLineMetrics();
int getRectsForRangeSize(unsigned start, unsigned end,
unsigned boxHeightStyle, unsigned boxWidthStyle);
void getRectsForRange(float* data, unsigned start, unsigned end,
unsigned boxHeightStyle, unsigned boxWidthStyle);
int getRectsForPlaceholdersSize();
void getRectsForPlaceholders(float* data);
void getPositionForOffset(float dx, float dy, int* offset);
void getWordBoundary(unsigned offset, int* boundaryPtr);
void getLineBoundary(unsigned offset, int* boundaryPtr);
int computeLineMetricsSize();
void computeLineMetrics(float* data);
size_t GetAllocationSize();
std::unique_ptr<txt::Paragraph> m_paragraph;
private:
size_t GetAllocationSize();
std::unique_ptr<txt::Paragraph> m_paragraph;
explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);
};
private:
explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);
};
} // namespace uiwidgets

880
engine/src/lib/ui/txt/paragraph_builder.cc


#include "lib/ui/ui_mono_state.h"
#include "lib/ui/ui_mono_state.h"
#include "TestLoadICU.h"
namespace {
// TextStyle
const int tsColorIndex = 1;
const int tsTextDecorationIndex = 2;
const int tsTextDecorationColorIndex = 3;
const int tsTextDecorationStyleIndex = 4;
const int tsFontWeightIndex = 5;
const int tsFontStyleIndex = 6;
const int tsTextBaselineIndex = 7;
const int tsTextDecorationThicknessIndex = 8;
const int tsFontFamilyIndex = 9;
const int tsFontSizeIndex = 10;
const int tsLetterSpacingIndex = 11;
const int tsWordSpacingIndex = 12;
const int tsHeightIndex = 13;
const int tsLocaleIndex = 14;
const int tsBackgroundIndex = 15;
const int tsForegroundIndex = 16;
const int tsTextShadowsIndex = 17;
const int tsFontFeaturesIndex = 18;
const int tsColorMask = 1 << tsColorIndex;
const int tsTextDecorationMask = 1 << tsTextDecorationIndex;
const int tsTextDecorationColorMask = 1 << tsTextDecorationColorIndex;
const int tsTextDecorationStyleMask = 1 << tsTextDecorationStyleIndex;
const int tsTextDecorationThicknessMask = 1 << tsTextDecorationThicknessIndex;
const int tsFontWeightMask = 1 << tsFontWeightIndex;
const int tsFontStyleMask = 1 << tsFontStyleIndex;
const int tsTextBaselineMask = 1 << tsTextBaselineIndex;
const int tsFontFamilyMask = 1 << tsFontFamilyIndex;
const int tsFontSizeMask = 1 << tsFontSizeIndex;
const int tsLetterSpacingMask = 1 << tsLetterSpacingIndex;
const int tsWordSpacingMask = 1 << tsWordSpacingIndex;
const int tsHeightMask = 1 << tsHeightIndex;
const int tsLocaleMask = 1 << tsLocaleIndex;
const int tsBackgroundMask = 1 << tsBackgroundIndex;
const int tsForegroundMask = 1 << tsForegroundIndex;
const int tsTextShadowsMask = 1 << tsTextShadowsIndex;
const int tsFontFeaturesMask = 1 << tsFontFeaturesIndex;
namespace {
const int tsColorIndex = 1;
const int tsTextDecorationIndex = 2;
const int tsTextDecorationColorIndex = 3;
const int tsTextDecorationStyleIndex = 4;
const int tsFontWeightIndex = 5;
const int tsFontStyleIndex = 6;
const int tsTextBaselineIndex = 7;
const int tsTextDecorationThicknessIndex = 8;
const int tsFontFamilyIndex = 9;
const int tsFontSizeIndex = 10;
const int tsLetterSpacingIndex = 11;
const int tsWordSpacingIndex = 12;
const int tsHeightIndex = 13;
const int tsLocaleIndex = 14;
const int tsBackgroundIndex = 15;
const int tsForegroundIndex = 16;
const int tsTextShadowsIndex = 17;
const int tsFontFeaturesIndex = 18;
// ParagraphStyle
const int tsColorMask = 1 << tsColorIndex;
const int tsTextDecorationMask = 1 << tsTextDecorationIndex;
const int tsTextDecorationColorMask = 1 << tsTextDecorationColorIndex;
const int tsTextDecorationStyleMask = 1 << tsTextDecorationStyleIndex;
const int tsTextDecorationThicknessMask = 1 << tsTextDecorationThicknessIndex;
const int tsFontWeightMask = 1 << tsFontWeightIndex;
const int tsFontStyleMask = 1 << tsFontStyleIndex;
const int tsTextBaselineMask = 1 << tsTextBaselineIndex;
const int tsFontFamilyMask = 1 << tsFontFamilyIndex;
const int tsFontSizeMask = 1 << tsFontSizeIndex;
const int tsLetterSpacingMask = 1 << tsLetterSpacingIndex;
const int tsWordSpacingMask = 1 << tsWordSpacingIndex;
const int tsHeightMask = 1 << tsHeightIndex;
const int tsLocaleMask = 1 << tsLocaleIndex;
const int tsBackgroundMask = 1 << tsBackgroundIndex;
const int tsForegroundMask = 1 << tsForegroundIndex;
const int tsTextShadowsMask = 1 << tsTextShadowsIndex;
const int tsFontFeaturesMask = 1 << tsFontFeaturesIndex;
const int psTextAlignIndex = 1;
const int psTextDirectionIndex = 2;
const int psFontWeightIndex = 3;
const int psFontStyleIndex = 4;
const int psMaxLinesIndex = 5;
const int psTextHeightBehaviorIndex = 6;
const int psFontFamilyIndex = 7;
const int psFontSizeIndex = 8;
const int psHeightIndex = 9;
const int psStrutStyleIndex = 10;
const int psEllipsisIndex = 11;
const int psLocaleIndex = 12;
// ParagraphStyle
const int psTextAlignMask = 1 << psTextAlignIndex;
const int psTextDirectionMask = 1 << psTextDirectionIndex;
const int psFontWeightMask = 1 << psFontWeightIndex;
const int psFontStyleMask = 1 << psFontStyleIndex;
const int psMaxLinesMask = 1 << psMaxLinesIndex;
const int psFontFamilyMask = 1 << psFontFamilyIndex;
const int psFontSizeMask = 1 << psFontSizeIndex;
const int psHeightMask = 1 << psHeightIndex;
const int psTextHeightBehaviorMask = 1 << psTextHeightBehaviorIndex;
const int psStrutStyleMask = 1 << psStrutStyleIndex;
const int psEllipsisMask = 1 << psEllipsisIndex;
const int psLocaleMask = 1 << psLocaleIndex;
const int psTextAlignIndex = 1;
const int psTextDirectionIndex = 2;
const int psFontWeightIndex = 3;
const int psFontStyleIndex = 4;
const int psMaxLinesIndex = 5;
const int psTextHeightBehaviorIndex = 6;
const int psFontFamilyIndex = 7;
const int psFontSizeIndex = 8;
const int psHeightIndex = 9;
const int psStrutStyleIndex = 10;
const int psEllipsisIndex = 11;
const int psLocaleIndex = 12;
// TextShadows decoding
const int psTextAlignMask = 1 << psTextAlignIndex;
const int psTextDirectionMask = 1 << psTextDirectionIndex;
const int psFontWeightMask = 1 << psFontWeightIndex;
const int psFontStyleMask = 1 << psFontStyleIndex;
const int psMaxLinesMask = 1 << psMaxLinesIndex;
const int psFontFamilyMask = 1 << psFontFamilyIndex;
const int psFontSizeMask = 1 << psFontSizeIndex;
const int psHeightMask = 1 << psHeightIndex;
const int psTextHeightBehaviorMask = 1 << psTextHeightBehaviorIndex;
const int psStrutStyleMask = 1 << psStrutStyleIndex;
const int psEllipsisMask = 1 << psEllipsisIndex;
const int psLocaleMask = 1 << psLocaleIndex;
constexpr uint32_t kColorDefault = 0xFF000000;
constexpr uint32_t kBytesPerShadow = 16;
constexpr uint32_t kShadowPropertiesCount = 4;
constexpr uint32_t kColorOffset = 0;
constexpr uint32_t kXOffset = 1;
constexpr uint32_t kYOffset = 2;
constexpr uint32_t kBlurOffset = 3;
// TextShadows decoding
// FontFeature decoding
constexpr uint32_t kBytesPerFontFeature = 8;
constexpr uint32_t kFontFeatureTagLength = 4;
constexpr uint32_t kColorDefault = 0xFF000000;
constexpr uint32_t kBytesPerShadow = 16;
constexpr uint32_t kShadowPropertiesCount = 4;
constexpr uint32_t kColorOffset = 0;
constexpr uint32_t kXOffset = 1;
constexpr uint32_t kYOffset = 2;
constexpr uint32_t kBlurOffset = 3;
// Strut decoding
const int sFontWeightIndex = 0;
const int sFontStyleIndex = 1;
const int sFontFamilyIndex = 2;
const int sFontSizeIndex = 3;
const int sHeightIndex = 4;
const int sLeadingIndex = 5;
const int sForceStrutHeightIndex = 6;
// FontFeature decoding
constexpr uint32_t kBytesPerFontFeature = 8;
constexpr uint32_t kFontFeatureTagLength = 4;
const int sFontWeightMask = 1 << sFontWeightIndex;
const int sFontStyleMask = 1 << sFontStyleIndex;
const int sFontFamilyMask = 1 << sFontFamilyIndex;
const int sFontSizeMask = 1 << sFontSizeIndex;
const int sHeightMask = 1 << sHeightIndex;
const int sLeadingMask = 1 << sLeadingIndex;
const int sForceStrutHeightMask = 1 << sForceStrutHeightIndex;
// Strut decoding
const int sFontWeightIndex = 0;
const int sFontStyleIndex = 1;
const int sFontFamilyIndex = 2;
const int sFontSizeIndex = 3;
const int sHeightIndex = 4;
const int sLeadingIndex = 5;
const int sForceStrutHeightIndex = 6;
} // namespace
const int sFontWeightMask = 1 << sFontWeightIndex;
const int sFontStyleMask = 1 << sFontStyleIndex;
const int sFontFamilyMask = 1 << sFontFamilyIndex;
const int sFontSizeMask = 1 << sFontSizeIndex;
const int sHeightMask = 1 << sHeightIndex;
const int sLeadingMask = 1 << sLeadingIndex;
const int sForceStrutHeightMask = 1 << sForceStrutHeightIndex;
fml::RefPtr<ParagraphBuilder> ParagraphBuilder::create(
int* encoded,
uint8_t* strutData,
int strutDataSize,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies,
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale) {
return fml::MakeRefCounted<ParagraphBuilder>(encoded, strutData, strutDataSize, fontFamily,
strutFontFamilies, fontSize,
height, ellipsis, locale);
}
} // namespace
void decodeTextShadows(uint8_t* shadows_data, int shadow_data_size,
std::vector<txt::TextShadow>& decoded_shadows) {
decoded_shadows.clear();
fml::RefPtr<ParagraphBuilder> ParagraphBuilder::create(
int* encoded, uint8_t* strutData, int strutDataSize,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies, float fontSize,
float height, const std::u16string& ellipsis, const std::string& locale) {
return fml::MakeRefCounted<ParagraphBuilder>(
encoded, strutData, strutDataSize, fontFamily, strutFontFamilies,
fontSize, height, ellipsis, locale);
}
FML_CHECK(shadow_data_size % kBytesPerShadow == 0);
const uint32_t* uint_data = reinterpret_cast<const uint32_t*>(shadows_data);
const float* float_data = reinterpret_cast<const float*>(shadows_data);
void decodeTextShadows(uint8_t* shadows_data, int shadow_data_size,
std::vector<txt::TextShadow>& decoded_shadows) {
decoded_shadows.clear();
size_t shadow_count = shadow_data_size / kBytesPerShadow;
size_t shadow_count_offset = 0;
for (size_t shadow_index = 0; shadow_index < shadow_count; ++shadow_index) {
shadow_count_offset = shadow_index * kShadowPropertiesCount;
SkColor color =
uint_data[shadow_count_offset + kColorOffset] ^ kColorDefault;
decoded_shadows.emplace_back(
color,
SkPoint::Make(float_data[shadow_count_offset + kXOffset],
float_data[shadow_count_offset + kYOffset]),
float_data[shadow_count_offset + kBlurOffset]);
}
}
FML_CHECK(shadow_data_size % kBytesPerShadow == 0);
const uint32_t* uint_data = reinterpret_cast<const uint32_t*>(shadows_data);
const float* float_data = reinterpret_cast<const float*>(shadows_data);
void decodeStrut(uint8_t* strut_data, int struct_data_size,
const std::vector<std::string>& strut_font_families,
txt::ParagraphStyle& paragraph_style) {
if (strut_data == nullptr) {
return;
}
size_t shadow_count = shadow_data_size / kBytesPerShadow;
size_t shadow_count_offset = 0;
for (size_t shadow_index = 0; shadow_index < shadow_count; ++shadow_index) {
shadow_count_offset = shadow_index * kShadowPropertiesCount;
SkColor color =
uint_data[shadow_count_offset + kColorOffset] ^ kColorDefault;
decoded_shadows.emplace_back(
color,
SkPoint::Make(float_data[shadow_count_offset + kXOffset],
float_data[shadow_count_offset + kYOffset]),
float_data[shadow_count_offset + kBlurOffset]);
}
}
if (struct_data_size == 0) {
return;
}
paragraph_style.strut_enabled = true;
void decodeStrut(uint8_t* strut_data, int struct_data_size,
const std::vector<std::string>& strut_font_families,
txt::ParagraphStyle& paragraph_style) {
if (strut_data == nullptr) {
return;
}
const uint8_t* uint8_data = static_cast<const uint8_t*>(strut_data);
uint8_t mask = uint8_data[0];
if (struct_data_size == 0) {
return;
}
paragraph_style.strut_enabled = true;
// Data is stored in order of increasing size, eg, 8 bit ints will be before
// any 32 bit ints. In addition, the order of decoding is the same order
// as it is encoded, and the order is used to maintain consistency.
size_t byte_count = 1;
if (mask & sFontWeightMask) {
paragraph_style.strut_font_weight =
static_cast<txt::FontWeight>(uint8_data[byte_count++]);
}
if (mask & sFontStyleMask) {
paragraph_style.strut_font_style =
static_cast<txt::FontStyle>(uint8_data[byte_count++]);
}
const uint8_t* uint8_data = static_cast<const uint8_t*>(strut_data);
uint8_t mask = uint8_data[0];
std::vector<float> float_data;
float_data.resize((struct_data_size - byte_count) / 4);
memcpy(float_data.data(),
reinterpret_cast<const char*>(strut_data) + byte_count,
struct_data_size - byte_count);
size_t float_count = 0;
if (mask & sFontSizeMask) {
paragraph_style.strut_font_size = float_data[float_count++];
}
if (mask & sHeightMask) {
paragraph_style.strut_height = float_data[float_count++];
paragraph_style.strut_has_height_override = true;
}
if (mask & sLeadingMask) {
paragraph_style.strut_leading = float_data[float_count++];
}
if (mask & sForceStrutHeightMask) {
// The boolean is stored as the last bit in the bitmask.
paragraph_style.force_strut_height = (mask & 1 << 7) != 0;
}
// Data is stored in order of increasing size, eg, 8 bit ints will be before
// any 32 bit ints. In addition, the order of decoding is the same order
// as it is encoded, and the order is used to maintain consistency.
size_t byte_count = 1;
if (mask & sFontWeightMask) {
paragraph_style.strut_font_weight =
static_cast<txt::FontWeight>(uint8_data[byte_count++]);
}
if (mask & sFontStyleMask) {
paragraph_style.strut_font_style =
static_cast<txt::FontStyle>(uint8_data[byte_count++]);
}
if (mask & sFontFamilyMask) {
paragraph_style.strut_font_families = strut_font_families;
}
else {
// Provide an empty font name so that the platform default font will be
// used.
paragraph_style.strut_font_families.push_back("");
}
}
std::vector<float> float_data;
float_data.resize((struct_data_size - byte_count) / 4);
memcpy(float_data.data(),
reinterpret_cast<const char*>(strut_data) + byte_count,
struct_data_size - byte_count);
size_t float_count = 0;
if (mask & sFontSizeMask) {
paragraph_style.strut_font_size = float_data[float_count++];
}
if (mask & sHeightMask) {
paragraph_style.strut_height = float_data[float_count++];
paragraph_style.strut_has_height_override = true;
}
if (mask & sLeadingMask) {
paragraph_style.strut_leading = float_data[float_count++];
}
if (mask & sForceStrutHeightMask) {
// The boolean is stored as the last bit in the bitmask.
paragraph_style.force_strut_height = (mask & 1 << 7) != 0;
}
ParagraphBuilder::ParagraphBuilder(
int* encoded,
uint8_t* strutData,
int strutData_size,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies,
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale) {
if (mask & sFontFamilyMask) {
paragraph_style.strut_font_families = strut_font_families;
} else {
// Provide an empty font name so that the platform default font will be
// used.
paragraph_style.strut_font_families.push_back("");
}
}
int32_t mask = encoded[0];
txt::ParagraphStyle style;
ParagraphBuilder::ParagraphBuilder(
int* encoded, uint8_t* strutData, int strutData_size,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies, float fontSize,
float height, const std::u16string& ellipsis, const std::string& locale) {
int32_t mask = encoded[0];
txt::ParagraphStyle style;
if (mask & psTextAlignMask) {
style.text_align = txt::TextAlign(encoded[psTextAlignIndex]);
}
if (mask & psTextAlignMask) {
style.text_align = txt::TextAlign(encoded[psTextAlignIndex]);
}
if (mask & psTextDirectionMask) {
style.text_direction = txt::TextDirection(encoded[psTextDirectionIndex]);
}
if (mask & psTextDirectionMask) {
style.text_direction = txt::TextDirection(encoded[psTextDirectionIndex]);
}
if (mask & psFontWeightMask) {
style.font_weight =
static_cast<txt::FontWeight>(encoded[psFontWeightIndex]);
}
if (mask & psFontWeightMask) {
style.font_weight =
static_cast<txt::FontWeight>(encoded[psFontWeightIndex]);
}
if (mask & psFontStyleMask) {
style.font_style = static_cast<txt::FontStyle>(encoded[psFontStyleIndex]);
}
if (mask & psFontStyleMask) {
style.font_style = static_cast<txt::FontStyle>(encoded[psFontStyleIndex]);
}
if (mask & psFontFamilyMask) {
style.font_family = fontFamily;
}
if (mask & psFontFamilyMask) {
style.font_family = fontFamily;
}
if (mask & psFontSizeMask) {
style.font_size = fontSize;
}
if (mask & psFontSizeMask) {
style.font_size = fontSize;
}
if (mask & psHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & psHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & psTextHeightBehaviorMask) {
style.text_height_behavior = encoded[psTextHeightBehaviorIndex];
}
if (mask & psTextHeightBehaviorMask) {
style.text_height_behavior = encoded[psTextHeightBehaviorIndex];
}
if (mask & psStrutStyleMask) {
decodeStrut(strutData, strutData_size, strutFontFamilies, style);
}
if (mask & psStrutStyleMask) {
decodeStrut(strutData, strutData_size, strutFontFamilies, style);
}
if (mask & psMaxLinesMask) {
style.max_lines = encoded[psMaxLinesIndex];
}
if (mask & psMaxLinesMask) {
style.max_lines = encoded[psMaxLinesIndex];
}
if (mask & psEllipsisMask) {
style.ellipsis = ellipsis;
}
if (mask & psEllipsisMask) {
style.ellipsis = ellipsis;
}
if (mask & psLocaleMask) {
style.locale = locale;
}
if (mask & psLocaleMask) {
style.locale = locale;
}
FontCollection& font_collection =
UIMonoState::Current()->window()->client()->GetFontCollection();
FontCollection& font_collection =
UIMonoState::Current()->window()->client()->GetFontCollection();
m_paragraphBuilder =
FLUTTER_PARAGRAPH_BUILDER(style, font_collection.GetFontCollection());
}
m_paragraphBuilder =
FLUTTER_PARAGRAPH_BUILDER(style, font_collection.GetFontCollection());
}
ParagraphBuilder::~ParagraphBuilder() = default;
ParagraphBuilder::~ParagraphBuilder() = default;
void decodeFontFeatures(uint8_t* font_features_data, int font_features_data_size,
txt::FontFeatures& font_features) {
uint8_t* byte_data(font_features_data);
FML_CHECK(font_features_data_size % kBytesPerFontFeature == 0);
void decodeFontFeatures(uint8_t* font_features_data,
int font_features_data_size,
txt::FontFeatures& font_features) {
uint8_t* byte_data(font_features_data);
FML_CHECK(font_features_data_size % kBytesPerFontFeature == 0);
size_t feature_count = font_features_data_size / kBytesPerFontFeature;
const char* char_data = reinterpret_cast<const char*>(font_features_data);
for (size_t feature_index = 0; feature_index < feature_count;
++feature_index) {
size_t feature_offset = feature_index * kBytesPerFontFeature;
const char* feature_bytes =
char_data + feature_offset;
std::string tag(feature_bytes, kFontFeatureTagLength);
int32_t value = *(reinterpret_cast<const int32_t*>(feature_bytes +
kFontFeatureTagLength));
font_features.SetFeature(tag, value);
}
}
void ParagraphBuilder::pushStyle(
int* encoded,
int encodedSize,
char** fontFamilies,
int fontFamiliesSize,
double fontSize,
double letterSpacing,
double wordSpacing,
double height,
double decorationThickness,
const std::string& locale,
void** background_objects,
uint8_t* background_data,
void** foreground_objects,
uint8_t* foreground_data,
uint8_t* shadows_data,
int shadow_data_size,
uint8_t* font_features_data,
int font_feature_data_size) {
size_t feature_count = font_features_data_size / kBytesPerFontFeature;
const char* char_data = reinterpret_cast<const char*>(font_features_data);
FML_DCHECK(encodedSize == 8);
for (size_t feature_index = 0; feature_index < feature_count;
++feature_index) {
size_t feature_offset = feature_index * kBytesPerFontFeature;
const char* feature_bytes = char_data + feature_offset;
std::string tag(feature_bytes, kFontFeatureTagLength);
int32_t value = *(reinterpret_cast<const int32_t*>(feature_bytes +
kFontFeatureTagLength));
font_features.SetFeature(tag, value);
}
}
int32_t mask = encoded[0];
void ParagraphBuilder::pushStyle(
int* encoded, int encodedSize, char** fontFamilies, int fontFamiliesSize,
float fontSize, float letterSpacing, float wordSpacing, float height,
float decorationThickness, const std::string& locale,
void** background_objects, uint8_t* background_data,
void** foreground_objects, uint8_t* foreground_data, uint8_t* shadows_data,
int shadow_data_size, uint8_t* font_features_data,
int font_feature_data_size) {
FML_DCHECK(encodedSize == 8);
// Set to use the properties of the previous style if the property is not
// explicitly given.
txt::TextStyle style = m_paragraphBuilder->PeekStyle();
int32_t mask = encoded[0];
// Only change the style property from the previous value if a new explicitly
// set value is available
if (mask & tsColorMask) {
style.color = encoded[tsColorIndex];
}
// Set to use the properties of the previous style if the property is not
// explicitly given.
txt::TextStyle style = m_paragraphBuilder->PeekStyle();
if (mask & tsTextDecorationMask) {
style.decoration =
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
}
// Only change the style property from the previous value if a new explicitly
// set value is available
if (mask & tsColorMask) {
style.color = encoded[tsColorIndex];
}
if (mask & tsTextDecorationColorMask) {
style.decoration_color = encoded[tsTextDecorationColorIndex];
}
if (mask & tsTextDecorationMask) {
style.decoration =
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
}
if (mask & tsTextDecorationStyleMask) {
style.decoration_style = static_cast<txt::TextDecorationStyle>(
encoded[tsTextDecorationStyleIndex]);
}
if (mask & tsTextDecorationColorMask) {
style.decoration_color = encoded[tsTextDecorationColorIndex];
}
if (mask & tsTextDecorationThicknessMask) {
style.decoration_thickness_multiplier = decorationThickness;
}
if (mask & tsTextDecorationStyleMask) {
style.decoration_style = static_cast<txt::TextDecorationStyle>(
encoded[tsTextDecorationStyleIndex]);
}
if (mask & tsTextBaselineMask) {
// TODO(abarth): Implement TextBaseline. The CSS version of this
// property wasn't wired up either.
}
if (mask & tsTextDecorationThicknessMask) {
style.decoration_thickness_multiplier = decorationThickness;
}
if (mask & (tsFontWeightMask | tsFontStyleMask | tsFontSizeMask |
tsLetterSpacingMask | tsWordSpacingMask)) {
if (mask & tsFontWeightMask)
style.font_weight =
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
if (mask & tsTextBaselineMask) {
// TODO(abarth): Implement TextBaseline. The CSS version of this
// property wasn't wired up either.
}
if (mask & tsFontStyleMask)
style.font_style = static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
if (mask & (tsFontWeightMask | tsFontStyleMask | tsFontSizeMask |
tsLetterSpacingMask | tsWordSpacingMask)) {
if (mask & tsFontWeightMask)
style.font_weight =
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
if (mask & tsFontSizeMask)
style.font_size = fontSize;
if (mask & tsFontStyleMask)
style.font_style = static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
if (mask & tsLetterSpacingMask)
style.letter_spacing = letterSpacing;
if (mask & tsFontSizeMask) style.font_size = fontSize;
if (mask & tsWordSpacingMask)
style.word_spacing = wordSpacing;
}
if (mask & tsLetterSpacingMask) style.letter_spacing = letterSpacing;
if (mask & tsHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & tsWordSpacingMask) style.word_spacing = wordSpacing;
}
if (mask & tsLocaleMask) {
style.locale = locale;
}
if (mask & tsHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & tsBackgroundMask) {
Paint background(background_objects, background_data);
if (background.paint()) {
style.has_background = true;
style.background = *background.paint();
}
}
if (mask & tsLocaleMask) {
style.locale = locale;
}
if (mask & tsForegroundMask) {
Paint foreground(foreground_objects, foreground_data);
if (foreground.paint()) {
style.has_foreground = true;
style.foreground = *foreground.paint();
}
}
if (mask & tsBackgroundMask) {
Paint background(background_objects, background_data);
if (background.paint()) {
style.has_background = true;
style.background = *background.paint();
}
}
if (mask & tsTextShadowsMask) {
decodeTextShadows(shadows_data, shadow_data_size, style.text_shadows);
}
if (mask & tsForegroundMask) {
Paint foreground(foreground_objects, foreground_data);
if (foreground.paint()) {
style.has_foreground = true;
style.foreground = *foreground.paint();
}
}
if (mask & tsFontFamilyMask) {
// The child style's font families override the parent's font families.
// If the child's fonts are not available, then the font collection will
// use the system fallback fonts (not the parent's fonts).
style.font_families = std::vector<std::string>(fontFamilies, fontFamilies + fontFamiliesSize);
}
if (mask & tsTextShadowsMask) {
decodeTextShadows(shadows_data, shadow_data_size, style.text_shadows);
}
if (mask & tsFontFeaturesMask) {
decodeFontFeatures(font_features_data, font_feature_data_size, style.font_features);
}
if (mask & tsFontFamilyMask) {
// The child style's font families override the parent's font families.
// If the child's fonts are not available, then the font collection will
// use the system fallback fonts (not the parent's fonts).
style.font_families =
std::vector<std::string>(fontFamilies, fontFamilies + fontFamiliesSize);
}
m_paragraphBuilder->PushStyle(style);
}
if (mask & tsFontFeaturesMask) {
decodeFontFeatures(font_features_data, font_feature_data_size,
style.font_features);
}
void ParagraphBuilder::pop() {
m_paragraphBuilder->Pop();
}
m_paragraphBuilder->PushStyle(style);
}
const char* ParagraphBuilder::addText(const std::u16string& text) {
if (text.empty())
return nullptr;
void ParagraphBuilder::pop() { m_paragraphBuilder->Pop(); }
// Use ICU to validate the UTF-16 input. Calling u_strToUTF8 with a null
// output buffer will return U_BUFFER_OVERFLOW_ERROR if the input is well
// formed.
const UChar* text_ptr = reinterpret_cast<const UChar*>(text.data());
UErrorCode error_code = U_ZERO_ERROR;
u_strToUTF8(nullptr, 0, nullptr, text_ptr, text.size(), &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR)
return "string is not well-formed UTF-16";
const char* ParagraphBuilder::addText(const std::u16string& text) {
if (text.empty()) return nullptr;
m_paragraphBuilder->AddText(text);
// Use ICU to validate the UTF-16 input. Calling u_strToUTF8 with a null
// output buffer will return U_BUFFER_OVERFLOW_ERROR if the input is well
// formed.
const UChar* text_ptr = reinterpret_cast<const UChar*>(text.data());
UErrorCode error_code = U_ZERO_ERROR;
u_strToUTF8(nullptr, 0, nullptr, text_ptr, text.size(), &error_code);
if (error_code != U_BUFFER_OVERFLOW_ERROR)
return "string is not well-formed UTF-16";
return nullptr;
}
m_paragraphBuilder->AddText(text);
fml::RefPtr<Paragraph> ParagraphBuilder::build(/*Dart_Handle paragraph_handle*/) {
return Paragraph::Create(/*paragraph_handle,*/ m_paragraphBuilder->Build());
}
return nullptr;
}
const char* ParagraphBuilder::addPlaceholder(
double width,
double height,
unsigned alignment,
double baseline_offset,
unsigned baseline) {
txt::PlaceholderRun placeholder_run(
width, height, static_cast<txt::PlaceholderAlignment>(alignment),
static_cast<txt::TextBaseline>(baseline), baseline_offset);
fml::RefPtr<Paragraph> ParagraphBuilder::build(
/*Dart_Handle paragraph_handle*/) {
return Paragraph::Create(/*paragraph_handle,*/ m_paragraphBuilder->Build());
}
m_paragraphBuilder->AddPlaceholder(placeholder_run);
const char* ParagraphBuilder::addPlaceholder(float width, float height,
unsigned alignment,
float baseline_offset,
unsigned baseline) {
txt::PlaceholderRun placeholder_run(
width, height, static_cast<txt::PlaceholderAlignment>(alignment),
static_cast<txt::TextBaseline>(baseline), baseline_offset);
return nullptr;
}
m_paragraphBuilder->AddPlaceholder(placeholder_run);
UIWIDGETS_API(ParagraphBuilder*) ParagraphBuilder_constructor(
int* encoded,
int encodedSize,
uint8_t* structData,
int structDataSize,
char* fontFamily,
char** structFontFamily,
int structFontFamilySize,
double fontSize,
double height,
char16_t* ellipsis,
char* locale) {
std::string fontFamily_s= fontFamily ? std::string(fontFamily) : "";
auto structFamily_v = structFontFamily ? std::vector<std::string>(structFontFamily, structFontFamily + structFontFamilySize) : std::vector<std::string>();
auto ellipsis_s = ellipsis ? std::u16string(ellipsis) : u"";
auto local_s = locale ? std::string(locale) : "";
fml::RefPtr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::create(
encoded,
structData,
structDataSize,
fontFamily_s,
structFamily_v,
fontSize,
height,
ellipsis_s,
local_s
);
paragraphBuilder->AddRef();
return paragraphBuilder.get();
}
return nullptr;
}
UIWIDGETS_API(void) ParagraphBuilder_dispose(Canvas* ptr) { ptr->Release(); }
UIWIDGETS_API(ParagraphBuilder*)
ParagraphBuilder_constructor(int* encoded, int encodedSize, uint8_t* structData,
int structDataSize, char* fontFamily,
char** structFontFamily, int structFontFamilySize,
float fontSize, float height, char16_t* ellipsis,
char* locale) {
std::string fontFamily_s = fontFamily ? std::string(fontFamily) : "";
auto structFamily_v =
structFontFamily
? std::vector<std::string>(structFontFamily,
structFontFamily + structFontFamilySize)
: std::vector<std::string>();
auto ellipsis_s = ellipsis ? std::u16string(ellipsis) : u"";
auto local_s = locale ? std::string(locale) : "";
fml::RefPtr<ParagraphBuilder> paragraphBuilder = ParagraphBuilder::create(
encoded, structData, structDataSize, fontFamily_s, structFamily_v,
fontSize, height, ellipsis_s, local_s);
paragraphBuilder->AddRef();
return paragraphBuilder.get();
}
UIWIDGETS_API(void) ParagraphBuilder_pushStyle(
ParagraphBuilder* ptr,
int* encoded,
int encodedSize,
char** fontFamilies,
int fontFamiliesSize,
double* fontSize,
double* letterSpacing,
double* wordSpacing,
double* height,
double* decorationThickness,
char* locale,
void** background_objects,
uint8_t* background_data,
void** foreground_objects,
uint8_t* foreground_data,
uint8_t* shadows_data,
int shadow_data_size,
uint8_t* font_features_data,
int font_feature_data_size
) {
UIWIDGETS_API(void) ParagraphBuilder_dispose(Canvas* ptr) { ptr->Release(); }
ptr->pushStyle(encoded,
encodedSize,
fontFamilies,
fontFamiliesSize,
*fontSize,
*letterSpacing,
*wordSpacing,
*height,
*decorationThickness,
locale,
background_objects,
background_data,
foreground_objects,
foreground_data,
shadows_data,
shadow_data_size,
font_features_data,
font_feature_data_size
);
}
UIWIDGETS_API(void) ParagraphBuilder_pop(ParagraphBuilder* ptr) {
ptr->pop();
}
UIWIDGETS_API(void)
ParagraphBuilder_pushStyle(ParagraphBuilder* ptr, int* encoded, int encodedSize,
char** fontFamilies, int fontFamiliesSize,
float fontSize, float letterSpacing,
float wordSpacing, float height,
float decorationThickness, char* locale,
void** background_objects, uint8_t* background_data,
void** foreground_objects, uint8_t* foreground_data,
uint8_t* shadows_data, int shadow_data_size,
uint8_t* font_features_data,
int font_feature_data_size) {
ptr->pushStyle(encoded, encodedSize, fontFamilies, fontFamiliesSize, fontSize,
letterSpacing, wordSpacing, height, decorationThickness,
locale, background_objects, background_data,
foreground_objects, foreground_data, shadows_data,
shadow_data_size, font_features_data, font_feature_data_size);
}
UIWIDGETS_API(void) ParagraphBuilder_pop(ParagraphBuilder* ptr) { ptr->pop(); }
UIWIDGETS_API(const char*) ParagraphBuilder_addText(ParagraphBuilder* ptr, char16_t* text) {
return ptr->addText(std::u16string(text));
}
UIWIDGETS_API(const char*)
ParagraphBuilder_addText(ParagraphBuilder* ptr, char16_t* text) {
return ptr->addText(std::u16string(text));
}
UIWIDGETS_API(const char*) ParagraphBuilder_addPlaceholder(ParagraphBuilder* ptr, float width, float height, int alignment, float baselineOffset, unsigned baseline) {
return ptr->addPlaceholder(width, height, alignment, baselineOffset, baseline);
}
UIWIDGETS_API(const char*)
ParagraphBuilder_addPlaceholder(ParagraphBuilder* ptr, float width,
float height, int alignment,
float baselineOffset, unsigned baseline) {
return ptr->addPlaceholder(width, height, alignment, baselineOffset,
baseline);
}
UIWIDGETS_API(Paragraph*) ParagraphBuilder_build(ParagraphBuilder* ptr/*, IntPtr outParagraph*/) {
auto paragraph = ptr->build();
paragraph->AddRef();
return paragraph.get();
}
}
UIWIDGETS_API(Paragraph*)
ParagraphBuilder_build(ParagraphBuilder* ptr /*, IntPtr outParagraph*/) {
auto paragraph = ptr->build();
paragraph->AddRef();
return paragraph.get();
}
} // namespace uiwidgets

88
engine/src/lib/ui/txt/paragraph_builder.h


#pragma once
#include <flutter/fml/memory/ref_counted.h>
#include <src\lib\ui\painting\canvas.h>
#include <flutter\third_party\txt\src\txt\paragraph.h>
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/third_party/txt/src/txt/paragraph.h"
#include "utils.h"
#include "src/lib/ui/painting/canvas.h"
class ParagraphBuilder : public fml::RefCountedThreadSafe<ParagraphBuilder> {
FML_FRIEND_MAKE_REF_COUNTED(ParagraphBuilder);
class ParagraphBuilder : public fml::RefCountedThreadSafe<ParagraphBuilder> {
FML_FRIEND_MAKE_REF_COUNTED(ParagraphBuilder);
public:
static fml::RefPtr<ParagraphBuilder> create(int* encoded, uint8_t* structData, int structDataSize, const std::string& fontFamily, const std::vector<std::string>& strutFontFamilies, double fontSize, double height, const std::u16string& ellipsis, const std::string& locale);
void pushStyle(
int* encoded,
int encodedSize,
char** fontFamilies,
int fontFamiliesSize,
double fontSize,
double letterSpacing,
double wordSpacing,
double height,
double decorationThickness,
const std::string& locale,
void** background_objects,
uint8_t* background_data,
void** foreground_objects,
uint8_t* foreground_data,
uint8_t* shadows_data,
int shadow_data_size,
uint8_t* font_features_data,
int font_feature_data_size);
public:
static fml::RefPtr<ParagraphBuilder> create(
int* encoded, uint8_t* structData, int structDataSize,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies, float fontSize,
float height, const std::u16string& ellipsis, const std::string& locale);
const char* addText(const std::u16string& text);
const char* addPlaceholder(
double width,
double height,
unsigned alignment,
double baseline_offset,
unsigned baseline);
fml::RefPtr<Paragraph> build(/*Dart_Handle paragraph_handle*/);
~ParagraphBuilder();
void pushStyle(int* encoded, int encodedSize, char** fontFamilies,
int fontFamiliesSize, float fontSize, float letterSpacing,
float wordSpacing, float height, float decorationThickness,
const std::string& locale, void** background_objects,
uint8_t* background_data, void** foreground_objects,
uint8_t* foreground_data, uint8_t* shadows_data,
int shadow_data_size, uint8_t* font_features_data,
int font_feature_data_size);
void pop();
const char* addText(const std::u16string& text);
const char* addPlaceholder(float width, float height, unsigned alignment,
float baseline_offset, unsigned baseline);
fml::RefPtr<Paragraph> build(/*Dart_Handle paragraph_handle*/);
~ParagraphBuilder();
private:
explicit ParagraphBuilder(
int* encoded,
uint8_t* strutData,
int strutData_size,
const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies,
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale);
void pop();
std::unique_ptr<txt::ParagraphBuilder> m_paragraphBuilder;
};
}
private:
explicit ParagraphBuilder(int* encoded, uint8_t* strutData,
int strutData_size, const std::string& fontFamily,
const std::vector<std::string>& strutFontFamilies,
float fontSize, float height,
const std::u16string& ellipsis,
const std::string& locale);
std::unique_ptr<txt::ParagraphBuilder> m_paragraphBuilder;
};
} // namespace uiwidgets

1
engine/src/render_api.h


virtual void SetImageTexture(void* ptr) = 0;
virtual void Draw() = 0;
virtual void Draw2(uiwidgets::Paragraph* paragraph) = 0;
virtual void PreDraw() = 0;

10
engine/src/render_api_d3d11.cc


void SetImageTexture(void* ptr) override;
void Draw() override;
void Draw2(uiwidgets::Paragraph* paragraph) override;
void PreDraw() override;
void PostDraw() override;

void draw(SkCanvas* canvas);
void draw2(SkCanvas* canvas, uiwidgets::Paragraph* paragraph);
private:
ID3D11Device* m_Device;

canvas->getGrContext()->submit(true);
// if (rdoc_api) rdoc_api->EndFrameCapture(m_DeviceSkia, NULL);
}
void RenderAPI_D3D11::Draw2(uiwidgets::Paragraph* paragraph) {
SkCanvas* canvas = m_SkSurface->getCanvas();
canvas->drawColor(SK_ColorWHITE);
paragraph->m_paragraph->Paint(canvas, 10, 150);
canvas->flush();
canvas->getGrContext()->submit(true);
}
void RenderAPI_D3D11::PreDraw() {

18
engine/src/shell/common/shell.cc


#define RAPIDJSON_HAS_STDSTRING 1
#include "shell.h"
#include <filesystem>
#include <future>
#include <memory>
#include <sstream>

#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
#include "flutter/fml/unique_fd.h"
#include "lib/ui/txt/icu_util.h"
#include "lib/ui/txt/icu_util.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "runtime/start_up.h"

}
if (settings.icu_initialization_required) {
char* icudata = std::getenv("UIWIDGETS_ICUDATA");
fml::icu2::InitializeICU(icudata);
if (settings.icu_data_path.length() > 0) {
uiwidgets::icu::InitializeICU(settings.icu_data_path);
}
}
});
}

weak_platform_view_ = platform_view_->GetWeakPtr();
fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(),
[engine = weak_engine_] {
if (engine) {
engine->SetupDefaultFontManager();
}
});
[engine = weak_engine_] {
if (engine) {
engine->SetupDefaultFontManager();
}
});
is_setup_ = true;

3
engine/src/shell/platform/unity/uiwidgets_panel.cc


args.struct_size = sizeof(UIWidgetsProjectArgs);
args.assets_path = streaming_assets_path;
args.icu_data_path = "";
std::string icu_path = std::string(streaming_assets_path) + "/icudtl.dat";
args.icu_data_path = icu_path.c_str();
args.command_line_argc = 0;
args.command_line_argv = nullptr;

186
Samples/UIWidgetsSamples_2019_4/Assets/TextTest.cs


using System;
using System.IO;
using Unity.UIWidgets.async2;
using Unity.UIWidgets.engine2;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.ui2;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui2.Canvas;
using Color = Unity.UIWidgets.ui2.Color;
using Paint = Unity.UIWidgets.ui2.Paint;
using ParagraphBuilder = Unity.UIWidgets.ui2.ParagraphBuilder;
using ParagraphConstraints = Unity.UIWidgets.ui2.ParagraphConstraints;
using ParagraphStyle = Unity.UIWidgets.ui2.ParagraphStyle;
using Picture = Unity.UIWidgets.ui2.Picture;
using PictureRecorder = Unity.UIWidgets.ui2.PictureRecorder;
using Rect = Unity.UIWidgets.ui.Rect;
using SceneBuilder = Unity.UIWidgets.ui2.SceneBuilder;
using TextDecoration = Unity.UIWidgets.ui2.TextDecoration;
using TextDecorationStyle = Unity.UIWidgets.ui2.TextDecorationStyle;
using TextPosition = Unity.UIWidgets.ui2.TextPosition;
using Window = Unity.UIWidgets.ui2.Window;
class TextTest : UIWidgetsPanel
{
private bool check = true;
void beginFrame(TimeSpan timeStamp)
{
// The timeStamp argument to beginFrame indicates the timing information we
// should use to clock our animations. It's important to use timeStamp rather
// than reading the system time because we want all the parts of the system to
// coordinate the timings of their animations. If each component read the
// system clock independently, the animations that we processed later would be
// slightly ahead of the animations we processed earlier.
// PAINT
Rect paintBounds = Offset.zero & (Window.instance.physicalSize / Window.instance.devicePixelRatio);
PictureRecorder recorder = new PictureRecorder();
Canvas canvas = new Canvas(recorder, paintBounds);
canvas.translate(paintBounds.width / 2.0f, paintBounds.height / 2.0f);
// Here we determine the rotation according to the timeStamp given to us by
// the engine.
float t = (float) timeStamp.TotalMilliseconds / 1800.0f;
canvas.rotate(Mathf.PI * (t % 2.0f));
var paint = new Paint();
paint.color = Color.fromARGB(100, 100, 100, 0);
canvas.drawRect(Rect.fromLTRB(0, 0, 100.0f, 100.0f), paint);
Draw(canvas);
Picture picture = recorder.endRecording();
// COMPOSITE
float devicePixelRatio = Window.instance.devicePixelRatio;
var deviceTransform = new float[16];
deviceTransform[0] = devicePixelRatio;
deviceTransform[5] = devicePixelRatio;
deviceTransform[10] = 1.0f;
deviceTransform[15] = 1.0f;
SceneBuilder sceneBuilder = new SceneBuilder();
sceneBuilder.pushTransform(deviceTransform);
sceneBuilder.addPicture(Offset.zero, picture);
sceneBuilder.pop();
Window.instance.render(sceneBuilder.build());
// After rendering the current frame of the animation, we ask the engine to
// schedule another frame. The engine will call beginFrame again when its time
// to produce the next frame.
Window.instance.scheduleFrame();
}
void Draw(Canvas canvas)
{
if (check)
{
var robot_regular_bold = File.ReadAllBytes("./Assets/StreamingAssets/Roboto-BlackItalic.ttf");
ui_.loadFontFromList(robot_regular_bold, "Roboto-RegularB").then(value =>
{
Debug.Log("finish loading");
return FutureOr.nil;
});
var robot_regular = File.ReadAllBytes("./Assets/StreamingAssets/Roboto-Italic.ttf");
ui_.loadFontFromList(robot_regular, "Roboto-Regular");
var ranchers = File.ReadAllBytes("./Assets/StreamingAssets/Ranchers-Regular.ttf");
ui_.loadFontFromList(ranchers, "ranchers");
check = false;
}
var style = new ParagraphStyle(fontFamily: "Arial", height: 4);
var pb = new ParagraphBuilder(style);
var ts_roboto_regular = new TextStyle(
color: new Color(0xF000000F),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "Roboto-Regular",
fontSize: 30,
height: 1.5f
);
pb.pushStyle(ts_roboto_regular);
pb.addText("just for test\n");
var ts_roboto_regular_bold = new TextStyle(
color: new Color(0xF000000F),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "Roboto-RegularB",
fontSize: 30,
height: 1.5f
);
pb.pushStyle(ts_roboto_regular_bold);
pb.addText("just for test\n");
var ts_rachers = new TextStyle(
color: new Color(0xF000000F),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "ranchers",
fontSize: 30,
height: 1.5f
);
pb.pushStyle(ts_rachers);
pb.addText("just for test\n");
var ts = new TextStyle(
color: new Color(0xFFFF00F0),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "Arial",
fontSize: 30,
height: 1.5f
);
pb.pushStyle(ts);
pb.addText("just for test\n 中文测试 分段测试 分段测试 分段测试 分段测试 分段测试 分段测试 分段测试\n1234");
var ts2 = new TextStyle(
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.dashed,
fontFamily: "Arial",
fontSize: 40,
height: 1.5f,
background: new Paint()
{
color = new Color(0xAAFF7F00),
},
foreground: new Paint()
{
color = new Color(0xAAFFFF00)
}
);
pb.pushStyle(ts2);
pb.addText("test push one more style");
pb.pop();
pb.addText("test pop style");
var p = pb.build();
p.layout(new ParagraphConstraints(300));
var wordBoundary = p.getWordBoundary(new TextPosition(10));
Debug.Log(wordBoundary);
var positionForOffset = p.getPositionForOffset(new Offset(10, 1));
Debug.Log(positionForOffset);
var lineBoundary = p.getLineBoundary(new TextPosition(10));
Debug.Log(lineBoundary);
foreach (var textBox in p.getBoxesForPlaceholders())
{
Debug.Log($"{textBox.bottom} {textBox.direction} {textBox.left} {textBox.right}");
}
foreach (var textBox in p.getBoxesForRange(1, 20))
{
Debug.Log($"{textBox.bottom} {textBox.direction} {textBox.left} {textBox.right}");
}
foreach (var lineMetrics in p.computeLineMetrics())
{
Debug.Log($"{lineMetrics.height} {lineMetrics.lineNumber}");
}
canvas.drawParagraph(p, new Offset(-100, -100));
}
protected override void main()
{
Window.instance.onBeginFrame = beginFrame;
Window.instance.scheduleFrame();
}
}

825
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Ranchers-Regular.ttf


GPOS)'^W��o�GSUB��� �OS/2krSo��`cmapE�1���cvt ��l0fpgmAy����Igasp��glyf0٬� {�head�/wM�86hheaN��\$hmtxT?c�p�loca���]|�xmaxp��|� name���U��tpost�nu��
qprep|m�q�a�3T @ +!!T��\~��V��7��!�$B@$#"!
+@* !5'"'#�;+33#3267#".54>5#3K�MO $.
<<�t���)+/; /41
,ac@+K�PX@  !5"#@$ !5""#Y�;+>3.#"#65� "%% %#�VL  C#(N!#���#�
���a(@@  ((+@*!'"'#�;+2&#"3267#".54>-;0!0(
%,87DjJ'$Ima'*#'!G$#I$ +PsGCsR/
��zaBn@ 42#  +K�PX@%.!'"'#@,.!5'"'#Y�;+>32".#"#".'.54>732654.'.546R"N(9  /'<K$$%$  
( !1
=M  =2,>( '  
  
#2$*T�Ka"y@!+K�PX@+!5"'"#@/!5""'"#Y�;+3>32#"&'#32654.#"�$O'-L7 "<Q/(I��-#&5 %0U1!-PnBDuV0"�)26*"6
��a"s@!+K�PX@&!'"'#@.!"'""'#Y�;+!#5#".54>325332654.#"��$P&-L7 ";Q/)J���-#&5  $01,OnADvW1#2�)26*"6
��I"w@!+K�PX@*!"'"'#@.!"'""'#Y�;+!#5#".54>32332654.#"��$P&-L7 ";Q/)J���-#&5  $01,OnADvW1#%� )26*"6 ���I-@  +@7'#�;+#2#".54>�1y3''( (8����%($)!�I@
 +@ "#�;+#>5<&45��I����DS5!X��D_NI/��I"y@!+K�PX@+!53""#@/!53"""#Y�;+3>32#"&'#32654.#"�I)/Q;" 7L-&P$��-#&5 %0I��#1WvDAnO,1i)26*"6���V#_@## +K�PX@!5"#@!!5""#Y�;+!5#".'.5332>53 D#)"�  �5# 5���#
 1!IIH LZ^$ ���a$+J@&%)(%+&+$$+@,!)'"'#�;+32>7#"&'.54>7632'"3.� <5%$ Na-\+&1
(>*39<`�&�';+6 A 5*&CGD(WOB0*(bB�#,('
�@a!1�@0.&$ +K�PX@9!'"'"'#K�$PX@=!"'"'"'#@;!)"'"'#YY�;+%#".54>3253#"&'5326532>54.#"t&?%2R;!%AV1I4��k-Q"IIBE�,$!  $0F)If=BsW2=2��Y|$jq{%84@)2#"6a2(@  +@ "'#�;+7!65<'����2��yR*!@ !C#�&�Az9
�Ka"w@!+K�PX@*!'"'"#@.!"'"'"#Y�;+#5#".54>325332654.#"��$P&-L7 ";Q/)J���-#&5  $0��,OnADvW1#2�)26*"6�a+�@++!   +K�PX@!!5"#K�"PX@%!5""#@+!53""#YY�;+>32>32#4&#"#4&#"#<645<&45�C&$<I+AE�"�#�V5 " !Sb�T3%!!��''$#��JLEOZ[&"I =@  +@%!)'"#�;+#535467>32.#"3##<.- F/'   QO�@�HBN!$4*T������@�>,p@$",,+K�PX@&!'""'#@)!5'"'#Y�;+#".'.546732653'2#".54>� Y�A'%( (&=B *)7�%'$(! ���a 6@     +@'"'#�;+2#"&5462>54.#"�ziiz{ii{
))
a���������!":$!�I=@
+@#!)""#�;+#'##65<&'337蠫�����V�����9<B&{1�=L0\�w_(��V:@
+@!"'#�;+# #332673327�r�21�t�)
1�4 'V��.��V��>��*> �V1@+@'"'#�;+3.546?#.5467!3��z��06�34&,"�77���V +@ +@"'#�;+#3327ʇ���:
6V��V��*>���K�V 1@
+@!"'#�;+#73327�Η/��7 9V���E��/#���V:@
+@ !)"#�;+7"#332>?3#'.� (����&

%����( � k,*i!!i����k ��A> %2R@1.*(%"
+@< 2& !)'"'#�;+232654&#">454&'>3 #"&32654&#"�
6@75�8v/I<aZ��%[j
(?AE= )(! �X.WUV.��^�?Y
qg��(%&(
���>)@@!
))+@* !'"'#�;+2&#"3267#".54>�$5&52C)/?%58:X�a30_�> &1%:E*J7
#L$&H$ :m�`\�q?��g>0@@(%00 +@*$!'"'#�;+>32#"&'>454&"32>54.9h%X�8320c�fg>�
 %?/)C/0>:�_]�l<.WUV.��9/]/477 7J*G:'���5':@#"! +@$)' "' #�;+."#><54&4&5:>7#3#3�\ii('^b^)ɯ��FZi8L��`  !##t�p0<Q�66@
+@)' "#�;+3><5<&'2>7#3#'^b^)ɧ�Mi~BB�rZ>��2bVE
��5>'M@''%" +@5&!5'"'#�;+#".54>32&#"3:7556S\�d52c�b*=1?7J-.E/ ��::m�`\�q? &2%:G!&H8"��2%3@%%  +@) "#�;+#>7##>45<&4533<&45������2?pmo?J�p<�T;�Q,\j~MDcRM/S�H.KEC'M2%7@%% +@' "'#�;+54&5#.5467!#3!.5467cJ4IL���@Z&,.-,C�PM$F$#G##G#$F$��`26@
 +@$ !' "'#�;+#"&'.546732>=#5!` g^E!('�(�G^<" K\ "G#$H$
,F0ī��2
6@ +@
!) "#�;+#3#'#3�����3d22��WJ �2&@

+@' "#�;+##>5<'#5!�s�s�yY�jDS5!,_o�N9T#�)>)E@))$" +@-&!)'"#�;+32>54.#">54&'>32#"&'�! #%�1c0ExY4,OnC� %'�~_�Uy�n;iRLkCH�H�21@ +@' "'#�;+3&5467!.5467!! �����+26�(5&+#�P77 �`S>+�@#!++
+K�PX@/!5'"'"#@/!58'"'#Y�;+23.'#".5462>54.#"0��SNC.9&A4)KnH"�� 1  1 /!!/>�ʮ� �)59m�f����3G++I66I*+G3��@3++@++"  +@ "'#�;+#".54>733265<.'6%=Z>@[>%�,9:)3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR��#2%@ +@ ! "#�;+3#>73~���¦p2��-DS5!A�]����72#@+@! "#�;+3#3������s2��2����*2 +@
+@ ! "#�;+3# #37��z�WW�~�?r�q2����J2��(���22@  +@!5 "#�;+##>54&'33#�]y��jw����.�z�vg�gg�g�+����� ��S> !6@!!  +@'"'#�;+2#".5462>54.#"0����KnH"�� 1  1 /!!/>����9m�f����3G++I66I*+G3 ���>B3@
:8(&+@!4!'"'#�;+4>32.#"#".'.54>732654.1K[* %)+ 0,1(,EU*782 *12 $6?6$g@S1-5
)9K1@X7 &.0,
'&+:O92'@
 +@! "#�;+3##>54&'3���ԉ��2������g�gg�g���!2 )@
+@ ! "#�;+3# #3n����ih����e2�~�QE��������.>#6@## +@'"'#�;+2#".5462>54.#"&BcB!��CdB!�' '('>8k�c��8k�b����7I*)F44H*)H6w<%@
+@'#�;+3!.54673<&45&5<>7)T��Sj<@z��d>>>== =*\\X& +, # �>-3@
*( +@!!5"'#�;+%!54>54.#".5467>32�'<F<+�H"4;4" #@-1/%WJ2g7O=1.3
A ?=�7P;-+. (<-1S���>MK@MJDB64" +@5+@!5)"'#�;+&54732654.#".54>7>32#".'.546732654.#*n  94 #$"  ,21-UB('/7-0M`/42-N((;,%p!2 
0 1I1&D6' -F1B^<3;%,1  �2 (9@"!  +@(!) "#�;+3##>7!.5<7>735<&45�::��� $+,'Z�2<mih60 ?�'R, >!0KTYO?�P;O;0���25O@55/.'%! +@5)!53' "'#�;+>32#".'.546732654&#"654&'!�+4X@#'JkD12-F(8BC;(B�s*&BY24cN/,(3**.yy;~:02��?2+F@#!+++@*!5' "'#�;+>32#".54>7"32>54.�Ki :0N.$3Sh52`K-:S47(.(, 
2N�K!'h2JpL'#HoL=���5�T5,&9#"1>*F@" **+@*!5'"'#�;+3>7#".54>322654&#"{Lj:BY63Sh52`K-:S45(.(, 
N�K 1JV&JqL'#IoL=���5�5,&9#"
�2(@  +@' "#�;+3.5467!#���(+*% i
3;.5#$aovtj+��,>#3AP@54%$;94A5A+)$3%3## +@.!)'"'#�;+"&54>7.54>32"32>54."32654.!��)1''AV0/VB((1(��+..)"
"#))"&*
 �x7M3*:&2L33L3#:,
!4J3x�3%&5!0 +0  ����!@
 +@'#�;+72#".54>v''( (�%($)!���Q��@+@ .�;+7>32'>54 <(.7/@&9''p*1;0 GHD8#F 3D� +@
+@&'$�;+!&45<7C���('((a�N 0@
+@)'#�;+#53533##���x��xx��x�%�@�I7@
+K�-PX@ "#@'#Y�;+#�kI�� ��@ +!5��O�ww �� >@ +@$)&'$�;+!.5467%!.5467��M��M&$##$�$##$�� +@
+@&'$�;+!&45<7��g�('((k� +@
+@&'$�;+!&45<7j���('((�@��� C@
+K�-PX@'#@&'$Y�;+!.5467���8"!#"��� @  +&547�8787p8==8]g�yy�m"m��s ��I@+@
.�;+#"&54>7�2+16%6!*#r *4D6!@9-&4+��I#@+@
 #�;+'37''7'7� o ~*�gXWTZh�+���Bi)nE��Em*ia2;B@ 1/"!+@.-# !) "'#�;+67'3.#"#7.'&54>73254.546V�-+#!-�/=%$)$� �y;+  +.#��
# !0&&K���R��@+@ .�;+7>32'>54 <(.7/@&9''q*1;0 GHD8#F 3���2 0@
+@

!' #�;+7'#75'$��T��2�����|��� ��I@+@ #�;+&454632'>54& 2+16%6!*#� )5D7!@8.%5+;2
O@  
 +@+! )
) "#�;+!5333##>7#5�h��pq��j����llp��d���m<K&N-m%�`6%@+@&'$�;+4>32#".%.:"8)*791 �(>*.=!8($:���I$8F@&%0.%8&8$$ +@*!5'"'#�;+4>54.#".5467>322#".54>q! -=c=#RF/'.(F''( (+%5*""(!-5,"-QB1D3(*2#_%($)!�I@+@'#�;+3#�^I��NI"@
+@'#�;+3#3#�^��^I��,����I@+@'#�;+3#]��[I� ���2@
+@ 8 #�;+#4t��2��^'����>@+@$)&'$�;+##�kkk��v���v���@+I4M@4321.*  +@1( !)'"'#�;+7#"&'.54673265#535467>32."#"3#�EU & ..@- 'NNis #F�H=M*6 ?)� ���+@
 +@&'$�;+2#".54>w''( (�%($)!�jN@ +''����NqDDDD$��_Z@ +K�PX@('#@#)&'$Y�;+%#>45<.'3#��td?poq??tst?d+_a_+V�S���_Z@
+K�PX@('#@#)&'$Y�;+7>5<.5#53#5|t��S�V+_a_+d?tst??qop?d~��&@ +@!7.�;+# #"�g��g������|
���b@ + ��w��2w+�F87E���a'6@'' +@'"'#�;+72#".54>2#".54>�''( (''( (�%($)!�%($)!���b@ +7 '7x1��x�E����F�
���b @
 +  ��w��2wG�w��2w+�F87E��F87E���b @  +7 '? '7x1��x�Fx1��x�E����F��E����F� ��H)@+@ $#.�;+#"&54>7#"&54>7�2+16%6!*#2+16%6!*#q *4D6!@9-&4+ *4D6!@9-&4+ ��H)@+@$##�;+&454632'>54&7&454632'>54& 2+16%6!*#�2+16%6!*#� )5D7!@8.%5+ )5D7!@8.%5+ �d��)@+@ $#.�;+7&454632'>54&7&454632'>54& 2+16%6!*#�2+16%6!*#: )5D7!@8.%5+ )5D7!@8.%5+����j'Q@'%+@9 !5))&'$�;+#";#".=4&#526=4>;++12%4((4%21$$�.:4<�$$j%9&�38Z4-�&9%
�� j'Q@'% 
+@9!5))&'$�;+323"+5326=4675.=4&+
12%4((4%21++j%9&�-4Z83�&9%j$$�<4:.�$$�X�2@ +@8&'$�;+#5!5Xz�6��ީy��/>0k@00/.*($"   +@E% & !
 )) '"'#�;+!#327#"&'#53&45<7#53>32.#"3��JC.<VIq�]QQZ�tIV6#6'��   m0@���m   l��� ,l��w�+�@('&%+K� PX@5 )$!+,)'#K� PX@3 )$!78)'#@< )$!78)&'$YY�;+467'3&#"3267#7.UV�(,$ !)+&�RY0c���#%# @! A
���2�3��@ +K� PX@!+'#K�'PX@!7'#@&!7&'$YY�;+#"&546733267�?+(.'#U'(�& G#?��; @
+@'#�;+4632#".7!%/5#�,+/%)/  �`- "@

+@' #�;+4632#".74>32#"./ %' �  &' �'"* )* )�����W @  +'>7�#PPN"]2795/1b���`&6�����7���>B_@BBA@42/-#! 
+@??%6!5 )'"'#�;+5467>32.#"3#3267#".#".5467>75#5I Q6 "##5oo013.-,, 
-�|<N(! 6 @ Ill C# :8$E
^l�KI"E@!+@/!5""'"#�;+3>32#"&'#32654.#"�$O'-L7 "<Q/(I��-#&5 %0I��!-PnBDuV0"�)26*"6*22B@22('  +@(!)) "#�;+32>54.#"2##4>5<.'�" #% E�f><e�G�3 &&H)' :o`Sh: m�X:=W|] �g� >@     +@$)&'$�;+2#"&5462654&#"�VUXVWU\Q ! ��y|��w���:**56*):��/@ +@&'$�;+3#.5<734&5.5467�6�22'IR`=%% )4r0  . � �,=@
)'+@+#!77&'$�;+7!54>54&#".5467>32 "(#���%#(  
4-"2&'#m#1&$  2� �IU@IF@>42 
+@?)<!))&'$�;+&4546732654&#"&45<65>32#"&'&45<732654.#*E #+   4'!.9? /$ j    
  ,)!- (7#$  
�:w
�@
+K� PX@1 !  7,&'$@0 !  78&'$Y�;+3##5#535$$o�|+Lw���cc����%��I @  +#'#>54&'373####53[M;IVyEPp`��O^M�������4d2<t;��0].?|?R��Rc
�Z]�@ +K�PX@#!('#K�"PX@-!)&'$K�'PX@+!)('#@5!)&)'$YYY�;+#5#".54>325332654&#"Wi./1%'5,l�#$�%1A&'G4�"% #&�?�a2@22('$"+K�PX@,!5""'#@0!5"""'#Y�;+>32#"&'&54732654&#"#46<5<&45�E#)" 4) 0 )�V6# 5�D$@0"#"$2!��!IIH LZ^$�?92$9@ $#!  +@%"! ""'#�;+%#"&'.54673265#>54&'336 aQ=/?#&������H`>!
ST  &��g�gg�g�"��S��AM�@LJFDAA?=53+)&#  +K�PX@I  (!   5)
 )

&)'#@J  (!   5)
 )

))'#Y�;+%#"&54>325332>54.#"3267#".54>32#"&/32654&#",YNX0C)8{!%,RsFK|X0��.-=c�r>Cz�h`�q>&C[45>�#*(&~Tuh8[A$(��36I+CkL)0\�X��u @v�fk�}E9i�XFzZ450� )- *+/�0D^@21<:1D2D(&00 
+@< !)) ('#�;+4>32.#"327#"&2>54.#"".54>32�.C,)"6$!'%Xd�Da>@bCAfF$"Eh=W�[/1]�VU�Y-.Y��+H4d /){i�.Ng9:dJ+(Gd<;hO.U;e�LN�]44]�LN�e;�uI'?Jk@"((JHB@(?(?=<;:2/''  +@A. 9! 5  )) 
('#�;+%".54>32'2>54.#"'645<'>32#'#'32>54&+HJrN(*OsHIpK''LqC9Q45R96U99V0%3&8J0
 �2UsACnP,-OnABsV2L'AV/0T>$!<S21WB'Q%K!0U,( &* �x>:�  ��M 3@     +@('#�;+2654&#""&54632y3443322�0;((88((;�81(@
+@( #�;+#".5332678(54(E+ +1#6$$6#&..&=<+_@%#++ +@E
 ! )&'$�;+%"''7&547'76327''2>54&#",</S]VV]T/:8+T\TU\R,9+;99@ ,BS\V298-U]VT]T-:=0T\Qc"-4HG5-" �4] Y@     +K�PX@'"'#@)'#Y�;+2#"&5462>54.#"�GMJJHLLH]_[UedV[_�KI 6@     +@'"'#�;+2654&#"".54>32�+..+*00*$<+*<%(<))<O3($66%'3K-<"";**:""=-��4I=H@<:765432/-+@0!58)'"#�;+#".'&546732654.54>54&#"##5354632�$)$/C)#" /"("'#/'�.-sl^h�+3&#!+=//N9 5O(M("/+, #LZ����8{�a�V9@
+@!)"#�;+#'##>5<&'337砫�����V�����9<B&D�j=L0�����24@
+@56' #�;+".54>;## D_<<_D�P<I�*EY.*R?'��4�� �?�V�@
+K�PX@%!"'"#K�)PX@)!""'"#@+!"'"'#YY�;+332673#5#"&'# �  
�� 8$"0�V��! 4!IIH LZ^$A. ����> :W@"!2/-,&%!:":  +@9$.!)'"'#�;+>32#"&'>45#.54673."3#32>54.39h%X�8320c�fg>32�
FF %?/)C/0>:�_]�l<.XY^6-.I�^l--j 7J*G:'  2$0G@&%,*%0&0+@/$#" !) "'#�;+.'37#".54>32.'5"32654&�&N �)*�k3%&E_:8\B$ ;Q0%* (��'.0'&./�*> -.F *bfh0BnN,(Fb:7^E& F#*F��4*,64-,3 ��c$+E@&%)(%+&+#!+@+ !)'"'#�;+7.5!.#".547632#"&7267#8 <5%$ Na-\+&1
(>*39<`�&�'O(bB*7 A:)&CGE(WOB0<"-('M>'H@%#
+@.'!)'"#�;+3>54&'>32##32654.#"1c3I�^7QE���),D9''_�Uy�n9dObp��1M�M�33&D39@
+@ !) "#�;+33###>45<&45�����2<\TY9�q�\�%^gm5,_o�ND_NI/�� +@
+@&'$�;+!&45<7��g�('((�?�V�@
+K�PX@%!"'"#K�)PX@)!""'"#@+!"'"'#YY�;+332673#5#"&'#�  
�� 8$"0�V��! 4!IIH LZ^$A. ����>S@ +K�PX@'""#@'"'#Y�;+3#2#".54>��M'%( (F��>%'$(!�Q�a$.@ $$+@ 8'#�;+7>32'>542#".54> <(.7/@&9''2''( (p*1;0 GHD8#F 3%($)! �@��6@  +@"8&'$�;+3".54>32 1y3''( (� ��}%($)!�@��$8D@&%0.%8&8$$ +@(!5)'#�;+3267#".54>?".54>32\! -=c=#RF/'.(F''( (^%5*""(!-5,"-QB1D3(*2#_%($)!����� @ +'>54&'n8==8p7878s������m"m�yy�g�^C@
+K�PX@' #@&'$Y�;+!5^��^^2�3���@ +#7�<`7��2�3����@
+K� PX@&'$K� PX@'#K� PX@&'$K�PX@'#@&'$YYYY�;+#7�<`6���F1@+K�PX@ "#@'#Y�;+3#��F�����@�FK@+K�PX@!"'#@!7'#Y�;+#".'.546732653� Y�&=B *)7�I#9@## +@!!5""#�;+>32#4&#"#65<&5�D#)"�'�I8SE;# 5�U,# �ʅ/�6I2$�a_@ +K�PX@!5"#@!!5""#Y�;+>32#4&#"#46<5<&45�E$,D �!!�V6#0!5!�U"-%��!IIH LZ^$�2�@&
+K�)PX@- 
) " ' " #@+  ) 
) " #Y�;+733733#3##7##7#537#537#�.j0s.k0}���3c0v3b0y���utJ����j�j����j�j���s�23@+@%
!' #�;+5'37'7'#75'���|����|�����������������=IW@?>EC>I?I64+)
+@=2"!53)&'$�;+#"&'&54673254.5467.54>32.#"2654&#"�=6807L-%M !A()1)>6:.6L.$L #?()0)�%$%$q=a"F-$:* %50  &9,=`#D,%<* &40  %8�* !**!!) ��a&8?�@":9('=<9?:?20'8(8"  && +K�'PX@F!  ) '
"'
" '#@R!  ) '
"'
" '"'#
Y�;+2>32!32>7#"&'#"&5462>54.#""3.�9P M+<`�� <5%$ Na1^(7q{ii{
))
Y&�'a"" $0*(bB+6 A;(&"&F�����!":$!#,(' ��^?"'E@$#&%#'$'+@+ !)'"'#�;+467!.#".5467>32#".27# mV^OM7;;O�[10WyI<aE&Z�'!H&]OG(!
=n�]\�q?+Pq�� ��'�';7@)(31(;);''  +@'#�;+72#".54>!2#".54>!2#".54>v''( (>''( (>''( (�%($)!%($)!%($)!���>.:DH@<;;D<D97+)+@2@=2" !'"'#�;+67'#".54>7.54>32>54&#"27.'�IM4 -3970 87y{B�H6V<!!7('$?V2(D2��/'"'(/$=*+�>f109S )-.D ,�q0,:S4$=965N$,M:"->G/ 5 )�; #>)("*�����2�@

+K� PX@0)) ' "' #K�'PX@0)) ' "'#@6  -))' "'#YY�;+.#>5##!#3#334&5#�Xdf(�%��뿣���1k V6�2�~�w0<Q"U�E ��>-A�@/.97.A/A)('&%$#"
 +K� PX@3!) '"
' #K�PX@3!) '"
'#K�PX@K!)'" '"'"
'#
K�PX@I!)' " '"'"
'#
@G!)' " '"'"
'#
YYYY�;+.#465#".5463252>7#3#3%2>54.#"Yef(E-IjE!��+D'[^[)����� 1  1 /!!/
!"9m�f��( <~�w0<Q�3G++I66I*+G3���a7>H@$98FD@?<;8>9>7753+)'& +K� PX@f 
-H !  5  5

) '"'"'" '# @m 
- H !  5  5  5

) '"'"'" '# Y�;+%#"&54>74&#"'>323>32!3267#"&'"3."3267kc8S[@gJ+ H"+.45@PX<3P8�� @/LN[Bj#�"�$��09&D$+aZ/D/*"�
 -'%/%Ca< /2 > =*&)&�*%#,�# ����'@ +733#3##7#.546737#.5467 7b8b�%��<\;c�$���$#f$#��#$f#$I�u M@  
 +@/))&'$�;+#53533##!5���x��x �cx~~x?xx~�1 @  +'7'77��U��U��U��U�U��U��U��U8�v#'~@$$$'$'&%##  +K�PX@$)('#@/))&'$Y�;+2#"&54>2#"&54>7!5� ,)   ,)  ��;v 3!�n 3!�ccI�e@ +% %|�����ۀ����I�e@ +5-5�����|$ۀ������?@
 +@-  !&)'$�;+>323267#".#"<222<<222<�  ~   �� / @& +>323267#".#">323267#".#" <222<<222<<222<<222<  ~  n  ~  ��25@
 +@#  !(' #�;+>323267#".#"-/,+33.-,, l��l� 4@     +@)' #�;+2#"&5462654&#"�VUXVWU\Q ! ��y|��w���:**56*):��%@ +@'#�;+3#.5<734&5.5467�6�22�'IR`=%% )4r0  . #�,4@
)'+@"#!77'#�;+7!54>54&#".5467>32#"(#���%#(  
4-x"2&'#m"2&$  2��"�IL@IF@>42 
+@6)<!))' #�;+7&4546732654&#"&45<65>32#"&'&45<732654.#*G #+   4'!.9? /$ �    
  ,)!- (7#$   ;�
>@
+@$ !  7)#�;+3##5#535$$o�|+L����cc����{��
@ +%!!!5���3�p��p��v�`\``%{��
@  +%!5%!5!%5��p��p3����``\`�v�TI=S@=<;:9830(&  +@-/!  )
' " #�;+#535467>32&#"3###535467>32.#"3##<.- =&
 QO�2.- F/'   QO�@�HBN!$!LT&���@�HBN!$4*T����I.H@.-,+*)&$ 
+@(#!)' "#�;+#>5<&45#535467>32&#"3##����.- =&
 QO�I����DS5!X��D_NI/���HBN!$!LT&���6I4Q@*QPONMLIG@>876543210/,*#! +K�PX@6F)!  )' ""
#K�PX@CF)!  )' "'""
#@EF)!  )' "'"'
#YY�;+3#2#".54>#535467>32&#"3###535467>32&#"3##���M'%( (��.- =&
 QO�2.- =&
 QO�F��>%'$(!��HBN!$!LT&���@�HBN!$!LT&���I.K^@&KJIHGFCA:8210/.-,+*)&$ +@0@#!
 ) ' "#�;+#>5<&45#535467>32&#"3###535467>32&#"3##���.- =&
 QO���.- =&
 QO�I����DS5!X��D_NI/���HBN!$!LT&���@�HBN!$!LT&���I4�@43210/,*#!  +K�PX@.)! )' ""
#K�PX@:)! )'"' ""
#@<)! )'"' "'
#YY�;+3#2#".54>#535467>32&#"3##P��M'%( (��.- =&
 QO�F��>%'$(!��HBN!$!LT&�����8I"? @,> +3>32#"&'#32654.#"#535467>32&#"3##@�I)/Q;" 7L-&P$��-#&5 %0�n.- =&
 QO�I��#1WvDAnO,1i)26*"6T�HBN!$!LT&�����jI"?\ @
I[,> +3>32#"&'#32654.#"#535467>32&#"3###535467>32&#"3##r�I)/Q;" 7L-&P$��-#&5 %0�n.- =&
 QO���.- =&
 QO�I��#1WvDAnO,1i)26*"6T�HBN!$!LT&���@�HBN!$!LT&����I#@ @-? +>32#4&#"#65<&5#535467>32&#"3##�D#)"�'���.- =&
 QO�I8SE;# 5�U,# �ʅ/�6I2$���HBN!$!LT&��� I#@] @J\-? +>32#4&#"#65<&5#535467>32&#"3###535467>32&#"3##D#)"�'���.- =&
 QO���.- =&
 QO�I8SE;# 5�U,# �ʅ/�6I2$���HBN!$!LT&���@�HBN!$!LT&����@I,I @6H" +#".'.546732653'2#".54>#535467>32&#"3##� Y�A'%( (��.- =&
 QO�&=B *)7�%'$(!��HBN!$!LT&���I8 @%7 +#'##65<&'337#535467>32&#"3##���������.- =&
 QO�V�����9<B&{1�=L0\�w_(����HBN!$!LT&����@6I,If @
Se6H" +#".'.546732653'2#".54>#535467>32&#"3###535467>32&#"3## Y�A'%( (��.- =&
 QO���.- =&
 QO�&=B *)7�%'$(!��HBN!$!LT&���@�HBN!$!LT&���PI8U @BT%7 +#'##65<&'337#535467>32&#"3###535467>32&#"3##E���������.- =&
 QO���.- =&
 QO�V�����9<B&{1�=L0\�w_(����HBN!$!LT&���@�HBN!$!LT&�����NI$A @.@ +33#3267#".54>5#3#535467>32&#"3##x�MO $.
<<��.- =&
 QO��t���)+/; /41
���HBN!$!LT&������I$A^ @K].@ +33#3267#".54>5#3#535467>32&#"3###535467>32&#"3##��MO $.
<<��.- =&
 QO���.- =&
 QO��t���)+/; /41
���HBN!$!LT&���@�HBN!$!LT&������2%C@CBA@;9/-%%  +K�PX@+71!'  "
'#K�PX@771!'  "
'"'#K�PX@571!'  "
'"'#@A71!'  "'  "
'"'# YYY�;+54&5#.5467!#3!.5467%#"&'.546732>=#5!cJ4IL��� g^E!('�(�@Z&,.-,C�PM$F$#G##G#$F$�G^<" K\ "G#$H$
,F0ī���@�>0D�@21<:1D2D0/,*  +K�PX@/(!'
 """'#@1(!'
 "'"'#Y�;+3#2#".54>#".'.546732653'2#".54>��M'%( (= Y�A'%( (F��>%'$(!��&=B *)7�%'$(!��v>0MT@111M1MGF?>87(%00 
+K� PX@<$!'"' "' #K�PX@K$!'"'"' "' # K�PX@I$! '"'"' "'#
@G$! '"' "' "'#
YYY�;+>32#"&'>454&"32>54.&5467!.5467!!9h%X�8320c�fg>�
 %?/)C������/0>:�_]�l<.WUV.��9/]/477 7J*G:'�h+26�(5&+#�P77��/>0N�@111N1NHG@?98(%00 
+K�PX@I$!'"'"' "' # @G$! '"'"' "'#
Y�;+>32#"&'>454&"32>54..546?#.5467!39h%X�8320c�fg>�
 %?/)C���z��/0>:�_]�l<.WUV.��9/]/477 7J*G:'�h06�34&,"�77
���I"@�@###@#@:921+*! +K�PX@I!"'"'"'
"'
#
@C!"'"'"'
"'#
Y�;+!#5#".54>32332654.#".546?#.5467!3��$P&-L7 ";Q/)J���-#&5  $0m��z��1,OnADvW1#%� )26*"6�l06�34&,"�77���2/{@/.-,'% +K�PX@*#!' "'#@.#!' ""'#Y�;+3##>54&'3%#"&'.546732>=#5!���ԉ�� g^E!('�(2������g�gg�g�bG^<" K\ "G#$H$
,F0ī�@->*>�@,+64+>,>*)&$ 
+K�PX@3"!'  """'#K�PX@7"! "' """'#@:"!5 "' ""'#YY�;+3##>54&'3#".'.546732653'2#".54>���ԉ��] Y�A'%( (2������g�gg�g���&=B *)7�%'$(!�@�>8LC@:9DB9L:L8742'$  +K� PX@;0!5 ' "
""'#K�PX@?0!5 ' "
"""'# K�PX@C0!5 ' ""
"""'#
@E0!53 ' ""
""'#
YYY�;+>32#4&#"#46<5<&45#".'.546732653'2#".54>�E$,D �!!�g Y�A'%( (V6#0!5!�U"-%��!IIH LZ^$��&=B *)7�%'$(!���21�@10/.)' +K�PX@(%!' "'#K�"PX@4%!' "'"'#@2%!' "'"'#YY�;+7!65<'#"&'.546732>=#5!����� g^E!('�(2��yR*!@ !B#�%�Az9�zG^<" K\ "G#$H$
,F0ī�@G>,@�@.-86-@.@,+(& 
+K�PX@4$!'  ""'"'#K�PX@8$! "' ""'"'# @;$!5 "' "'"'# YY�;+7!65<'#".'.546732653'2#".54>���� Y�A'%( (2��yR*!@ !C#�&�Az9��&=B *)7�%'$(!�@�I*>�@,+64+>,>*)&$  +K�PX@-"!'"""'#K�PX@1"!"'"""'#@4"!5"'""'#YY�;+#>5<&45#".'.546732653'2#".54>��i Y�A'%( (I����DS5!X��D_NI/��&=B *)7�%'$(!�jN@ +77���
DEEDr��I@+@'#�;+#'3�[�����oI"@
+@'#�;+3#73#Wn^Q�n^QI���Z��I@+@'#�;+3#lh+OI�
��I"&�@&%$#!+K�PX@2!'"'"'#@:!'""'""'# Y�;+!#5#".54>325332654.#"3#��$P&-L7 ";Q/)J���-#&5  $0i��[1,OnADvW1#2�)26*"6��
��N"(�@!+K�PX@/!('&%$#'"'#@7!('&%$#"'""'#Y�;+!#5#".54>325332654.#"''��$P&-L7 ";Q/)J���-#&5  $0_���1,OnADvW1#2�)26*"6�qDDDD
��-"0@�@=;75-+'%!
+K�PX@4! ' "'"'#@<! ' ""'""'# Y�;+!#5#".54>325332654.#"4632#".74>32#".��$P&-L7 ";Q/)J���-#&5  $0G/ %' �  &' 1,OnADvW1#2�)26*"6P'"* )* )
��M".:�@0/$#64/:0:*(#.$.! +K�PX@>!
 ) ' "'"'#@F!
 ) ' ""'""'#
Y�;+!#5#".54>325332654.#"2654&#""&54632��$P&-L7 ";Q/)J���-#&5  $0_34433221,OnADvW1#2�)26*"6&0;((88((;
��1"4�@###4#420.-)'! +K�PX@7!)
 "'"'#@?!)
 ""'""'# Y�;+!#5#".54>325332654.#"#".533267��$P&-L7 ";Q/)J���-#&5  $0�(54(E+ +1,OnADvW1#2�)26*"6�#6$$6#&..&
��"&�@###&#&%$! +K�PX@3!' "'"'#@9!)"'""'#Y�;+!#5#".54>325332654.#"!5��$P&-L7 ";Q/)J���-#&5  $0 ��1,OnADvW1#2�)26*"6�^^
��2":�@8631,*'%!
+K�PX@F.#:/ !) ' "'"'#@N.#:/ !) ' ""'""'#
Y�;+!#5#".54>325332654.#">323267#".#"��$P&-L7 ";Q/)J���-#&5  $0W-/,+33.-,,1,OnADvW1#2�)26*"6� l
��I"&�@&%$#!+K�PX@2!'"'"'#@:!'""'""'# Y�;+!#5#".54>325332654.#"7#'3��$P&-L7 ";Q/)J���-#&5  $0�[��1,OnADvW1#2�)26*"6�� ���I$+/Z@&%/.-,)(%+&+$$
+@8!)'" '"'#�;+32>7#"&'.54>7632'"3.3#� <5%$ Na-\+&1
(>*39<`�&�'��[;+6 A 5*&CGD(WOB0*(bB�#,('T� ���N$+1S@&%)(%+&+$$+@5!10/.-,)'"'#�;+32>7#"&'.54>7632'"3.''� <5%$ Na-\+&1
(>*39<`�&�'���;+6 A 5*&CGD(WOB0*(bB�#,('YqDDDD ���;$+9Z@&%640.)(%+&+$$
+@8!)'" '"'#�;+32>7#"&'.54>7632'"3.'4632#".� <5%$ Na-\+&1
(>*39<`�&�'t7!%/5#;+6 A 5*&CGD(WOB0*(bB�#,('�,+/%)/   ���-$+9I`@&%FD@>640.)(%+&+$$ +@:!
) ' " '"'#�;+32>7#"&'.54>7632'"3.'4632#".74>32#".� <5%$ Na-\+&1
(>*39<`�&�'�/ %' �  &' ;+6 A 5*&CGD(WOB0*(bB�#,('�'"* )* ) ���1$+=g@",,&%,=,=;97620)(%+&+$$ +@=!)
)  " '"'#�;+32>7#"&'.54>7632'"3.#".533267� <5%$ Na-\+&1
(>*39<`�&�'t(54(E+ +;+6 A 5*&CGD(WOB0*(bB�#,('<#6$$6#&..& ���$+/�@,,&%,/,/.-)(%+&+$$ +K�PX@9!)'
 " '"'#@7!
)) '"'#Y�;+32>7#"&'.54>7632'"3.!5� <5%$ Na-\+&1
(>*39<`�&�'���;+6 A 5*&CGD(WOB0*(bB�#,(''^^ ���2$+Cr@&%A?<:530.)(%+&+$$ +@L7,C8 !)
) ' " '"'# �;+32>7#"&'.54>7632'"3.>323267#".#"� <5%$ Na-\+&1
(>*39<`�&�'�-/,+33.-,,;+6 A 5*&CGD(WOB0*(bB�#,('! l ���N$+1S@&%)(%+&+$$+@5!10/.-,)'"'#�;+32>7#"&'.54>7632'"3.77� <5%$ Na-\+&1
(>*39<`�&�'����;+6 A 5*&CGD(WOB0*(bB�#,('DEEDr ���I$+/Z@&%/.-,)(%+&+$$
+@8!)'" '"'#�;+32>7#"&'.54>7632'"3.7#'3� <5%$ Na-\+&1
(>*39<`�&�'![��;+6 A 5*&CGD(WOB0*(bB�#,('��
�@N!17�@0.&$ +K�PX@B!765432'"'"'#K�$PX@F!765432"'"'"'# @D!765432)"'"'#YY�;+%#".54>3253#"&'5326532>54.#"''t&?%2R;!%AV1I4��k-Q"IIBE�,$!  $0_���F)If=BsW2=2��Y|$jq{%84@)2#"6�qDDDD
�@;!1?@<:640.&$  +K�PX@E!'"'"'"'# K�$PX@I!'""'"'"'#
@G!)'""'"'# YY�;+%#".54>3253#"&'5326532>54.#"4632#".t&?%2R;!%AV1I4��k-Q"IIBE�,$!  $0 7!%/5#F)If=BsW2=2��Y|$jq{%84@)2#"6P,+/%)/  
�@1!1C@222C2CA?=<860.&$  +K�PX@J!  )
 "'"'"'# K�$PX@N!  )
 ""'"'"'#
@L!  ))
 ""'"'# YY�;+%#".54>3253#"&'5326532>54.#"#".533267t&?%2R;!%AV1I4��k-Q"IIBE�,$!  $0�(54(E+ +F)If=BsW2=2��Y|$jq{%84@)2#"6�#6$$6#&..&�I#{@#"!  +K�PX@)!5'""#@-!5'"""#Y�;+>32#4&#"#46<5<&4573#�E$,D �!!�Ւ�[V6#0!5!�U"-%��!IIH LZ^$���;-{@*($" +K�PX@)!5'""#@-!5'"""#Y�;+>32#4&#"#46<5<&4574632#".�E$,D �!!�u7!%/5#V6#0!5!�U"-%��!IIH LZ^$�,+/%)/  �27�@530.)'$" 
+K�PX@=+ 7,!5)' " "#@A+ 7,!5)' "" "#Y�;+>32#4&#"#46<5<&457>323267#".#"�E$,D �!!�-/,+33.-,,V6#0!5!�U"-%��!IIH LZ^$� l�N%q@ +K�PX@&!%$#"! 5"#@*!%$#"! 5""#Y�;+>32#4&#"#46<5<&45?7�E$,D �!!� ���V6#0!5!�U"-%��!IIH LZ^$�DEEDr ���I !F@ !     +@('"'"'#�;+2#"&5462>54.#"3#�ziiz{ii{
))
��[a���������!":$!i� ���N #?@     +@%#"! '"'#�;+2#"&5462>54.#"''�ziiz{ii{
))
���a���������!":$!nqDDDD ���- +;L@ 8620(&"    
+@*' "'" '#�;+2#"&5462>54.#"4632#".74>32#".�ziiz{ii{
))
�/ %' �  &' a���������!":$!'"* )* ) ���1 /S@ //-+)($"    +@-)
 "'" '#�;+2#"&5462>54.#"#".533267�ziiz{ii{
))
�(54(E+ +a���������!":$!Q#6$$6#&..& ��� !{@ !!     +K�PX@)' "'"'#@')'"'#Y�;+2#"&5462>54.#"!5�ziiz{ii{
))
���a���������!":$!<^^ ���2 5`@ 31.,'%"    
+@>)5*!)' "'" '#�;+2#"&5462>54.#">323267#".#"�ziiz{ii{
))
�-/,+33.-,,a���������!":$!6 l ���I !F@ !     +@('"'"'#�;+2#"&5462>54.#"#'3�ziiz{ii{
))
T[��a���������!":$!�� ���I !%L@ %$#"!    
+@*'"'" '#�;+2#"&5462>54.#"3#73#�ziiz{ii{
))
'n^Q�n^Qa���������!":$!i���GI@+K�PX@, !5'""#@0 !5'"""#Y�;+>3.#"#6573#� "%% %#����[VL  C#(N!#���#���VNu@+K�PX@) !5"#@- !5""#Y�;+>3.#"#65'77� "%% %#����VL  C#(N!#���#��DEEDr
��zIBF�@FEDC42#  +K�PX@1.!'"'"'#@8.!5'"'"'#Y�;+>32".#"#".'.54>732654.'.5463#R"N(9  /'<K$$%$  
( !���[1
=M  =2,>( '  
  
#2$*T8�
��zNBH�@ 42#  +K�PX@..!HGFEDC'"'#@5.!HGFEDC5'"'#Y�;+>32".#"#".'.54>732654.'.546''R"N(9  /'<K$$%$  
( !����1
=M  =2,>( '  
  
#2$*T=qDDDD
��zNBH�@ 42#  +K�PX@..!HGFEDC'"'#@5.!HGFEDC5'"'#Y�;+>32".#"#".'.54>732654.'.546'77R"N(9  /'<K$$%$  
( !���1
=M  =2,>( '  
  
#2$*T�DEEDr���I#'{@'&%$## +K�PX@)!5'""#@-!5'"""#Y�;+!5#".'.5332>533# D#)"�  ����[5# 5���#
 1!IIH LZ^$I����N#)q@## +K�PX@&!)('&%$5"#@*!)('&%$5""#Y�;+!5#".'.5332>53'' D#)"�  �ʫ��5# 5���#
 1!IIH LZ^$NqDDDD���-#1A�@><86.,(&## 
+K�PX@+!5' "" #@/!5' "" "#Y�;+!5#".'.5332>534632#".74>32#". D#)"�  ���/ %' �  &' 5# 5���#
 1!IIH LZ^$�'"* )* )���M#/;�@ 10%$750;1;+)$/%/##  +K�PX@5!5
 )'"" #@9!5
 )'"" "#Y�;+!5#".'.5332>532654&#""&54632 D#)"�  ��34433225# 5���#
 1!IIH LZ^$�0;((88((;���1#5�@$$$5$531/.*(##  +K�PX@.!5)
 "" #@2!5)
 "" "#Y�;+!5#".'.5332>53#".533267 D#)"�  �8(54(E+ +5# 5���#
 1!IIH LZ^$1#6$$6#&..&���#'@$$$'$'&%##  +K�PX@*!5' ""#@,!5)""#Y�;+!5#".'.5332>53!5 D#)"�  ���5# 5���#
 1!IIH LZ^$^^���2#;�@9742-+(&## 
+K�PX@=/$;0!5)' "" #@A/$;0!5)' "" "#Y�;+!5#".'.5332>53>323267#".#" D#)"�  ���-/,+33.-,,5# 5���#
 1!IIH LZ^$ l���I#'{@'&%$## +K�PX@)!5'""#@-!5'"""#Y�;+!5#".'.5332>53#'3 D#)"�  ��[��5# 5���#
 1!IIH LZ^$�����I#'+�@+*)('&%$## 
+K�PX@+!5'"" #@/!5'"" "#Y�;+!5#".'.5332>533#73# D#)"�  ���n^Q�n^Q5# 5���#
 1!IIH LZ^$I����IJ@

+@*!'" "'#�;+# #332673327'3#�r�21�t�)
1�4 '���[V��.��V��>��*>���NC@
+@'!"'#�;+# #332673327'''�r�21�t�)
1�4 'ǫ��V��.��V��>��*>�qDDDD�-%5P@20,*" 
 +@,!
'  " "'#�;+# #332673327%4632#".74>32#".�r�21�t�)
1�4 '��/ %' �  &' V��.��V��>��*>�'"* )* )�IJ@

+@*!'" "'#�;+# #332673327'#'3�r�21�t�)
1�4 '�[��V��.��V��>��*>4����K�I A@
+@'!'""'#�;+#73327'3#�Η/��7 9E��[V���E��/#�����K�N :@
+@$! "'#�;+#73327'''�Η/��7 9O���V���E��/#�qDDDD���K�- *G@'%!
 +@)!' ""'#�;+#73327'4632#".74>32#".�Η/��7 9�/ %' �  &' V���E��/#�'"* )* )���K�2 $Y@" 
 +@; $!)' ""'#�;+#73327%>323267#".#"�Η/��7 9��-/,+33.-,,V���E��/#� l���K�I A@
+@'!'""'#�;+#73327'#'3�Η/��7 9[��V���E��/#4� �I!A@! +@''"'"'#�;+3.546?#.5467!33#��z�����[06�34&,"�77I� �;+A@(&" +@''"'"'#�;+3.546?#.5467!34632#".��z����7!%/5#06�34&,"�77�,+/%)/   �N#:@+@$#"! '"'#�;+3.546?#.5467!377��z�������06�34&,"�77
DEEDr
���I(,P@,+*)  ((+@6!'"'"'#�;+2&#"3267#".54>73#-;0!0(
%,87DjJ'$Im"��[a'*#'!G$#I$ +PsGCsR/��
���N(.I@  ((+@3!.-,+*)'"'#�;+2&#"3267#".54>7''-;0!0(
%,87DjJ'$Im���a'*#'!G$#I$ +PsGCsR/�qDDDD
���;(6P@31-+  ((+@6!'"'"'#�;+2&#"3267#".54>'4632#".-;0!0(
%,87DjJ'$Im>7!%/5#a'*#'!G$#I$ +PsGCsR/�,+/%)/  
���N(.I@  ((+@3!.-,+*)'"'#�;+2&#"3267#".54>'77-;0!0(
%,87DjJ'$Im����a'*#'!G$#I$ +PsGCsR/�DEEDr�����W @  +'>7�#PPN"]2795/1b���`&6�����7 ���2@
+@ 8 #�;+ #���t42��^���I#{@#"!  +K�PX@)!5'""#@-!5'"""#Y�;+>32#4&#"#46<5<&45'3#�E$,D �!!�h+OV6#0!5!�U"-%��!IIH LZ^$�����I7>HL$@(98LKJIFD@?<;8>9>7753+)'& +K� PX@r 
-H !  5 5

) ' " '"'"'" '#@y 
- H !  5  5 5

) ' " '"'"'" '#Y�;+%#"&54>74&#"'>323>32!3267#"&'"3."32673#kc8S[@gJ+ H"+.45@PX<3P8�� @/LN[Bj#�"�$��09&l��[D$+aZ/D/*"�
 -'%/%Ca< /2 > =*&)&�*%#,�# ��
���I"&�@&%$#!+K�PX@2!'"'"'#@6!'"'""'#Y�;+!#5#".54>32332654.#"3#��$P&-L7 ";Q/)J���-#&5  $0nh+O1,OnADvW1#%� )26*"6���#)B@## +@*!)('&%$5""#�;+>32#4&#"#65<&57''�D#)"�'�̫��I8SE;# 5�U,# �ʅ/�6I2$�qDDDD
��?I*�@)'!

+K�PX@6 !)" '"'#@: !)" '""'#Y�;+3##5#".54>325#535332654.#">>�$P&-L7 ";Q/)J�����-#&5  $0p�b1,OnADvW1#zp;� )26*"6
�@�5E�@DB:831-+%$" +K�PX@D#0/! 7'"'"'# K�$PX@H#0/! 7"'"'"'#
@F#0/! 7)"'"'# YY�;+#"&54>7#".54>3253#"&'5326532>54.#"s('*!&?%2R;!%AV1I4��k-Q"IIBE�,$!  $0�#6+2.' )#�V)If=BsW2=2��Y|$jq{%84@)2#"6���I&M@&&%$#" 
+@-!5) ""#�;+3#>32#4&#"#><5#535�|�D#)"�'�<<I;p#<# 5�U,# ��B���mp;MI+@ +@'"#�;+#>5<&45;#���h+OI����DS5!X��D_NI/���%I,@
 +@!"#�;+7#>757<&<5�MN�JJIY�`pHhH0  ?�ap:ZG:55����a&�@&& +K�PX@1%$ !'"'#@9%$ !"'""'#Y�;+273#"'#7&5467&#"2>54'�h8'>H&izj7'>H&i) l))R
c a>3^K���=2]K����� �:�!�����I *�@"!!*"* 
+K�PX@=)( !'"'" '#@E)( !'""'"" '# Y�;+273#"'#7&54673#7&#"2>54'�h8'>H&izj7'>H&i���[ l))R
c a>3^K���=2]K������� �:�!�
��".:>�@"0/$#>=<;64/:0:*(#.$.!+K�PX@H!
)  ) ' "'"'# @P!
)  ) ' ""'""'# Y�;+!#5#".54>325332654.#"2654&#""&546323#��$P&-L7 ";Q/)J���-#&5  $0_3443322��[1,OnADvW1#2�)26*"60;((88((;������6�(T@('&%$#"!  +@4!75) '
"#�;+33#3#3267#".=#535#53V�OQYY $.
WZPP�t�SpA)+/;dpS�
���N"@F�@###@#@:921+*! +K�PX@UFECA!DB"'"'"'
"'
# @OFECA!DB"'"'"'
"'# Y�;+!#5#".54>32332654.#".546?#.5467!377��$P&-L7 ";Q/)J���-#&5  $0m��z�������1,OnADvW1#%� )26*"6�l06�34&,"�77
DEEDr���I$(R@('&%$#"!
 +@6 !5'"'"'#�;+33#3267#".54>5#373#K�MO $.
<<�h+O�t���)+/; /41
�� ���@  +2#".54>w''( (�%($)!�I%2@%% +@)"#�;+#>5<&452#".54>��(''( (I����DS5!X��D_NI/�}%($)!-@ +@)"#�;+3##>5<&45p�l[z��!����DS5!X��D_NI/��
D@ +@(
!)) "#�;+#3#'#33#�����3d2
��[2��WJo���
?@ +@'
! ) "#�;+#3#'#3''�����3d2���2��WJtqDDDD���
(J@%# 
+@*
!)) " #�;+#3#'#3 4632#".74>32#".�����3d2�/ %' �  &' 2��WJ
'"* )* )��
"\@  ""    +@4
!)
 )) " #�;+#3#'#352654&#""&54632�����3d234433222��WJ�0;((88((;���
S@    +@/
!
7)) " #�;+#3#'#3#".533267�����3d2�(54(E+ +2��WJW#6$$6#&..&���
I@    +@)
!)) "#�;+#3#'#3!5�����3d2���2��WJB^^���
"\@  
+@< "
!))) " #�;+#3#'#3 >323267#".#"�����3d2�-/,+33.-,,2��WJ< l��
D@ +@(
!)) "#�;+#3#'#37#'3�����3d2?[��2��WJ�������#�@#"! 
 +K� PX@:

))) ' "' #K�'PX@:

))) ' "'#@@  -

)))' "'#YY�;+.#>5##!#3#334&5#3#�Xdf(�%��뿣���1k ���[V6�2�~�w0<Q"U�Ew�
��)-N@-,+*!
))+@4 !)'"'#�;+2&#"3267#".54>73#�$5&52C)/?%58:X�a30_�O��[> &1%:E*J7
#L$&H$ :m�`\�q?ҿ
��)/I@!
))+@3 !/.-,+*'"'#�;+2&#"3267#".54>7''�$5&52C)/?%58:X�a30_�E���> &1%:E*J7
#L$&H$ :m�`\�q?�qDDDD
���)7N@42.,!
))+@4 !)'"'#�;+2&#"3267#".54>'4632#".�$5&52C)/?%58:X�a30_�7!%/5#> &1%:E*J7
#L$&H$ :m�`\�q?m,+/%)/  
��)/I@!
))+@3 !/.-,+*'"'#�;+2&#"3267#".54>'77�$5&52C)/?%58:X�a30_�f���> &1%:E*J7
#L$&H$ :m�`\�q?�DEEDr���> :W@"!2/-,&%!:":  +@9$.!)'"'#�;+>32#"&'>45#.54673."3#32>54.39h%X�8320c�fg>32�
FF %?/)C/0>:�_]�l<.XY^6-.I�^l--j 7J*G:'��g06I@(%00 +@3$!654321'"'#�;+>32#"&'>454&"32>54.779h%X�8320c�fg>�
 %?/)C����/0>:�_]�l<.WUV.��9/]/477 7J*G:'9DEEDr���'+H@+*)(#"! +@.))' "' #�;+."#><54&4&5:>7#3#33#�\ii('^b^)ɯ�����[FZi8L��`  !##t�p0<Qۿ���'-C@#"! +@--,+*)()' "' #�;+."#><54&4&5:>7#3#3''�\ii('^b^)ɯ������FZi8L��`  !##t�p0<Q�qDDDD���'5H@20,*#"! +@.))' "' #�;+."#><54&4&5:>7#3#34632#".�\ii('^b^)ɯ����7!%/5#FZi8L��`  !##t�p0<Qv,+/%)/  ����'5EN@B@<:20,*#"! 
+@0 ))' "' #�;+."#><54&4&5:>7#3#34632#".74>32#".�\ii('^b^)ɯ����/ %' �  &' FZi8L��`  !##t�p0<Qv'"* )* )����'9W@(((9(97532.,#"!  +@5
7))' "' #�;+."#><54&4&5:>7#3#3#".533267�\ii('^b^)ɯ��(54(E+ +FZi8L��`  !##t�p0<Q�#6$$6#&..&����'+M@(((+(+*)#"!  +@/))' "' #�;+."#><54&4&5:>7#3#3!5�\ii('^b^)ɯ����FZi8L��`  !##t�p0<Q�^^����'?b@=;861/,*#"! 
+@D3(?4 !  )))' "' #�;+."#><54&4&5:>7#3#3>323267#".#"�\ii('^b^)ɯ����-/,+33.-,,FZi8L��`  !##t�p0<Q� l���'-C@#"! +@--,+*)()' "' #�;+."#><54&4&5:>7#3#377�\ii('^b^)ɯ�������FZi8L��`  !##t�p0<Q�DEEDr���'+H@+*)(#"! +@.))' "' #�;+."#><54&4&5:>7#3#3#'3�\ii('^b^)ɯ��o[��FZi8L��`  !##t�p0<Q�
��5'-V@''%" +@>&!-,+*)(5'"'#�;+#".54>32&#"3:75''56S\�d52c�b*=1?7J-.E/ M�����::m�`\�q? &2%:G!&H8"�NqDDDD
��5'5[@20,*''%" +@?&!5)'"'#�;+#".54>32&#"3:754632#".56S\�d52c�b*=1?7J-.E/ �7!%/5#��::m�`\�q? &2%:G!&H8"��,+/%)/  
��5�'9j@(((9(97532.,''%"  +@F&!
7 5)'"'#�;+#".54>32&#"3:75#".53326756S\�d52c�b*=1?7J-.E/ E(54(E+ +��::m�`\�q? &2%:G!&H8"�1#6$$6#&..&�%+<@%%  +@"+*)('&) "#�;+#>7##>45<&4533<&45'''������H���2?pmo?J�p<�T;�Q,\j~MDcRM/S�H.KEC'�qDDDDO%)E@)('&%%  +@')' "'#�;+54&5#.5467!#3!.54673#cJ4IL�����[�@Z&,.-,C�PM$F$#G##G#$F$��^%+@@%% +@&+*)('&' "'#�;+54&5#.5467!#3!.5467''cJ4IL�������@Z&,.-,C�PM$F$#G##G#$F$�qDDDDM%3E@0.*(%%  +@')' "'#�;+54&5#.5467!#3!.54674632#".cJ4IL��E7!%/5#�@Z&,.-,C�PM$F$#G##G#$F$�,+/%)/   Y�%3CK@@>:80.*(%%  +@) )' "
'#�;+54&5#.5467!#3!.54674632#".74>32#".cJ4IL�� / %' �  &' �@Z&,.-,C�PM$F$#G##G#$F$�'"* )* )M�%7T@&&&7&75310,*%%  +@. 7)' "
'#�;+54&5#.5467!#3!.5467#".533267cJ4IL��-(54(E+ +�@Z&,.-,C�PM$F$#G##G#$F$�#6$$6#&..&`�%)J@&&&)&)('%% 
+@( )' "'#�;+54&5#.5467!#3!.5467!5cJ4IL��H���@Z&,.-,C�PM$F$#G##G#$F$�^^��x�%=_@;964/-*(%%  +@=1&=2 !  ))' "
'#�;+54&5#.5467!#3!.5467>323267#".#"cJ4IL��-/,+33.-,,�@Z&,.-,C�PM$F$#G##G#$F$� lM%)E@)('&%%  +@')' "'#�;+54&5#.5467!#3!.5467#'3cJ4IL���[���@Z&,.-,C�PM$F$#G##G#$F$6���t#?@
 +@- !#"! ' "'#�;+#"&'.546732>=#5!'''` g^E!('�(�����G^<" K\ "G#$H$
,F0ī�qDDDD95@ +@!) "#�;+3##>54&'33#���ԉ��t��[2������g�gg�g�ƿ95@ +@!) "#�;+3##>54&'34632#".���ԉ���7!%/5#2������g�gg�g�a,+/%)/  9�)M@'%"  +@3)!)) "#�;+3##>54&'3>323267#".#"���ԉ����-/,+33.-,,2������g�gg�g�� l90@
 +@! "#�;+3##>54&'377���ԉ�������2������g�gg�g��DEEDr ��S !%D@%$#"!!  +@&)'"'#�;+2#".5462>54.#"3#0����KnH"�� 1  1 /!!/*��[>����9m�f����3G++I66I*+G3� ��S !'?@!!  +@%'&%$#"'"'#�;+2#".5462>54.#"''0����KnH"�� 1  1 /!!/ ���>����9m�f����3G++I66I*+G3qDDDD ��S� !/?J@<:64,*&$!! 
+@()'" '#�;+2#".5462>54.#"4632#".74>32#".0����KnH"�� 1  1 /!!/�/ %' �  &' >����9m�f����3G++I66I*+G3�'"* )* ) ��S� !3S@"""3"31/-,(&!!  +@-
7)'" '#�;+2#".5462>54.#"#".5332670����KnH"�� 1  1 /!!/�(54(E+ +>����9m�f����3G++I66I*+G3#6$$6#&..& ��S� !%I@"""%"%$#!!  +@')'"'#�;+2#".5462>54.#"!50����KnH"�� 1  1 /!!/���>����9m�f����3G++I66I*+G3�^^ ��S� !9^@7520+)&$!! 
+@<-"9.!))'" '#�;+2#".5462>54.#">323267#".#"0����KnH"�� 1  1 /!!/�-/,+33.-,,>����9m�f����3G++I66I*+G3� l ��S !%D@%$#"!!  +@&)'"'#�;+2#".5462>54.#"#'30����KnH"�� 1  1 /!!/_[��>����9m�f����3G++I66I*+G3Z� ��S !%)J@)('&%$#"!! 
+@()'" '#�;+2#".5462>54.#"3#73#0����KnH"�� 1  1 /!!/n^Q�n^Q>����9m�f����3G++I66I*+G3���M'+V@+*)(%#
 +@8'!))'"#�;+3>54&'>32##32654.#"3#1c3I�^7QE���),D9''a��[_�Uy�n9dObp��1M�M�33&��M'-Q@%#
+@7'!-,+*)()'"#�;+3>54&'>32##32654.#"771c3I�^7QE���),D9''T���_�Uy�n9dObp��1M�M�33&KDEEDr ���BFA@FEDC:8(&+@+4!)'"'#�;+4>32.#"#".'.54>732654.3#1K[* %)+ 0,1(,EU*782 *12 $6?6$ ��[g@S1-5
)9K1@X7 &.0,
'&+:O�� ���BH<@
:8(&+@*4!HGFEDC'"'#�;+4>32.#"#".'.54>732654.''1K[* %)+ 0,1(,EU*782 *12 $6?6$���g@S1-5
)9K1@X7 &.0,
'&+:O�qDDDD ���BH<@
:8(&+@*4!HGFEDC'"'#�;+4>32.#"#".'.54>732654.771K[* %)+ 0,1(,EU*782 *12 $6?6$V���g@S1-5
)9K1@X7 &.0,
'&+:O�DEEDr �/@

+@' "#�;+##>5<'#5!%77�s�s������yY�jDS5!,_o�N9T#��DEEDr��@+/9@/.-,++"  +@) "'#�;+#".54>733265<./3#6%=Z>@[>%�,9:)M��[3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR޿��@+14@++"  +@10/.-, "'#�;+#".54>733265<./''6%=Z>@[>%�,9:)W���3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR�qDDDD��@�+9I?@FD@>640.++"  +@!) "'#�;+#".54>733265<./4632#".74>32#".6%=Z>@[>%�,9:)�/ %' �  &' 3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsRy'"* )* )��@+7CQ@98-,?=8C9C31,7-7++"  +@+) 
) "'#�;+#".54>733265<./2654&#""&546326%=Z>@[>%�,9:)W34433223��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsRO0;((88((;��@�+=H@,,,=,=;97620++" 
+@& 7) "'#�;+#".54>733265<.'7#".5332676%=Z>@[>%�,9:);(54(E+ +3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR�#6$$6#&..&��@�+/>@,,,/,/.-++"  +@ ) "'#�;+#".54>733265<.'7!56%=Z>@[>%�,9:)V��3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR�^^��@�+CS@A?<:530.++"  +@57,C8!)) "'#�;+#".54>733265<.'%>323267#".#"6%=Z>@[>%�,9:)��-/,+33.-,,3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR� l��@+/9@/.-,++"  +@) "'#�;+#".54>733265<./#'36%=Z>@[>%�,9:)[��3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR���@+/3?@3210/.-,++"  +@!) "'#�;+#".54>733265<./3#73#6%=Z>@[>%�,9:)�n^Q�n^Q3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR޿����* 9@
+@! !) "#�;+3# #373#��z�WW�~�?r�q���[2����J2��(�� ���* 4@
+@ !  "#�;+3# #37''��z�WW�~�?r�q����2����J2��(��qDDDD��*� *?@'%!
 +@# !) "#�;+3# #374632#".74>32#".��z�WW�~�?r�q��/ %' �  &' 2����J2��(���'"* )* )��* 9@
+@! !) "#�;+3# #37#'3��z�WW�~�?r�qt[��2����J2��(��N���#3@  +@ !) "#�;+3#>733#~���¦p ��[2��-DS5!A�]��3���#.@ +@ ! "#�;+3#>73''~���¦p���2��-DS5!A�]��8qDDDD��#�-9@*($" +@! !) "#�;+3#>734632#".74>32#".~���¦p�/ %' �  &' 2��-DS5!A�]���'"* )* )��#�'K@%#  +@3' !)) "#�;+3#>73>323267#".#"~���¦p�-/,+33.-,,2��-DS5!A�]�� l��#3@  +@ !) "#�;+3#>73#'3~���¦p>[��2��-DS5!A�]��t�� ?@  +@%)' "'#�;+3&5467!.5467!!3# �����Ғ�[+26�(5&+#�P77��*?@'%! +@%)' "'#�;+3&5467!.5467!!4632#". �������7!%/5#+26�(5&+#�P77�,+/%)/  �":@ +@$"! ' "'#�;+3&5467!.5467!!77 ������y���+26�(5&+#�P77�DEEDr��!d@ !!
 +@< !   5) 

)) "#�;+23#'##3463 3#2654&#" 01�����3d2 k6K#�7%��2%7��Jtt���v0MSx@111M1MGF?>87(%00 
+K� PX@E$!SRQPON'"' "' #K�PX@T$!SRQPON'"'"' "' #
K�PX@R$! SRQPON'"'"' "'# @P$! SRQPON'"' "' "'# YYY�;+>32#"&'>454&"32>54.&5467!.5467!!779h%X�8320c�fg>�
 %?/)C�������y���/0>:�_]�l<.WUV.��9/]/477 7J*G:'�h+26�(5&+#�P77�DEEDr��/N0NT�@111N1NHG@?98(%00 
+K�PX@VSQO$!T RP'"'"' "' # @RSQO$!T RP'"'"' "'# Y�;+>32#"&'>454&"32>54..546?#.5467!3779h%X�8320c�fg>�
 %?/)C���z�������/0>:�_]�l<.WUV.��9/]/477 7J*G:'�h06�34&,"�77
DEEDr�2:@ +@ )' "#�;+#3##>5#535#5!�vll�jis�y�\�s'V`oA\���� 2&.R@"'''.'.+*&&%$!  +@(
 )   )  "#�;+3##>7##>454&5#5353354&5#�&(���&&���2/*RF�PJ�p<�T;�Q,\j~MB_)RY-Y��$= = a6@ +@) "'#�;+7!65<'73#����]��[2��yR*!@ !C#�&�Az9޿�I]@ +K� PX@' "'#@  "'"'#Y�;+7!65<'73#�����h+O2��yR*!@ !C#�&�Az9�c25@ +@!! "'#�;+77!>757<&5�hj���25�S#p$�!@ !C#W�[
p
FiP>�2';@'' +@) "'#�;+7!65<'2#".54>����6''( (2��yR*!@ !C#�&�Az9�%($)!����x> *�@"!!*"*
+K�PX@1)(!'"'#K�PX@5)(! "'"'#@9)(! "'""'#YY�;+273#"&'#7.546&#"2>54'5<^#&`U5��<]#'`V�� 2 /!� 1 �>#"9~d���#":�6�[���{G0&6I�3G+(%�� ����x $.�@&%%.&.$#"!

+K�PX@;-,!)'" '#K�PX@?-,!) "'" '#@C-,!) "'"" '#YY�;+273#"&'#7.546&#"3#2>54'5<^#&`U5��<]#'`V�� 2 /!���[? 1 �>#"9~d���#":�6�[���{G0&6I-���3G+(%�� IM@
+K�PX@'""#@'"'#Y�;+3#3#��V��[F��I���- U@
+K�PX@' ""#@' "'#Y�;+4632#".74632#".3#6) %'  �( &'  c���'"* )&"* )������N C@ +K�PX@"#@'#Y�;+''3#f�yyK��NqDDDD������2}@ +K�PX@.  !)' ""#@0  !)' "'#Y�;+>323267#".#"3#! "$$!;�� lb�����q@+K�PX@' ""#K�PX@)"#@)'#YY�;+#53#��"��^^������1_@
+K�PX@) ""#@) "'#Y�;+3##".533267���(54(E+ +F��1#6$$6#&..&���@�N]@
+K�PX@"!"'#@"!7'#Y�;+''#".'.546732653^�yy� Y�NqDDDD� &=B *)7���IM@
+K�PX@'""#@'"'#Y�;+3##'3���[��F�������3�>)�@!)) +K�PX@0  !'"""'#K�'PX@2  !'"'"'#@/  !('"'#YY�;+3#3267#"&5467#2#".54>�'(?+(.'#*M'%( (F��?C& G#>%'$(! �3�a5<�@76:96<7<31" +K�'PX@<&5!5)'"'#@9&5!5)('#Y�;+#"&5467.'.54>7632!32>73267"3.�?+(.! "D &1
(>*39<`�� <5%$ =L!(e&�'�& B"CGD(WOB0*(bB+6 A 5*9i#,('
�3a'5�@42,*%# +K�PX@?
'! '"'"'#K�'PX@G
'! "'""'"'#
@D
'! ("'""'# YY�;+#"&5467#5#".54>3253326732654.#"?+(.'#4$P&-L7 ";Q/)J� (��-#&5  $0�& G#1,OnADvW1#2��
�)26*"6�3�V4�@20"! +K�PX@5
4!, 5""'#K�'PX@9
4!, 5"""'#@6
4!, 5(""#YY�;+#"&5467#5#".'.5332>533267�?+(.'#<D#)"�  �'(�& G#5# 5���#
 1!IIH LZ^$? �3�a0z@ *(0 0+K�'PX@.!5'"'#@+!5('#Y�;+#"&5467.5463232672>54.#"M?+(.! 4I/i{ziR]"(U
))
�& B!-NmF������:T!":$!�3�55�@31-,'&%$#"!   +K�'PX@;5!)' "'"'#@85!)(' "'#Y�;+#"&5467#><54&4&5:>7#3#3#3267>?+(.&#�'^b^)ɯ��r&(�& G#FZi8L��`  !##t�p/<P8>�3M27�@53/.('#"  +K�'PX@37!' "'"'#@07!(' "'#Y�;+#"&5467#.5467354&5#.5467!#3#3267?+(.'#�KJ4IL^'(�& G##G#$F$�@Z&,.-,C�PM$F$#G#?���32�@
+K�'PX@2!) ""'#@/!)( "#Y�;+#"&5467#'##3#32673?+(.&#,�����(&(��d2�& G#��2��?�J�3@28h@ 64('+K�'PX@'8!5 "'#@$8!5( #Y�;+#"&5467.54>733265<.'33267�?+(.!Sa2�,9:)�.YL"(�& B!Jo�B%Th�QZ}T1 abjl /OsR��KD�lJ : �3S>0z@(&00 +K�'PX@.!5'"'#@+!5('#Y�;+#"&5467.5463232672>54.#"�?+(.!�{����r}"(V 1  1 /!!/�& B! �����ʻ�:k3G++I66I*+G3���3�>#�@## +K�PX@&'"""'#K�'PX@('"'"'#@%('"'#YY�;+3#2#".54>2#"&546��M'%( ($''$$''F��>%'$(!��0//0�3�I#/�@%$+)$/%/##  +K�'PX@.!5"""'#@+!5(""#Y�;+>32#4&#"#65<&52#"&546�D#)"�'��$''$$''I8SE;# 5�U,# �ʅ/�6I2$��0//0 �3�a$+7�@-,&%31,7-7)(%+&+$$ +K�'PX@9!) '"'"
'#@6!)
( '"'#Y�;+32>7#"&'.54>7632'"3.2#"&546� <5%$ Na-\+&1
(>*39<`�&�'$''$$'';+6 A 5*&CGD(WOB0*(bB�#,('��0//0�3!�$0�@&%,*%0&0$#"!

+K�'PX@7 !5'"'" '#@4 !5 ('"'#Y�;+33#3267#".54>5#32#"&546K�MO $.
<<j$''$$''�t���)+/; /41
�v0//0�3,a#�@##+K�PX@- !5""'#K�'PX@1 !5"""'#@. !5(""#YY�;+>3.#"#652#"&546� "%% %#�T$''$$''VL  C#(N!#���#��v0//0
�3zaBN�@DCJHCNDN42#  +K�PX@2.!'"'"'#K�'PX@9.!5'"'"'#@6.!5('"'#YY�;+>32".#"#".'.54>732654.'.5462#"&546R"N(9  /'<K$$%$  
( !�$''$$''1
=M  =2,>( '  
  
#2$*T��0//0
�3I".�@$#*(#.$.! +K�PX@8!5"'""'#K�'PX@<!5"'"""'# @9!5("'""#YY�;+!#5#".54>32332654.#"2#"&546��$P&-L7 ";Q/)J���-#&5  $0S$''$$''1,OnADvW1#%� )26*"6�80//0�3�V#/�@%$+)$/%/##  +K�PX@*!5""'#K�'PX@.!5"""'#@+!5(""#YY�;+!5#".'.5332>532#"&546 D#)"�  ��$''$$''5# 5���#
 1!IIH LZ^$40//0 �3�a )z@ %#))    +K�'PX@)'"'"'#@&('"'#Y�;+2#"&5462>54.#"2#"&546�ziiz{ii{
))
$''$$''a���������!":$!��0//0 �3�V)t@%#))+K�'PX@('"'"'#@%('"'#Y�;+3.546?#.5467!32#"&546��z���$''$$''06�34&,"�7740//0�3g>0<�@21861<2<(%00 +K�'PX@7$!'"'"'#@4$!('"'#Y�;+>32#"&'>454&"32>54.2#"&5469h%X�8320c�fg>�
 %?/)C#$''$$''/0>:�_]�l<.WUV.��9/]/477 7J*G:'�40//0�3�5'3�@)(/-(3)3#"!  +K�'PX@1)' "' "'#@.)(' "' #Y�;+."#><54&4&5:>7#3#32#"&546�\ii('^b^)ɯ���$''$$''FZi8L��`  !##t�p0<Qi0//0�3�2%1t@'&-+&1'1%%  
+K�'PX@&) "" '#@#) ( "#Y�;+#>7##>45<&4533<&452#"&546������H$''$$''2?pmo?J�p<�T;�Q,\j~MDcRM/S�H.KEC'��0//0�3M2%1|@'&-+&1'1%% 
+K�'PX@*' "'" '#@' (' "'#Y�;+54&5#.5467!#3!.54672#"&546cJ4IL���$''$$''�@Z&,.-,C�PM$F$#G##G#$F$��0//0 �3�2!b@!!
+K�'PX@!' ""'#@(' "#Y�;+##>5<'#5!2#"&546�s�s��$''$$''yY�jDS5!,_o�N9T#���0//0�3�2(t@$"(( +K�'PX@(' "'"'#@%(' "'#Y�;+3&5467!.5467!!2#"&546 ������$''$$''+26�(5&+#�P7740//0�3@3+7h@-,31,7-7++"  +K�'PX@" "'"'#@( "'#Y�;+#".54>733265<.'2#"&5466%=Z>@[>%�,9:)V$''$$''3��K1aXK8!8MX^/%Th�QZ}T1 abjl /OsR��0//0 �3S> !-z@#")'"-#-!!  +K�'PX@)'"'"'#@&('"'#Y�;+2#".5462>54.#"2#"&5460����KnH"�� 1  1 /!!/!$''$$''>����9m�f����3G++I66I*+G3��0//0 �3�>BN|@DCJHCNDN:8(&+K�'PX@.4!'"'"'#@+4!('"'#Y�;+4>32.#"#".'.54>732654.2#"&5461K[* %)+ 0,1(,EU*782 *12 $6?6$�$''$$''g@S1-5
)9K1@X7 &.0,
'&+:O��0//0�3M>'3�@)(/-(3)3%#

+K�'PX@;'!)'"" '#@8'!) ('"#Y�;+3>54&'>32##32654.#"2#"&5461c3I�^7QE���),D9''g$''$$''_�Uy�n9dObp��1M�M�33&�F0//0
�3�a(,L@))),),+*  ((+K� PX@4!('"'#K� PX@7!'"'"'#K� PX@4!('"'#K�PX@7!'"'"'#@4!('"'#YYYY�;+2&#"3267#".54>#7-;0!0(
%,87DjJ'$Im|<`a'*#'!G$#I$ +PsGCsR/�i��
�3�>)-L@***-*-,+!
))+K� PX@4 !('"'#K� PX@7 !'"'"'#K� PX@4 !('"'#K�PX@7 !'"'"'#@4 !('"'#YYYY�;+2&#"3267#".54>#7�$5&52C)/?%58:X�a30_��<`> &1%:E*J7
#L$&H$ :m�`\�q?�����3�a#A@ # #"!  +K� PX@'!5("#K� PX@*!5""'#K� PX@'!5("#K�PX@*!5""'#K�PX@'!5("#@+!5(""#YYYYY�;+>32#4&#"#46<5<&45#7�E$,D �!!�<`V6#0!5!�U"-%��!IIH LZ^$�s���3,aQ@+K� PX@* !5("#K� PX@- !5""'#K� PX@* !5("#K�PX@- !5""'#K�PX@* !5("#@. !5(""#YYYYY�;+>3.#"#65#7� "%% %#��<`VL  C#(N!#���#��s�� �3�I�@ +K� PX@("#K� PX@""'#K� PX@("#K�PX@""'#@("#YYYY�;+#>5<&45#7���<`I����DS5!X��D_NI/�����3a2�@ +K� PX@( "'#K� PX@! "'"'#K� PX@( "'#K�PX@! "'"'#@( "'#YYYY�;+7!65<'#7�����<`2��yR*!@ !C#�&�Az9�����3�I-@

+K� PX@-!) (""#K� PX@0!)""" '#K� PX@-!) (""#K�PX@0!)""" '#@-!) (""#YYYY�;+#'##65<&'337#7蠫�����<`V�����9<B&{1�=L0\�w_(��s��
�35>'+�@(((+(+*)''%"  +K� PX@?&!5('"'#K� PX@B&!5'"'"'#K� PX@?&!5('"'#K�PX@B&!5'"'"'#@?&!5('"'#YYYY�;+#".54>32&#"3:75#756S\�d52c�b*=1?7J-.E/ <`��::m�`\�q? &2%:G!&H8"�����392�@ +K� PX@!( "#K� PX@"! ""'#K� PX@!( "#K�PX@"! ""'#@!( "#YYYY�;+3##>54&'3#7���ԉ��Q<`2������g�gg�g�����3M>'+d@(((+(+*)%#

+K� PX@8'!) ('"#K� PX@;'!)'"" '#K� PX@8'!) ('"#K�PX@;'!)'"" '#@8'!) ('"#YYYY�;+3>54&'>32##32654.#"#71c3I�^7QE���),D9''�<`_�Uy�n9dObp��1M�M�33&�C���3D3!@!! 

+K� PX@) !) ( "#K� PX@, !) "" '#K� PX@) !) ( "#K�PX@, !) "" '#@) !) ( "#YYYY�;+33###>45<&45#7�����<<`2<\TY9�q�\�%^gm5,_o�ND_NI/�����3!�$(N@%%%(%('&$#"!

+K� PX@4 !5 ('"'#K� PX@7 !5'"'" '#K� PX@4 !5 ('"'#K�PX@7 !5'"'" '#@4 !5 ('"'#YYYY�;+33#3267#".54>5#3#7K�MO $.
<<�<`�t���)+/; /41
�s��
�3zaBFp@CCCFCFED42#  +K� PX@/.!('"'#K� PX@2.!'"'"'#K� PX@/.!('"'#K�PX@2.!'"'"'#K�PX@/.!('"'#@6.!5('"'#YYYYY�;+>32".#"#".'.54>732654.'.546#7R"N(9  /'<K$$%$  
( !�<`1
=M  =2,>( '  
  
#2$*T���� �3�2�@
+K� PX@(' "#K� PX@!' ""'#K� PX@(' "#K�PX@!' ""'#@(' "#YYYY�;+##>5<'#5!#7�s�s��<`yY�jDS5!,_o�N9T#����� �3�>BF@CCCFCFED:8(&+K� PX@+4!('"'#K� PX@.4!'"'"'#K� PX@+4!('"'#K�PX@.4!'"'"'#@+4!('"'#YYYY�;+4>32.#"#".'.54>732654.#71K[* %)+ 0,1(,EU*782 *12 $6?6$<`g@S1-5
)9K1@X7 &.0,
'&+:O�����3!�$(N@%%%(%('&$#"!

+K� PX@4 !5 ('"'#K� PX@7 !5'"'" '#K� PX@4 !5 ('"'#K�PX@7 !5'"'" '#@4 !5 ('"'#YYYY�;+33#3267#".54>5#3#7K�MO $.
<<�<`�t���)+/; /41
�t��
�3zaBFp@CCCFCFED42#  +K� PX@/.!('"'#K� PX@2.!'"'"'#K� PX@/.!('"'#K�PX@2.!'"'"'#K�PX@/.!('"'#@6.!5('"'#YYYYY�;+>32".#"#".'.54>732654.'.546#7R"N(9  /'<K$$%$  
( !�<`1
=M  =2,>( '  
  
#2$*T���� �3�2�@
+K� PX@(' "#K� PX@!' ""'#K� PX@(' "#K�PX@!' ""'#@(' "#YYYY�;+##>5<'#5!#7�s�s��<`yY�jDS5!,_o�N9T#����� �3�>BF@CCCFCFED:8(&+K� PX@+4!('"'#K� PX@.4!'"'"'#K� PX@+4!('"'#K�PX@.4!'"'"'#@+4!('"'#YYYY�;+4>32.#"#".'.54>732654.#71K[* %)+ 0,1(,EU*782 *12 $6?6$<`g@S1-5
)9K1@X7 &.0,
'&+:O�������>'3�@*)(/-(3)3#!'' +K�PX@5 )   )'  "'
#K�PX@9 )   ) "' "'
#@= )   ) "' "
"'#YY�;+332#"&5462654&#"2#"&5462654&#"]�\�~EEGFFEKA {EEGFFEKA 2��>kbdlk`gk��8((33)'8�kbdlk`gk��8((33)'8���>'3?K@:A@54)(GE@KAK;94?5?/-(3)3#!'' +K�PX@;)
   )' " ' #K�PX@?)
   ) "'" ' #@C)
   ) "'"" ' #YY�;+332#"&5462654&#"2#"&5462654&#"2#"&5462654&#"^�\�~EEGFFEKA {EEGFFEKA UEEGFFEKA 2��>kbdlk`gk��8((33)'8�kbdlk`gk��8((33)'8*kbdlk`gk��8((33)'8���"O�@LJ><21+*
+K�PX@9F@!5)'#@@F@!55)'#Y�;+ '%3#.5<734&5.54677!54>54&#".5467>32%��>T��6�22�"(#���%#(  
4-1��&[('IR`=%% )4r0  . � "2&'#m"2&$  2���"ll@licaWUCA31-+
+@P=5)L_#!&))' #�;+ '%3#.5<734&5.5467&4546732654&#"&45<65>32#"&'&45<732654.#*.��>T��6�22� #+   4'!.9? /$ 1��&[('IR`=%% )4r0  . �s    
  ,)!- (7#$  ���"-0_@##/.#-#-+*)('&%$
+@?0!,  5))#�;+ '%3#.5<734&5.54673##5#5350��>T��6�22�$$o�|+L1��&[('IR`=%% )4r0  . �����cc��������0zy@zwqoecQOA?;9-+
+@['!KC7Z m1 !77&)  )' # �;+ '7!54>54&#".5467>32&4546732654&#"&45<65>32#"&'&45<732654.#*:��>T�"(#���%#(  
4-� #+   4'!.9? /$ 1��&[S"2&'#m#1&$  2��    
  ,)!- (7#$  ����MX[�@NNZYNXNXVUTSRQPOMJDB86$" +K� PX@W
-@[!W ))
)  )#@^
-@[
!W  

5)))  )# Y�;+ '&4546732654&#"&45<65>32#"&'&45<732654.#*3##5#5357��>T�V #+   4'!.9? /$ a$$o�|+L1��&[�    
  ,)!- (7#$  ����cc�����{*5<�Io�"�&�An�B�^���Y��6}�� 1 �

h
�  e �  Q � �  c �8h��N��'x���t�:u�)R����6e���K��L��@[����\���Ip���7��y�z ���� O � �!9!�"!"W"�#}#�$�%*%�&&8&�''Q'�( (C(�)A)�**q*�*�+j+�,,J,�,�-
--v-�-�-�.9.�//M/�0�0�1m1�2�3�4�4�5515�5�5�66i6�6�7+7�8 8E8b88�9e:W:�;�<<�<�=m=�>/>�?=?�@AA�B�C�DUD�E�F�GWH#H�H�I I1ILI�JMJ�K�L;L�MpM�NgN�O^O�P�QQ�R.R�SpTKU7U�V'V�W:W�W�XdX�YEY�ZZzZ�[S[�\�]I]�^8^�_x`
`�a,a�b&b}b�cPc�c�d,d�d�e<e�e�fKf�gg�g�hh6h�i�j*j�kk�lRl�l�mMm�n�oo�p9p]p�p�q)qkq�r4r�r�s7swt"t�t�uju�vRv�w*w�w�x�x�ycy�zPz�{!{�| ||�}@}�~/~� ���I���ׁ>���݂:���.����j�υ=���0���8�|�ۈ<���C�������j�����P���͍ �m�Ў �c�Ə���������N�����-���2���/���–-�x�̗-�g����q�!���9�ɜ;���@�ȞM���|��塘�6���)�ɤS�ԥY���6���7���|�c�L�#���z��ۮޯu�k�-��+���������E�5���򺲻|���ٽ�ᲲV_<���fd�f����3v r�|/:�



 ��

n
�#���� ��� ���������H
q��H
cz��� .�` U��2��,���` � U��C��� �DC�
>� ���_��%�� ����� �s����� K�%��\ � �';��� ~$�
��
�� � � ��
yA�$2�t����2t �4-G
�%r
�T����LM@ T3�� � 
M-������ ����r22����|����� h 1 ����* �������� �~84O ��%U�/"�Bt�%� *?\������>�
�!��;�~ � Z



















����� � � � � � � � ::


����������������������������� � � �
�
�
�
s��� ���
�

����"��������
:���
/� ���������������������



�q���������H
H
H
cccc ccc��czUUUU` ` ` ` ` ` ` ` MM� � � � UUUUUUUUU,��,��,��,������������������>���nsp�i��i���������������������������

�� �c��U` ����
/:

�� � q�c� �U` � M�

�:� n�H
UM-/
� � /
� � ��������3����yv�z�������2� ��P[PYRS@ ��3��V2 �l@,AJ~~������7Y���� %E[cm��������    " & 0 : D p t � �!"!T""""H"`"e����� BK�������7Y���� $DZbl��������    & 0 9 D p t � �!"!S""""H"`"d�������������_�/����2�F�y���)���-߼�T�1����c�D�N �l��������������
  S�K��RH�JA?@>456789:<=;^��D�Qz&�/20(*�1'+-.3,)ZU[\G� 
�� �eBf���inOV�l{w`g�|���stT��X�r�a����+$%*&'��;346G@AC�KSMNRO�yb[\]hp��������������{}|������������o)�(���- . /0218�7�5���:�<�>�=��?tF~ED���B���H����u#��vx"wI���L�yxQ�P�T���U���V�W�X���Y���Z sa�`�_�^�c���eijm n
o qr��������p,z����Y�~k}j������J�������gdf����9�������lkINLM�P]_��������, d� `f#�PXeY-�, d ��P�&Z�E[X!#!�X �PPX!�@Y �8PX!�8YY �
Ead�(PX!�
E �0PX!�0Y ��PX f ��a �
PX` � PX!�
` �6PX!�6``YYY�+YY#�PXeYY-�,�#B�#B�#B�C�CQX�C+�C`B�eY-�,�C E �Ec�Eb`D-�,�C E �+#�%` E�#a d � PX!��0PX� �@YY#�PXeY�%#aDD-�,�E�aD-�,�` � CJ�PX � #BY�
CJ�RX �
#BY-�,�C�%B�C`B� %B�
%B�# �%PX�C�%B�� �#a�*!#�a �#a�*!�C�%B�%a�*!Y� CG�
CG`��b �Ec�Eb`�#D�C�>�C`B-�,�ETX `�a� B�`�+"Y-� ,�+�ETX `�a� B�`�+"Y-�
, `� ` C#�`C�%�%QX# <�`#�e!!Y-� ,�
+�
*-� , G �Ec�Eb`#a8# �UX G �Ec�Eb`#a8!Y-� ,�ETX�� *�0"Y-�,�+�ETX�� *�0"Y-�, 5�`-�,�Ec�Eb�+�Ec�Eb�+��D>#8�*-�, < G �Ec�Eb`�Ca8-�,.<-�, < G �Ec�Eb`�Ca�Cc8-�,�% . G�#B�%I��G#G#ab�#B�*-�,��%�%G#G#a�+e�.# <�8-�,��%�% .G#G#a �#B�+ �`PX �@QX�  �&YBB# �C �#G#G#a#F`�C��b` �+ ��a �C`d#�CadPX�Ca�C`Y�%��ba# �&#Fa8#�CF�%�CG#G#a` �C��b`# �+#�C`�+�%a�%��b�&a �%`d#�%`dPX!#!Y# �&#Fa8Y-�,� �& .G#G#a#<8-�,� �#B F#G�+#a8-�,��%�%G#G#a�TX. <#!�%�%G#G#a �%�%G#G#a�%�%I�%a�Ec#bc�Eb`#.# <�8#!Y-�,� �C .G#G#a `� `f��b# <�8-�,# .F�%FRX <Y.� +-�,# .F�%FPX <Y.� +-�,# .F�%FRX <Y# .F�%FPX <Y.� +-�,� G�#B�.�*-�,� G�#B�.�*-� ,��*-�!,�*-�&,�+# .F�%FRX <Y.� +-�),�+� <�#B�8# .F�%FRX <Y.� +�C.� +-�',��%�& .G#G#a�+# < .#8� +-�$,�%B��%�% .G#G#a �#B�+ �`PX �@QX�  �&YBB# G�C��b` �+ ��a �C`d#�CadPX�Ca�C`Y�%��ba�%Fa8# <#8! F#G�+#a8!Y� +-�#,�#B�"+-�%,�+.� +-�(,�+!# <�#B#8� +�C.� +-�",�E# . F�#a8� +-�*,�+.� +-�+,�+�+-�,,�+�+-�-,��+�+-�.,�+.� +-�/,�+�+-�0,�+�+-�1,�+�+-�2,�+.� +-�3,�+�+-�4,�+�+-�5,�+�+-�6,�+.� +-�7,�+�+-�8,�+�+-�9,�+�+-�:,+-�;,�ETX�:*�0"Y-K��RX��Y�c �#D �#p�E �(`f �UX�%a�Ec#b�#D�
+� +�+Y�(ERD� +������D������2��IV�K>��Ia���@� * * : TH * \�  � V :n :n
�� "D "D  f 4�Copyright (c) 2012, Pablo Impallari (www.impallari.com|impallari@gmail.com), Brenda Gallo. (gbrenda1987@gmail.com), with Reserved Font Name Ranchers.RanchersRegularPabloImpallari,BrendaGallo: Ranchers: 2012Version 1.000; ttfautohint (v0.8) -G 200 -r 50Ranchers-RegularRanchers is a trademark of Pablo Impallari.Pablo Impallari, Brenda GalloRanchers is one of the many hand-lettering artist "Relaxed interpretations" of sans serif typefaces typical of 1950. It's great for big posters and fun headlines. Use it bigger than 40px for maximum effect.www.impallari.comThis Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFLhttp://scripts.sil.org/OFL��9�WUFVSDGOEXHJ/TPIMRNZ]Y\[%&'()*+,-$73=48<9:0261;_� ��B � �����"
�?����>@A�������^`��������������#������������ 5.
 L�� � �� KQ���� �������!a���� !"#$%&'()*+,-.�C�/ikln01mjpr2s3456q78�9:x;y{|<=}z>?@AB�~��CDEFGHIJK�L�MNOP��QRSTUVWXYZ��[\]^_`ab��bccd��e�fg�hie�j�klmn�op�q����rst�uvwfx��gyz��{|}~����h�����������������������������twv����u������������������������������od�����������������������NULLEuro zerosuperior foursuperiorengEng kgreenlandicschwauni00ADuni03BC commaaccentdotlessjuni00A0Schwa zeroinferior oneinferior twoinferior threeinferior fourinferiorf_ff_lf_f_if_f_lf_if_bf_f_bf_hf_f_hf_jf_kf_f_jf_f_kf_tf_f_tIJijuni01F1uni01F2uni01F3uni01CAuni01CBuni01CCuni01C7uni01C8uni01C9
apostropheabreveamacron
edotaccentebreveemacronetildeecaron gcircumflex
gdotaccentnacute
ndotaccentncaronobreveomacron ohungarumlautracutercaronsacute scircumflexuringubreveumacronutilde uhungarumlautwacute wcircumflex wdieresiswgrave ycircumflexytildeygravezacute
zdotaccent ccircumflex
cdotaccentuni2215 napostropheaeacutedcaron hcircumflex gcommaaccenthbarlcaron oslashacute
aringacutetbaruni01C6tcaronuni2219ldotlacuteAbreveAmacronAEacute Ccircumflex
CdotaccentDcroatDcaron
EdotaccentEbreveEmacronEtildeEcaron Gcircumflex
Gdotaccent HcircumflexIbreveImacronItilde JcircumflexNacute
NdotaccentNcaronObreveOmacron OhungarumlautRacuteRcaronSacute ScircumflexTcaronUringUbreveUmacronUtilde UhungarumlautWacute Wcircumflex WdieresisWgrave YcircumflexYtildeYgraveZacute
Zdotaccent
Aringacuteuni01C4uni01C5TbarHbarLacuteLcaronLdot Oslashacuteitildeimacronibreve jcircumflexiogonekeogonekaogonekuogonekoogonekEogonekIogonekAogonekUogonekOogonek idotbelow hdotbelow edotbelow tdotbelow rdotbelow sdotbelow ddotbelow udotbelow odotbelow zdotbelow Ddotbelow Edotbelow Hdotbelow Idotbelow Tdotbelow Zdotbelow Udotbelow Odotbelow Sdotbelow Rdotbelow ncommaaccent rcommaaccent lcommaaccent Lcommaaccent kcommaaccent Gcommaaccent Ncommaaccent Rcommaaccent Kcommaaccentuni021Buni0219uni021Auni0218uni0163uni015Funi0162uni015Eonethird twothirds��
,latn��kern$.&�[��h�f!. �#.B���B��R!��!�!�RPt��� �j�&!���t�#\�  PD�" z#�"�Pr�����8r �� 0���� 0 0�
� X �
� � � �

"
� N
� $ N � �B � " L r | �j � �"6"| 0 � N d � �� �!!�>���TZd����BB!!�!��!�fft� PP8��������������B��RRR!!|!��&\��
��������<RRRR�����PPP � �<!��!R!p�$$�fP|���������� � � �jj���������!�!�!��������F�t"""" z z z z z z z z"6"6#�#�#�#\ P P P P P P P P P����   � PH�!��R�T� ~�.��<������ P8!��!.#.��Pj���#\  P z#�"6 � �!!.!`!�!�!�""6"|"�#.#\#�##.#\#�
FHJCLLFNNGRSHUUJXXKZZL]fMmmWopXxzZ��]��_��e��j��l��n��p��t��v�� �#����=��A
��-�������������������1��--��U��v������������-3J[ fw��������{|=}8~(�1�@�2,- 3 J
Q[
fvw �
�����
0{|E}@~0�+�H� �� ��-��3��U��[��f��v���������������������-��U��[fv���������������-��3��<��J��Q��U��[��f��v��w��|��������������  �� ������8��:��=��J z��{��������������������)��{��|>}9~(�4�A�/�� ��-��3��8��:��; =��JU��[��f��v��z�������������������|}~� ����-��3��U��[��f��v����������s��%�� ������4��6��8��:��;��<=��U [fvz��{��|��������������������� ��������0{��|?}7~1�C�>�; ��4��6:��;��<U[fv{��|���������
������� ��2|>},~3�I�4�B-��3��U��[��f��m�������-��3;��C��U��m���-��3C��-��U��[��f��m������� -��<��U��[��f��m����������m����
-��3��<��U��[��f��m����������-��3��U��[��f��m�������- 38��:��A��C��D��X��i��m�������������-��U��[��f��m���������-��4��;�����y��z��5��<��&|"}~ ��&�!5��<��<����J��3
4��8��:��;��=��H��e���������������Fy��z��|} ~�(�J�=� ����1st{|3},~1�1���-��4��;�����-38��:��z�������"|3}-~! �.�5�9��-��4��8��:��;��=�����������yz5��<��?��-34��8��:��;��=��H��e������,yz|=}"~*�5�?�>-�����s������-��3�� 
s��  3��� |~�)���Jz��������������+t{|@};~+�(�C
��-��3
4��;�����y z �?��-34��8��:��;��=��H��e������)yz|;}~)�4�?�=[��f�����4��8��:��;��< =�� ����-��3��5��<��J��U��[��f��v��w����������s��
,��-��Q��U��v��w����������� ���|*}&~�!�-�-��3��8��:������-��3��J��Q��U��[��f��v��w��|����������� ����-��3������� |}� � ������J��Q��U��[��f��v��w��|��������������-��3��5��<��s����-��������s��
-���������
6��-��3 ���������  y z �6[��f�����- 3 J
[
fw �
����0{|E}@~0�+�H� ����-��3��U��[��f��v�������s����-��s��<��5��<������-3J[ fw���������{|=}8~(�1�@�2
-3 ���
|*}%~�"�-�,- 3 J
[
fw �
������ 0{|E}@~0�+�H� ����-��3��J��Q��U��[��f��v��w��|������������� ,- 3 J
[
fw �
������ %6{|K}F~6�1�N� ,-3 J
Q[
fvw �
�����
0{|E}@~0�+�H� ����������-��3��J��Q��U��v��w����������� ��-��Q��U��v��w���������������-��3��J��Q��U��[��f��v��w�����������������-��3��J��Q��U��[��f��v��w������������� �� �� -��3��U[fv������������� ��#-��3��BQU[%f"vw ����� ����*��� ����-��J��U��f��v������������  ����-��J��U��f��v������������ ����-��J��U��fv������������
-��U��v������ �� ��-��3��U��[��f��v��������������� ��-��3��U��[��f��v����������������������� ��-��3��U��[��f��v���������������������-��U��v�����������-��U��v���������������- 34��8��:��;��=����������|)}~�2�!�+> S�3BrJsQrU�[�f�v�wo{|I�q�/�e������� C|&}!~��)�&83BJ5Q#U[0f-v%w.| �,����|&}!~��)�&-��U��v���������!? T�-3 BtJtQsU�[�f�v�wp{|K�q�0�e��� ����Q�;�f� D9|*}%~�"�-�, ��-3 ���|*}%~�"�-�,����-��3��J��QU��[��f��v��w ���������-��U��v��������) =s -��B]J_Q]Uq[{fyvjwY|4�\��O�y�
�����:�O"{1 -3 ���|*}%~�"�-�, ��J�������"|7}2~"�,�:�% ��������|1},~�'�4� �����|-}(~�#�1� �� ����8��:��=��U[ fz��{��������������������� ��,{��|<}3~,�;�<�5:�� ������4��6��8��:��;��< =��U[fv z��{��|���������������������������������������������������� ���������������������� �� ������/{��|<}-~2�G�5�@����-��4��6;��J��Q��U��[f v��w��{��|�������������� �� ������4��8��:��=��Jz��{����������������������������������({��|<}7~'�2�?�+  Jw� ���|-}(~�&�0�����-"3(;��<��J��Q��U[fv
w��{��|�����������t ����-��;��<��J��Q��U��v��w��{��|�������������s������-��;��<��J��Q��U��v��w��{��|���������������������������� �� ��-��3��U[fv� �����s�� - 3 B&JQ U/[CfBv(w�
�B�����/0{|E}@~0�+�H�  L- 3 B'J5Q7U+[Af>v9w;|�<�����0{|E}@~0�+�H� G- 3 B"J-Q2U['f!v(w5�7�����0{|E}@~0�+�H� 3- 3 B J%QU#[*f)vw'�%�����0{|E}@~0�+�H� - 3 J
U[fvw �
����0{|E}@~0�+�H� 0- 3 BJQ&U6[:f9v/w�"� �-����0{|E}@~0�+�H�  J- 3 B%J0Q5U [&f$v+w8�:�����0{|E}@~0�+�H� - 3 J[fw�����0{|E}@~0�+�H� ;- 3 ? J
L [
fw �
����0{|E}@~0�+�H� L-��?LU��v��� ������ N-��?!L!U��v�����������F��-��4��6;��?J��LQ��U��[f v��w��{��|���������������-- 3 J
[
fw �
����0{|E}@~0�+�H� ������-��3��J��Q��U��v��w�����������-��U��v��������3���|&}!~��)�&-��U��v������������-��3��J��Q��U��[��f��v��w�������������-��U��v����������� ����-��3��U��[��f��v����������
 s�� �������� |3}.~�(�6�$���|-}(~�&�0�
�������|1},~�'�4� ��{�����|3}/~�'�7�
3�������|)}%~��,� ����-��3��U��[��f��v����������s��-��U��v����������� ��J������"|7}2~"�,�:�% ��-��Q��U��v��w����������� �� ��-��3��U��[��f��v�������������
#-3 ���|*}%~�"�-�,����-��;��<��J��Q��U��v��w��{��|������������� -��U��[fv�������������-�����|}�����|*}&~�!�-� -��8��:��[ f v��������������|}~�����4��68��:��;��< BU["f v {��|���������������� ��-|9}$~0�G�,�@-��U��v��������-��U��v�������� ����-��J��U��f��v������������ �� ������4��8��:��=��J z��{����������������������������������({��|<}7~'�2�?�+����-��3��� �����|)}$~��,�'��&����&��'��,��N��c�����������������������$��%��&��'��(��)��*��+��,��Z��h��i��j��k��l��p��s��������������o ��
������������%��&��'��)��,��.��>��?��@��E��F��IL��]��^��`��bd�������������������������������������������������������������������������������������������������������������������������������� ��
�� ��������������$��%��&��'��(��)��*��+��,��H��Z��d��e��f��g��h��i��j��k��l��m��n��o��p��s���������������������������������>���� P v�:��V`�4���V����T6 v!�4�#�$�%b%b%x%�(,(6(�(�),+�,�,�-�-�-�-�.�1x1�2`2`2~2�3B3�444~4�>!(-3456789:;<=HJUZdepz���������������  stvyz{|}~���&������$����������������������������������������� �� ����������@��A��B��C��D��E��F��G���������������������������� ��
��������������"��'��*��,��.��0��1@��E��F��I ]��`��b ������������������������������������������������������������������������������������������������������������������������������������������������������������ �� ����������������������-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��WXYZ��d��e��f��g��h��i��j��k��l��s��y��z��������������������������������������������������3����&��'��,��.��I��N��R��S��^��_��a��b��c��������������������������$��%��&��'��(��)��*��+��,��Z��d��e��f��g��h��i��j��k��l��p��s������������������������� ��
������������������������"��%��&��*��0��>��?��@��E��F��L��]��^��_��`��a��d��x��������� ���� ���������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������ ��
�� �� �� ������������������������ ��$��%��&��'��(��)��*��+��,��-��.��/��0��<��=��>��H��M��N��O��P��Q��R��S��T��p��y��z�� � ������������� ������������������������������������������������������r�� ��
���������� $��%��&��)��,��>��?��@��E��F��L��]��`��d��������������������������������������������������������������������������������������������������������     �� ��������������������$��%��&��'��(��)��*��+��,��@��A��B��C��D��E��F��G��H��h��i��j��k��l��m��n��o��p������������������������������������������� ��
�������������� ����������"��%��&��)��*��0��1��>��?��@��E��F��L��RS]��^��_��`��a��d��x��������� ���� ���������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������ ��
�� �� �� �������������������������� ��$��%��&��'��(��)��*��+��,��-��.��/��0��<��=��>��H��M��N��O��P��Q��R��S��T��W��X��Y��m��n��o��p��y��z��� ������������� ����������������������������������������������������������������������� ��
��������������������"��*��+��0��@��E��F��RS]��`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ �� ������������������������ ��-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��[��\��]��^��_��`��a��b��c��y��z��������������������������������������������������&��'��,��>��?��L��d��������$��%��&��'��(��)��*��+��,��Z��h��i��j��k��l��p��s�������������� &'��,��.��R��S���$%&'()*+,Z��d��e��f��g��h��i��j��k��l��ps������������,���,h��i��j��k��l��,�����,��h��i��j��k��l��'��,��.��R��S�����,��Z��d��e��f��g��h��i��j��k��l��s��������������,��%'��,��.��R��S��HZ��d��e��f��g��h��i��j��k��l��s�����������%��&��)��,��>��?��L��d��������$��%��&��'��(��)��*��+��,��H��h��i��j��k��l��m��n��o��p��������&"��&��,.>��?��@��E��F��L��d�����������$��%��&��'��(��)��*��+��,��<��=��>��defghijklp��������'��,��.��Z��d��e��f��g��h��i��j��k��l��s�������������������� ��
����������������������"��*��,0��1��x����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �� ���������������������� ��-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��W��X��Y��hijkl���������������������������������������������������������������������X���� ��
����������%��&��' ��������������������������������������������������������������������������������������������������������� �� ��������������������$��%��&��'��(��)��*��+��,��H��Z p��������������������������� ������� ���� ����� ��
��������������������"��'��*��+��,��.��0��N��R��S��c�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �� ������������������ ��-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��Z��[��\��]��^��_��`��a��b��c��d��e��f��g��h��i��j��k��l��s���������������������������������������������������������������� ��
��������������������"��&*��,. 0��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �� ������������������ ��$%&'()*+,-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��d e f g hijklp��������������������������������������������,����� ��
��������������������"��& *��,.
0������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ �� �������������������� ��$ % & ' ( ) * + ,-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��d
e
f
g
hijklp ���������� ���������������������������������B$��%��&��'��)��,��.��1��>��?��I��L��N��R��S��b��c��d�����������$��%��&��'��(��)��*��+��,��@��A��B��C��D��E��F��G��H��W��X��Y��Z��d��e��f��g��h��i��j��k��l��m��n��o��p��������������������������������'��,��.��R��S�����,��Z��d��e��f��g��h��i��j��k��l��s�����������8��������'��,��.��I��N��R��S��b��c�������������������������������������������������������������������� ��Z��d��e��f��g��h��i��j��k��l��s��������������������5������&��'��)��,��.��_��a����������������������� ��
�� ��$��%��&��'��(��)��*��+��,��Z��d��e��f��g��h��i��j��k��l��m��n��o��p��s��������������������������I��N��R��S��^��_��a��b��c����������������������� ��
�� �����B�� ��
����������,�������������������������������������������������������������������������������������������� �� ��������������������h��i��j��k��l������������������������� ��
������������������"��'��*��+��,��.��0��������� ��������������������������������������������������������������������������������������������������������������������������������������������������������� �� ������������������ ��, -��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��Z��[��\��]��^��_��`��a��b��c��d��e��f��g��h��i��j��k��l��s�����������������������������������������������������<$��%��&��'��)��,��.��1��>��?��L��d�����������$��%��&��'��(��)��*��+��,��@��A��B��C��D��E��F��G��H��W��X��Y��Z��d��e��f��g��h��i��j��k��l��m��n��o��p��������������������������������/
��%'��),��.��1 N��R��S��c�������������


HW X Y Z��d��e��f��g��h��i��j��k��l��mno�
����� ���� ���� ����$IRSb�@ABCDEFG������������� ��
�� �� ��������������������������o��x�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��
�� �� �� �������������������������������� ��"��#��{��|��}��~����������������������������������������������������������������������������������RS  NRSco�����"#{|}~������������{|}~������ � � � { | } ~  � � � � � ����������� ��
������������������������"��&��*��,.0��x����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��
�� �� �� �������������������������� ��$��%��&��'��(��)��*��+��,��-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��defghijklp��y��z��������������������������������������������������������������������20 | ~9~IfN|R�S�bfc|o~�������~�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9��~~||0 0"|#|{�������~�0�|�~�0�0I*N-R&S&b*c-�2�2�2�2{22�2�221 } :IgN|R�S�bgc|o��������:�:�:�:�:�:�:�:�:�:�:�:�:�:�:��}}1 1"}#}{��������1�}��1�1
�
�
�
IR��S��b= g h$hIQNfRuSubQcfoh�m�m�m�h�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�mhhgg "g#g|m}m~mm�m�m�m�m�m�h��g�h������������� ��
������������������������"��*��0��@��E��F��]��^��_��`��a��x��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��
�� �� �� �������������������������� ��-��.��/��0��<��=��>��M��N��O��P��Q��R��S��T��y��z������������������������������������������������������������������� IN bc ����{��- ',$.I��NRSb��co� � � �� Zdefgh$i$j$k$l$s{ | } ~  � � � � � �����'RSZ��� ' ((NR=S=co(� � �(� (''"'#' � � �(�'�( ( ((I.NBR7S7b.cBo(�F�F�(�F((("(#(F�F�F�(�(�( # ##I&N=R1S1b&c=o#�A�A�#�A###"###A�A�A�#�#�#  IN(R"S"bc(o�-�-��-"#-�-�-���RS  IN/R2S2bc/o�*�*��*"#*�*�*��� & &&I)N@R4S4b)c@o&�D�D�&�D&&&"&#&D�D�D�&�&�&Nc����� 4 "�*%���������������������������������������������������������������������������������������������������������������������������� �������������������� ���������������������������������������������������������� ����������������������������������������������������������������������������������
������������������������������������������������������������������������������ ������������������������������������������������������������������������������������������������������������������������������������������������ ���������������������������������������������������������� ���������������� ������������������������������������������������������������������������������������ �������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������'  ""$'),..!01">@$EF'II)LL*NN+RS,]d.oo6xx7��8��9��<��>��@��B��C��F�Z�� �#>�@H�Ms�u�������� ����!�&$%')(   ! "##!" 
&&))$$%%%''''((((()))&)&
)   &$%) 
$
&% &% �# $#
 # ""$$%%&&''))**++,,
..0011>?@@ EF II LLNNRS]]^^"__!``aa!bb ccddxx#���� �� ��"�� ��#���������������� ������ ����#����#��$��    #  $+,,-0<>@GHHMTWYZZ[cdghl
moppssyz{� �� ������������ �� ����#��$���������������������� ����#������$��������$����
&dlatn��frac liga&ordn,sinf2sups8�(p� (08@HPX^djpv|��� � �������� � �������D ,8�6�7�8�7�8567y=48
$, &4=0w�w� &0

1001
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-BlackItalic.ttf
文件差异内容过多而无法显示
查看文件

1001
Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-Italic.ttf
文件差异内容过多而无法显示
查看文件

124
Samples/UIWidgetsSamples_2019_4/Assets/Behavior1.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UIWidgetsSample;
using Unity.UIWidgets.engine2;
using Unity.UIWidgets.external;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.ui2;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui2.Canvas;
using Color = Unity.UIWidgets.ui2.Color;
using Paint = Unity.UIWidgets.ui2.Paint;
using ParagraphBuilder = Unity.UIWidgets.ui2.ParagraphBuilder;
using ParagraphConstraints = Unity.UIWidgets.ui2.ParagraphConstraints;
using ParagraphStyle = Unity.UIWidgets.ui2.ParagraphStyle;
using Picture = Unity.UIWidgets.ui2.Picture;
using PictureRecorder = Unity.UIWidgets.ui2.PictureRecorder;
using Rect = Unity.UIWidgets.ui.Rect;
using SceneBuilder = Unity.UIWidgets.ui2.SceneBuilder;
using TextDecoration = Unity.UIWidgets.ui2.TextDecoration;
using TextDecorationStyle = Unity.UIWidgets.ui2.TextDecorationStyle;
using Window = Unity.UIWidgets.ui2.Window;
class Behavior1 : UIWidgetsPanel
{
void beginFrame(TimeSpan timeStamp) {
// The timeStamp argument to beginFrame indicates the timing information we
// should use to clock our animations. It's important to use timeStamp rather
// than reading the system time because we want all the parts of the system to
// coordinate the timings of their animations. If each component read the
// system clock independently, the animations that we processed later would be
// slightly ahead of the animations we processed earlier.
// PAINT
Rect paintBounds = Offset.zero & (Window.instance.physicalSize / Window.instance.devicePixelRatio);
PictureRecorder recorder = new PictureRecorder();
Canvas canvas = new Canvas(recorder, paintBounds);
canvas.translate(paintBounds.width / 2.0f, paintBounds.height / 2.0f);
// Here we determine the rotation according to the timeStamp given to us by
// the engine.
float t = (float) timeStamp.TotalMilliseconds / 1800.0f;
canvas.rotate(Mathf.PI * (t % 2.0f));
var paint = new Paint();
paint.color = Color.fromARGB(100, 100, 100, 0);
canvas.drawRect(Rect.fromLTRB(0, 0, 100.0f, 100.0f), paint);
Draw(canvas);
Picture picture = recorder.endRecording();
// COMPOSITE
float devicePixelRatio = Window.instance.devicePixelRatio;
var deviceTransform = new float[16];
deviceTransform[0] = devicePixelRatio;
deviceTransform[5] = devicePixelRatio;
deviceTransform[10] = 1.0f;
deviceTransform[15] = 1.0f;
SceneBuilder sceneBuilder = new SceneBuilder();
sceneBuilder.pushTransform(deviceTransform);
sceneBuilder.addPicture(Offset.zero, picture);
sceneBuilder.pop();
Window.instance.render(sceneBuilder.build());
// After rendering the current frame of the animation, we ask the engine to
// schedule another frame. The engine will call beginFrame again when its time
// to produce the next frame.
Window.instance.scheduleFrame();
}
void Draw(Canvas canvas)
{
var style = new ParagraphStyle(fontFamily: "Arial", height: 4);
var pb = new ParagraphBuilder(style);
var ts = new TextStyle(
color: new Color(0xFFFF00F0),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "Arial",
fontSize:30,
height:1.5
);
pb.pushStyle(ts);
pb.addText("just for test\n 中文测试 分段测试 分段测试 分段测试 分段测试 分段测试 分段测试 分段测试\n1234");
var ts2 = new TextStyle(
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.dashed,
fontFamily: "Arial",
fontSize:40,
height:1.5,
background: new Paint()
{
color = new Color(0xAAFF7F00),
}
,
foreground:new Paint()
{
color = new Color(0xAAFFFF00)
}
);
pb.pushStyle(ts2);
pb.addText("test push one more style");
pb.pop();
pb.addText("test pop style");
var p = pb.build();
p.layout(new ParagraphConstraints(300));
canvas.drawParagraph(p, new Offset(-100, -100));
}
protected override void main()
{
Window.instance.onBeginFrame = beginFrame;
Window.instance.scheduleFrame();
}
}

20
engine/src/lib/ui/txt/utils.h


#pragma once
namespace uiwidgets {
#define DATALIST(T,N) \
extern "C" struct N{\
T* data;\
int length;\
};
DATALIST(float, Float32List)
DATALIST(int, Int32List)
DATALIST(size_t, SizeTList)
DATALIST(char, CharList)
DATALIST(CharList, StringList)
extern "C" struct StringList2 {
char** data;
int length;
};
}
正在加载...
取消
保存