浏览代码

Merge pull request #12 from Unity-Technologies/siyaoH/skia

add paragrah
/siyaoH-1.17-PlatformMessage
GitHub 4 年前
当前提交
51985979
共有 39 个文件被更改,包括 6321 次插入107 次删除
  1. 18
      com.unity.uiwidgets/Runtime/ui/painting/shader.cs
  2. 174
      com.unity.uiwidgets/Runtime/ui2/painting.cs
  3. 62
      engine/Build.bee.cs
  4. 24
      engine/README.md
  5. 3
      engine/src/TestLoadICU.cpp
  6. 2
      engine/src/lib/ui/window/window.h
  7. 3
      engine/src/render_api.h
  8. 7
      engine/src/render_api_d3d11.cc
  9. 6
      engine/src/runtime/runtime_controller.cc
  10. 3
      engine/src/runtime/runtime_controller.h
  11. 9
      engine/src/runtime/runtime_delegate.h
  12. 12
      engine/src/shell/common/engine.cc
  13. 8
      engine/src/shell/common/engine.h
  14. 22
      engine/src/shell/common/shell.cc
  15. 1
      engine/src/shell/platform/embedder/embedder.cc
  16. 2
      engine/src/shell/platform/embedder/embedder.h
  17. 13
      engine/src/shell/platform/unity/uiwidgets_panel.cc
  18. 198
      Samples/UIWidgetsSamples_2019_4/Assets/TextTest.cs
  19. 641
      Samples/UIWidgetsSamples_2019_4/Assets/TextTest.unity
  20. 1001
      com.unity.uiwidgets/Runtime/ui2/text.cs
  21. 9
      engine/src/shell/common/lists.cc
  22. 9
      engine/src/shell/common/lists.h
  23. 42
      engine/src/shell/common/switches.cc
  24. 10
      engine/src/shell/common/switches.h
  25. 825
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Ranchers-Regular.ttf
  26. 1001
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-BlackItalic.ttf
  27. 1001
      Samples/UIWidgetsSamples_2019_4/Assets/StreamingAssets/Roboto-Italic.ttf
  28. 228
      engine/src/lib/ui/text/paragraph.cc
  29. 50
      engine/src/lib/ui/text/paragraph.h
  30. 49
      engine/src/lib/ui/text/paragraph_builder.h
  31. 129
      engine/src/lib/ui/text/asset_manager_font_provider.cc
  32. 82
      engine/src/lib/ui/text/asset_manager_font_provider.h
  33. 129
      engine/src/lib/ui/text/font_collection.cc
  34. 35
      engine/src/lib/ui/text/font_collection.h
  35. 116
      engine/src/lib/ui/text/icu_util.cc
  36. 15
      engine/src/lib/ui/text/icu_util.h
  37. 489
      engine/src/lib/ui/text/paragraph_builder.cc

18
com.unity.uiwidgets/Runtime/ui/painting/shader.cs


return true;
}
return _listEquals(colors, other.colors) &&
_listEquals(positions, other.positions);
return colors.equalsList(other.colors) &&
positions.equalsList(other.positions);
}
public override bool Equals(object obj) {

return hashCode;
}
}
static bool _listEquals<T>(List<T> left, List<T> right) {
if (left.Count != right.Count) {
return false;
}
for (int i = 0; i < left.Count; i++) {
if (!left[i].Equals(right[i])) {
return false;
}
}
return true;
}
}
}

174
com.unity.uiwidgets/Runtime/ui2/painting.cs


}
}
internal static T[] range<T>(this T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
internal static uint[] _encodeColorList(List<Color> colors) {
int colorCount = colors.Count;
var result = new uint[colorCount];

public static readonly Color black = new Color(0xFF000000);
public static readonly Color white = new Color(0xFFFFFFFF);
public static Color fromARGB(int a, int r, int g, int b) {
return new Color(
(uint) (((a & 0xff) << 24) |

}
/* TODO
void drawParagraph(Paragraph paragraph, Offset offset) {
assert(paragraph != null);
assert(_offsetIsValid(offset));
public void drawParagraph(Paragraph paragraph, Offset offset) {
D.assert(paragraph != null);
D.assert(PaintingUtils._offsetIsValid(offset));
*/
public unsafe void drawRawPoints(PointMode pointMode, float[] points, Paint paint) {
D.assert(points != null);

static extern IntPtr PictureRecorder_endRecording(IntPtr ptr);
}
// TODO: for text.
public class Shadow {
public class Shadow : IEquatable<Shadow> {
public Shadow(
Color color,
Offset offset,
float blurRadius = 0) {
D.assert(color != null);
D.assert(offset != null);
D.assert(blurRadius >= 0.0);
this.color = color ?? new Color(_kColorDefault);
this.offset = offset ?? Offset.zero;
this.blurRadius = blurRadius;
}
static readonly uint _kColorDefault = 0xFF000000;
// Constants for shadow encoding.
static readonly int _kBytesPerShadow = 16;
static readonly int _kColorOffset = 0 << 2;
static readonly int _kXOffset = 1 << 2;
static readonly int _kYOffset = 2 << 2;
static readonly int _kBlurOffset = 3 << 2;
public readonly Color color;
public readonly Offset offset;
public readonly float blurRadius;
public static float convertRadiusToSigma(float radius) {
return radius * 0.57735f + 0.5f;
}
public float blurSigma {
get { return convertRadiusToSigma(blurRadius); }
}
public Paint toPaint() {
return new Paint() {
color = color,
maskFilter = MaskFilter.blur(BlurStyle.normal, blurSigma)
};
}
public Shadow scale(float factor) {
return new Shadow(
color: color,
offset: offset * factor,
blurRadius: blurRadius * factor
);
}
public static Shadow lerp(Shadow a, Shadow b, float t) {
D.assert(t != null);
if (a == null && b == null)
return null;
if (a == null)
return b.scale(t);
if (b == null)
return a.scale(1.0f - t);
return new Shadow(
color: Color.lerp(a.color, b.color, t),
offset: Offset.lerp(a.offset, b.offset, t),
blurRadius: Mathf.Lerp(a.blurRadius, b.blurRadius, t)
);
}
public static List<Shadow> lerpList(List<Shadow> a, List<Shadow> b, float t) {
D.assert(t != null);
if (a == null && b == null)
return null;
a = a ?? new List<Shadow>();
b = b ?? new List<Shadow>();
List<Shadow> result = new List<Shadow>();
int commonLength = Math.Min(a.Count, b.Count);
for (int i = 0; i < commonLength; i += 1)
result.Add(Shadow.lerp(a[i], b[i], t));
for (int i = commonLength; i < a.Count; i += 1)
result.Add(a[i].scale(1.0f - t));
for (int i = commonLength; i < b.Count; i += 1)
result.Add(b[i].scale(t));
return result;
}
internal static byte[] _encodeShadows(List<Shadow> shadows) {
if (shadows == null)
return new byte[0];
int byteCount = shadows.Count * _kBytesPerShadow;
byte[] shadowsData = new byte[byteCount];
int shadowOffset = 0;
for (int shadowIndex = 0; shadowIndex < shadows.Count; ++shadowIndex) {
Shadow shadow = shadows[shadowIndex];
if (shadow == null)
continue;
shadowOffset = shadowIndex * _kBytesPerShadow;
shadowsData.setInt32(_kColorOffset + shadowOffset,
(int) (shadow.color.value ^ Shadow._kColorDefault));
shadowsData.setFloat32(_kXOffset + shadowOffset,
shadow.offset.dx);
shadowsData.setFloat32(_kYOffset + shadowOffset,
shadow.offset.dy);
shadowsData.setFloat32(_kBlurOffset + shadowOffset,
shadow.blurRadius);
}
return shadowsData;
}
public override string ToString() => $"TextShadow({color}, {offset}, {blurRadius})";
public bool Equals(Shadow other)
{
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return Equals(color, other.color) && Equals(offset, other.offset) && blurRadius.Equals(other.blurRadius);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != GetType()) {
return false;
}
return Equals((Shadow) obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = (color != null ? color.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (offset != null ? offset.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ blurRadius.GetHashCode();
return hashCode;
}
}
}
delegate void _Callback<T>(T result);

62
engine/Build.bee.cs


"src/lib/ui/compositing/scene.h",
"src/lib/ui/compositing/scene_builder.cc",
"src/lib/ui/compositing/scene_builder.h",
"src/lib/ui/text/icu_util.h",
"src/lib/ui/text/icu_util.cc",
"src/lib/ui/text/asset_manager_font_provider.cc",
"src/lib/ui/text/asset_manager_font_provider.h",
"src/lib/ui/text/paragraph_builder.cc",
"src/lib/ui/text/paragraph_builder.h",
"src/lib/ui/text/font_collection.cc",
"src/lib/ui/text/font_collection.h",
"src/lib/ui/text/paragraph.cc",
"src/lib/ui/text/paragraph.h",
"src/lib/ui/painting/canvas.cc",
"src/lib/ui/painting/canvas.h",

"src/shell/common/canvas_spy.h",
"src/shell/common/engine.cc",
"src/shell/common/engine.h",
"src/shell/common/lists.h",
"src/shell/common/lists.cc",
"src/shell/common/persistent_cache.cc",
"src/shell/common/persistent_cache.h",
"src/shell/common/pipeline.cc",

"src/shell/common/shell_io_manager.h",
"src/shell/common/surface.cc",
"src/shell/common/surface.h",
"src/shell/common/switches.cc",
"src/shell/common/switches.h",
"src/shell/common/thread_host.cc",
"src/shell/common/thread_host.h",
"src/shell/common/vsync_waiter.cc",

},
OutputName = {c => $"libUIWidgets{(c.CodeGen == CodeGen.Debug ? "_d" : "")}"},
};
np.Libraries.Add(new BagOfObjectFilesLibrary(
new NPath[]{
skiaRoot+"third_party/externals/icu/flutter/icudtl.o"
}));
np.IncludeDirectories.Add("src");
np.IncludeDirectories.Add("src");
np.Defines.Add("UIWIDGETS_ENGINE_VERSION=\\\"0.0\\\"", "SKIA_VERSION=\\\"0.0\\\"");

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/");
// }
return np;
}

new StaticLibrary(basePath + "/skottie.lib"),
new StaticLibrary(basePath + "/sksg.lib"),
new StaticLibrary(basePath + "/skshaper.lib"),
new StaticLibrary(basePath + "/icu.lib"),
new StaticLibrary(basePath + "/harfbuzz.lib"),
new StaticLibrary(basePath + "/libEGL.dll.lib"),
new StaticLibrary(basePath + "/libGLESv2.dll.lib"),

"U_ENABLE_DYLOAD=0", "USE_CHROMIUM_ICU=1", "U_STATIC_IMPLEMENTATION",
"ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC"
});
np.IncludeDirectories.Add(flutterRoot + "/flutter/third_party/txt/src");
np.IncludeDirectories.Add(skiaRoot + "/third_party/externals/harfbuzz/src");
np.IncludeDirectories.Add(skiaRoot + "/third_party/externals/icu/source/common");

24
engine/README.md


```
Ignore this error: "lld-link: error: could not open 'EGL': no such file or directory"
convert icudtl.dat to object file in skia
```
cd SkiaRoot/third_party/externals/icu/flutter/
ld -r -b binary -o icudtl.o icudtl.dat
```
### Build flutter fml
1. Setting up the Engine development environment

+ ]
+}
```
cmd
```
set GYP_MSVS_OVERRIDE_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community
cd engine/src

## Create symbolic
### Create symbolic
cmd
cd <uiwidigets_dir>\engine
cd third_party \\ create the directory if not exists
mklink /D skia <SKIA_ROOT>
cd <uiwidigets_dir>\engine
cd third_party   \\ create the directory if not exists
mklink /D skia <SKIA_ROOT>
```
Flutter engine txt include skia header in this pattern 'third_party/skia/*', so without symbolic, the txt lib will include skia
header file in flutter engine, instead of headers in skia repo.

bee
```
## Set ICU Data Enviroment Varaible
```
set UIWIDGETS_ICUDATA=<SKIA_ROOT>/out/Debug/icudtl.dat
```
Unity Editor need to run with those environment variables set.
```

3
engine/src/TestLoadICU.cpp


return end ? std::string(path, end - path) : std::string();
}
bool TestLoadICU()
bool TestLoadICU()
{
static bool good = false;
static std::once_flag flag;

}
}
});
return good;
}

2
engine/src/lib/ui/window/window.h


virtual void ScheduleFrame() = 0;
virtual void Render(Scene* scene) = 0;
virtual void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) = 0;
// virtual FontCollection& GetFontCollection() = 0;
virtual FontCollection& GetFontCollection() = 0;
virtual void SetNeedsReportTimings(bool value) = 0;
protected:

3
engine/src/render_api.h


#pragma once
#include "Unity/IUnityGraphics.h"
class RenderAPI {
public:
virtual ~RenderAPI() {}

virtual void SetImageTexture(void* ptr) = 0;
virtual void Draw() = 0;
virtual void Draw() = 0;
virtual void PreDraw() = 0;

7
engine/src/render_api_d3d11.cc


#include "TestLoadICU.h"
#include "Unity/IUnityGraphicsD3D11.h"
#include "flutter/fml/message_loop.h"
#include "txt/paragraph.h"
#include "txt/paragraph_builder.h"
#include "txt/font_collection.h"
#include "flutter/third_party/txt/src/txt/font_collection.h"
#include "flutter/third_party/txt/src/txt/paragraph.h"
#include "flutter/third_party/txt/src/txt/paragraph_builder.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"

6
engine/src/runtime/runtime_controller.cc


}
// |WindowClient|
// FontCollection& RuntimeController::GetFontCollection() {
// return client_.GetFontCollection();
//}
FontCollection& RuntimeController::GetFontCollection() {
return client_.GetFontCollection();
}
// |WindowClient|
void RuntimeController::SetNeedsReportTimings(bool value) {

3
engine/src/runtime/runtime_controller.h


#include "flow/layers/layer_tree.h"
#include "flutter/fml/macros.h"
#include "lib/ui/io_manager.h"
//#include "lib/ui/text/font_collection.h"
#include "lib/ui/ui_mono_state.h"
#include "lib/ui/window/pointer_data_packet.h"

void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) override;
// |WindowClient|
// FontCollection& GetFontCollection() override;
FontCollection& GetFontCollection() override;
// |WindowClient|
void SetNeedsReportTimings(bool value) override;

9
engine/src/runtime/runtime_delegate.h


#include <vector>
#include "flow/layers/layer_tree.h"
//#include "lib/ui/text/font_collection.h"
#include "lib/ui/text/font_collection.h"
#include "lib/ui/window/platform_message.h"
namespace uiwidgets {

virtual void Render(std::unique_ptr<LayerTree> layer_tree) = 0;
virtual void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) = 0;
//virtual FontCollection& GetFontCollection() = 0;
virtual FontCollection& GetFontCollection() = 0;
virtual void SetNeedsReportTimings(bool value) = 0;
protected:

12
engine/src/shell/common/engine.cc


#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
#include "flutter/fml/unique_fd.h"
//#include "lib/ui/text/font_collection.h"
#include "lib/ui/text/font_collection.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPictureRecorder.h"
#include "rapidjson/document.h"

}
//// Using libTXT as the text engine.
// font_collection_.RegisterFonts(asset_manager_);
font_collection_.RegisterFonts(asset_manager_);
return true;
}

runtime_controller_ = runtime_controller_->Clone();
UpdateAssetManager(nullptr);
return Run(std::move(configuration)) == RunStatus::Success;
}
void Engine::SetupDefaultFontManager() {
TRACE_EVENT0("uiwidgets", "Engine::SetupDefaultFontManager");
font_collection_.SetupDefaultFontManager();
}
Engine::RunStatus Engine::Run(RunConfiguration configuration) {

delegate_.SetNeedsReportTimings(needs_reporting);
}
// FontCollection& Engine::GetFontCollection() { return font_collection_; }
FontCollection& Engine::GetFontCollection() { return font_collection_; }
void Engine::DoDispatchPacket(std::unique_ptr<PointerDataPacket> packet,
uint64_t trace_flow_id) {

8
engine/src/shell/common/engine.h


#include "flutter/fml/memory/weak_ptr.h"
#include "lib/ui/painting/image_decoder.h"
#include "lib/ui/snapshot_delegate.h"
//#include "lib/ui/text/font_collection.h"
#include "lib/ui/text/font_collection.h"
#include <flutter/fml/concurrent_message_loop.h>
#include "include/core/SkPicture.h"

[[nodiscard]] RunStatus Run(RunConfiguration configuration);
[[nodiscard]] bool Restart(RunConfiguration configuration);
void SetupDefaultFontManager();
bool UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager);

void ScheduleFrame(bool regenerate_layer_tree = true) override;
// |RuntimeDelegate|
// FontCollection& GetFontCollection() override;
FontCollection& GetFontCollection() override;
// |PointerDataDispatcher::Delegate|
void DoDispatchPacket(std::unique_ptr<PointerDataPacket> packet,

std::shared_ptr<AssetManager> asset_manager_;
bool activity_running_;
bool have_surface_;
// FontCollection font_collection_;
FontCollection font_collection_;
ImageDecoder image_decoder_;
TaskRunners task_runners_;
fml::WeakPtrFactory<Engine> weak_factory_;

22
engine/src/shell/common/shell.cc


#include "flutter/fml/unique_fd.h"
#include "include/core/SkGraphics.h"
#include "include/utils/SkBase64.h"
#include "lib/ui/text/icu_util.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "runtime/start_up.h"

}
if (settings.icu_initialization_required) {
// if (settings.icu_data_path.size() != 0) {
// fml::icu::InitializeICU(settings.icu_data_path);
//} else if (settings.icu_mapper) {
// fml::icu::InitializeICUFromMapping(settings.icu_mapper());
//} else {
// FML_DLOG(WARNING) << "Skipping ICU initialization in the shell.";
//}
if (settings.icu_data_path.length() > 0) {
uiwidgets::icu::InitializeICU(settings.icu_data_path);
} else if (settings.icu_mapper) {
uiwidgets::icu::InitializeICUFromMapping(settings.icu_mapper());
} else {
FML_DLOG(WARNING) << "Skipping ICU initialization in the shell.";
}
}
});
}

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

1
engine/src/shell/platform/embedder/embedder.cc


Settings settings; // = SettingsFromCommandLine(command_line);
settings.icu_data_path = icu_data_path;
settings.icu_mapper = args->icu_mapper;
settings.assets_path = args->assets_path;
settings.task_observer_add = [task_observer_add = args->task_observer_add,

2
engine/src/shell/platform/embedder/embedder.h


#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "src/common/settings.h"
#if defined(__cplusplus)
extern "C" {

size_t struct_size;
const char* assets_path;
const char* icu_data_path;
uiwidgets::MappingCallback icu_mapper;
int command_line_argc;
const char* const* command_line_argv;
UIWidgetsPlatformMessageCallback platform_message_callback;

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


#include "lib/ui/window/viewport_metrics.h"
#include "runtime/mono_api.h"
#include "shell/platform/embedder/embedder_engine.h"
#include "shell/common/switches.h"
#include "uiwidgets_system.h"
#include "unity_external_texture_gl.h"

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.icu_mapper = GetICUStaticMapping;
// Used for IOS build
// std::string icu_symbol_prefix = "_binary_icudtl_dat_start";
// std::string native_lib_path =
// "pathtodll/Plugins/x86_64/libUIWidgets_d.dll"; args.icu_mapper =
// [icu_symbol_prefix, native_lib_path] {
// return GetSymbolMapping(icu_symbol_prefix, native_lib_path);
// };
args.command_line_argc = 0;
args.command_line_argv = nullptr;

198
Samples/UIWidgetsSamples_2019_4/Assets/TextTest.cs


using System;
using System.Collections.Generic;
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 TextBaseline = Unity.UIWidgets.ui2.TextBaseline;
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,
strutStyle: new StrutStyle(fontFamily: "ranchers",
fontFamilyFallback: new List<string>() {"Roboto-RegularB"},
fontSize: 30),
ellipsis: "and so on..."
);
var pb = new ParagraphBuilder(style);
pb.addText("just for testxxx\n");
var ts_roboto_regular = new TextStyle(
color: new Color(0xF000000F),
decoration: TextDecoration.lineThrough,
decorationStyle: TextDecorationStyle.doubleLine,
fontFamily: "Roboto-Regular",
fontFamilyFallback: new List<string>() {"ranchers"},
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");
pb.addPlaceholder(10, 10, PlaceholderAlignment.baseline, TextBaseline.alphabetic);
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();
}
}

641
Samples/UIWidgetsSamples_2019_4/Assets/TextTest.unity


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &764046566
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 764046568}
- component: {fileID: 764046567}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &764046567
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 764046566}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &764046568
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 764046566}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &847097468
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 847097469}
- component: {fileID: 847097471}
- component: {fileID: 847097470}
m_Layer: 5
m_Name: RawImage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &847097469
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 847097468}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2122288190}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -1.3, y: 0.8}
m_SizeDelta: {x: 483, y: 399}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &847097470
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 847097468}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: db61290d6ca38264995f5749021d562c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!222 &847097471
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 847097468}
m_CullTransparentMesh: 0
--- !u!1 &1140493537
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1140493542}
- component: {fileID: 1140493541}
- component: {fileID: 1140493540}
- component: {fileID: 1140493539}
- component: {fileID: 1140493538}
m_Layer: 0
m_Name: Plane
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!114 &1140493538
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1140493537}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ff655c85f67513d4d9e0967df8685a48, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!64 &1140493539
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1140493537}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 4
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &1140493540
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1140493537}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &1140493541
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1140493537}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1140493542
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1140493537}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1548023132
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1548023135}
- component: {fileID: 1548023134}
- component: {fileID: 1548023133}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1548023133
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1548023132}
m_Enabled: 1
--- !u!20 &1548023134
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1548023132}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5.6
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1548023135
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1548023132}
m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0}
m_LocalPosition: {x: 0, y: 1, z: 0.32}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 90, y: 180, z: 0}
--- !u!1 &1900497009
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1900497012}
- component: {fileID: 1900497011}
- component: {fileID: 1900497010}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1900497010
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1900497009}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1900497011
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1900497009}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1900497012
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1900497009}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2122288186
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2122288190}
- component: {fileID: 2122288189}
- component: {fileID: 2122288188}
- component: {fileID: 2122288187}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2122288187
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2122288186}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &2122288188
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2122288186}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &2122288189
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2122288186}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &2122288190
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2122288186}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 847097469}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}

1001
com.unity.uiwidgets/Runtime/ui2/text.cs
文件差异内容过多而无法显示
查看文件

9
engine/src/shell/common/lists.cc


#pragma once
#include "lists.h"
namespace uiwidgets {
namespace {
UIWIDGETS_API(void) Lists_Free(void* data) { free(data); } // namespace
} // namespace
} // namespace uiwidgets

9
engine/src/shell/common/lists.h


#pragma once
#include "runtime/mono_api.h"
namespace uiwidgets {
struct Float32List {
float* data;
int length;
};
} // namespace uiwidgets

42
engine/src/shell/common/switches.cc


#include "switches.h"
#include <cstdint>
namespace uiwidgets {
extern "C" uint8_t _binary_icudtl_dat_start[];
extern "C" uint8_t _binary_icudtl_dat_end[];
std::unique_ptr<fml::Mapping> GetICUStaticMapping() {
return std::make_unique<fml::NonOwnedMapping>(
_binary_icudtl_dat_start,
_binary_icudtl_dat_end - _binary_icudtl_dat_start);
}
std::unique_ptr<fml::Mapping> GetSymbolMapping(std::string symbol_prefix,
std::string native_lib_path) {
const uint8_t* mapping;
intptr_t size;
auto lookup_symbol = [&mapping, &size, symbol_prefix](
const fml::RefPtr<fml::NativeLibrary>& library) {
mapping = library->ResolveSymbol((symbol_prefix + "_start").c_str());
size = reinterpret_cast<intptr_t>(
library->ResolveSymbol((symbol_prefix + "_size").c_str()));
};
fml::RefPtr<fml::NativeLibrary> library =
fml::NativeLibrary::CreateForCurrentProcess();
lookup_symbol(library);
if (!(mapping && size)) {
// Symbol lookup for the current process fails on some devices. As a
// fallback, try doing the lookup based on the path to the Flutter library.
library = fml::NativeLibrary::Create(native_lib_path.c_str());
lookup_symbol(library);
}
FML_CHECK(mapping && size) << "Unable to resolve symbols: " << symbol_prefix;
return std::make_unique<fml::NonOwnedMapping>(mapping, size);
}
} // namespace uiwidgets

10
engine/src/shell/common/switches.h


#pragma once
#include <flutter/fml/memory/ref_counted.h>
#include "flutter/fml/mapping.h"
namespace uiwidgets {
std::unique_ptr<fml::Mapping> GetICUStaticMapping();
std::unique_ptr<fml::Mapping> GetSymbolMapping(std::string symbol_prefix,
std::string native_lib_path);
} // namespace uiwidgets

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
文件差异内容过多而无法显示
查看文件

228
engine/src/lib/ui/text/paragraph.cc


#pragma once
#include "paragraph.h"
namespace uiwidgets {
Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraph(std::move(paragraph)) {}
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;
}
float Paragraph::width() { return m_paragraph->GetMaxWidth(); }
float Paragraph::height() { return m_paragraph->GetHeight(); }
float Paragraph::longestLine() { return m_paragraph->GetLongestLine(); }
float Paragraph::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
float Paragraph::maxIntrinsicWidth() {
return m_paragraph->GetMaxIntrinsicWidth();
}
float Paragraph::alphabeticBaseline() {
return m_paragraph->GetAlphabeticBaseline();
}
float Paragraph::ideographicBaseline() {
return m_paragraph->GetIdeographicBaseline();
}
bool Paragraph::didExceedMaxLines() { return m_paragraph->DidExceedMaxLines(); }
void Paragraph::layout(float width) { m_paragraph->Layout(width); }
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.
int size = boxes.size() * 5;
Float32List result = {(float*)malloc(sizeof(float) * size),
boxes.size() * size};
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;
}
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[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);
}
Float32List Paragraph::getRectsForPlaceholders() {
std::vector<txt::Paragraph::TextBox> boxes =
m_paragraph->GetRectsForPlaceholders();
return EncodeTextBoxes(boxes);
}
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;
}
Float32List Paragraph::computeLineMetrics() {
std::vector<txt::LineMetrics> metrics = m_paragraph->GetLineMetrics();
// Layout:
// boxes.size() groups of 9 which are the line metrics
// properties
int size = metrics.size() * 9;
Float32List result = {(float*)malloc(sizeof(float) * size), size};
unsigned long position = 0;
for (unsigned long i = 0; i < metrics.size(); i++) {
const txt::LineMetrics& line = metrics[i];
result.data[position++] = static_cast<float>(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<float>(line.line_number);
}
return result;
}
UIWIDGETS_API(float) Paragraph_width(Paragraph* ptr) { return ptr->width(); }
UIWIDGETS_API(float) Paragraph_height(Paragraph* ptr) { return ptr->height(); }
UIWIDGETS_API(float) Paragraph_longestLine(Paragraph* ptr) {
return ptr->longestLine();
}
UIWIDGETS_API(float) Paragraph_minIntrinsicWidth(Paragraph* ptr) {
return ptr->minIntrinsicWidth();
}
UIWIDGETS_API(float) Paragraph_maxIntrinsicWidth(Paragraph* ptr) {
return ptr->maxIntrinsicWidth();
}
UIWIDGETS_API(float) Paragraph_alphabeticBaseline(Paragraph* ptr) {
return ptr->alphabeticBaseline();
}
UIWIDGETS_API(float) Paragraph_ideographicBaseline(Paragraph* ptr) {
return ptr->ideographicBaseline();
}
UIWIDGETS_API(bool) Paragraph_didExceedMaxLines(Paragraph* ptr) {
return ptr->didExceedMaxLines();
}
UIWIDGETS_API(void) Paragraph_layout(Paragraph* ptr, float width) {
ptr->layout(width);
}
UIWIDGETS_API(Float32List)
Paragraph_getRectsForRange(Paragraph* ptr, int start, int end,
int boxHeightStyle, int boxWidthStyle) {
return ptr->getRectsForRange(start, end, boxHeightStyle, boxWidthStyle);
}
UIWIDGETS_API(Float32List)
Paragraph_getRectsForPlaceholders(Paragraph* ptr) {
return ptr->getRectsForPlaceholders();
}
UIWIDGETS_API(void)
Paragraph_getPositionForOffset(Paragraph* ptr, float dx, float dy,
int* offset) {
return ptr->getPositionForOffset(dx, dy, offset);
}
UIWIDGETS_API(void)
Paragraph_getWordBoundary(Paragraph* ptr, int offset, int* boundaryPtr) {
ptr->getWordBoundary(offset, boundaryPtr);
}
UIWIDGETS_API(void)
Paragraph_getLineBoundary(Paragraph* ptr, int offset, int* boundaryPtr) {
ptr->getLineBoundary(offset, boundaryPtr);
}
UIWIDGETS_API(void)
Paragraph_paint(Paragraph* ptr, Canvas* canvas, float x, float y) {
ptr->paint(canvas, x, y);
}
UIWIDGETS_API(Float32List)
Paragraph_computeLineMetrics(Paragraph* ptr, float* data) {
return ptr->computeLineMetrics();
}
UIWIDGETS_API(void) Paragraph_dispose(Paragraph* ptr) { ptr->Release(); }
} // namespace uiwidgets

50
engine/src/lib/ui/text/paragraph.h


#pragma once
#include "flutter/fml/memory/ref_counted.h"
#include "txt/paragraph.h"
#include "shell/common/lists.h"
#include "lib/ui/painting/canvas.h"
#include "lib/ui/ui_mono_state.h"
namespace uiwidgets {
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));
}
~Paragraph();
float width();
float height();
float longestLine();
float minIntrinsicWidth();
float maxIntrinsicWidth();
float alphabeticBaseline();
float ideographicBaseline();
bool didExceedMaxLines();
void layout(float width);
void paint(Canvas* canvas, float x, float y);
Float32List getRectsForRange(unsigned start, unsigned end,
unsigned boxHeightStyle, unsigned boxWidthStyle);
Float32List getRectsForPlaceholders();
void getPositionForOffset(float dx, float dy, int* offset);
void getWordBoundary(unsigned offset, int* boundaryPtr);
void getLineBoundary(unsigned offset, int* boundaryPtr);
Float32List computeLineMetrics();
size_t GetAllocationSize();
std::unique_ptr<txt::Paragraph> m_paragraph;
private:
explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);
};
} // namespace uiwidgets

49
engine/src/lib/ui/text/paragraph_builder.h


#pragma once
#include "flutter/fml/memory/ref_counted.h"
#include "txt/paragraph.h"
#include "txt/paragraph_builder.h"
#include "font_collection.h"
#include "paragraph.h"
#include "lib/ui/painting/canvas.h"
namespace uiwidgets {
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, float fontSize,
float height, const std::u16string& ellipsis, const std::string& locale);
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);
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();
void pop();
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

129
engine/src/lib/ui/text/asset_manager_font_provider.cc


#pragma once
#include "asset_manager_font_provider.h"
#include "flutter/fml/logging.h"
#include "include/core/SkData.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
namespace uiwidgets {
namespace {
void MappingReleaseProc(const void* ptr, void* context) {
delete reinterpret_cast<fml::Mapping*>(context);
}
} // anonymous namespace
AssetManagerFontProvider::AssetManagerFontProvider(
std::shared_ptr<AssetManager> asset_manager)
: asset_manager_(asset_manager) {}
AssetManagerFontProvider::~AssetManagerFontProvider() = default;
// |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|
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);
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);
}
AssetManagerFontStyleSet::AssetManagerFontStyleSet(
std::shared_ptr<AssetManager> asset_manager, std::string family_name)
: asset_manager_(asset_manager), family_name_(family_name) {}
AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;
void AssetManagerFontStyleSet::registerAsset(std::string asset) {
assets_.emplace_back(asset);
}
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();
}
}
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;
}
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;
}
return SkRef(asset.typeface.get());
}
SkTypeface* AssetManagerFontStyleSet::matchStyle(const SkFontStyle& pattern) {
return matchStyleCSS3(pattern);
}
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(std::string a)
: asset(std::move(a)) {}
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(
const AssetManagerFontStyleSet::TypefaceAsset& other) = default;
AssetManagerFontStyleSet::TypefaceAsset::~TypefaceAsset() = default;
} // namespace uiwidgets

82
engine/src/lib/ui/text/asset_manager_font_provider.h


#pragma once
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "assets/asset_manager.h"
#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "txt/font_asset_provider.h"
namespace uiwidgets {
class AssetManagerFontStyleSet : public SkFontStyleSet {
public:
AssetManagerFontStyleSet(std::shared_ptr<AssetManager> asset_manager,
std::string family_name);
~AssetManagerFontStyleSet() override;
void registerAsset(std::string asset);
// |SkFontStyleSet|
int count() override;
// |SkFontStyleSet|
void getStyle(int index, SkFontStyle*, SkString* style) override;
// |SkFontStyleSet|
SkTypeface* createTypeface(int index) override;
// |SkFontStyleSet|
SkTypeface* matchStyle(const SkFontStyle& pattern) override;
private:
std::shared_ptr<AssetManager> asset_manager_;
std::string family_name_;
struct TypefaceAsset {
TypefaceAsset(std::string a);
TypefaceAsset(const TypefaceAsset& other);
~TypefaceAsset();
std::string asset;
sk_sp<SkTypeface> typeface;
};
std::vector<TypefaceAsset> assets_;
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontStyleSet);
};
class AssetManagerFontProvider : public txt::FontAssetProvider {
public:
AssetManagerFontProvider(std::shared_ptr<AssetManager> asset_manager);
~AssetManagerFontProvider() override;
void RegisterAsset(std::string family_name, std::string asset);
// |FontAssetProvider|
size_t GetFamilyCount() const override;
// |FontAssetProvider|
std::string GetFamilyName(int index) const override;
// |FontAssetProvider|
SkFontStyleSet* MatchFamily(const std::string& family_name) override;
private:
std::shared_ptr<AssetManager> asset_manager_;
std::unordered_map<std::string, sk_sp<AssetManagerFontStyleSet>>
registered_families_;
std::vector<std::string> family_names_;
FML_DISALLOW_COPY_AND_ASSIGN(AssetManagerFontProvider);
};
} // namespace uiwidgets

129
engine/src/lib/ui/text/font_collection.cc


#pragma once
#include "font_collection.h"
#include <mutex>
#include "include/core/SkFontMgr.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "asset_manager_font_provider.h"
#include "lib/ui/ui_mono_state.h"
#include "lib/ui/window/window.h"
#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"
#include "txt/asset_font_manager.h"
#include "txt/test_font_manager.h"
namespace uiwidgets {
namespace {
typedef void (*LoadFontCallback)(Mono_Handle callback_handle);
UIWIDGETS_API(void)
Font_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);
}
} // namespace
FontCollection::FontCollection()
: collection_(std::make_shared<txt::FontCollection>()) {
dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
collection_->SetDynamicFontManager(dynamic_font_manager_);
}
FontCollection::~FontCollection() {
collection_.reset();
SkGraphics::PurgeFontCache();
}
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;
}
if (!document.IsArray()) {
return;
}
auto font_provider =
std::make_unique<AssetManagerFontProvider>(asset_manager);
for (const auto& family : document.GetArray()) {
auto family_name = family.FindMember("family");
if (family_name == family.MemberEnd() || !family_name->value.IsString()) {
continue;
}
auto family_fonts = family.FindMember("fonts");
if (family_fonts == family.MemberEnd() || !family_fonts->value.IsArray()) {
continue;
}
for (const auto& family_font : family_fonts->value.GetArray()) {
if (!family_font.IsObject()) {
continue;
}
auto font_asset = family_font.FindMember("asset");
if (font_asset == family_font.MemberEnd() ||
!font_asset->value.IsString()) {
continue;
}
// TODO: Handle weights and styles.
font_provider->RegisterAsset(family_name->value.GetString(),
font_asset->value.GetString());
}
}
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 uiwidgets

35
engine/src/lib/ui/text/font_collection.h


#pragma once
#include <memory>
#include <vector>
#include "assets/asset_manager.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "txt/font_collection.h"
namespace uiwidgets {
class FontCollection {
public:
FontCollection();
~FontCollection();
std::shared_ptr<txt::FontCollection> GetFontCollection() const;
void SetupDefaultFontManager();
void RegisterFonts(std::shared_ptr<AssetManager> asset_manager);
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_;
FML_DISALLOW_COPY_AND_ASSIGN(FontCollection);
};
} // namespace uiwidgets

116
engine/src/lib/ui/text/icu_util.cc


#pragma once
#include "icu_util.h"
#include <memory>
#include <mutex>
#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "unicode/udata.h"
namespace uiwidgets {
namespace icu {
class ICUContext {
public:
ICUContext(const std::string& icu_data_path) : valid_(false) {
valid_ = SetupMapping(icu_data_path) && SetupICU();
}
ICUContext(std::unique_ptr<fml::Mapping> mapping)
: mapping_(std::move(mapping)) {
valid_ = SetupICU();
}
~ICUContext() = default;
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 (!directory.first) {
return false;
}
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);
}
if (!fd.is_valid()) {
return false;
}
std::initializer_list<fml::FileMapping::Protection> protection = {
fml::FileMapping::Protection::kRead};
auto file_mapping =
std::make_unique<fml::FileMapping>(fd, std::move(protection));
if (file_mapping->GetSize() != 0) {
mapping_ = std::move(file_mapping);
return true;
}
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);
}
const uint8_t* GetMapping() const {
return mapping_ ? mapping_->GetMapping() : nullptr;
}
size_t GetSize() const { return mapping_ ? mapping_->GetSize() : 0; }
bool IsValid() const { return valid_; }
private:
bool valid_;
std::unique_ptr<fml::Mapping> mapping_;
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;
}
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<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<fml::Mapping> mapping) {
std::call_once(g_icu_init_flag, [mapping = std::move(mapping)]() mutable {
InitializeICUFromMappingOnce(std::move(mapping));
});
}
} // namespace icu
} // namespace uiwidgets

15
engine/src/lib/ui/text/icu_util.h


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

489
engine/src/lib/ui/text/paragraph_builder.cc


#pragma once
#include "paragraph_builder.h"
#include "lib/ui/ui_mono_state.h"
#include "unicode/ustring.h"
namespace uiwidgets {
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;
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;
// ParagraphStyle
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;
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;
// TextShadows decoding
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;
// FontFeature decoding
constexpr uint32_t kBytesPerFontFeature = 8;
constexpr uint32_t kFontFeatureTagLength = 4;
// 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;
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;
} // namespace
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);
}
void decodeTextShadows(uint8_t* shadows_data, int shadow_data_size,
std::vector<txt::TextShadow>& decoded_shadows) {
decoded_shadows.clear();
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);
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]);
}
}
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;
}
if (struct_data_size == 0) {
return;
}
paragraph_style.strut_enabled = true;
const uint8_t* uint8_data = static_cast<const uint8_t*>(strut_data);
uint8_t mask = uint8_data[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++]);
}
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;
}
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("");
}
}
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 & psTextDirectionMask) {
style.text_direction = txt::TextDirection(encoded[psTextDirectionIndex]);
}
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 & psFontFamilyMask) {
style.font_family = fontFamily;
}
if (mask & psFontSizeMask) {
style.font_size = fontSize;
}
if (mask & psHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & psTextHeightBehaviorMask) {
style.text_height_behavior = encoded[psTextHeightBehaviorIndex];
}
if (mask & psStrutStyleMask) {
decodeStrut(strutData, strutData_size, strutFontFamilies, style);
}
if (mask & psMaxLinesMask) {
style.max_lines = encoded[psMaxLinesIndex];
}
if (mask & psEllipsisMask) {
style.ellipsis = ellipsis;
}
if (mask & psLocaleMask) {
style.locale = locale;
}
FontCollection& font_collection =
UIMonoState::Current()->window()->client()->GetFontCollection();
m_paragraphBuilder = txt::ParagraphBuilder::CreateTxtBuilder(
style, font_collection.GetFontCollection());
}
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);
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,
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);
int32_t mask = encoded[0];
// Set to use the properties of the previous style if the property is not
// explicitly given.
txt::TextStyle style = m_paragraphBuilder->PeekStyle();
// 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 & tsTextDecorationMask) {
style.decoration =
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
}
if (mask & tsTextDecorationColorMask) {
style.decoration_color = encoded[tsTextDecorationColorIndex];
}
if (mask & tsTextDecorationStyleMask) {
style.decoration_style = static_cast<txt::TextDecorationStyle>(
encoded[tsTextDecorationStyleIndex]);
}
if (mask & tsTextDecorationThicknessMask) {
style.decoration_thickness_multiplier = decorationThickness;
}
if (mask & tsTextBaselineMask) {
// TODO(abarth): Implement TextBaseline. The CSS version of this
// property wasn't wired up either.
}
if (mask & (tsFontWeightMask | tsFontStyleMask | tsFontSizeMask |
tsLetterSpacingMask | tsWordSpacingMask)) {
if (mask & tsFontWeightMask)
style.font_weight =
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
if (mask & tsFontStyleMask)
style.font_style = static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
if (mask & tsFontSizeMask) style.font_size = fontSize;
if (mask & tsLetterSpacingMask) style.letter_spacing = letterSpacing;
if (mask & tsWordSpacingMask) style.word_spacing = wordSpacing;
}
if (mask & tsHeightMask) {
style.height = height;
style.has_height_override = true;
}
if (mask & tsLocaleMask) {
style.locale = locale;
}
if (mask & tsBackgroundMask) {
Paint background(background_objects, background_data);
if (background.paint()) {
style.has_background = true;
style.background = *background.paint();
}
}
if (mask & tsForegroundMask) {
Paint foreground(foreground_objects, foreground_data);
if (foreground.paint()) {
style.has_foreground = true;
style.foreground = *foreground.paint();
}
}
if (mask & tsTextShadowsMask) {
decodeTextShadows(shadows_data, shadow_data_size, style.text_shadows);
}
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 & tsFontFeaturesMask) {
decodeFontFeatures(font_features_data, font_feature_data_size,
style.font_features);
}
m_paragraphBuilder->PushStyle(style);
}
void ParagraphBuilder::pop() { m_paragraphBuilder->Pop(); }
const char* ParagraphBuilder::addText(const std::u16string& text) {
if (text.empty()) return nullptr;
// 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";
m_paragraphBuilder->AddText(text);
return nullptr;
}
fml::RefPtr<Paragraph> ParagraphBuilder::build(
/*Dart_Handle paragraph_handle*/) {
return Paragraph::Create(/*paragraph_handle,*/ m_paragraphBuilder->Build());
}
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);
m_paragraphBuilder->AddPlaceholder(placeholder_run);
return nullptr;
}
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_dispose(Canvas* ptr) { ptr->Release(); }
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_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) {
auto paragraph = ptr->build();
paragraph->AddRef();
return paragraph.get();
}
} // namespace uiwidgets
正在加载...
取消
保存